mirror of https://github.com/mono/CppSharp.git
23 changed files with 4399 additions and 1009 deletions
@ -1,5 +1,6 @@
@@ -1,5 +1,6 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CLI/@EntryIndexedValue">CLI</s:String> |
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MD/@EntryIndexedValue">MD</s:String> |
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSVC/@EntryIndexedValue">MSVC</s:String> |
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=diag/@EntryIndexedValue">True</s:Boolean> |
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=undefine/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> |
@ -0,0 +1,221 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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