Browse Source

Add initial implementation of declaration maps.

pull/1511/head
Joao Matos 5 years ago committed by João Matos
parent
commit
643639d163
  1. 2
      src/Generator/BindingContext.cs
  2. 4
      src/Generator/Driver.cs
  3. 52
      src/Generator/Types/DeclMap.cs
  4. 85
      src/Generator/Types/DeclMapDatabase.cs

2
src/Generator/BindingContext.cs

@ -14,7 +14,9 @@ namespace CppSharp.Generators @@ -14,7 +14,9 @@ namespace CppSharp.Generators
public ParserTargetInfo TargetInfo { get; set; }
public SymbolContext Symbols { get; }
public TypeMapDatabase TypeMaps { get; set; }
public DeclMapDatabase DeclMaps { get; set; }
public PassBuilder<TranslationUnitPass> TranslationUnitPasses { get; }
public PassBuilder<GeneratorOutputPass> GeneratorOutputPasses { get; }

4
src/Generator/Driver.cs

@ -77,6 +77,9 @@ namespace CppSharp @@ -77,6 +77,9 @@ namespace CppSharp
public void SetupTypeMaps() =>
Context.TypeMaps = new TypeMapDatabase(Context);
public void SetupDeclMaps() =>
Context.DeclMaps = new DeclMapDatabase(Context);
void OnSourceFileParsed(IEnumerable<string> files, ParserResult result)
{
OnFileParsed(files, result);
@ -453,6 +456,7 @@ namespace CppSharp @@ -453,6 +456,7 @@ namespace CppSharp
driver.SetupPasses(library);
driver.SetupTypeMaps();
driver.SetupDeclMaps();
library.Preprocess(driver, driver.Context.ASTContext);

52
src/Generator/Types/DeclMap.cs

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
using System;
using CppSharp.AST;
using CppSharp.Generators;
using CppSharp.Generators.C;
using Attribute = System.Attribute;
namespace CppSharp.Types
{
/// <summary>
/// Declaration maps allow customization of generated code, either
/// partially or fully, depending on how its setup.
/// </summary>
public abstract class DeclMap
{
public BindingContext Context { get; set; }
public IDeclMapDatabase DeclMapDatabase { get; set; }
public bool IsEnabled { get; set; } = true;
public virtual bool IsIgnored => false;
public Declaration Declaration { get; set; }
public DeclarationContext DeclarationContext { get; set; }
public abstract Declaration GetDeclaration();
public virtual void Generate(CCodeGenerator generator)
{
}
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class DeclMapAttribute : Attribute
{
public GeneratorKind GeneratorKind { get; set; }
public DeclMapAttribute() : this(0)
{
}
public DeclMapAttribute(GeneratorKind generatorKind)
{
GeneratorKind = generatorKind;
}
}
public interface IDeclMapDatabase
{
bool FindDeclMap(Declaration declaration, out DeclMap declMap);
}
}

85
src/Generator/Types/DeclMapDatabase.cs

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.Generators;
namespace CppSharp.Types
{
public class DeclMapDatabase : IDeclMapDatabase
{
public IDictionary<Declaration, DeclMap> DeclMaps { get; set; }
public DeclMapDatabase(BindingContext bindingContext)
{
DeclMaps = new Dictionary<Declaration, DeclMap>();
SetupDeclMaps(bindingContext);
}
private void SetupDeclMaps(BindingContext bindingContext)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
var types = assembly.FindDerivedTypes(typeof(DeclMap));
SetupDeclMaps(types, bindingContext);
}
catch (System.Reflection.ReflectionTypeLoadException ex)
{
Diagnostics.Error("Error loading decl maps from assembly '{0}': {1}",
assembly.GetName().Name, ex.Message);
}
}
}
private void SetupDeclMaps(IEnumerable<System.Type> types,
BindingContext bindingContext)
{
foreach (var type in types)
{
var attrs = type.GetCustomAttributes(typeof(DeclMapAttribute), true);
foreach (DeclMapAttribute attr in attrs)
{
if (attr.GeneratorKind == 0 ||
attr.GeneratorKind == bindingContext.Options.GeneratorKind)
{
var declMap = (DeclMap) Activator.CreateInstance(type);
declMap.Context = bindingContext;
declMap.DeclMapDatabase = this;
var decl = declMap.GetDeclaration();
if (decl == null)
continue;
DeclMaps[decl] = declMap;
}
}
}
}
public bool FindDeclMap(Declaration decl, out DeclMap declMap)
{
// Looks up the decl in the cache map.
if (declMaps.ContainsKey(decl))
{
declMap = declMaps[decl];
return declMap.IsEnabled;
}
var foundDecl = DeclMaps.Keys.FirstOrDefault(d => d.OriginalPtr == decl.OriginalPtr);
if (foundDecl != null)
{
declMap = DeclMaps[foundDecl];
declMaps[decl] = declMap;
return declMap.IsEnabled;
}
declMap = null;
return false;
}
private readonly Dictionary<Declaration, DeclMap> declMaps =
new Dictionary<Declaration, DeclMap>();
}
}
Loading…
Cancel
Save