Browse Source

Major refactor: TypePrinter: improve modular design + cleanup (#1796)

pull/1803/head
deadlocklogic 3 years ago committed by GitHub
parent
commit
8c2da6d542
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/Generator/Generator.cs
  2. 49
      src/Generator/GeneratorKind.cs
  3. 8
      src/Generator/Generators/C/CGenerator.cs
  4. 8
      src/Generator/Generators/C/CppGenerator.cs
  5. 7
      src/Generator/Generators/C/CppTypePrinter.cs
  6. 8
      src/Generator/Generators/CLI/CLIGenerator.cs
  7. 10
      src/Generator/Generators/CSharp/CSharpGenerator.cs
  8. 7
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  9. 10
      src/Generator/Generators/Marshal.cs
  10. 11
      src/Generator/Generators/NAPI/NAPITypePrinter.cs
  11. 8
      src/Generator/Generators/TS/TSGenerator.cs
  12. 3
      src/Generator/Generators/TypePrinter.cs
  13. 37
      src/Generator/Passes/CheckDuplicatedNamesPass.cs

8
src/Generator/Generator.cs

@ -28,9 +28,12 @@ namespace CppSharp.Generators
{ {
public BindingContext Context { get; } public BindingContext Context { get; }
protected readonly TypePrinter typePrinter;
protected Generator(BindingContext context) protected Generator(BindingContext context)
{ {
Context = context; Context = context;
typePrinter = Context.Options.GeneratorKind.CreateTypePrinter(context);
CppSharp.AST.Type.TypePrinterDelegate += TypePrinterDelegate; CppSharp.AST.Type.TypePrinterDelegate += TypePrinterDelegate;
} }
@ -155,7 +158,10 @@ namespace CppSharp.Generators
return output; return output;
} }
protected abstract string TypePrinterDelegate(CppSharp.AST.Type type); protected virtual string TypePrinterDelegate(CppSharp.AST.Type type)
{
return type.Visit(typePrinter);
}
public static string GeneratedIdentifier(string id) => public static string GeneratedIdentifier(string id) =>
$"__{(id.StartsWith("@") ? id.Substring(1) : id)}"; $"__{(id.StartsWith("@") ? id.Substring(1) : id)}";

49
src/Generator/GeneratorKind.cs

@ -20,10 +20,11 @@ namespace CppSharp.Generators
public string ID { get; } public string ID { get; }
public string Name { get; } public string Name { get; }
public System.Type Type { get; } public System.Type GeneratorType { get; }
public System.Type TypePrinterType { get; }
public string[] CLIOptions { get; } public string[] CLIOptions { get; }
public GeneratorKind(string id, string name, System.Type type, string[] cLIOptions = null) public GeneratorKind(string id, string name, System.Type generatorType, System.Type typePrinterType, string[] cLIOptions = null)
{ {
if (Registered.Any(kind => kind.ID == id)) if (Registered.Any(kind => kind.ID == id))
{ {
@ -31,14 +32,20 @@ namespace CppSharp.Generators
} }
ID = id; ID = id;
Name = name; Name = name;
Type = type; GeneratorType = generatorType;
TypePrinterType = typePrinterType;
CLIOptions = cLIOptions; CLIOptions = cLIOptions;
Registered.Add(this); Registered.Add(this);
} }
public Generator CreateGenerator(BindingContext context) public Generator CreateGenerator(BindingContext context)
{ {
return (Generator)Activator.CreateInstance(Type, context); return (Generator)Activator.CreateInstance(GeneratorType, context);
}
public TypePrinter CreateTypePrinter(BindingContext context)
{
return (TypePrinter)Activator.CreateInstance(TypePrinterType, context);
} }
public bool IsCLIOptionMatch(string cliOption) public bool IsCLIOptionMatch(string cliOption)
@ -93,37 +100,44 @@ namespace CppSharp.Generators
} }
public const string CLI_ID = "CLI"; public const string CLI_ID = "CLI";
public static readonly GeneratorKind CLI = new(CLI_ID, "C++/CLI", typeof(CLIGenerator), new[] { "cli" }); public static readonly GeneratorKind CLI = new(CLI_ID, "C++/CLI", typeof(CLIGenerator), typeof(CLITypePrinter), new[] { "cli" });
public const string CSharp_ID = "CSharp"; public const string CSharp_ID = "CSharp";
public static readonly GeneratorKind CSharp = new(CSharp_ID, "C#", typeof(CSharpGenerator), new[] { "csharp" }); public static readonly GeneratorKind CSharp = new(CSharp_ID, "C#", typeof(CSharpGenerator), typeof(CSharpTypePrinter), new[] { "csharp" });
public const string C_ID = "C"; public const string C_ID = "C";
public static readonly GeneratorKind C = new(C_ID, "C", typeof(CGenerator), new[] { "c" }); public static readonly GeneratorKind C = new(C_ID, "C", typeof(CGenerator), typeof(CppTypePrinter), new[] { "c" });
public const string CPlusPlus_ID = "CPlusPlus"; public const string CPlusPlus_ID = "CPlusPlus";
public static readonly GeneratorKind CPlusPlus = new(CPlusPlus_ID, "CPlusPlus", typeof(CppGenerator), new[] { "cpp" }); public static readonly GeneratorKind CPlusPlus = new(CPlusPlus_ID, "CPlusPlus", typeof(CppGenerator), typeof(CppTypePrinter), new[] { "cpp" });
public const string Emscripten_ID = "Emscripten"; public const string Emscripten_ID = "Emscripten";
public static readonly GeneratorKind Emscripten = new(Emscripten_ID, "Emscripten", typeof(EmscriptenGenerator), new[] { "emscripten" }); public static readonly GeneratorKind Emscripten = new(Emscripten_ID, "Emscripten", typeof(EmscriptenGenerator), typeof(EmscriptenTypePrinter), new[] { "emscripten" });
public const string ObjectiveC_ID = "ObjectiveC"; public const string ObjectiveC_ID = "ObjectiveC";
public static readonly GeneratorKind ObjectiveC = new(ObjectiveC_ID, "ObjectiveC", typeof(NotImplementedGenerator)); public static readonly GeneratorKind ObjectiveC = new(ObjectiveC_ID, "ObjectiveC", typeof(NotImplementedGenerator), typeof(NotImplementedTypePrinter));
public const string Java_ID = "Java"; public const string Java_ID = "Java";
public static readonly GeneratorKind Java = new(Java_ID, "Java", typeof(NotImplementedGenerator)); public static readonly GeneratorKind Java = new(Java_ID, "Java", typeof(NotImplementedGenerator), typeof(NotImplementedTypePrinter));
public const string Swift_ID = "Swift"; public const string Swift_ID = "Swift";
public static readonly GeneratorKind Swift = new(Swift_ID, "Swift", typeof(NotImplementedGenerator)); public static readonly GeneratorKind Swift = new(Swift_ID, "Swift", typeof(NotImplementedGenerator), typeof(NotImplementedTypePrinter));
public const string QuickJS_ID = "QuickJS"; public const string QuickJS_ID = "QuickJS";
public static readonly GeneratorKind QuickJS = new(QuickJS_ID, "QuickJS", typeof(QuickJSGenerator), new[] { "qjs" }); public static readonly GeneratorKind QuickJS = new(QuickJS_ID, "QuickJS", typeof(QuickJSGenerator), typeof(QuickJSTypePrinter), new[] { "qjs" });
public const string NAPI_ID = "NAPI"; public const string NAPI_ID = "NAPI";
public static readonly GeneratorKind NAPI = new(NAPI_ID, "N-API", typeof(NAPIGenerator), new[] { "napi" }); public static readonly GeneratorKind NAPI = new(NAPI_ID, "N-API", typeof(NAPIGenerator), typeof(NAPITypePrinter), new[] { "napi" });
public const string TypeScript_ID = "TypeScript"; public const string TypeScript_ID = "TypeScript";
public static readonly GeneratorKind TypeScript = new(TypeScript_ID, "TypeScript", typeof(TSGenerator), new[] { "ts", "typescript" }); public static readonly GeneratorKind TypeScript = new(TypeScript_ID, "TypeScript", typeof(TSGenerator), typeof(TSTypePrinter), new[] { "ts", "typescript" });
}
public class NotImplementedTypePrinter : TypePrinter
{
public NotImplementedTypePrinter(BindingContext context) : base(context)
{
}
} }
public class NotImplementedGenerator : Generator public class NotImplementedGenerator : Generator
@ -142,10 +156,5 @@ namespace CppSharp.Generators
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
protected override string TypePrinterDelegate(CppSharp.AST.Type type)
{
throw new NotImplementedException();
}
} }
} }

8
src/Generator/Generators/C/CGenerator.cs

@ -10,11 +10,8 @@ namespace CppSharp.Generators.C
/// </summary> /// </summary>
public class CGenerator : Generator public class CGenerator : Generator
{ {
private readonly CppTypePrinter typePrinter;
public CGenerator(BindingContext context) : base(context) public CGenerator(BindingContext context) : base(context)
{ {
typePrinter = new CppTypePrinter(Context);
} }
public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units) public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
@ -31,10 +28,5 @@ namespace CppSharp.Generators.C
} }
public override bool SetupPasses() => true; public override bool SetupPasses() => true;
protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
} }
} }

8
src/Generator/Generators/C/CppGenerator.cs

@ -11,11 +11,8 @@ namespace CppSharp.Generators.Cpp
/// </summary> /// </summary>
public class CppGenerator : CGenerator public class CppGenerator : CGenerator
{ {
private readonly CppTypePrinter typePrinter;
public CppGenerator(BindingContext context) : base(context) public CppGenerator(BindingContext context) : base(context)
{ {
typePrinter = new CppTypePrinter(Context);
} }
public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units) public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
@ -44,11 +41,6 @@ namespace CppSharp.Generators.Cpp
return @class.IsRefType && (!@class.HasBase || !@class.HasRefBase()); return @class.IsRefType && (!@class.HasBase || !@class.HasRefBase());
} }
protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
} }
/// <summary> /// <summary>

7
src/Generator/Generators/C/CppTypePrinter.cs

@ -28,18 +28,13 @@ namespace CppSharp.Generators.C
public TypePrintScopeKind MethodScopeKind = TypePrintScopeKind.Qualified; public TypePrintScopeKind MethodScopeKind = TypePrintScopeKind.Qualified;
public CppTypePrinter() : base(TypePrinterContextKind.Native) public CppTypePrinter(BindingContext context) : base(context, TypePrinterContextKind.Native)
{ {
PrintFlavorKind = CppTypePrintFlavorKind.Cpp; PrintFlavorKind = CppTypePrintFlavorKind.Cpp;
PrintTypeQualifiers = true; PrintTypeQualifiers = true;
PrintTypeModifiers = true; PrintTypeModifiers = true;
} }
public CppTypePrinter(BindingContext context) : this()
{
Context = context;
}
public TypeMapDatabase TypeMapDatabase => Context.TypeMaps; public TypeMapDatabase TypeMapDatabase => Context.TypeMaps;
public DriverOptions Options => Context.Options; public DriverOptions Options => Context.Options;

8
src/Generator/Generators/CLI/CLIGenerator.cs

@ -10,11 +10,8 @@ namespace CppSharp.Generators.CLI
/// </summary> /// </summary>
public class CLIGenerator : Generator public class CLIGenerator : Generator
{ {
private readonly CppTypePrinter typePrinter;
public CLIGenerator(BindingContext context) : base(context) public CLIGenerator(BindingContext context) : base(context)
{ {
typePrinter = new CLITypePrinter(context);
} }
public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units) public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
@ -39,10 +36,5 @@ namespace CppSharp.Generators.CLI
return @class.IsRefType && (!@class.NeedsBase || !@class.HasRefBase()); return @class.IsRefType && (!@class.NeedsBase || !@class.HasRefBase());
} }
protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
} }
} }

10
src/Generator/Generators/CSharp/CSharpGenerator.cs

@ -7,18 +7,15 @@ namespace CppSharp.Generators.CSharp
{ {
public class CSharpGenerator : Generator public class CSharpGenerator : Generator
{ {
private readonly CSharpTypePrinter typePrinter;
public CSharpGenerator(BindingContext context) : base(context) public CSharpGenerator(BindingContext context) : base(context)
{ {
typePrinter = new CSharpTypePrinter(context);
} }
public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units) public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
{ {
var outputs = new List<CodeGenerator>(); var outputs = new List<CodeGenerator>();
var gen = new CSharpSources(Context, units) { TypePrinter = typePrinter }; var gen = new CSharpSources(Context, units) { TypePrinter = (CSharpTypePrinter)typePrinter };
outputs.Add(gen); outputs.Add(gen);
return outputs; return outputs;
@ -42,10 +39,5 @@ namespace CppSharp.Generators.CSharp
return true; return true;
} }
protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter);
}
} }
} }

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

@ -21,15 +21,10 @@ namespace CppSharp.Generators.CSharp
public bool PrintModuleOutputNamespace = true; public bool PrintModuleOutputNamespace = true;
public CSharpTypePrinter() public CSharpTypePrinter(BindingContext context) : base(context)
{ {
} }
public CSharpTypePrinter(BindingContext context)
{
Context = context;
}
public string QualifiedType(string name) public string QualifiedType(string name)
{ {
return IsGlobalQualifiedScope ? $"global::{name}" : name; return IsGlobalQualifiedScope ? $"global::{name}" : name;

10
src/Generator/Generators/Marshal.cs

@ -1,13 +1,13 @@
using CppSharp.AST; using CppSharp.AST;
using CppSharp.Generators.C; using CppSharp.Generators.C;
using System;
namespace CppSharp.Generators namespace CppSharp.Generators
{ {
public class MarshalContext : TypePrinter public class MarshalContext : TypePrinter
{ {
public MarshalContext(BindingContext context, uint indentation) public MarshalContext(BindingContext context, uint indentation) : base(context)
{ {
Context = context;
Before = new TextGenerator { CurrentIndentation = indentation }; Before = new TextGenerator { CurrentIndentation = indentation };
Return = new TextGenerator { CurrentIndentation = indentation }; Return = new TextGenerator { CurrentIndentation = indentation };
Cleanup = new TextGenerator { CurrentIndentation = indentation }; Cleanup = new TextGenerator { CurrentIndentation = indentation };
@ -34,16 +34,16 @@ namespace CppSharp.Generators
public uint Indentation { get; } public uint Indentation { get; }
} }
public abstract class MarshalPrinter<C, P> : AstVisitor where C : MarshalContext where P : TypePrinter, new() public abstract class MarshalPrinter<C, P> : AstVisitor where C : MarshalContext where P : TypePrinter
{ {
public C Context { get; } public C Context { get; }
protected MarshalPrinter(C ctx) protected MarshalPrinter(C ctx)
{ {
Context = ctx; Context = ctx;
typePrinter.Context = ctx.Context; typePrinter = (P)Activator.CreateInstance(typeof(P), ctx.Context);
} }
protected P typePrinter = new P(); protected P typePrinter;
} }
} }

11
src/Generator/Generators/NAPI/NAPITypePrinter.cs

@ -0,0 +1,11 @@
using CppSharp.Generators.C;
namespace CppSharp.Generators.C
{
public class NAPITypePrinter : CppTypePrinter
{
public NAPITypePrinter(BindingContext context) : base(context)
{
}
}
}

8
src/Generator/Generators/TS/TSGenerator.cs

@ -11,11 +11,8 @@ namespace CppSharp.Generators.TS
/// </summary> /// </summary>
public class TSGenerator : CGenerator public class TSGenerator : CGenerator
{ {
private readonly TSTypePrinter typePrinter;
public TSGenerator(BindingContext context) : base(context) public TSGenerator(BindingContext context) : base(context)
{ {
typePrinter = new TSTypePrinter(Context);
} }
public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units) public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
@ -32,10 +29,5 @@ namespace CppSharp.Generators.TS
{ {
return true; return true;
} }
protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
} }
} }

3
src/Generator/Generators/TypePrinter.cs

@ -64,8 +64,9 @@ namespace CppSharp.Generators
public TypePrintScopeKind ScopeKind => scopeKinds.Peek(); public TypePrintScopeKind ScopeKind => scopeKinds.Peek();
public bool IsGlobalQualifiedScope => ScopeKind == TypePrintScopeKind.GlobalQualified; public bool IsGlobalQualifiedScope => ScopeKind == TypePrintScopeKind.GlobalQualified;
public TypePrinter(TypePrinterContextKind contextKind = TypePrinterContextKind.Managed) public TypePrinter(BindingContext context, TypePrinterContextKind contextKind = TypePrinterContextKind.Managed)
{ {
Context = context;
contexts = new Stack<TypePrinterContextKind>(); contexts = new Stack<TypePrinterContextKind>();
marshalKinds = new Stack<MarshalKind>(); marshalKinds = new Stack<MarshalKind>();
scopeKinds = new Stack<TypePrintScopeKind>(); scopeKinds = new Stack<TypePrintScopeKind>();

37
src/Generator/Passes/CheckDuplicatedNamesPass.cs

@ -4,10 +4,6 @@ using System.Linq;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.AST.Extensions; using CppSharp.AST.Extensions;
using CppSharp.Generators; using CppSharp.Generators;
using CppSharp.Generators.C;
using CppSharp.Generators.CLI;
using CppSharp.Generators.CSharp;
using CppSharp.Generators.Emscripten;
using CppSharp.Types; using CppSharp.Types;
namespace CppSharp.Passes namespace CppSharp.Passes
@ -190,43 +186,12 @@ namespace CppSharp.Passes
public override bool VisitASTContext(ASTContext context) public override bool VisitASTContext(ASTContext context)
{ {
var typePrinter = GetTypePrinter(Options.GeneratorKind, Context); DeclarationName.ParameterTypeComparer.TypePrinter = Options.GeneratorKind.CreateTypePrinter(Context);
DeclarationName.ParameterTypeComparer.TypePrinter = typePrinter;
DeclarationName.ParameterTypeComparer.TypeMaps = Context.TypeMaps; DeclarationName.ParameterTypeComparer.TypeMaps = Context.TypeMaps;
DeclarationName.ParameterTypeComparer.GeneratorKind = Options.GeneratorKind; DeclarationName.ParameterTypeComparer.GeneratorKind = Options.GeneratorKind;
return base.VisitASTContext(context); return base.VisitASTContext(context);
} }
private TypePrinter GetTypePrinter(GeneratorKind kind, BindingContext context)
{
TypePrinter typePrinter;
switch (kind)
{
case var _ when ReferenceEquals(kind, GeneratorKind.C):
typePrinter = new CppTypePrinter(Context) { PrintFlavorKind = CppTypePrintFlavorKind.C };
break;
case var _ when ReferenceEquals(kind, GeneratorKind.Emscripten):
typePrinter = new EmscriptenTypePrinter(Context);
break;;
case var _ when ReferenceEquals(kind, GeneratorKind.CPlusPlus):
case var _ when ReferenceEquals(kind, GeneratorKind.QuickJS):
case var _ when ReferenceEquals(kind, GeneratorKind.NAPI):
case var _ when ReferenceEquals(kind, GeneratorKind.TypeScript):
typePrinter = new CppTypePrinter(Context);
break;
case var _ when ReferenceEquals(kind, GeneratorKind.CLI):
typePrinter = new CLITypePrinter(Context);
break;
case var _ when ReferenceEquals(kind, GeneratorKind.CSharp):
typePrinter = new CSharpTypePrinter(Context);
break;
default:
throw new System.NotImplementedException();
}
return typePrinter;
}
public override bool VisitProperty(Property decl) public override bool VisitProperty(Property decl)
{ {
if (!VisitDeclaration(decl)) if (!VisitDeclaration(decl))

Loading…
Cancel
Save