Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 && ([email protected] || [email protected]());
}

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 && ([email protected] || [email protected]());
}

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