Browse Source

Reworked declaration storage in the managed AST layer.

Instead of keeping separate lists for different types of declarations, which limits future extensibility, provide a generalized declaration list like Clang. This also introduces a new DeclIterator<T> type to help migrating the rest of the codebase.

This is the first step of a progressive cleanup to modernize the AST/parser layer.
pull/404/head
triton 11 years ago
parent
commit
250825fd59
  1. 67
      src/AST/DeclIterator.cs
  2. 75
      src/AST/Namespace.cs
  3. 8
      src/Generator/Passes/SortDeclarationsPass.cs

67
src/AST/DeclIterator.cs

@ -0,0 +1,67 @@
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;
}
}
}

75
src/AST/Namespace.cs

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
namespace CppSharp.AST namespace CppSharp.AST
@ -12,16 +11,49 @@ namespace CppSharp.AST
{ {
public bool IsAnonymous { get; set; } public bool IsAnonymous { get; set; }
public List<Namespace> Namespaces; public List<Declaration> Declarations;
public List<Enumeration> Enums;
public List<Function> Functions;
public List<Class> Classes;
public List<Template> Templates;
public List<TypedefDecl> Typedefs;
public List<Variable> Variables;
public List<Event> Events;
public List<TypeReference> TypeReferences; public List<TypeReference> TypeReferences;
public DeclIterator<Namespace> Namespaces
{
get { return new DeclIterator<Namespace>(Declarations); }
}
public DeclIterator<Enumeration> Enums
{
get { return new DeclIterator<Enumeration>(Declarations); }
}
public DeclIterator<Function> Functions
{
get { return new DeclIterator<Function>(Declarations); }
}
public DeclIterator<Class> Classes
{
get { return new DeclIterator<Class>(Declarations); }
}
public DeclIterator<Template> Templates
{
get { return new DeclIterator<Template>(Declarations); }
}
public DeclIterator<TypedefDecl> Typedefs
{
get { return new DeclIterator<TypedefDecl>(Declarations); }
}
public DeclIterator<Variable> Variables
{
get { return new DeclIterator<Variable>(Declarations); }
}
public DeclIterator<Event> Events
{
get { return new DeclIterator<Event>(Declarations); }
}
// Used to keep track of anonymous declarations. // Used to keep track of anonymous declarations.
public Dictionary<ulong, Declaration> Anonymous; public Dictionary<ulong, Declaration> Anonymous;
@ -40,14 +72,7 @@ namespace CppSharp.AST
protected DeclarationContext() protected DeclarationContext()
{ {
Namespaces = new List<Namespace>(); Declarations = new List<Declaration>();
Enums = new List<Enumeration>();
Functions = new List<Function>();
Classes = new List<Class>();
Templates = new List<Template>();
Typedefs = new List<TypedefDecl>();
Variables = new List<Variable>();
Events = new List<Event>();
TypeReferences = new List<TypeReference>(); TypeReferences = new List<TypeReference>();
Anonymous = new Dictionary<ulong, Declaration>(); Anonymous = new Dictionary<ulong, Declaration>();
} }
@ -55,14 +80,7 @@ namespace CppSharp.AST
protected DeclarationContext(DeclarationContext dc) protected DeclarationContext(DeclarationContext dc)
: base(dc) : base(dc)
{ {
Namespaces = new List<Namespace>(dc.Namespaces); Declarations = dc.Declarations;
Enums = new List<Enumeration>(dc.Enums);
Functions = new List<Function>(dc.Functions);
Classes = new List<Class>(dc.Classes);
Templates = new List<Template>(dc.Templates);
Typedefs = new List<TypedefDecl>(dc.Typedefs);
Variables = new List<Variable>(dc.Variables);
Events = new List<Event>(dc.Events);
TypeReferences = new List<TypeReference>(dc.TypeReferences); TypeReferences = new List<TypeReference>(dc.TypeReferences);
Anonymous = new Dictionary<ulong, Declaration>(dc.Anonymous); Anonymous = new Dictionary<ulong, Declaration>(dc.Anonymous);
IsAnonymous = dc.IsAnonymous; IsAnonymous = dc.IsAnonymous;
@ -304,9 +322,8 @@ namespace CppSharp.AST
// Replace the incomplete declaration with the complete one. // Replace the incomplete declaration with the complete one.
if (@class.IsIncomplete) if (@class.IsIncomplete)
{ {
var index = Classes.FindIndex(c => c == @class);
@class.CompleteDeclaration = newClass; @class.CompleteDeclaration = newClass;
Classes[index] = newClass; Classes.Replace(@class, newClass);
} }
return newClass; return newClass;
@ -400,7 +417,7 @@ namespace CppSharp.AST
{ {
get get
{ {
Predicate<Declaration> pred = (t => t.IsGenerated); Func<Declaration, bool> pred = (t => t.IsGenerated);
return Enums.Exists(pred) || HasFunctions || Typedefs.Exists(pred) return Enums.Exists(pred) || HasFunctions || Typedefs.Exists(pred)
|| Classes.Any() || Namespaces.Exists(n => n.HasDeclarations); || Classes.Any() || Namespaces.Exists(n => n.HasDeclarations);
} }
@ -410,7 +427,7 @@ namespace CppSharp.AST
{ {
get get
{ {
Predicate<Declaration> pred = (t => t.IsGenerated); Func<Declaration, bool> pred = (t => t.IsGenerated);
return Functions.Exists(pred) || Namespaces.Exists(n => n.HasFunctions); return Functions.Exists(pred) || Namespaces.Exists(n => n.HasFunctions);
} }
} }

8
src/Generator/Passes/SortDeclarationsPass.cs

@ -1,5 +1,5 @@
using CppSharp.AST; using System.Linq;
using CppSharp.Types; using CppSharp.AST;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
@ -7,8 +7,8 @@ namespace CppSharp.Passes
{ {
private static void SortDeclarations(Namespace @namespace) private static void SortDeclarations(Namespace @namespace)
{ {
@namespace.Classes.Sort((c, c1) => @namespace.Declarations = @namespace.Declarations.OrderBy(
(int)(c.DefinitionOrder - c1.DefinitionOrder)); declaration => declaration.DefinitionOrder).ToList();
foreach (var childNamespace in @namespace.Namespaces) foreach (var childNamespace in @namespace.Namespaces)
SortDeclarations(childNamespace); SortDeclarations(childNamespace);

Loading…
Cancel
Save