Browse Source

Reworked the ASTRecord functionality.

pull/144/head
triton 12 years ago
parent
commit
f0cb4b4c51
  1. 71
      src/Generator/AST/ASTRecord.cs

71
src/Generator/AST/ASTRecord.cs

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using Type = CppSharp.AST.Type;
@ -9,6 +9,7 @@ namespace CppSharp.Generators.AST @@ -9,6 +9,7 @@ namespace CppSharp.Generators.AST
{
public ASTRecord Parent;
public object Object;
public bool Visited;
public bool GetParent<T>(out T @out)
{
@ -25,7 +26,19 @@ namespace CppSharp.Generators.AST @@ -25,7 +26,19 @@ namespace CppSharp.Generators.AST
return true;
}
// Pushes ancestors into the stack until it is found one of type T.
// Finds the first ancestor of type T.
public ASTRecord FindAncestor<T>()
{
if (Parent == null)
return null;
if (Parent.Object is T)
return Parent;
return Parent.FindAncestor<T>();
}
// Pushes ancestors into the stack until it has found one of type T.
public bool GetAncestors<T>(ref Stack<object> ancestors)
{
ancestors.Push(this);
@ -76,6 +89,7 @@ namespace CppSharp.Generators.AST @@ -76,6 +89,7 @@ namespace CppSharp.Generators.AST
Parent = parent,
Object = value
};
recordStack.Push(record);
return record;
}
@ -84,6 +98,25 @@ namespace CppSharp.Generators.AST @@ -84,6 +98,25 @@ namespace CppSharp.Generators.AST
{
recordStack.Pop();
}
public bool Contains(object decl)
{
return recordStack.Any(rec => decl == rec.Object);
}
public bool IsBeingVisited(Declaration decl)
{
var record = recordStack.FirstOrDefault(rec => decl == rec.Object);
if (record != null)
{
var isBeingVisited = record.Visited;
record.Visited = true;
return isBeingVisited;
}
return false;
}
}
static class ASTRecordExtensions
@ -91,7 +124,11 @@ namespace CppSharp.Generators.AST @@ -91,7 +124,11 @@ namespace CppSharp.Generators.AST
public static bool IsBaseClass(this ASTRecord record)
{
Class decl;
return record.GetParent(out decl) && decl.BaseClass == record.Object;
if (!record.GetParent(out decl))
return false;
var recordDecl = record.Object as Class;
return recordDecl != null && recordDecl == decl.BaseClass;
}
public static bool IsFieldValueType(this ASTRecord record)
@ -103,10 +140,7 @@ namespace CppSharp.Generators.AST @@ -103,10 +140,7 @@ namespace CppSharp.Generators.AST
var field = (Field)ancestors.Pop();
Class decl;
if (!field.Type.Desugar().IsTagDecl(out decl))
return false;
return decl.IsValueType;
return field.Type.Desugar().IsTagDecl(out decl) && decl.IsValueType;
}
}
@ -115,20 +149,13 @@ namespace CppSharp.Generators.AST @@ -115,20 +149,13 @@ namespace CppSharp.Generators.AST
public readonly ISet<ASTRecord<Declaration>> Declarations;
private readonly ASTRecordStack recordStack;
public TranslationUnit translationUnit;
public ISet<object> Visited2 { get; private set; }
public bool AlreadyVisited2(object o)
{
return !Visited2.Add(o);
}
private readonly TranslationUnit translationUnit;
public RecordCollector(TranslationUnit translationUnit)
{
this.translationUnit = translationUnit;
Declarations = new HashSet<ASTRecord<Declaration>>();
recordStack = new ASTRecordStack();
Visited2 = new HashSet<object>();
}
public override bool VisitDeclaration(Declaration decl)
@ -136,9 +163,8 @@ namespace CppSharp.Generators.AST @@ -136,9 +163,8 @@ namespace CppSharp.Generators.AST
if (decl.IsIncomplete && decl.CompleteDeclaration != null)
decl = decl.CompleteDeclaration;
if(AlreadyVisited2(decl))
if (recordStack.Contains(decl))
return ShouldVisitChilds(decl);
Visited.Remove(decl); // So Class can be revisited
Declarations.Add(recordStack.Push(decl));
decl.Visit(this);
@ -151,7 +177,7 @@ namespace CppSharp.Generators.AST @@ -151,7 +177,7 @@ namespace CppSharp.Generators.AST
{
type = type.Desugar();
if(AlreadyVisited2(type))
if(recordStack.Contains(type))
return true;
recordStack.Push(type);
@ -169,11 +195,14 @@ namespace CppSharp.Generators.AST @@ -169,11 +195,14 @@ namespace CppSharp.Generators.AST
if (decl is TranslationUnit)
return false;
if (recordStack.IsBeingVisited(decl))
return false;
if (decl.Namespace == null)
return true;
// No need to continue visiting after a declaration of
// another translation unit is encountered.
// No need to continue visiting after a declaration of another
// translation unit is encountered.
return decl.Namespace.TranslationUnit == translationUnit;
}
}

Loading…
Cancel
Save