Browse Source

Optimized the walking of the managed AST.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1142/head
Dimitar Dobrev 7 years ago committed by João Matos
parent
commit
8427ff8e92
  1. 4
      src/AST/ClassExtensions.cs
  2. 67
      src/AST/DeclIterator.cs
  3. 145
      src/AST/DeclarationsList.cs
  4. 74
      src/AST/Namespace.cs
  5. 4
      src/Generator.Tests/AST/TestAST.cs
  6. 3
      src/Generator/Driver.cs
  7. 2
      src/Generator/Library.cs
  8. 4
      src/Generator/Passes/GenerateAbstractImplementationsPass.cs
  9. 2
      src/Generator/Passes/HandleDefaultParamValuesPass.cs
  10. 3
      src/Generator/Passes/MarkUsedClassInternalsPass.cs
  11. 2
      src/Generator/Passes/MultipleInheritancePass.cs
  12. 2
      src/Generator/Passes/ResolveIncompleteDeclsPass.cs
  13. 18
      src/Generator/Passes/SortDeclarationsPass.cs
  14. 16
      src/Parser/ASTConverter.cs

4
src/AST/ClassExtensions.cs

@ -184,13 +184,13 @@ namespace CppSharp.AST @@ -184,13 +184,13 @@ namespace CppSharp.AST
Class @interface = null;
if (specialization == null)
{
@interface = @class.Namespace.Classes.Find(
@interface = @class.Namespace.Classes.FirstOrDefault(
c => c.OriginalClass == @class && c.IsInterface);
}
else
{
Class template = specialization.TemplatedDecl.TemplatedClass;
Class templatedInterface = @class.Namespace.Classes.Find(
Class templatedInterface = @class.Namespace.Classes.FirstOrDefault(
c => c.OriginalClass == template && c.IsInterface);
if (templatedInterface != null)
@interface = templatedInterface.Specializations.FirstOrDefault(

67
src/AST/DeclIterator.cs

@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace CppSharp.AST
{
public struct DeclIterator<T> : IEnumerable<T> where T : Declaration
{
private readonly List<Declaration> Declarations;
public DeclIterator(List<Declaration> declarations)
{
Declarations = declarations;
}
public int Count
{
get { return Declarations.OfType<T>().ToArray().Length; }
}
public T this[int index]
{
get { return Declarations.OfType<T>().ToArray()[index]; }
}
public void Add(T declaration)
{
Declarations.Add(declaration);
}
public void AddRange(IEnumerable<T> range)
{
Declarations.AddRange(range);
}
public T Find(Func<T, bool> predicate)
{
return Declarations.OfType<T>().SingleOrDefault<T>(predicate);
}
public int FindIndex(Predicate<T> predicate)
{
return Declarations.OfType<T>().ToList().FindIndex(predicate);
}
public bool Exists(Func<T, bool> predicate)
{
return Declarations.OfType<T>().Any(predicate);
}
public IEnumerator<T> GetEnumerator()
{
return Declarations.OfType<T>().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Replace(T decl, T newDecl)
{
Declarations[Declarations.FindIndex(d => d == decl)] = newDecl;
}
}
}

145
src/AST/DeclarationsList.cs

@ -0,0 +1,145 @@ @@ -0,0 +1,145 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace CppSharp.AST
{
public class DeclarationsList : ObservableCollection<Declaration>
{
public IEnumerable<Namespace> Namespaces => OfType<Namespace>(Kind.Namespace);
public IEnumerable<Enumeration> Enums => OfType<Enumeration>(Kind.Enum);
public IEnumerable<Function> Functions => OfType<Function>(Kind.Function);
public IEnumerable<Class> Classes => OfType<Class>(Kind.Class);
public IEnumerable<Template> Templates => OfType<Template>(Kind.Template);
public IEnumerable<TypedefNameDecl> Typedefs => OfType<TypedefNameDecl>(Kind.Typedef);
public IEnumerable<Variable> Variables => OfType<Variable>(Kind.Variable);
public IEnumerable<Event> Events => OfType<Event>(Kind.Event);
public void AddRange(IEnumerable<Declaration> declarations)
{
foreach (Declaration declaration in declarations)
{
Add(declaration);
}
}
protected override void InsertItem(int index, Declaration item)
{
Kind kind = GetKind(item);
int offset = GetOffset(kind);
if (GetStart(kind) < index && index < offset)
{
base.InsertItem(index, item);
}
else
{
base.InsertItem(offset, item);
}
for (Kind i = kind; i <= Kind.Event; i++)
{
if (offsets.ContainsKey(i))
{
offsets[i]++;
}
}
}
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
for (Kind i = Kind.Namespace; i <= Kind.Event; i++)
{
if (offsets.ContainsKey(i) && index < offsets[i])
{
offsets[i]--;
}
}
}
private IEnumerable<T> OfType<T>(Kind kind) where T : Declaration
{
if (!offsets.ContainsKey(kind))
{
yield break;
}
int offset = offsets[kind];
for (int i = GetStart(kind); i < offset; i++)
{
yield return (T) this[i];
}
}
private static Kind GetKind(Declaration item)
{
if (item is Namespace)
return Kind.Namespace;
if (item is Enumeration)
return Kind.Enum;
if (item is Function)
return Kind.Function;
if (item is Class)
return Kind.Class;
if (item is Template)
return Kind.Template;
if (item is TypedefNameDecl)
return Kind.Typedef;
if (item is Variable)
return Kind.Variable;
if (item is Friend)
return Kind.Friend;
if (item is Event)
return Kind.Event;
throw new System.ArgumentOutOfRangeException(nameof(item),
"Unsupported type of declaration.");
}
private int GetOffset(Kind kind)
{
if (!offsets.ContainsKey(kind))
{
for (Kind i = kind - 1; i >= Kind.Namespace; i--)
{
if (offsets.ContainsKey(i))
{
return offsets[kind] = offsets[i];
}
}
offsets[kind] = 0;
}
return offsets[kind];
}
private int GetStart(Kind kind)
{
for (Kind i = kind - 1; i >= Kind.Namespace; i--)
{
if (offsets.ContainsKey(i))
{
return offsets[i];
}
}
return 0;
}
private Dictionary<Kind, int> offsets = new Dictionary<Kind, int>();
private enum Kind
{
Namespace,
Enum,
Function,
Class,
Template,
Typedef,
Variable,
Friend,
Event
}
}
}

74
src/AST/Namespace.cs

@ -11,48 +11,24 @@ namespace CppSharp.AST @@ -11,48 +11,24 @@ namespace CppSharp.AST
{
public bool IsAnonymous { get; set; }
public List<Declaration> Declarations;
public DeclarationsList Declarations;
public List<TypeReference> TypeReferences;
public DeclIterator<Namespace> Namespaces
{
get { return new DeclIterator<Namespace>(Declarations); }
}
public IEnumerable<Namespace> Namespaces => Declarations.Namespaces;
public DeclIterator<Enumeration> Enums
{
get { return new DeclIterator<Enumeration>(Declarations); }
}
public IEnumerable<Enumeration> Enums => Declarations.Enums;
public DeclIterator<Function> Functions
{
get { return new DeclIterator<Function>(Declarations); }
}
public IEnumerable<Function> Functions => Declarations.Functions;
public DeclIterator<Class> Classes
{
get { return new DeclIterator<Class>(Declarations); }
}
public IEnumerable<Class> Classes => Declarations.Classes;
public DeclIterator<Template> Templates
{
get { return new DeclIterator<Template>(Declarations); }
}
public IEnumerable<Template> Templates => Declarations.Templates;
public DeclIterator<TypedefNameDecl> Typedefs
{
get { return new DeclIterator<TypedefNameDecl>(Declarations); }
}
public IEnumerable<TypedefNameDecl> Typedefs => Declarations.Typedefs;
public DeclIterator<Variable> Variables
{
get { return new DeclIterator<Variable>(Declarations); }
}
public IEnumerable<Variable> Variables => Declarations.Variables;
public DeclIterator<Event> Events
{
get { return new DeclIterator<Event>(Declarations); }
}
public IEnumerable<Event> Events => Declarations.Events;
// Used to keep track of anonymous declarations.
public Dictionary<ulong, Declaration> Anonymous;
@ -72,7 +48,7 @@ namespace CppSharp.AST @@ -72,7 +48,7 @@ namespace CppSharp.AST
protected DeclarationContext()
{
Declarations = new List<Declaration>();
Declarations = new DeclarationsList();
TypeReferences = new List<TypeReference>();
Anonymous = new Dictionary<ulong, Declaration>();
}
@ -121,7 +97,7 @@ namespace CppSharp.AST @@ -121,7 +97,7 @@ namespace CppSharp.AST
foreach (var @namespace in namespaces)
{
var childNamespace = currentNamespace.Namespaces.Find(
var childNamespace = currentNamespace.Namespaces.FirstOrDefault(
e => e.Name.Equals(@namespace));
if (childNamespace == null)
@ -145,7 +121,7 @@ namespace CppSharp.AST @@ -145,7 +121,7 @@ namespace CppSharp.AST
Namespace = this,
};
Namespaces.Add(@namespace);
Declarations.Add(@namespace);
}
return @namespace;
@ -158,12 +134,12 @@ namespace CppSharp.AST @@ -158,12 +134,12 @@ namespace CppSharp.AST
if (entries.Count <= 1)
{
var @enum = Enums.Find(e => e.Name.Equals(name));
var @enum = Enums.FirstOrDefault(e => e.Name.Equals(name));
if (@enum == null && createDecl)
{
@enum = new Enumeration() { Name = name, Namespace = this };
Enums.Add(@enum);
Declarations.Add(@enum);
}
return @enum;
@ -194,12 +170,12 @@ namespace CppSharp.AST @@ -194,12 +170,12 @@ namespace CppSharp.AST
if (entries.Count <= 1)
{
var function = Functions.Find(e => e.Name.Equals(name));
var function = Functions.FirstOrDefault(e => e.Name.Equals(name));
if (function == null && createDecl)
{
function = new Function() { Name = name, Namespace = this };
Functions.Add(function);
Declarations.Add(function);
}
return function;
@ -240,7 +216,7 @@ namespace CppSharp.AST @@ -240,7 +216,7 @@ namespace CppSharp.AST
{
if (string.IsNullOrEmpty(name)) return null;
var @class = Classes.Find(c => c.Name.Equals(name, stringComparison)) ??
var @class = Classes.FirstOrDefault(c => c.Name.Equals(name, stringComparison)) ??
Namespaces.Select(n => n.FindClass(name, stringComparison)).FirstOrDefault(c => c != null);
if (@class != null)
return @class.CompleteDeclaration == null ?
@ -258,7 +234,7 @@ namespace CppSharp.AST @@ -258,7 +234,7 @@ namespace CppSharp.AST
if (createDecl)
{
@class = CreateClass(name, isComplete);
Classes.Add(@class);
Declarations.Add(@class);
}
return @class;
@ -276,7 +252,7 @@ namespace CppSharp.AST @@ -276,7 +252,7 @@ namespace CppSharp.AST
if (@class.IsIncomplete)
{
@class.CompleteDeclaration = newClass;
Classes.Replace(@class, newClass);
Declarations[Declarations.IndexOf(@class)] = newClass;
}
return newClass;
@ -316,12 +292,12 @@ namespace CppSharp.AST @@ -316,12 +292,12 @@ namespace CppSharp.AST
if (entries.Count <= 1)
{
var typeDef = Typedefs.Find(e => e.Name.Equals(name));
var typeDef = Typedefs.FirstOrDefault(e => e.Name.Equals(name));
if (typeDef == null && createDecl)
{
typeDef = new TypedefDecl { Name = name, Namespace = this };
Typedefs.Add(typeDef);
Declarations.Add(typeDef);
}
return typeDef;
@ -349,7 +325,7 @@ namespace CppSharp.AST @@ -349,7 +325,7 @@ namespace CppSharp.AST
public Enumeration FindEnumWithItem(string name)
{
return Enums.Find(e => e.ItemsByName.ContainsKey(name)) ??
return Enums.FirstOrDefault(e => e.ItemsByName.ContainsKey(name)) ??
(from declContext in Namespaces.Union<DeclarationContext>(Classes)
let @enum = declContext.FindEnumWithItem(name)
where @enum != null
@ -374,8 +350,8 @@ namespace CppSharp.AST @@ -374,8 +350,8 @@ namespace CppSharp.AST
get
{
Func<Declaration, bool> pred = (t => t.IsGenerated);
return Enums.Exists(pred) || HasFunctions || Typedefs.Exists(pred)
|| Classes.Any() || Namespaces.Exists(n => n.HasDeclarations) ||
return Enums.Any(pred) || HasFunctions || Typedefs.Any(pred)
|| Classes.Any() || Namespaces.Any(n => n.HasDeclarations) ||
Templates.Any(pred);
}
}
@ -385,7 +361,7 @@ namespace CppSharp.AST @@ -385,7 +361,7 @@ namespace CppSharp.AST
get
{
Func<Declaration, bool> pred = (t => t.IsGenerated);
return Functions.Exists(pred) || Namespaces.Exists(n => n.HasFunctions);
return Functions.Any(pred) || Namespaces.Any(n => n.HasFunctions);
}
}

4
src/Generator.Tests/AST/TestAST.cs

@ -246,7 +246,7 @@ namespace CppSharp.Generator.Tests.AST @@ -246,7 +246,7 @@ namespace CppSharp.Generator.Tests.AST
{
var @class = AstContext.FindClass("TestTemplateFunctions").FirstOrDefault();
Assert.IsNotNull(@class, "Couldn't find TestTemplateFunctions class.");
Assert.AreEqual(6, @class.Templates.Count);
Assert.AreEqual(6, @class.Templates.Count());
var twoParamMethodTemplate = @class.Templates.OfType<FunctionTemplate>()
.FirstOrDefault(t => t.Name == "MethodTemplateWithTwoTypeParameter");
Assert.IsNotNull(twoParamMethodTemplate);
@ -533,7 +533,7 @@ namespace CppSharp.Generator.Tests.AST @@ -533,7 +533,7 @@ namespace CppSharp.Generator.Tests.AST
{
var template = AstContext.FindDecl<ClassTemplate>("TestTemplateClass").First();
var cppTypePrinter = new CppTypePrinter { PrintScopeKind = TypePrintScopeKind.Qualified };
Assert.That(template.Specializations[3].Classes[0].Visit(cppTypePrinter),
Assert.That(template.Specializations[3].Classes.First().Visit(cppTypePrinter),
Is.EqualTo("TestTemplateClass<Math::Complex>::NestedInTemplate"));
}

3
src/Generator/Driver.cs

@ -212,8 +212,7 @@ namespace CppSharp @@ -212,8 +212,7 @@ namespace CppSharp
public void SetupPasses(ILibrary library)
{
var TranslationUnitPasses = Context.TranslationUnitPasses;
TranslationUnitPasses.AddPass(new SortDeclarationsPass());
TranslationUnitPasses.AddPass(new ResolveIncompleteDeclsPass());
TranslationUnitPasses.AddPass(new IgnoreSystemDeclarationsPass());
if (Options.IsCSharpGenerator)

2
src/Generator/Library.cs

@ -172,7 +172,7 @@ namespace CppSharp @@ -172,7 +172,7 @@ namespace CppSharp
if (@enum.Items.Count > 0)
{
unit.Enums.Add(@enum);
unit.Declarations.Add(@enum);
break;
}
}

4
src/Generator/Passes/GenerateAbstractImplementationsPass.cs

@ -24,9 +24,9 @@ namespace CppSharp.Passes @@ -24,9 +24,9 @@ namespace CppSharp.Passes
var result = base.VisitTranslationUnit(unit);
foreach (var internalImpl in internalImpls)
if (internalImpl.Namespace != null)
internalImpl.Namespace.Classes.Add(internalImpl);
internalImpl.Namespace.Declarations.Add(internalImpl);
else
unit.Classes.AddRange(internalImpls);
unit.Declarations.AddRange(internalImpls);
internalImpls.Clear();
return result;

2
src/Generator/Passes/HandleDefaultParamValuesPass.cs

@ -30,7 +30,7 @@ namespace CppSharp.Passes @@ -30,7 +30,7 @@ namespace CppSharp.Passes
return false;
var result = base.VisitTranslationUnit(unit);
foreach (var overload in overloads)
overload.Key.Functions.AddRange(overload.Value);
overload.Key.Declarations.AddRange(overload.Value);
overloads.Clear();
return result;
}

3
src/Generator/Passes/MarkUsedClassInternalsPass.cs

@ -60,7 +60,8 @@ namespace CppSharp.Passes @@ -60,7 +60,8 @@ namespace CppSharp.Passes
if (template?.Ignore == true)
template.GenerationKind = GenerationKind.Internal;
Class nested = template?.Classes.Find(c => c.OriginalName == decl.OriginalName);
Class nested = template?.Classes.FirstOrDefault(
c => c.OriginalName == decl.OriginalName);
if (nested?.Ignore == true)
nested.GenerationKind = GenerationKind.Internal;

2
src/Generator/Passes/MultipleInheritancePass.cs

@ -144,7 +144,7 @@ namespace CppSharp.Passes @@ -144,7 +144,7 @@ namespace CppSharp.Passes
@interface.Methods.Add(dispose);
}
@interface.Events.AddRange(@base.Events);
@interface.Declarations.AddRange(@base.Events);
var type = new QualifiedType(new BuiltinType(PrimitiveType.IntPtr));
var adjustmentTo = new Property

2
src/Generator/Passes/ResolveIncompleteDeclsPass.cs

@ -39,7 +39,7 @@ namespace CppSharp.Passes @@ -39,7 +39,7 @@ namespace CppSharp.Passes
Class templatedClass = template.TemplatedClass;
var parentSpecialization = templatedClass.Namespace as ClassTemplateSpecialization;
if (parentSpecialization != null)
templatedClass = parentSpecialization.TemplatedDecl.TemplatedClass.Classes.Find(
templatedClass = parentSpecialization.TemplatedDecl.TemplatedClass.Classes.FirstOrDefault(
c => c.OriginalName == template.OriginalName) ?? template.TemplatedClass;
// store all specializations in the real template class because ClassTemplateDecl only forwards
foreach (var specialization in template.Specializations.Where(

18
src/Generator/Passes/SortDeclarationsPass.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
using System.Linq;
using CppSharp.AST;
namespace CppSharp.Passes
{
public class SortDeclarationsPass : TranslationUnitPass
{
public override bool VisitNamespace(Namespace @namespace)
{
if (!base.VisitNamespace(@namespace) || @namespace.Ignore)
return false;
@namespace.Declarations = @namespace.Declarations.OrderBy(
d => d.DefinitionOrder).ToList();
return true;
}
}
}

16
src/Parser/ASTConverter.cs

@ -983,28 +983,28 @@ namespace CppSharp @@ -983,28 +983,28 @@ namespace CppSharp
{
var decl = ctx.GetNamespaces(i);
var _decl = Visit(decl) as AST.Namespace;
_ctx.Namespaces.Add(_decl);
_ctx.Declarations.Add(_decl);
}
for (uint i = 0; i < ctx.EnumsCount; ++i)
{
var decl = ctx.GetEnums(i);
var _decl = Visit(decl) as AST.Enumeration;
_ctx.Enums.Add(_decl);
_ctx.Declarations.Add(_decl);
}
for (uint i = 0; i < ctx.FunctionsCount; ++i)
{
var decl = ctx.GetFunctions(i);
var _decl = Visit(decl) as AST.Function;
_ctx.Functions.Add(_decl);
_ctx.Declarations.Add(_decl);
}
for (uint i = 0; i < ctx.TemplatesCount; ++i)
{
var decl = ctx.GetTemplates(i);
var _decl = Visit(decl) as AST.Template;
_ctx.Templates.Add(_decl);
_ctx.Declarations.Add(_decl);
}
for (uint i = 0; i < ctx.ClassesCount; ++i)
@ -1012,28 +1012,28 @@ namespace CppSharp @@ -1012,28 +1012,28 @@ namespace CppSharp
var decl = ctx.GetClasses(i);
var _decl = Visit(decl) as AST.Class;
if (!_decl.IsIncomplete || _decl.IsOpaque)
_ctx.Classes.Add(_decl);
_ctx.Declarations.Add(_decl);
}
for (uint i = 0; i < ctx.TypedefsCount; ++i)
{
var decl = ctx.GetTypedefs(i);
var _decl = Visit(decl) as AST.TypedefDecl;
_ctx.Typedefs.Add(_decl);
_ctx.Declarations.Add(_decl);
}
for (uint i = 0; i < ctx.TypeAliasesCount; ++i)
{
var decl = ctx.GetTypeAliases(i);
var _decl = Visit(decl) as AST.TypeAlias;
_ctx.Typedefs.Add(_decl);
_ctx.Declarations.Add(_decl);
}
for (uint i = 0; i < ctx.VariablesCount; ++i)
{
var decl = ctx.GetVariables(i);
var _decl = Visit(decl) as AST.Variable;
_ctx.Variables.Add(_decl);
_ctx.Declarations.Add(_decl);
}
for (uint i = 0; i < ctx.FriendsCount; ++i)

Loading…
Cancel
Save