Browse Source

Ensured delegates are generated within the main name-space and reused them more.

pull/742/head
Dimitar Dobrev 9 years ago
parent
commit
930dd85f15
  1. 40
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  2. 49
      src/Generator/Passes/DelegatesPass.cs

40
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -34,10 +34,7 @@ namespace CppSharp.Generators.CSharp
return new CSharpTypePrinterResult {Type = type}; return new CSharpTypePrinterResult {Type = type};
} }
public override string ToString() public override string ToString() => Type;
{
return Type;
}
} }
public class CSharpTypePrinter : ITypePrinter<CSharpTypePrinterResult>, public class CSharpTypePrinter : ITypePrinter<CSharpTypePrinterResult>,
@ -45,32 +42,21 @@ namespace CppSharp.Generators.CSharp
{ {
public const string IntPtrType = "global::System.IntPtr"; public const string IntPtrType = "global::System.IntPtr";
public static bool AppendGlobal { get; set; } public bool FullyQualify { get; set; } = true;
static CSharpTypePrinter()
{
AppendGlobal = true;
}
private readonly Stack<CSharpTypePrinterContextKind> contexts; private readonly Stack<CSharpTypePrinterContextKind> contexts;
private readonly Stack<CSharpMarshalKind> marshalKinds; private readonly Stack<CSharpMarshalKind> marshalKinds;
public CSharpTypePrinterContextKind ContextKind public CSharpTypePrinterContextKind ContextKind => contexts.Peek();
{
get { return contexts.Peek(); }
}
public CSharpMarshalKind MarshalKind public CSharpMarshalKind MarshalKind => marshalKinds.Peek();
{
get { return marshalKinds.Peek(); }
}
public CSharpTypePrinterContext TypePrinterContext; public CSharpTypePrinterContext TypePrinterContext;
public BindingContext Context { get; set; } public BindingContext Context { get; set; }
public DriverOptions Options { get { return Context.Options; } } public DriverOptions Options => Context.Options;
public TypeMapDatabase TypeMapDatabase { get { return Context.TypeMaps; } } public TypeMapDatabase TypeMapDatabase => Context.TypeMaps;
public CSharpTypePrinter(BindingContext context) public CSharpTypePrinter(BindingContext context)
{ {
@ -88,20 +74,14 @@ namespace CppSharp.Generators.CSharp
contexts.Push(contextKind); contexts.Push(contextKind);
} }
public CSharpTypePrinterContextKind PopContext() public CSharpTypePrinterContextKind PopContext() => contexts.Pop();
{
return contexts.Pop();
}
public void PushMarshalKind(CSharpMarshalKind marshalKind) public void PushMarshalKind(CSharpMarshalKind marshalKind)
{ {
marshalKinds.Push(marshalKind); marshalKinds.Push(marshalKind);
} }
public CSharpMarshalKind PopMarshalKind() public CSharpMarshalKind PopMarshalKind() => marshalKinds.Pop();
{
return marshalKinds.Pop();
}
public CSharpTypePrinterResult VisitTagType(TagType tag, TypeQualifiers quals) public CSharpTypePrinterResult VisitTagType(TagType tag, TypeQualifiers quals)
{ {
@ -726,10 +706,10 @@ namespace CppSharp.Generators.CSharp
names.Reverse(); names.Reverse();
var isInCurrentOutputNamespace = names[0] == Generator.CurrentOutputNamespace; var isInCurrentOutputNamespace = names[0] == Generator.CurrentOutputNamespace;
if (isInCurrentOutputNamespace) if (isInCurrentOutputNamespace || !FullyQualify)
names.RemoveAt(0); names.RemoveAt(0);
return (isInCurrentOutputNamespace || !AppendGlobal ? return (isInCurrentOutputNamespace || !FullyQualify ?
string.Empty : "global::") + string.Join(".", names); string.Empty : "global::") + string.Join(".", names);
} }

49
src/Generator/Passes/DelegatesPass.cs

@ -20,9 +20,9 @@ namespace CppSharp.Passes
Signature = signature; Signature = signature;
} }
public string Namespace { get; private set; } public string Namespace { get; }
public string Signature { get; private set; } public string Signature { get; }
} }
public DelegatesPass() public DelegatesPass()
@ -37,8 +37,8 @@ namespace CppSharp.Passes
public override bool VisitASTContext(ASTContext context) public override bool VisitASTContext(ASTContext context)
{ {
foreach (var library in Options.Modules.SelectMany(m => m.Libraries)) foreach (var module in Options.Modules)
libsDelegates[library] = new Dictionary<string, DelegateDefinition>(); libsDelegates[module] = new Dictionary<string, DelegateDefinition>();
var unit = context.TranslationUnits.GetGenerated().LastOrDefault(); var unit = context.TranslationUnits.GetGenerated().LastOrDefault();
@ -48,7 +48,7 @@ namespace CppSharp.Passes
var result = base.VisitASTContext(context); var result = base.VisitASTContext(context);
foreach (var module in Options.Modules.Where(m => namespacesDelegates.ContainsKey(m))) foreach (var module in Options.Modules.Where(m => namespacesDelegates.ContainsKey(m)))
module.Units.Last(u => u.HasDeclarations).Declarations.Add(namespacesDelegates[module]); namespacesDelegates[module].Namespace.Declarations.Add(namespacesDelegates[module]);
return result; return result;
} }
@ -100,10 +100,20 @@ namespace CppSharp.Passes
} }
else else
{ {
Namespace parent = null;
if (string.IsNullOrEmpty(module.OutputNamespace))
{
var group = module.Units.SelectMany(u => u.Declarations).OfType<Namespace>(
).GroupBy(d => d.Name).Where(g => g.Any(d => d.HasDeclarations)).ToList();
if (group.Count == 1)
parent = group.Last().Last();
}
if (parent == null)
parent = module.Units.Last();
namespaceDelegates = new Namespace namespaceDelegates = new Namespace
{ {
Name = DelegatesNamespace, Name = DelegatesNamespace,
Namespace = module.Units.Last() Namespace = parent
}; };
namespacesDelegates.Add(module, namespaceDelegates); namespacesDelegates.Add(module, namespaceDelegates);
} }
@ -126,10 +136,9 @@ namespace CppSharp.Passes
Access = AccessSpecifier.Private Access = AccessSpecifier.Private
}; };
Generator.CurrentOutputNamespace = module.OutputNamespace;
var delegateString = @delegate.Visit(TypePrinter).Type; var delegateString = @delegate.Visit(TypePrinter).Type;
var existingDelegate = GetExistingDelegate( var existingDelegate = GetExistingDelegate(
method.TranslationUnit.Module.Libraries, delegateString); method.TranslationUnit.Module, delegateString);
if (existingDelegate != null) if (existingDelegate != null)
{ {
@ -140,24 +149,22 @@ namespace CppSharp.Passes
existingDelegate = new DelegateDefinition(module.OutputNamespace, delegateString); existingDelegate = new DelegateDefinition(module.OutputNamespace, delegateString);
Context.Delegates.Add(method, existingDelegate); Context.Delegates.Add(method, existingDelegate);
foreach (var library in module.Libraries) libsDelegates[module].Add(delegateString, existingDelegate);
libsDelegates[library].Add(delegateString, existingDelegate);
namespaceDelegates.Declarations.Add(@delegate); namespaceDelegates.Declarations.Add(@delegate);
return true; return true;
} }
private DelegateDefinition GetExistingDelegate(IList<string> libraries, string delegateString) private DelegateDefinition GetExistingDelegate(Module module, string delegateString)
{ {
if (libraries.Count == 0) if (module.Libraries.Count == 0)
return Context.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString); return Context.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString);
DelegateDefinition @delegate = null; DelegateDefinition @delegate = null;
if (libraries.Union( if (new[] { module }.Union(module.Dependencies).Any(
Context.Symbols.Libraries.Where(l => libraries.Contains(l.FileName)).SelectMany( m => libsDelegates.ContainsKey(m) && libsDelegates[m].TryGetValue(
l => l.Dependencies)).Any(l => libsDelegates.ContainsKey(l) && delegateString, out @delegate)))
libsDelegates[l].TryGetValue(delegateString, out @delegate)))
return @delegate; return @delegate;
return null; return null;
@ -165,8 +172,6 @@ namespace CppSharp.Passes
private string GenerateDelegateSignature(IEnumerable<Parameter> @params, QualifiedType returnType) private string GenerateDelegateSignature(IEnumerable<Parameter> @params, QualifiedType returnType)
{ {
TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
CSharpTypePrinter.AppendGlobal = false;
var typesBuilder = new StringBuilder(); var typesBuilder = new StringBuilder();
if (!returnType.Type.IsPrimitiveType(PrimitiveType.Void)) if (!returnType.Type.IsPrimitiveType(PrimitiveType.Void))
{ {
@ -186,8 +191,6 @@ namespace CppSharp.Passes
else else
delegateName = "Func_" + delegateName; delegateName = "Func_" + delegateName;
TypePrinter.PopContext();
CSharpTypePrinter.AppendGlobal = true;
return delegateName; return delegateName;
} }
@ -197,7 +200,7 @@ namespace CppSharp.Passes
{ {
if (typePrinter == null) if (typePrinter == null)
{ {
typePrinter = new CSharpTypePrinter(Context); typePrinter = new CSharpTypePrinter(Context) { FullyQualify = false };
typePrinter.PushContext(CSharpTypePrinterContextKind.Native); typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
typePrinter.PushMarshalKind(CSharpMarshalKind.GenericDelegate); typePrinter.PushMarshalKind(CSharpMarshalKind.GenericDelegate);
} }
@ -207,7 +210,7 @@ namespace CppSharp.Passes
private Dictionary<Module, Namespace> namespacesDelegates = new Dictionary<Module, Namespace>(); private Dictionary<Module, Namespace> namespacesDelegates = new Dictionary<Module, Namespace>();
private CSharpTypePrinter typePrinter; private CSharpTypePrinter typePrinter;
private static readonly Dictionary<string, Dictionary<string, DelegateDefinition>> libsDelegates = private static readonly Dictionary<Module, Dictionary<string, DelegateDefinition>> libsDelegates =
new Dictionary<string, Dictionary<string, DelegateDefinition>>(); new Dictionary<Module, Dictionary<string, DelegateDefinition>>();
} }
} }

Loading…
Cancel
Save