Skip to content

Commit

Permalink
Major refactor: TypePrinter: improve modular design + cleanup (#1796)
Browse files Browse the repository at this point in the history
  • Loading branch information
deadlocklogic authored Nov 13, 2023
1 parent 0edd48c commit 8c2da6d
Show file tree
Hide file tree
Showing 13 changed files with 58 additions and 116 deletions.
8 changes: 7 additions & 1 deletion src/Generator/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ public abstract class Generator : IDisposable
{
public BindingContext Context { get; }

protected readonly TypePrinter typePrinter;

protected Generator(BindingContext context)
{
Context = context;
typePrinter = Context.Options.GeneratorKind.CreateTypePrinter(context);
CppSharp.AST.Type.TypePrinterDelegate += TypePrinterDelegate;
}

Expand Down Expand Up @@ -155,7 +158,10 @@ public virtual GeneratorOutput GenerateModule(Module module)
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) =>
$"__{(id.StartsWith("@") ? id.Substring(1) : id)}";
Expand Down
49 changes: 29 additions & 20 deletions src/Generator/GeneratorKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,32 @@ public class GeneratorKind : IEquatable<GeneratorKind>

public string ID { 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 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))
{
throw new Exception($"GeneratorKind has an already registered ID: {ID}");
}
ID = id;
Name = name;
Type = type;
GeneratorType = generatorType;
TypePrinterType = typePrinterType;
CLIOptions = cLIOptions;
Registered.Add(this);
}

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)
Expand Down Expand Up @@ -93,37 +100,44 @@ public override int GetHashCode()
}

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 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 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 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 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 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 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 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 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 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 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
Expand All @@ -142,10 +156,5 @@ public override bool SetupPasses()
{
throw new NotImplementedException();
}

protected override string TypePrinterDelegate(CppSharp.AST.Type type)
{
throw new NotImplementedException();
}
}
}
8 changes: 0 additions & 8 deletions src/Generator/Generators/C/CGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ namespace CppSharp.Generators.C
/// </summary>
public class CGenerator : Generator
{
private readonly CppTypePrinter typePrinter;

public CGenerator(BindingContext context) : base(context)
{
typePrinter = new CppTypePrinter(Context);
}

public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
Expand All @@ -31,10 +28,5 @@ public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
}

public override bool SetupPasses() => true;

protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
}
}
8 changes: 0 additions & 8 deletions src/Generator/Generators/C/CppGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ namespace CppSharp.Generators.Cpp
/// </summary>
public class CppGenerator : CGenerator
{
private readonly CppTypePrinter typePrinter;

public CppGenerator(BindingContext context) : base(context)
{
typePrinter = new CppTypePrinter(Context);
}

public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
Expand Down Expand Up @@ -44,11 +41,6 @@ public static bool ShouldGenerateClassNativeInstanceField(Class @class)

return @class.IsRefType && (!@class.HasBase || !@class.HasRefBase());
}

protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
}

/// <summary>
Expand Down
7 changes: 1 addition & 6 deletions src/Generator/Generators/C/CppTypePrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,13 @@ public class CppTypePrinter : TypePrinter

public TypePrintScopeKind MethodScopeKind = TypePrintScopeKind.Qualified;

public CppTypePrinter() : base(TypePrinterContextKind.Native)
public CppTypePrinter(BindingContext context) : base(context, TypePrinterContextKind.Native)
{
PrintFlavorKind = CppTypePrintFlavorKind.Cpp;
PrintTypeQualifiers = true;
PrintTypeModifiers = true;
}

public CppTypePrinter(BindingContext context) : this()
{
Context = context;
}

public TypeMapDatabase TypeMapDatabase => Context.TypeMaps;
public DriverOptions Options => Context.Options;

Expand Down
8 changes: 0 additions & 8 deletions src/Generator/Generators/CLI/CLIGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ namespace CppSharp.Generators.CLI
/// </summary>
public class CLIGenerator : Generator
{
private readonly CppTypePrinter typePrinter;

public CLIGenerator(BindingContext context) : base(context)
{
typePrinter = new CLITypePrinter(context);
}

public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
Expand All @@ -39,10 +36,5 @@ public static bool ShouldGenerateClassNativeField(Class @class)

return @class.IsRefType && (!@class.NeedsBase || !@class.HasRefBase());
}

protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
}
}
10 changes: 1 addition & 9 deletions src/Generator/Generators/CSharp/CSharpGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@ namespace CppSharp.Generators.CSharp
{
public class CSharpGenerator : Generator
{
private readonly CSharpTypePrinter typePrinter;

public CSharpGenerator(BindingContext context) : base(context)
{
typePrinter = new CSharpTypePrinter(context);
}

public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
{
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);

return outputs;
Expand All @@ -42,10 +39,5 @@ public override bool SetupPasses()

return true;
}

protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter);
}
}
}
7 changes: 1 addition & 6 deletions src/Generator/Generators/CSharp/CSharpTypePrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,10 @@ public class CSharpTypePrinter : TypePrinter

public bool PrintModuleOutputNamespace = true;

public CSharpTypePrinter()
public CSharpTypePrinter(BindingContext context) : base(context)
{
}

public CSharpTypePrinter(BindingContext context)
{
Context = context;
}

public string QualifiedType(string name)
{
return IsGlobalQualifiedScope ? $"global::{name}" : name;
Expand Down
10 changes: 5 additions & 5 deletions src/Generator/Generators/Marshal.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using CppSharp.AST;
using CppSharp.Generators.C;
using System;

namespace CppSharp.Generators
{
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 };
Return = new TextGenerator { CurrentIndentation = indentation };
Cleanup = new TextGenerator { CurrentIndentation = indentation };
Expand All @@ -34,16 +34,16 @@ public MarshalContext(BindingContext context, uint indentation)
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; }

protected MarshalPrinter(C ctx)
{
Context = ctx;
typePrinter.Context = ctx.Context;
typePrinter = (P)Activator.CreateInstance(typeof(P), ctx.Context);
}

protected P typePrinter = new P();
protected P typePrinter;
}
}
11 changes: 11 additions & 0 deletions src/Generator/Generators/NAPI/NAPITypePrinter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using CppSharp.Generators.C;

namespace CppSharp.Generators.C
{
public class NAPITypePrinter : CppTypePrinter
{
public NAPITypePrinter(BindingContext context) : base(context)
{
}
}
}
8 changes: 0 additions & 8 deletions src/Generator/Generators/TS/TSGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ namespace CppSharp.Generators.TS
/// </summary>
public class TSGenerator : CGenerator
{
private readonly TSTypePrinter typePrinter;

public TSGenerator(BindingContext context) : base(context)
{
typePrinter = new TSTypePrinter(Context);
}

public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
Expand All @@ -32,10 +29,5 @@ public override bool SetupPasses()
{
return true;
}

protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
}
}
3 changes: 2 additions & 1 deletion src/Generator/Generators/TypePrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ public class TypePrinter : ITypePrinter<TypePrinterResult>,
public TypePrintScopeKind ScopeKind => scopeKinds.Peek();
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>();
marshalKinds = new Stack<MarshalKind>();
scopeKinds = new Stack<TypePrintScopeKind>();
Expand Down
Loading

0 comments on commit 8c2da6d

Please sign in to comment.