Browse Source

Merge 11b37ba40f into e093f713b9

pull/1808/merge
deadlocklogic 2 months ago committed by GitHub
parent
commit
68307b6981
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 10
      src/Generator/Generators/Registrable/Lua/Sol/LuaSolGenerationContext.cs
  2. 30
      src/Generator/Generators/Registrable/Lua/Sol/LuaSolGenerator.cs
  3. 24
      src/Generator/Generators/Registrable/Lua/Sol/LuaSolGeneratorOptions.cs
  4. 82
      src/Generator/Generators/Registrable/Lua/Sol/LuaSolHeaders.cs
  5. 10
      src/Generator/Generators/Registrable/Lua/Sol/LuaSolNamingStrategy.cs
  6. 2068
      src/Generator/Generators/Registrable/Lua/Sol/LuaSolSources.cs
  7. 12
      src/Generator/Generators/Registrable/Lua/Sol/LuaSolTypePrinter.cs
  8. 16
      src/Generator/Generators/Registrable/RegistrableCodeGenerator.cs
  9. 64
      src/Generator/Generators/Registrable/RegistrableGenerator.cs
  10. 129
      src/Generator/Generators/Registrable/RegistrableGeneratorContext.cs
  11. 98
      src/Generator/Generators/Registrable/RegistrableGeneratorOptions.cs
  12. 13
      src/Generator/Generators/Registrable/RegistrableHeaders.cs
  13. 6
      src/Generator/Generators/Registrable/RegistrableInfoEntries.cs
  14. 19
      src/Generator/Generators/Registrable/RegistrableModuleHeader.cs
  15. 19
      src/Generator/Generators/Registrable/RegistrableModuleSource.cs
  16. 460
      src/Generator/Generators/Registrable/RegistrableNamingStrategy.cs
  17. 13
      src/Generator/Generators/Registrable/RegistrableSources.cs
  18. 44
      src/Generator/Generators/Registrable/Utils/FQNOption.cs
  19. 65
      src/Generator/Generators/Registrable/Utils/InfoEntry.cs
  20. 16
      src/Generator/Generators/Registrable/Utils/InfoMap.cs
  21. 74
      src/Generator/Generators/Registrable/Utils/InfoMapStack.cs
  22. 22
      src/Generator/Generators/Registrable/Utils/TemplateParameterOption.cs
  23. 139
      src/Generator/Generators/Registrable/Utils/Utils.cs

10
src/Generator/Generators/Registrable/Lua/Sol/LuaSolGenerationContext.cs

@ -0,0 +1,10 @@
namespace CppSharp.Generators.Registrable.Lua.Sol
{
public class LuaSolGenerationContext : RegistrableGeneratorContext
{
public LuaSolGenerationContext()
: base()
{
}
}
}

30
src/Generator/Generators/Registrable/Lua/Sol/LuaSolGenerator.cs

@ -0,0 +1,30 @@
using CppSharp.AST;
using System.Collections.Generic;
namespace CppSharp.Generators.Registrable.Lua.Sol
{
public class LuaSolGenerator : RegistrableGenerator<LuaSolGeneratorOptions, LuaSolHeaders, LuaSolSources>
{
public const string Id = "Lua::Sol";
public static readonly GeneratorKind Kind = new(Id, "lua::sol", typeof(LuaSolGenerator), typeof(LuaSolTypePrinter), new[] { "lua::sol" });
public LuaSolGenerator(BindingContext context) : base(context)
{
}
protected override LuaSolGeneratorOptions CreateOptions()
{
return new LuaSolGeneratorOptions(this);
}
protected override LuaSolHeaders CreateHeader(IEnumerable<TranslationUnit> units)
{
return new LuaSolHeaders(this, units);
}
protected override LuaSolSources CreateSource(IEnumerable<TranslationUnit> units)
{
return new LuaSolSources(this, units);
}
}
}

24
src/Generator/Generators/Registrable/Lua/Sol/LuaSolGeneratorOptions.cs

@ -0,0 +1,24 @@
namespace CppSharp.Generators.Registrable.Lua.Sol
{
public class LuaSolGeneratorOptions : TRegistrableGeneratorOptions<LuaSolGenerator>
{
public LuaSolNamingStrategy NamingStrategy;
public LuaSolGeneratorOptions(LuaSolGenerator generator) : base(generator)
{
NamingStrategy = new LuaSolNamingStrategy(generator);
}
public override string DefaultRootContextType => "::sol::state_view&";
public override string DefaultRootContextName => "state";
public override string DefaultTemplateContextDefaultType => "::sol::table";
public override string DefaultTemplateContextDefaultValue => "::sol::nil";
public override string DefaultCmakeVariableHeader => "LUA_SOL_BINDINGS_HEADER";
public override string DefaultCmakeVariableSource => "LUA_SOL_BINDINGS_SOURCE";
}
}

82
src/Generator/Generators/Registrable/Lua/Sol/LuaSolHeaders.cs

@ -0,0 +1,82 @@
using System.Collections.Generic;
using CppSharp.AST;
namespace CppSharp.Generators.Registrable.Lua.Sol
{
public class LuaSolHeaders : LuaSolSources
{
public LuaSolHeaders(LuaSolGenerator generator, IEnumerable<TranslationUnit> units)
: base(generator, units)
{
}
public override string FileExtension => "h";
protected override bool TemplateAllowed { get { return true; } }
public override void Process()
{
GenerateFilePreamble(CommentKind.BCPL);
PushBlock();
WriteLine("#pragma once");
PopBlock(NewLineKind.BeforeNextBlock);
TranslationUnit.Visit(this);
}
#region TranslationUnit
public virtual void GenerateTranslationUnitRegistrationFunctionDeclaration(TranslationUnit translationUnit)
{
NewLine();
GenerateTranslationUnitRegistrationFunctionSignature(translationUnit);
WriteLine(";");
NewLine();
}
public override void GenerateTranslationUnit(TranslationUnit translationUnit)
{
GenerateTranslationUnitNamespaceBegin(translationUnit);
GenerateTranslationUnitRegistrationFunctionBody(translationUnit);
GenerateTranslationUnitRegistrationFunctionDeclaration(translationUnit);
GenerateTranslationUnitNamespaceEnd(translationUnit);
}
public override bool CanGenerateTranslationUnit(TranslationUnit unit)
{
if (AlreadyVisited(unit))
{
return false;
}
return true;
}
public override bool VisitTranslationUnit(TranslationUnit unit)
{
if (!CanGenerateTranslationUnit(unit))
{
return false;
}
GenerateTranslationUnit(unit);
return true;
}
#endregion
public virtual void GenerateMain()
{
VisitNamespace(TranslationUnit);
}
public virtual void GenerateIncludes()
{
if (Generator.GeneratorOptions.BaseInclude != null)
{
WriteLineIndent(Generator.GeneratorOptions.BaseInclude.ToString());
}
}
}
}

10
src/Generator/Generators/Registrable/Lua/Sol/LuaSolNamingStrategy.cs

@ -0,0 +1,10 @@
namespace CppSharp.Generators.Registrable.Lua.Sol
{
public class LuaSolNamingStrategy : RegistrableNamingStrategy<LuaSolGenerator>
{
public LuaSolNamingStrategy(LuaSolGenerator generator)
: base(generator)
{
}
}
}

2068
src/Generator/Generators/Registrable/Lua/Sol/LuaSolSources.cs

File diff suppressed because it is too large Load Diff

12
src/Generator/Generators/Registrable/Lua/Sol/LuaSolTypePrinter.cs

@ -0,0 +1,12 @@
using CppSharp.Generators;
using CppSharp.Generators.C;
namespace CppSharp.Generators.Registrable.Lua.Sol
{
public class LuaSolTypePrinter : CppTypePrinter
{
public LuaSolTypePrinter(BindingContext context) : base(context)
{
}
}
}

16
src/Generator/Generators/Registrable/RegistrableCodeGenerator.cs

@ -0,0 +1,16 @@
using CppSharp.AST;
using System.Collections.Generic;
namespace CppSharp.Generators.Registrable
{
public abstract class RegistrableCodeGenerator<TGenerator> : CodeGenerator
where TGenerator : Generator
{
public TGenerator Generator { get; set; }
public RegistrableCodeGenerator(TGenerator generator, IEnumerable<TranslationUnit> units) : base(generator.Context, units)
{
Generator = generator;
}
}
}

64
src/Generator/Generators/Registrable/RegistrableGenerator.cs

@ -0,0 +1,64 @@
using CppSharp.AST;
using System.Collections.Generic;
using System.IO;
namespace CppSharp.Generators.Registrable
{
public abstract class RegistrableGenerator<TOptions, THeader, TSource> : Generator
where TOptions : RegistrableGeneratorOptions
where THeader : CodeGenerator
where TSource : CodeGenerator
{
public TOptions GeneratorOptions { get; }
public TranslationUnit GlobalTranslationUnit { get; private set; }
public TranslationUnit InheritanceTranslationUnit { get; private set; }
// TODO: Implement when Generator interface is cleaner
// public CodeGenerator ModuleHeaderCodeGenerator { get; private set; }
// TODO: Implement when Generator interface is cleaner
//public CodeGenerator ModuleSourceCodeGenerator { get; private set; }
public RegistrableGenerator(BindingContext context) : base(context)
{
GeneratorOptions = CreateOptions();
}
protected abstract TOptions CreateOptions();
protected abstract THeader CreateHeader(IEnumerable<TranslationUnit> units);
protected abstract TSource CreateSource(IEnumerable<TranslationUnit> units);
public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
{
return new List<CodeGenerator>
{
CreateHeader(units),
CreateSource(units)
};
}
// TODO: Should be a better method for this maybe Configure.
public override bool SetupPasses()
{
{
var module = Context.Options.Modules[1];
GlobalTranslationUnit = Context.ASTContext.FindOrCreateTranslationUnit(
Path.Combine(Context.Options.OutputDir, GeneratorOptions.OutputSubDir, "@package", "global.h")
);
GlobalTranslationUnit.Module = module;
}
{
var module = Context.Options.Modules[1];
InheritanceTranslationUnit = Context.ASTContext.FindOrCreateTranslationUnit(
Path.Combine(Context.Options.OutputDir, GeneratorOptions.OutputSubDir, "@package", "inheritance.h")
);
InheritanceTranslationUnit.Module = module;
}
return true;
}
}
}

129
src/Generator/Generators/Registrable/RegistrableGeneratorContext.cs

@ -0,0 +1,129 @@
namespace CppSharp.Generators.Registrable
{
public class RegistrableGeneratorContext : InfoMapStack<object>
{
public static readonly InfoEntry IndentLevel = new("CppSharp.Generators.Registrable.IndentLevel");
public static readonly InfoEntry IsDetach = new("CppSharp.Generators.Registrable.IsDetach");
public static readonly InfoEntry RootContextName = new("CppSharp.Generators.Registrable.RootContextName");
public static readonly InfoEntry BindingContext = new("CppSharp.Generators.Registrable.BindingContext");
public static readonly InfoEntry CppContext = new("CppSharp.Generators.Registrable.CppContext");
public static readonly InfoEntry SanitizeType = new("CppSharp.Generators.Registrable.SanitizeType");
public static readonly InfoEntry TypeArgumentsPack = new("CppSharp.Generators.Registrable.TypeArgumentsPack");
public static readonly InfoEntry Resolvable = new("CppSharp.Generators.Registrable.Resolvable");
public static readonly InfoEntry TemplateLevel = new("CppSharp.Generators.Registrable.TemplateLevel");
public RegistrableGeneratorContext()
{
}
public DetachmentOption PeekIsDetach()
{
return PeekIsDetach(DetachmentOption.Off);
}
public DetachmentOption PeekIsDetach(DetachmentOption defaultValue)
{
return Peek(IsDetach, defaultValue);
}
public void PushIsDetach(DetachmentOption item)
{
Push(IsDetach, item);
}
public DetachmentOption PopIsDetach()
{
return Pop<DetachmentOption>(IsDetach);
}
public string PeekRootContextName(string defaultValue = default)
{
return Peek(RootContextName, defaultValue);
}
public void PushRootContextName(string item)
{
Push(RootContextName, item);
}
public string PopRootContextName()
{
return Pop<string>(RootContextName);
}
public string PeekBindingContext(string defaultValue = default)
{
return Peek(BindingContext, defaultValue);
}
public void PushBindingContext(string item)
{
Push(BindingContext, item);
}
public string PopBindingContext()
{
return Pop<string>(BindingContext);
}
public CppContext PeekCppContext(CppContext defaultValue = default)
{
return Peek(CppContext, defaultValue);
}
public void PushCppContext(CppContext item)
{
Push(CppContext, item);
}
public CppContext PopCppContext()
{
return Pop<CppContext>(CppContext);
}
public int PeekTemplateLevel(int defaultValue = default)
{
return Peek(TemplateLevel, defaultValue);
}
public void PushTemplateLevel(int item)
{
Push(TemplateLevel, item);
}
public int PopTemplateLevel()
{
return Pop<int>(TemplateLevel);
}
}
public class CppContext
{
public string FullyQualifiedName { get; set; }
public FQNOption Option { get; set; } = FQNOption.IgnoreAll;
public string GetFullQualifiedName(FQNOption option)
{
if (!option.IgnoreTemplateTypenameKeyword)
{
if (!Option.IgnoreTemplateTypenameKeyword)
{
return "typename " + FullyQualifiedName;
}
}
return FullyQualifiedName;
}
public string GetFullQualifiedName()
{
return GetFullQualifiedName(FQNOption.IgnoreNone);
}
};
public enum DetachmentOption
{
On,
Off,
Forced
}
}

98
src/Generator/Generators/Registrable/RegistrableGeneratorOptions.cs

@ -0,0 +1,98 @@
using CppSharp.Generators.C;
namespace CppSharp.Generators.Registrable
{
public enum ImportedClassTemplateMode
{
Direct,
Indirect,
Import
}
public abstract class RegistrableGeneratorOptions
{
public delegate string Delegate(string name);
public virtual Generator Generator { get; set; }
public virtual string OutputSubDir { get; }
public virtual string RootContextType { get; }
public virtual string RootContextName { get; }
public virtual string RegisterFunctionName { get; }
public virtual CInclude? BaseInclude { get; }
public Delegate BindingIdNamePredicate { get; }
public Delegate BindingIdValuePredicate { get; }
public Delegate BindingNamePredicate { get; }
public string TemplateTypenameState { get; }
public string TemplateTypenameContext { get; }
public string TemplateIdentifierState { get; }
public string TemplateIdentifierContext { get; }
public string TemplateContextDefaultType { get; }
public string TemplateContextDefaultValue { get; }
public ImportedClassTemplateMode ImportedTemplateMode { get; }
public string CppValidatorFileName { get; }
public string CmakeVariableHeader { get; }
public string CmakeVariableSource { get; }
public string EqualityFunctionTemplateFullyQualifiedName { get; }
public string StaticCastFunctionTemplateFullyQualifiedName { get; }
public string DynamicCastFunctionTemplateFullyQualifiedName { get; }
public virtual string DefaultOutputSubdir => "";
public abstract string DefaultRootContextType { get; }
public abstract string DefaultRootContextName { get; }
public virtual string DefaultRegisterFunctionName => "register_";
public virtual CInclude? DefaultBaseInclude => null;
public virtual Delegate DefaultBindingIdNamePredicate => (string name) => $"_cppbind_id_{name}";
public virtual Delegate DefaultBindingIdValuePredicate => (string name) => $"typeid({name}).name()";
public virtual Delegate DefaultBindingNamePredicate => (string name) => $"_cppbind_{name}";
public virtual string DefaultTemplateTypenameState => "CppBindState";
public virtual string DefaultTemplateTypenameContext => "CppBindContext";
public virtual string DefaultTemplateIdentifierState => "cpp_bind_state";
public virtual string DefaultTemplateIdentifierContext => "cpp_bind_context";
public abstract string DefaultTemplateContextDefaultType { get; }
public abstract string DefaultTemplateContextDefaultValue { get; }
public virtual ImportedClassTemplateMode DefaultImportedTemplateMode => ImportedClassTemplateMode.Indirect;
public virtual string DefaulCppValidatorFileName => "_cppbind_validator_";
public virtual string DefaultCmakeVariableHeader => "BINDINGS_HEADER";
public virtual string DefaultCmakeVariableSource => "BINDINGS_SOURCE";
public virtual string DefaultEqualityFunctionTemplateFullyQualifiedName => null;
public virtual string DefaultStaticCastFunctionTemplateFullyQualifiedName => null;
public virtual string DefaultDynamicCastFunctionTemplateFullyQualifiedName => null;
public RegistrableGeneratorOptions(Generator generator)
{
Generator = generator;
OutputSubDir = DefaultOutputSubdir;
RootContextType = DefaultRootContextType;
RootContextName = DefaultRootContextName;
RegisterFunctionName = DefaultRegisterFunctionName;
BaseInclude = DefaultBaseInclude;
BindingIdNamePredicate = DefaultBindingIdNamePredicate;
BindingIdValuePredicate = DefaultBindingIdValuePredicate;
BindingNamePredicate = DefaultBindingNamePredicate;
TemplateTypenameState = DefaultTemplateTypenameState;
TemplateTypenameContext = DefaultTemplateTypenameContext;
TemplateIdentifierState = DefaultTemplateIdentifierState;
TemplateIdentifierContext = DefaultTemplateIdentifierContext;
TemplateContextDefaultType = DefaultTemplateContextDefaultType;
TemplateContextDefaultValue = DefaultTemplateContextDefaultValue;
ImportedTemplateMode = DefaultImportedTemplateMode;
CppValidatorFileName = DefaulCppValidatorFileName;
CmakeVariableHeader = DefaultCmakeVariableHeader;
CmakeVariableSource = DefaultCmakeVariableSource;
EqualityFunctionTemplateFullyQualifiedName = DefaultEqualityFunctionTemplateFullyQualifiedName;
StaticCastFunctionTemplateFullyQualifiedName = DefaultStaticCastFunctionTemplateFullyQualifiedName;
DynamicCastFunctionTemplateFullyQualifiedName = DefaultDynamicCastFunctionTemplateFullyQualifiedName;
}
}
public abstract class TRegistrableGeneratorOptions<TGenerator> : RegistrableGeneratorOptions
where TGenerator : Generator
{
public override TGenerator Generator => (TGenerator)base.Generator;
public TRegistrableGeneratorOptions(TGenerator generator) : base(generator)
{
}
}
}

13
src/Generator/Generators/Registrable/RegistrableHeaders.cs

@ -0,0 +1,13 @@
using CppSharp.AST;
using System.Collections.Generic;
namespace CppSharp.Generators.Registrable
{
public abstract class RegistrableHeaders<TGenerator> : RegistrableCodeGenerator<TGenerator>
where TGenerator : Generator
{
public RegistrableHeaders(TGenerator generator, IEnumerable<TranslationUnit> units) : base(generator, units)
{
}
}
}

6
src/Generator/Generators/Registrable/RegistrableInfoEntries.cs

@ -0,0 +1,6 @@
namespace CppSharp.Generators.Registrable
{
public class RegistrableInfoEntries
{
}
}

19
src/Generator/Generators/Registrable/RegistrableModuleHeader.cs

@ -0,0 +1,19 @@
using CppSharp.AST;
using System.Collections.Generic;
namespace CppSharp.Generators.Registrable
{
public class RegistrableModuleHeader<TGenerator> : RegistrableCodeGenerator<TGenerator>
where TGenerator : Generator
{
public RegistrableModuleHeader(TGenerator generator, IEnumerable<TranslationUnit> units) : base(generator, units)
{
}
public override string FileExtension { get; } = "h";
public override void Process()
{
}
}
}

19
src/Generator/Generators/Registrable/RegistrableModuleSource.cs

@ -0,0 +1,19 @@
using CppSharp.AST;
using System.Collections.Generic;
namespace CppSharp.Generators.Registrable
{
public class RegistrableModuleSource<TGenerator> : RegistrableCodeGenerator<TGenerator>
where TGenerator : Generator
{
public RegistrableModuleSource(TGenerator generator, IEnumerable<TranslationUnit> units) : base(generator, units)
{
}
public override string FileExtension { get; } = "cpp";
public override void Process()
{
}
}
}

460
src/Generator/Generators/Registrable/RegistrableNamingStrategy.cs

@ -0,0 +1,460 @@
using CppSharp.AST;
using CppSharp.Generators.C;
using CppSharp.Generators.Registrable.Lua.Sol;
using System.Collections.Generic;
using System.Text;
namespace CppSharp.Generators.Registrable
{
public class RegistrableNamingStrategy<T> where T : LuaSolGenerator
{
protected T Generator;
public RegistrableNamingStrategy(T generator)
{
Generator = generator;
}
public bool IsNestedTemplate(Declaration declaration)
{
var currentDeclaration = declaration;
while (true)
{
currentDeclaration = currentDeclaration.OriginalNamespace;
if (currentDeclaration == null || currentDeclaration is TranslationUnit)
{
break;
}
if (Utils.FindDescribedTemplate(currentDeclaration) != null)
{
return true;
}
}
return false;
}
public virtual string PrintClassTemplateParameter(Declaration declaration, TemplateParameterOption option)
{
var builder = new StringBuilder();
if (declaration is TypeTemplateParameter typeTemplateParameter)
{
if (!option.IgnoreKeyword)
{
builder.Append("typename");
if (typeTemplateParameter.IsParameterPack)
{
builder.Append("...");
}
}
if (!string.IsNullOrEmpty(typeTemplateParameter.OriginalName))
{
if (!option.IgnoreKeyword)
{
builder.Append(' ');
}
if (option.CustomPrefix != null)
{
builder.Append(option.CustomPrefix);
}
builder.Append(typeTemplateParameter.OriginalName);
}
if (!option.IgnoreKeyword)
{
if (!option.IgnoreDefault)
{
if (typeTemplateParameter.DefaultArgument.Type != null)
{
builder.Append(" = ");
builder.Append(typeTemplateParameter.DefaultArgument.Type.Visit(new CppTypePrinter(Generator.Context)));
}
}
}
else
{
if (typeTemplateParameter.IsParameterPack)
{
builder.Append("...");
}
}
}
else if (declaration is NonTypeTemplateParameter nonTypeTemplateParameter)
{
if (!option.IgnoreKeyword)
{
builder.Append(nonTypeTemplateParameter.Type.Visit(new CppTypePrinter(Generator.Context)));
if (nonTypeTemplateParameter.IsParameterPack)
{
builder.Append("...");
}
}
if (!string.IsNullOrEmpty(nonTypeTemplateParameter.OriginalName))
{
if (!option.IgnoreKeyword)
{
builder.Append(' ');
}
if (option.CustomPrefix != null)
{
builder.Append(option.CustomPrefix);
}
builder.Append(nonTypeTemplateParameter.OriginalName);
}
if (!option.IgnoreKeyword)
{
if (!option.IgnoreDefault)
{
if (nonTypeTemplateParameter.DefaultArgument != null)
{
builder.Append(" = ");
builder.Append(nonTypeTemplateParameter.DefaultArgument.ToString());
}
}
}
else
{
if (nonTypeTemplateParameter.IsParameterPack)
{
builder.Append("...");
}
}
}
return builder.ToString();
}
public virtual string PrintClassTemplateParameters(List<Declaration> parameters, bool includeEnclosingBrackets, TemplateParameterOption option)
{
var builder = new StringBuilder();
if (includeEnclosingBrackets)
{
builder.Append('<');
}
for (int i = 0; i < parameters.Count; i++)
{
if (i > 0)
{
builder.Append(", ");
}
builder.Append(PrintClassTemplateParameter(parameters[i], option));
}
if (includeEnclosingBrackets)
{
builder.Append('>');
}
return builder.ToString();
}
public virtual string PrintClassTemplateSpecializationArgument(TemplateArgument templateArgument)
{
if (templateArgument.Kind == TemplateArgument.ArgumentKind.Integral)
{
return templateArgument.Integral.ToString();
}
return templateArgument.Type.Type.Visit(new CppTypePrinter(Generator.Context));
}
public virtual string PrintClassTemplateSpecializationArguments(List<TemplateArgument> arguments, bool includeEnclosingBrackets)
{
var builder = new StringBuilder();
if (includeEnclosingBrackets)
{
builder.Append('<');
}
for (int i = 0; i < arguments.Count; i++)
{
if (i > 0)
{
builder.Append(", ");
}
builder.Append(PrintClassTemplateSpecializationArgument(arguments[i]));
}
if (includeEnclosingBrackets)
{
builder.Append('>');
}
return builder.ToString();
}
public virtual string GetQualifiedName(Declaration declaration, FQNOption option)
{
if (declaration is TranslationUnit)
{
return "";
}
var name = declaration.OriginalName;
var currentDeclaration = declaration;
if (currentDeclaration is ClassTemplateSpecialization specialization)
{
if (!option.IgnoreTemplateParameters)
{
name = ($"{name}{PrintClassTemplateSpecializationArguments(specialization.Arguments, true)}");
}
}
else
{
Template template = null;
if (currentDeclaration is not ClassTemplate)
{
var describedTemplate = Utils.FindDescribedTemplate(currentDeclaration);
if (describedTemplate is ClassTemplate)
{
template = (ClassTemplate)describedTemplate;
}
}
if (template != null)
{
if (!option.IgnoreTemplateParameters)
{
name = ($"{name}{PrintClassTemplateParameters(template.Parameters, true, TemplateParameterOption.AsArgument)}");
}
}
}
return name;
}
public virtual string GetFullyQualifiedName(Declaration declaration, FQNOption option)
{
if (declaration is TranslationUnit)
{
return "";
}
var name = new StringBuilder();
var currentDeclaration = declaration;
var needsTypename = false;
var depth = 0;
while (true)
{
if (currentDeclaration == null || currentDeclaration is TranslationUnit)
{
break;
}
depth += 1;
var currentName = new StringBuilder();
currentName.Append(currentDeclaration.OriginalName);
if (currentDeclaration is ClassTemplateSpecialization specialization)
{
if (!option.IgnoreTemplateTemplateKeyword)
{
if (IsNestedTemplate(currentDeclaration))
{
currentName.Insert(0, "template ");
}
}
if (!option.IgnoreTemplateParameters)
{
if (depth > 1)
{
needsTypename = true;
}
currentName.Append(PrintClassTemplateSpecializationArguments(specialization.Arguments, true));
}
}
else
{
if (currentDeclaration is not ClassTemplate template)
{
template = (ClassTemplate)Utils.FindDescribedTemplate(currentDeclaration);
}
if (template != null)
{
if (!option.IgnoreTemplateTemplateKeyword)
{
if (IsNestedTemplate(currentDeclaration))
{
currentName.Insert(0, "template ");
}
}
if (!option.IgnoreTemplateParameters)
{
if (depth > 1)
{
needsTypename = true;
}
currentName.Append($"{name}{PrintClassTemplateParameters(template.Parameters, true, TemplateParameterOption.AsArgument)}");
}
}
}
if (name.Length != 0)
{
name.Insert(0, "::");
}
name.Insert(0, currentName);
currentDeclaration = currentDeclaration.OriginalNamespace;
}
if (!option.IgnoreGlobalNamespace)
{
name.Insert(0, "::");
}
if (!option.IgnoreTemplateTypenameKeyword)
{
if (needsTypename)
{
name.Insert(0, "typename ");
}
}
return name.ToString();
}
public virtual string GetContextualName(Declaration declaration, RegistrableGeneratorContext context, FQNOption option)
{
Class @class = null;
Template template = null;
if (declaration is Class)
{
@class = declaration as Class;
template = Utils.FindDescribedTemplate(declaration);
}
else if (declaration is ClassTemplate classTemplate)
{
@class = classTemplate.TemplatedClass;
template = classTemplate;
}
if (@class is Class)
{
if (template is ClassTemplate)
{
// TODO: check if ClassTemplate is collapsible
}
if (@class.Access == AccessSpecifier.Protected)
{
return GetCppContext(@class, context, FQNOption.IgnoreNone);
}
return GetFullyQualifiedName(declaration, option);
}
return GetCppContext(declaration, context, new FQNOption(false, true, false, false)) + "::" + GetQualifiedName(declaration, option);
}
public virtual string GetRegistrationFunctionName(Declaration declaration, bool isRecusrive = false)
{
if (declaration is TranslationUnit translationUnit)
{
return isRecusrive ? "" : $"register_{translationUnit.FileNameWithoutExtension}";
}
var name = declaration.OriginalName;
var currentDeclaration = declaration;
while (true)
{
currentDeclaration = currentDeclaration.OriginalNamespace;
if (currentDeclaration == null || currentDeclaration is TranslationUnit)
{
break;
}
name = currentDeclaration.OriginalName + "_" + name;
}
return name;
}
public virtual string GetRegistrationNameQuoted(Declaration declaration)
{
return $"\"{declaration.Name}\"";
}
public virtual string GetBindingIdName(Declaration declaration)
{
return Generator.GeneratorOptions.BindingIdNamePredicate(GetRegistrationFunctionName(declaration));
}
public virtual string GetBindingIdValue(Declaration declaration, RegistrableGeneratorContext context)
{
return Generator.GeneratorOptions.BindingIdValuePredicate(GetContextualName(declaration, context, FQNOption.IgnoreNone));
}
public virtual string GetBindingName(Declaration declaration)
{
return Generator.GeneratorOptions.BindingNamePredicate(GetRegistrationFunctionName(declaration));
}
public virtual string GetRootContextName(RegistrableGeneratorContext context)
{
if (context != null)
{
var rootContextName = context.PeekRootContextName();
if (rootContextName != null)
{
return rootContextName;
}
}
return "state";
}
public virtual string GetBindingContextNamespacePredicate(string state, string key)
{
return $"get_namespace({state}, \"{key}\")";
}
public virtual string GetBindingContext(Declaration declaration, RegistrableGeneratorContext context)
{
if (context != null)
{
var rootContextName = context.PeekRootContextName();
if (rootContextName != null)
{
return rootContextName;
}
}
if (declaration.Namespace is TranslationUnit)
{
return GetRootContextName(context);
}
else
{
var name = GetRootContextName(context);
var currentDeclaration = declaration.Namespace;
var parentList = new List<Declaration>();
while (true)
{
if (currentDeclaration == null || currentDeclaration is TranslationUnit)
{
break;
}
parentList.Insert(0, currentDeclaration);
currentDeclaration = currentDeclaration.Namespace;
}
foreach (var parent in parentList)
{
name = GetBindingContextNamespacePredicate(name, parent.Name);
}
return name;
}
}
public virtual string GetCppContext(Declaration entity, RegistrableGeneratorContext context, FQNOption option)
{
if (context != null)
{
var cppContext = context.PeekCppContext();
if (cppContext != null)
{
return cppContext.GetFullQualifiedName(option);
}
}
return GetFullyQualifiedName(entity.OriginalNamespace, option);
}
public virtual string GetMembershipScopeName(Function function, RegistrableGeneratorContext context)
{
if (function is Method method)
{
return GetCppContext(method, context, new FQNOption()
{
IgnoreTemplateTypenameKeyword = true
}) + "::";
}
return "";
}
public virtual string GetClassTemplateName(Declaration declaration)
{
return $"functor_{GetRegistrationFunctionName(declaration)}";
}
}
}

13
src/Generator/Generators/Registrable/RegistrableSources.cs

@ -0,0 +1,13 @@
using CppSharp.AST;
using System.Collections.Generic;
namespace CppSharp.Generators.Registrable
{
public abstract class RegistrableSources<TGenerator> : RegistrableCodeGenerator<TGenerator>
where TGenerator : Generator
{
public RegistrableSources(TGenerator generator, IEnumerable<TranslationUnit> units) : base(generator, units)
{
}
}
}

44
src/Generator/Generators/Registrable/Utils/FQNOption.cs

@ -0,0 +1,44 @@
namespace CppSharp.Generators.Registrable
{
public class FQNOption
{
public static readonly FQNOption IgnoreNone = new(false, false, false, false);
public static readonly FQNOption IgnoreAll = new(true, true, true, true);
public bool IgnoreGlobalNamespace { get; set; }
public bool IgnoreTemplateTypenameKeyword { get; set; }
public bool IgnoreTemplateTemplateKeyword { get; set; }
public bool IgnoreTemplateParameters { get; set; }
public FQNOption(bool ignoreGlobalNamespace = false,
bool ignoreTemplateTypenameKeyword = false,
bool ignoreTemplateTemplateKeyword = false,
bool ignoreTemplateParameters = false)
{
IgnoreGlobalNamespace = ignoreGlobalNamespace;
IgnoreTemplateTypenameKeyword = ignoreTemplateTypenameKeyword;
IgnoreTemplateTemplateKeyword = ignoreTemplateTemplateKeyword;
IgnoreTemplateParameters = ignoreTemplateParameters;
}
public static FQNOption operator |(FQNOption lhs, FQNOption rhs)
{
return new FQNOption(
lhs.IgnoreGlobalNamespace | rhs.IgnoreGlobalNamespace,
lhs.IgnoreTemplateTypenameKeyword | rhs.IgnoreTemplateTypenameKeyword,
lhs.IgnoreTemplateTemplateKeyword | rhs.IgnoreTemplateTemplateKeyword,
lhs.IgnoreTemplateParameters | rhs.IgnoreTemplateParameters
);
}
public static FQNOption operator &(FQNOption lhs, FQNOption rhs)
{
return new FQNOption(
lhs.IgnoreGlobalNamespace & rhs.IgnoreGlobalNamespace,
lhs.IgnoreTemplateTypenameKeyword & rhs.IgnoreTemplateTypenameKeyword,
lhs.IgnoreTemplateTemplateKeyword & rhs.IgnoreTemplateTemplateKeyword,
lhs.IgnoreTemplateParameters & rhs.IgnoreTemplateParameters
);
}
}
}

65
src/Generator/Generators/Registrable/Utils/InfoEntry.cs

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace CppSharp.Generators.Registrable
{
public class InfoEntry : IEquatable<InfoEntry>
{
public static readonly HashSet<InfoEntry> Registered = new();
public string Name { get; }
public InfoEntry(string name)
{
if (Registered.Any(kind => kind.Name == name))
{
throw new Exception($"InfoEntry has an already registered name: {Name}");
}
Name = name;
Registered.Add(this);
}
public static bool operator ==(InfoEntry obj1, InfoEntry obj2)
{
if (ReferenceEquals(obj1, obj2))
{
return true;
}
if (obj1 is null)
{
return false;
}
if (obj2 is null)
{
return false;
}
return obj1.Equals(obj2);
}
public static bool operator !=(InfoEntry obj1, InfoEntry obj2) => !(obj1 == obj2);
public bool Equals(InfoEntry other)
{
if (other is null)
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
return Name.Equals(other.Name);
}
public override bool Equals(object obj) => Equals(obj as InfoEntry);
public override int GetHashCode()
{
unchecked
{
return Name.GetHashCode();
}
}
}
}

16
src/Generator/Generators/Registrable/Utils/InfoMap.cs

@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace CppSharp.Generators.Registrable
{
public class InfoMap<T> : Dictionary<InfoEntry, T>
{
public InfoMap() : base()
{
}
public T1 Get<T1>(InfoEntry infoEntry) where T1 : T
{
return (T1)this[infoEntry];
}
}
}

74
src/Generator/Generators/Registrable/Utils/InfoMapStack.cs

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace CppSharp.Generators.Registrable
{
public class InfoMapStack<T> : InfoMap<Stack<T>>
{
public InfoMapStack() : base()
{
}
public T1 Peek<T1>(InfoEntry infoEntry, T1 defaultValue = default) where T1 : T
{
if (TryGetValue(infoEntry, out Stack<T> stack))
{
if (stack.Count > 0)
{
return (T1)stack.Peek();
}
}
return defaultValue;
}
public T1 Pop<T1>(InfoEntry infoEntry) where T1 : T
{
if (TryGetValue(infoEntry, out Stack<T> stack))
{
return (T1)stack.Pop();
}
throw new InvalidOperationException();
}
public void Push<T1>(InfoEntry infoEntry, T1 item) where T1 : T
{
if (!TryGetValue(infoEntry, out Stack<T> stack))
{
this[infoEntry] = stack = new Stack<T>();
}
stack.Push(item);
}
public bool TryPeek<T1>(InfoEntry infoEntry, [MaybeNullWhen(false)] out T1 result) where T1 : T
{
if (TryGetValue(infoEntry, out Stack<T> stack))
{
bool tempReturn = stack.TryPop(out T tempResult);
result = (T1)tempResult;
return tempReturn;
}
result = default;
return false;
}
public bool TryPop<T1>(InfoEntry infoEntry, [MaybeNullWhen(false)] out T1 result) where T1 : T
{
if (TryGetValue(infoEntry, out Stack<T> stack))
{
bool tempReturn = stack.TryPop(out T tempResult);
result = (T1)tempResult;
return tempReturn;
}
result = default;
return false;
}
public void Scoped(InfoEntry infoEntry, T item, Action action)
{
Push(infoEntry, item);
action();
Pop<T>(infoEntry);
}
}
}

22
src/Generator/Generators/Registrable/Utils/TemplateParameterOption.cs

@ -0,0 +1,22 @@
namespace CppSharp.Generators.Registrable
{
public class TemplateParameterOption
{
public static readonly TemplateParameterOption AsParameter = new(false, false);
public static readonly TemplateParameterOption AsParameterNoDefault = new(false, true);
public static readonly TemplateParameterOption AsArgument = new(true, true);
public bool IgnoreKeyword { get; set; }
public bool IgnoreDefault { get; set; }
public string CustomPrefix { get; set; }
TemplateParameterOption(bool ignoreKeyword = false,
bool ignoreDefault = false,
string customPrefix = "")
{
IgnoreKeyword = ignoreKeyword;
IgnoreDefault = ignoreDefault;
CustomPrefix = customPrefix;
}
}
}

139
src/Generator/Generators/Registrable/Utils/Utils.cs

@ -0,0 +1,139 @@
using CppSharp.AST;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CppSharp.Generators.Registrable
{
public static class Utils
{
public static Template FindDescribedTemplate(Declaration declaration)
{
foreach (var template in declaration.Namespace.Templates)
{
if (template.TemplatedDecl == declaration)
{
return template;
}
}
return null;
}
public static DetachmentOption FindDetachmentOption(Declaration declaration)
{
return (declaration.Namespace is Class) ? DetachmentOption.Off : DetachmentOption.On;
}
public static bool HasPossibleOverload(Function function)
{
var parent = function.OriginalNamespace;
if (parent is Class @class)
{
foreach (var item in @class.Methods)
{
if (item.OriginalFunction == null)
{
if (item != function)
{
if (item.OriginalName == function.Name)
{
return true;
}
}
}
}
foreach (var item in @class.Functions)
{
if (item.OriginalFunction == null)
{
if (item != function)
{
if (item.OriginalName == function.Name)
{
return true;
}
}
}
}
foreach (var item in @class.Templates.Where(template => template is FunctionTemplate).Cast<FunctionTemplate>())
{
var templatedFunction = item.TemplatedFunction;
if (templatedFunction.OriginalFunction == null)
{
if (templatedFunction != function)
{
if (templatedFunction.OriginalName == function.Name)
{
return true;
}
}
}
}
return false;
}
return true;
}
public static bool HasPossibleTemplateOverload(Function function)
{
var parent = function.OriginalNamespace;
if (parent is Class @class)
{
foreach (var item in @class.Templates.Where(template => template is FunctionTemplate).Cast<FunctionTemplate>())
{
var templatedFunction = item.TemplatedFunction;
if (templatedFunction.OriginalFunction == null)
{
if (templatedFunction != function)
{
if (templatedFunction.OriginalName == function.Name)
{
return true;
}
}
}
}
return false;
}
return true;
}
public static bool HasPossibleTemplateOverload(Method method)
{
if (method.Kind == CXXMethodKind.UsingDirective)
{
return true;
}
return HasPossibleTemplateOverload(method as Function);
}
public static bool IsDefaultTemplateParameter(Declaration parameter)
{
if (parameter is TypeTemplateParameter typeTemplateParameter)
{
return typeTemplateParameter.DefaultArgument.Type != null;
}
else if (parameter is NonTypeTemplateParameter nonTypeTemplateParameter)
{
return nonTypeTemplateParameter.DefaultArgument != null;
}
else if (parameter is TemplateTemplateParameter templateTemplateParameter)
{
throw new InvalidOperationException();
}
throw new InvalidOperationException();
}
public static bool IsDefaultTemplateParameterList(List<Declaration> parameters)
{
foreach (var parameter in parameters)
{
if (!IsDefaultTemplateParameter(parameter))
{
return false;
}
}
return true;
}
}
}
Loading…
Cancel
Save