mirror of https://github.com/mono/CppSharp.git
14 changed files with 1280 additions and 100 deletions
@ -0,0 +1,221 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using CppSharp.AST; |
||||||
|
using CppSharp.AST.Extensions; |
||||||
|
using CppSharp.Generators; |
||||||
|
using CppSharp.Generators.C; |
||||||
|
using CppSharp.Generators.CSharp; |
||||||
|
|
||||||
|
using static CppSharp.CodeGeneratorHelpers; |
||||||
|
|
||||||
|
namespace CppSharp |
||||||
|
{ |
||||||
|
internal class DeclDeclarationsCodeGenerator : DeclarationsCodeGenerator |
||||||
|
{ |
||||||
|
public DeclDeclarationsCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations) |
||||||
|
: base(context, declarations) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override string BaseTypeName => "Decl"; |
||||||
|
|
||||||
|
public override void GenerateIncludes() |
||||||
|
{ |
||||||
|
WriteInclude("Sources.h", CInclude.IncludeKind.Quoted); |
||||||
|
WriteInclude("Types.h", CInclude.IncludeKind.Quoted); |
||||||
|
WriteInclude("string", CInclude.IncludeKind.Angled); |
||||||
|
} |
||||||
|
|
||||||
|
public override void GenerateForwardDecls() |
||||||
|
{ |
||||||
|
WriteLine("class Expr;"); |
||||||
|
WriteLine("class Stmt;"); |
||||||
|
WriteLine("class LabelStmt;"); |
||||||
|
WriteLine("class EvaluatedStmt;"); |
||||||
|
WriteLine("class CompoundStmt;"); |
||||||
|
WriteLine("enum class OverloadedOperatorKind;"); |
||||||
|
NewLine(); |
||||||
|
WriteLine("class Declaration;"); |
||||||
|
WriteLine("class UsingDirectiveDecl;"); |
||||||
|
WriteLine("class FriendDecl;"); |
||||||
|
WriteLine("class ConstructorUsingShadowDecl;"); |
||||||
|
WriteLine("class LinkageSpecDecl;"); |
||||||
|
WriteLine("class NamedDecl;"); |
||||||
|
WriteLine("class NamespaceDecl;"); |
||||||
|
WriteLine("class TemplateDecl;"); |
||||||
|
WriteLine("class ClassTemplateDecl;"); |
||||||
|
WriteLine("class VarTemplateDecl;"); |
||||||
|
WriteLine("class TypeAliasTemplateDecl;"); |
||||||
|
WriteLine("class FunctionDecl;"); |
||||||
|
WriteLine("class FunctionTemplateDecl;"); |
||||||
|
WriteLine("class CXXMethodDecl;"); |
||||||
|
WriteLine("class CXXConstructorDecl;"); |
||||||
|
WriteLine("class CXXDestructorDecl;"); |
||||||
|
WriteLine("class BaseUsingDecl;"); |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitClassDecl(Class @class) |
||||||
|
{ |
||||||
|
if (SkipClass(@class)) |
||||||
|
return false; |
||||||
|
|
||||||
|
@class.Bases.Find(x => x.Class?.Name == "Node") |
||||||
|
?.ExplicitlyIgnore(); |
||||||
|
|
||||||
|
return base.VisitClassDecl(@class); |
||||||
|
} |
||||||
|
|
||||||
|
public override bool GenerateClassBody(Class @class) |
||||||
|
{ |
||||||
|
Unindent(); |
||||||
|
WriteLine("public:"); |
||||||
|
Indent(); |
||||||
|
|
||||||
|
PushBlock(); |
||||||
|
VisitDeclContext(@class); |
||||||
|
PopBlock(NewLineKind.Always); |
||||||
|
|
||||||
|
WriteLine($"{@class.Name}();"); |
||||||
|
|
||||||
|
foreach (var method in @class.Methods) |
||||||
|
{ |
||||||
|
if (SkipMethod(method)) |
||||||
|
continue; |
||||||
|
|
||||||
|
var iteratorType = GetIteratorType(method); |
||||||
|
string iteratorTypeName = GetIteratorTypeName(iteratorType, CodeGeneratorHelpers.CppTypePrinter); |
||||||
|
|
||||||
|
WriteLine($"VECTOR({iteratorTypeName}, {method.Name})"); |
||||||
|
} |
||||||
|
|
||||||
|
foreach (var property in @class.Properties) |
||||||
|
{ |
||||||
|
if (SkipProperty(property) || property.IsStatic) |
||||||
|
continue; |
||||||
|
|
||||||
|
string typeName = GetDeclTypeName(property); |
||||||
|
|
||||||
|
if (typeName.StartsWith("TemplateArgumentList")) |
||||||
|
{ |
||||||
|
WriteLine($"VECTOR(TemplateArgument*, {GetDeclName(property)})"); |
||||||
|
} |
||||||
|
else if (typeName.StartsWith("TemplateParameterList")) |
||||||
|
{ |
||||||
|
WriteLine($"VECTOR(NamedDecl*, {GetDeclName(property)})"); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
WriteLine($"{typeName} {GetDeclName(property)};"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class DeclDefinitionsCodeGenerator : DefinitionsCodeGenerator |
||||||
|
{ |
||||||
|
public DeclDefinitionsCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations) |
||||||
|
: base(context, declarations) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override string BaseTypeName => "Decl"; |
||||||
|
|
||||||
|
public override void GenerateIncludes() |
||||||
|
{ |
||||||
|
GenerateCommonIncludes(); |
||||||
|
NewLine(); |
||||||
|
WriteInclude("Decl.h", CInclude.IncludeKind.Quoted); |
||||||
|
WriteInclude("Types.h", CInclude.IncludeKind.Quoted); |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitClassDecl(Class @class) |
||||||
|
{ |
||||||
|
if (!@class.IsGenerated) |
||||||
|
return false; |
||||||
|
|
||||||
|
VisitDeclContext(@class); |
||||||
|
|
||||||
|
var isBaseType = @class.Name == BaseTypeName; |
||||||
|
if (!isBaseType && !@class.HasBaseClass) |
||||||
|
{ |
||||||
|
WriteLine($"{GetQualifiedName(@class)}::{@class.Name}()"); |
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
NewLine(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
WriteLine($"{@class.Name}::{@class.Name}()"); |
||||||
|
GenerateMemberInits(@class); |
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
NewLine(); |
||||||
|
|
||||||
|
foreach (var method in @class.Methods) |
||||||
|
{ |
||||||
|
if (SkipMethod(method)) |
||||||
|
continue; |
||||||
|
|
||||||
|
var iteratorType = GetIteratorType(method); |
||||||
|
string iteratorTypeName = GetIteratorTypeName(iteratorType, |
||||||
|
CodeGeneratorHelpers.CppTypePrinter); |
||||||
|
|
||||||
|
WriteLine($"DEF_VECTOR({@class.Name}, {iteratorTypeName}, {method.Name})"); |
||||||
|
NewLine(); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class DeclASTConverterCodeGenerator : ASTConverterCodeGenerator |
||||||
|
{ |
||||||
|
public DeclASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations) |
||||||
|
: base(context, declarations) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override string BaseTypeName => "Decl"; |
||||||
|
|
||||||
|
public override bool IsAbstractASTNode(Class kind) |
||||||
|
{ |
||||||
|
return IsAbstractDecl(kind); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void GenerateVisitorSwitch(IEnumerable<string> classes) |
||||||
|
{ |
||||||
|
WriteLine($"switch({ParamName}.DeclKind)"); |
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
|
||||||
|
GenerateSwitchCases(classes); |
||||||
|
|
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
} |
||||||
|
|
||||||
|
private void GenerateSwitchCases(IEnumerable<string> classes) |
||||||
|
{ |
||||||
|
foreach (var className in classes) |
||||||
|
{ |
||||||
|
WriteLine($"case Parser.AST.{BaseTypeName}Kind.{className}:"); |
||||||
|
WriteLineIndent($"return Visit{className}({ParamName} as Parser.AST.{className}Decl);"); |
||||||
|
} |
||||||
|
foreach (var className in classes) |
||||||
|
{ |
||||||
|
WriteLine($"case StmtClass.{className}:"); |
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
|
||||||
|
WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);"); |
||||||
|
|
||||||
|
WriteLine($"return Visit{className}(_{ParamName});"); |
||||||
|
|
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
} |
||||||
|
|
||||||
|
WriteLine("default:"); |
||||||
|
WriteLineIndent($"throw new System.NotImplementedException({ParamName}.DeclKind.ToString());"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using CppSharp.AST; |
||||||
|
|
||||||
|
namespace CppSharp |
||||||
|
{ |
||||||
|
class InheritanceValidator |
||||||
|
{ |
||||||
|
private readonly HashSet<string> _processedClasses = new(); |
||||||
|
|
||||||
|
public void ValidateInheritance(IEnumerable<Declaration> declarations) |
||||||
|
{ |
||||||
|
foreach (var decl in declarations.OfType<Class>()) |
||||||
|
{ |
||||||
|
if (!_processedClasses.Add(decl.Name)) |
||||||
|
continue; |
||||||
|
|
||||||
|
ValidateClassInheritance(decl); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void ValidateClassInheritance(Class @class) |
||||||
|
{ |
||||||
|
if (@class.Bases.Count == 0) |
||||||
|
return; |
||||||
|
|
||||||
|
foreach (var @base in @class.Bases) |
||||||
|
{ |
||||||
|
if (@base.Class == null) |
||||||
|
continue; |
||||||
|
|
||||||
|
ValidateClassInheritance(@base.Class); |
||||||
|
} |
||||||
|
|
||||||
|
// Ensure base class properties don't conflict
|
||||||
|
foreach (var property in @class.Properties) |
||||||
|
{ |
||||||
|
if (@class.GetBaseProperty(property) != null) |
||||||
|
{ |
||||||
|
property.ExplicitlyIgnore(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Handle method overrides
|
||||||
|
foreach (var method in @class.Methods) |
||||||
|
{ |
||||||
|
if (@class.GetBaseMethod(method) != null) |
||||||
|
{ |
||||||
|
method.ExplicitlyIgnore(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using CppSharp.AST; |
||||||
|
using CppSharp.AST.Extensions; |
||||||
|
using CppSharp.Generators; |
||||||
|
using CppSharp.Generators.C; |
||||||
|
using CppSharp.Generators.CSharp; |
||||||
|
|
||||||
|
using static CppSharp.CodeGeneratorHelpers; |
||||||
|
|
||||||
|
namespace CppSharp |
||||||
|
{ |
||||||
|
class DeclParserCodeGenerator : StmtParserCodeGenerator |
||||||
|
{ |
||||||
|
public DeclParserCodeGenerator(BindingContext context, |
||||||
|
IEnumerable<Declaration> declarations) |
||||||
|
: base(context, declarations, null) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override void GenerateIncludes() |
||||||
|
{ |
||||||
|
WriteInclude("clang/AST/Decl.h", CInclude.IncludeKind.Angled); |
||||||
|
WriteInclude("clang/AST/DeclCXX.h", CInclude.IncludeKind.Angled); |
||||||
|
WriteInclude("clang/AST/DeclTemplate.h", CInclude.IncludeKind.Angled); |
||||||
|
} |
||||||
|
|
||||||
|
public override string BaseTypeName => "Decl"; |
||||||
|
|
||||||
|
public override string MethodSig => |
||||||
|
"AST::Decl* Parser::WalkDeclaration(const clang::Decl* Decl)"; |
||||||
|
|
||||||
|
public override bool VisitProperty(Property property) |
||||||
|
{ |
||||||
|
if (SkipDeclProperty(property)) |
||||||
|
return false; |
||||||
|
|
||||||
|
var typeName = GetDeclTypeName(property); |
||||||
|
var fieldName = GetDeclName(property); |
||||||
|
var methodName = property.GetMethod?.Name; |
||||||
|
|
||||||
|
Write($"_D->{fieldName} = "); |
||||||
|
if (property.Type.TryGetClass(out Class @class)) |
||||||
|
{ |
||||||
|
if (@class.Name.Contains("Type")) |
||||||
|
WriteLine($"GetQualifiedType(D->{methodName}());"); |
||||||
|
else if (@class.Name.Contains("Decl")) |
||||||
|
WriteLine($"WalkDeclaration(D->{methodName}());"); |
||||||
|
else |
||||||
|
WriteLine($"D->{methodName}();"); |
||||||
|
} |
||||||
|
else |
||||||
|
WriteLine($"D->{methodName}();"); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class TypeParserCodeGenerator : StmtParserCodeGenerator |
||||||
|
{ |
||||||
|
public TypeParserCodeGenerator(BindingContext context, |
||||||
|
IEnumerable<Declaration> declarations) |
||||||
|
: base(context, declarations, null) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override void GenerateIncludes() |
||||||
|
{ |
||||||
|
WriteInclude("clang/AST/Type.h", CInclude.IncludeKind.Angled); |
||||||
|
WriteInclude("clang/AST/CXXType.h", CInclude.IncludeKind.Angled); |
||||||
|
} |
||||||
|
|
||||||
|
public override string BaseTypeName => "Type"; |
||||||
|
|
||||||
|
public override string MethodSig => |
||||||
|
"AST::Type* Parser::WalkType(const clang::Type* Type)"; |
||||||
|
|
||||||
|
public override bool VisitProperty(Property property) |
||||||
|
{ |
||||||
|
if (CodeGeneratorHelpers.SkipTypeProperty(property)) |
||||||
|
return false; |
||||||
|
|
||||||
|
var typeName = GetDeclTypeName(property); |
||||||
|
var fieldName = GetDeclName(property); |
||||||
|
var methodName = property.GetMethod?.Name; |
||||||
|
|
||||||
|
WriteLine($"_T->{fieldName} = "); |
||||||
|
if (property.Type.TryGetClass(out Class @class)) |
||||||
|
{ |
||||||
|
if (@class.Name.Contains("Type")) |
||||||
|
WriteLine($"GetQualifiedType(T->{methodName}());"); |
||||||
|
else if (@class.Name.Contains("Decl")) |
||||||
|
WriteLine($"WalkDeclaration(T->{methodName}());"); |
||||||
|
else |
||||||
|
WriteLine($"T->{methodName}();"); |
||||||
|
} |
||||||
|
else |
||||||
|
WriteLine($"T->{methodName}();"); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,323 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using CppSharp.AST; |
||||||
|
using CppSharp.AST.Extensions; |
||||||
|
using CppSharp.Generators; |
||||||
|
using CppSharp.Generators.C; |
||||||
|
using CppSharp.Generators.CSharp; |
||||||
|
|
||||||
|
using static CppSharp.CodeGeneratorHelpers; |
||||||
|
|
||||||
|
namespace CppSharp |
||||||
|
{ |
||||||
|
class TypeDeclarationsCodeGenerator : StmtDeclarationsCodeGenerator |
||||||
|
{ |
||||||
|
public TypeDeclarationsCodeGenerator(BindingContext context, |
||||||
|
IEnumerable<Declaration> declarations) |
||||||
|
: base(context, declarations) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override void GenerateIncludes() |
||||||
|
{ |
||||||
|
WriteInclude("Sources.h", CInclude.IncludeKind.Quoted); |
||||||
|
WriteInclude("string", CInclude.IncludeKind.Angled); |
||||||
|
WriteInclude("memory", CInclude.IncludeKind.Angled); |
||||||
|
WriteInclude("vector", CInclude.IncludeKind.Angled); |
||||||
|
} |
||||||
|
|
||||||
|
public override void GenerateForwardDecls() |
||||||
|
{ |
||||||
|
WriteLine("class Decl;"); |
||||||
|
WriteLine("class TemplateArgument;"); |
||||||
|
WriteLine("class TemplateParameterList;"); |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitClassDecl(Class @class) |
||||||
|
{ |
||||||
|
if (!@class.IsGenerated) |
||||||
|
return false; |
||||||
|
|
||||||
|
GenerateClassSpecifier(@class); |
||||||
|
NewLine(); |
||||||
|
|
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
|
||||||
|
PushBlock(); |
||||||
|
VisitDeclContext(@class); |
||||||
|
PopBlock(NewLineKind.Always); |
||||||
|
|
||||||
|
WriteLine($"public:"); |
||||||
|
Indent(); |
||||||
|
|
||||||
|
WriteLine($"{@class.Name}();"); |
||||||
|
|
||||||
|
if (@class.Name == "Type") |
||||||
|
WriteLine("TypeClass typeClass;"); |
||||||
|
|
||||||
|
foreach (var method in @class.Methods) |
||||||
|
{ |
||||||
|
if (SkipMethod(method)) |
||||||
|
continue; |
||||||
|
|
||||||
|
GenerateMethod(method); |
||||||
|
} |
||||||
|
|
||||||
|
foreach (var property in @class.Properties) |
||||||
|
{ |
||||||
|
if (SkipProperty(property)) |
||||||
|
continue; |
||||||
|
|
||||||
|
GenerateProperty(property); |
||||||
|
} |
||||||
|
|
||||||
|
Unindent(); |
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
protected void GenerateMethod(Method method) |
||||||
|
{ |
||||||
|
// Validate all method parameters first
|
||||||
|
foreach (var param in method.Parameters) |
||||||
|
{ |
||||||
|
ValidateTypeMethodParameter(param); |
||||||
|
} |
||||||
|
|
||||||
|
var iteratorType = GetIteratorType(method); |
||||||
|
var iteratorTypeName = GetIteratorTypeName(iteratorType, CodeGeneratorHelpers.CppTypePrinter); |
||||||
|
|
||||||
|
// Handle special cases for type-specific methods
|
||||||
|
if (method.ReturnType.Type.IsPointer()) |
||||||
|
{ |
||||||
|
var returnTypeName = ValidateTypeMethodReturnType(method.ReturnType.Type); |
||||||
|
WriteLine($"{returnTypeName} Get{method.Name}(uint i);"); |
||||||
|
} |
||||||
|
else |
||||||
|
WriteLine($"{iteratorTypeName} Get{method.Name}(uint i);"); |
||||||
|
|
||||||
|
WriteLine($"uint Get{method.Name}Count();"); |
||||||
|
} |
||||||
|
|
||||||
|
private string ValidateTypeMethodReturnType(AST.Type type) |
||||||
|
{ |
||||||
|
if (type.IsPointerTo(out TagType tagType)) |
||||||
|
{ |
||||||
|
var pointeeType = tagType.Declaration?.Visit(CodeGeneratorHelpers.CppTypePrinter).Type ?? "void"; |
||||||
|
if (pointeeType.Contains("Type") || pointeeType.Contains("QualType")) |
||||||
|
return $"AST::{pointeeType}*"; |
||||||
|
return $"{pointeeType}*"; |
||||||
|
} |
||||||
|
|
||||||
|
if (type is TemplateSpecializationType template) |
||||||
|
{ |
||||||
|
if (template.Template.TemplatedDecl.Name.Contains("Type")) |
||||||
|
return $"AST::{template.Template.TemplatedDecl.Name}"; |
||||||
|
} |
||||||
|
|
||||||
|
return type.Visit(CodeGeneratorHelpers.CppTypePrinter).ToString(); |
||||||
|
} |
||||||
|
|
||||||
|
private void ValidateTypeMethodParameter(Parameter param) |
||||||
|
{ |
||||||
|
// Handle pointer types
|
||||||
|
if (param.Type.IsPointer()) |
||||||
|
{ |
||||||
|
var pointee = param.Type.GetFinalPointee(); |
||||||
|
if (pointee is ArrayType) |
||||||
|
{ |
||||||
|
param.ExplicitlyIgnore(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Special handling for type-related pointers
|
||||||
|
if (pointee is TagType tagType && |
||||||
|
tagType.Declaration?.Name.Contains("Type") == true) |
||||||
|
{ |
||||||
|
// These are valid, don't ignore
|
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Handle template parameters specific to types
|
||||||
|
if (param.Type is TemplateSpecializationType template) |
||||||
|
{ |
||||||
|
var templateName = template.Template.TemplatedDecl.Name; |
||||||
|
if (!templateName.Contains("Type") && |
||||||
|
!templateName.Contains("QualType")) |
||||||
|
{ |
||||||
|
param.ExplicitlyIgnore(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void GenerateProperty(Property property) |
||||||
|
{ |
||||||
|
var typeName = GetDeclTypeName(property); |
||||||
|
var fieldName = GetDeclName(property); |
||||||
|
|
||||||
|
// Handle special type properties
|
||||||
|
if (typeName.Contains("QualType")) |
||||||
|
{ |
||||||
|
WriteLine($"AST::{typeName} {fieldName};"); |
||||||
|
|
||||||
|
if (property.GetMethod != null) |
||||||
|
WriteLine($"AST::{typeName} Get{FirstLetterToUpperCase(fieldName)}() const;"); |
||||||
|
if (property.SetMethod != null) |
||||||
|
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}(AST::{typeName} value);"); |
||||||
|
} |
||||||
|
else if (property.Type.IsPointerTo(out TagType tagType)) |
||||||
|
{ |
||||||
|
var pointeeType = tagType.Declaration?.Visit(CodeGeneratorHelpers.CppTypePrinter).Type ?? typeName; |
||||||
|
if (pointeeType.Contains("Type") || pointeeType.Contains("QualType")) |
||||||
|
{ |
||||||
|
WriteLine($"AST::{pointeeType}* {fieldName};"); |
||||||
|
|
||||||
|
if (property.GetMethod != null) |
||||||
|
WriteLine($"AST::{pointeeType}* Get{FirstLetterToUpperCase(fieldName)}() const;"); |
||||||
|
if (property.SetMethod != null) |
||||||
|
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}(AST::{pointeeType}* value);"); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
WriteLine($"{pointeeType}* {fieldName};"); |
||||||
|
|
||||||
|
if (property.GetMethod != null) |
||||||
|
WriteLine($"{pointeeType}* Get{FirstLetterToUpperCase(fieldName)}() const;"); |
||||||
|
if (property.SetMethod != null) |
||||||
|
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}({pointeeType}* value);"); |
||||||
|
} |
||||||
|
} |
||||||
|
// Handle template specialization types
|
||||||
|
else if (property.Type is TemplateSpecializationType templateType) |
||||||
|
{ |
||||||
|
var templateName = templateType.Template.TemplatedDecl.Name; |
||||||
|
WriteLine($"AST::{templateName} {fieldName};"); |
||||||
|
|
||||||
|
if (property.GetMethod != null) |
||||||
|
WriteLine($"AST::{templateName} Get{FirstLetterToUpperCase(fieldName)}() const;"); |
||||||
|
if (property.SetMethod != null) |
||||||
|
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}(AST::{templateName} value);"); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
WriteLine($"{typeName} {fieldName};"); |
||||||
|
|
||||||
|
if (property.GetMethod != null) |
||||||
|
WriteLine($"{typeName} Get{FirstLetterToUpperCase(fieldName)}() const;"); |
||||||
|
if (property.SetMethod != null) |
||||||
|
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}({typeName} value);"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class TypeDefinitionsCodeGenerator : StmtDefinitionsCodeGenerator |
||||||
|
{ |
||||||
|
public TypeDefinitionsCodeGenerator(BindingContext context, |
||||||
|
IEnumerable<Declaration> declarations) |
||||||
|
: base(context, declarations) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override void GenerateIncludes() |
||||||
|
{ |
||||||
|
GenerateCommonIncludes(); |
||||||
|
WriteInclude("Type.h", CInclude.IncludeKind.Quoted); |
||||||
|
} |
||||||
|
|
||||||
|
protected void GenerateMethodDefinition(Class @class, Method method) |
||||||
|
{ |
||||||
|
var iteratorType = GetIteratorType(method); |
||||||
|
var iteratorTypeName = GetIteratorTypeName(iteratorType, CodeGeneratorHelpers.CppTypePrinter); |
||||||
|
|
||||||
|
WriteLine($"uint {GetQualifiedName(@class)}::Get{method.Name}Count()"); |
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
WriteLine($"return {method.Name}().size();"); |
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
NewLine(); |
||||||
|
|
||||||
|
// Handle pointer types specially
|
||||||
|
if (method.ReturnType.Type.IsPointerTo(out TagType tagType)) |
||||||
|
{ |
||||||
|
var pointeeType = tagType.Declaration?.Name ?? iteratorTypeName; |
||||||
|
WriteLine($"AST::{pointeeType}* {GetQualifiedName(@class)}::Get{method.Name}(uint i)"); |
||||||
|
} |
||||||
|
else |
||||||
|
WriteLine($"{iteratorTypeName} {GetQualifiedName(@class)}::Get{method.Name}(uint i)"); |
||||||
|
|
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
WriteLine($"auto elements = {method.Name}();"); |
||||||
|
WriteLine($"auto it = elements.begin();"); |
||||||
|
WriteLine($"std::advance(it, i);"); |
||||||
|
WriteLine($"return *it;"); |
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
NewLine(); |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitClassDecl(Class @class) |
||||||
|
{ |
||||||
|
if (!@class.IsGenerated) |
||||||
|
return false; |
||||||
|
|
||||||
|
WriteLine($"{@class.Name}::{@class.Name}()"); |
||||||
|
var isBaseType = @class.Name == "Type"; |
||||||
|
var typeMember = isBaseType ? "typeClass" : @class.BaseClass.Name; |
||||||
|
var typeClass = @class.Name == "Type" ? "None" : @class.Name; |
||||||
|
WriteLineIndent($": {typeMember}(TypeClass::{typeClass})"); |
||||||
|
GenerateMemberInits(@class); |
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
NewLine(); |
||||||
|
|
||||||
|
foreach (var method in @class.Methods) |
||||||
|
{ |
||||||
|
if (SkipMethod(method)) |
||||||
|
continue; |
||||||
|
|
||||||
|
GenerateMethodDefinition(@class, method); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class TypeASTConverterCodeGenerator : ASTConverterCodeGenerator |
||||||
|
{ |
||||||
|
public TypeASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations) |
||||||
|
: base(context, declarations) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public override string BaseTypeName => "Type"; |
||||||
|
|
||||||
|
public override bool IsAbstractASTNode(Class kind) |
||||||
|
{ |
||||||
|
return IsAbstractType(kind); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void GenerateVisitorSwitch(IEnumerable<string> classes) |
||||||
|
{ |
||||||
|
WriteLine($"switch({ParamName}.DeclKind)"); |
||||||
|
WriteOpenBraceAndIndent(); |
||||||
|
|
||||||
|
GenerateSwitchCases(classes); |
||||||
|
|
||||||
|
UnindentAndWriteCloseBrace(); |
||||||
|
} |
||||||
|
|
||||||
|
public void GenerateSwitchCases(IEnumerable<string> classes) |
||||||
|
{ |
||||||
|
foreach (var className in classes) |
||||||
|
{ |
||||||
|
WriteLine($"case Parser.AST.TypeClass.{className}:"); |
||||||
|
WriteLineIndent($"return Visit{className}({ParamName} as Parser.AST.{className}Type);"); |
||||||
|
} |
||||||
|
|
||||||
|
WriteLine("default:"); |
||||||
|
WriteLineIndent($"throw new System.NotImplementedException(" + |
||||||
|
$"{ParamName}.TypeClass.ToString());"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue