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

Loading…
Cancel
Save