From 14c15e432e25b486199f941f00132036885f2248 Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Tue, 25 Feb 2025 13:33:49 +0100 Subject: [PATCH] Abstract some `ASTConverterCodeGenerator` code --- src/CppParser/Bootstrap/Bootstrap.cs | 75 ++++----------- src/CppParser/Bootstrap/StmtCodeGenerators.cs | 96 ++++++++++++++++++- src/Parser/ASTConverter.Expr.cs | 4 +- src/Parser/ASTConverter.Stmt.cs | 4 +- 4 files changed, 117 insertions(+), 62 deletions(-) diff --git a/src/CppParser/Bootstrap/Bootstrap.cs b/src/CppParser/Bootstrap/Bootstrap.cs index 11ac750f..0e5ed063 100644 --- a/src/CppParser/Bootstrap/Bootstrap.cs +++ b/src/CppParser/Bootstrap/Bootstrap.cs @@ -752,11 +752,14 @@ namespace CppSharp internal abstract class ASTConverterCodeGenerator : ManagedParserCodeGenerator { - readonly Enumeration StmtClassEnum; - protected ASTConverterCodeGenerator(BindingContext context, IEnumerable declarations, Enumeration stmtClassEnum) + public abstract string BaseTypeName { get; } + public string ParamName => BaseTypeName.ToLowerInvariant(); + + public abstract bool IsAbstractASTNode(Class kind); + + protected ASTConverterCodeGenerator(BindingContext context, IEnumerable declarations) : base(context, declarations) { - StmtClassEnum = stmtClassEnum; } public override void Process() @@ -765,6 +768,7 @@ namespace CppSharp NewLine(); WriteLine("using CppSharp.Parser.AST;"); + NewLine(); WriteLine("using static CppSharp.ConversionUtils;"); NewLine(); @@ -779,11 +783,9 @@ namespace CppSharp UnindentAndWriteCloseBrace(); } - public virtual string BaseTypeName { get; } + protected abstract void GenerateVisitorSwitch(IEnumerable classes); - public string ParamName => BaseTypeName.ToLowerInvariant(); - - private void GenerateVisitor() + protected virtual void GenerateVisitor() { var comment = new RawComment { @@ -792,12 +794,13 @@ namespace CppSharp GenerateComment(comment); - WriteLine($"public abstract class {BaseTypeName}Visitor where TRet : class"); + WriteLine($"public abstract class {BaseTypeName}Visitor"); + WriteLineIndent("where TRet : class"); WriteOpenBraceAndIndent(); var classes = Declarations .OfType() - .Where(@class => !IsAbstractStmt(@class)) + .Where(@class => !IsAbstractASTNode(@class)) .Select(@class => @class.Name) .ToArray(); @@ -812,62 +815,24 @@ namespace CppSharp WriteLineIndent("return default(TRet);"); NewLine(); - WriteLine($"switch({ParamName}.StmtClass)"); - WriteOpenBraceAndIndent(); - - var enumItems = StmtClassEnum != null ? - StmtClassEnum.Items.Where(item => item.IsGenerated) - .Select(item => RemoveFromEnd(item.Name, "Class")) - .Where(@class => !IsAbstractStmt(@class)) - : new List(); - - GenerateSwitchCases(StmtClassEnum != null ? enumItems : classes); + GenerateVisitorSwitch(classes); UnindentAndWriteCloseBrace(); UnindentAndWriteCloseBrace(); - UnindentAndWriteCloseBrace(); - } - - public virtual void GenerateSwitchCases(IEnumerable classes) - { - foreach (var className in classes) - { - WriteLine($"case StmtClass.{className}:"); - WriteOpenBraceAndIndent(); - - WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);"); - - var isExpression = Declarations - .OfType() - .All(c => c.Name != className); - - if (isExpression) - WriteLine($"return VisitExpression(_{ParamName} as Expr) as TRet;"); - else - WriteLine($"return Visit{className}(_{ParamName});"); - - UnindentAndWriteCloseBrace(); - } - - WriteLine("default:"); - WriteLineIndent($"throw new System.NotImplementedException(" + - $"{ParamName}.StmtClass.ToString());"); } private void GenerateConverter() { - WriteLine("public unsafe class {0}Converter : {0}Visitor", - BaseTypeName); + WriteLine("public unsafe class {0}Converter : {0}Visitor", BaseTypeName); WriteOpenBraceAndIndent(); foreach (var @class in Declarations.OfType()) { - if (IsAbstractStmt(@class)) + if (IsAbstractASTNode(@class)) continue; PushBlock(); - WriteLine("public override AST.{0} Visit{1}({1} {2})", - BaseTypeName, @class.Name, ParamName); + WriteLine("public override AST.{0} Visit{1}({1} {2})", BaseTypeName, @class.Name, ParamName); WriteOpenBraceAndIndent(); var qualifiedName = $"{GetQualifiedName(@class)}"; @@ -923,8 +888,7 @@ namespace CppSharp public override bool VisitMethodDecl(Method method) { var managedName = GetDeclName(method, GeneratorKind.CSharp); - var nativeName = CaseRenamePass.ConvertCaseString(method, - RenameCasePattern.LowerCamelCase); + var nativeName = CaseRenamePass.ConvertCaseString(method, RenameCasePattern.LowerCamelCase); WriteLine($"for (uint i = 0; i < {ParamName}.Get{nativeName}Count; i++)"); WriteOpenBraceAndIndent(); @@ -942,7 +906,7 @@ namespace CppSharp return true; } - private void MarshalDecl(AST.Type type, string declTypeName, string bindingsName) + protected virtual void MarshalDecl(AST.Type type, string declTypeName, string bindingsName) { var typeName = $"AST.{declTypeName}"; if (type.TryGetEnum(out Enumeration @enum)) @@ -975,8 +939,7 @@ namespace CppSharp { internal readonly IEnumerable Declarations; - public NativeParserCodeGenerator(BindingContext context, - IEnumerable declarations) + public NativeParserCodeGenerator(BindingContext context, IEnumerable declarations) : base(context) { Declarations = declarations; diff --git a/src/CppParser/Bootstrap/StmtCodeGenerators.cs b/src/CppParser/Bootstrap/StmtCodeGenerators.cs index 922002e6..7c50a958 100644 --- a/src/CppParser/Bootstrap/StmtCodeGenerators.cs +++ b/src/CppParser/Bootstrap/StmtCodeGenerators.cs @@ -445,13 +445,61 @@ namespace CppSharp internal class StmtASTConverterCodeGenerator : ASTConverterCodeGenerator { - public StmtASTConverterCodeGenerator(BindingContext context, - IEnumerable declarations, Enumeration stmtClassEnum) - : base(context, declarations, stmtClassEnum) + private readonly Enumeration StmtClassEnum; + + public StmtASTConverterCodeGenerator(BindingContext context, IEnumerable declarations, Enumeration stmtClassEnum) + : base(context, declarations) { + StmtClassEnum = stmtClassEnum; } public override string BaseTypeName => "Stmt"; + + public override bool IsAbstractASTNode(Class kind) + { + return CodeGeneratorHelpers.IsAbstractStmt(kind); + } + + protected override void GenerateVisitorSwitch(IEnumerable classes) + { + WriteLine($"switch({ParamName}.StmtClass)"); + WriteOpenBraceAndIndent(); + + var enumItems = StmtClassEnum != null ? + StmtClassEnum.Items.Where(item => item.IsGenerated) + .Select(item => RemoveFromEnd(item.Name, "Class")) + .Where(@class => !IsAbstractStmt(@class)) + : new List(); + + GenerateSwitchCases(StmtClassEnum != null ? enumItems : classes); + + UnindentAndWriteCloseBrace(); + } + + private void GenerateSwitchCases(IEnumerable classes) + { + foreach (var className in classes) + { + WriteLine($"case StmtClass.{className}:"); + WriteOpenBraceAndIndent(); + + WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);"); + + var isExpression = Declarations + .OfType() + .All(c => c.Name != className); + + if (isExpression) + WriteLine($"return VisitExpression(_{ParamName} as Expr) as TRet;"); + else + WriteLine($"return Visit{className}(_{ParamName});"); + + UnindentAndWriteCloseBrace(); + } + + WriteLine("default:"); + WriteLineIndent($"throw new System.NotImplementedException({ParamName}.StmtClass.ToString());"); + } } internal class ExprDeclarationsCodeGenerator : StmtDeclarationsCodeGenerator @@ -513,7 +561,7 @@ namespace CppSharp "AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)"; } - internal class ExprASTConverterCodeGenerator : ASTConverterCodeGenerator + internal class ExprASTConverterCodeGenerator : StmtASTConverterCodeGenerator { public ExprASTConverterCodeGenerator(BindingContext context, IEnumerable declarations) @@ -522,5 +570,45 @@ namespace CppSharp } public override string BaseTypeName => "Expr"; + + public override bool IsAbstractASTNode(Class kind) + { + return CodeGeneratorHelpers.IsAbstractStmt(kind); + } + + protected override void GenerateVisitorSwitch(IEnumerable classes) + { + WriteLine($"switch({ParamName}.StmtClass)"); + WriteOpenBraceAndIndent(); + + GenerateSwitchCases(classes); + + UnindentAndWriteCloseBrace(); + } + + private void GenerateSwitchCases(IEnumerable classes) + { + foreach (var className in classes) + { + WriteLine($"case StmtClass.{className}:"); + WriteOpenBraceAndIndent(); + + WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);"); + + var isExpression = Declarations + .OfType() + .All(c => c.Name != className); + + if (isExpression) + WriteLine($"return VisitExpression(_{ParamName} as Expr) as TRet;"); + else + WriteLine($"return Visit{className}(_{ParamName});"); + + UnindentAndWriteCloseBrace(); + } + + WriteLine("default:"); + WriteLineIndent($"throw new System.NotImplementedException({ParamName}.StmtClass.ToString());"); + } } } diff --git a/src/Parser/ASTConverter.Expr.cs b/src/Parser/ASTConverter.Expr.cs index 621a3d9d..fd23661e 100644 --- a/src/Parser/ASTConverter.Expr.cs +++ b/src/Parser/ASTConverter.Expr.cs @@ -6,6 +6,7 @@ // ---------------------------------------------------------------------------- using CppSharp.Parser.AST; + using static CppSharp.ConversionUtils; namespace CppSharp @@ -13,7 +14,8 @@ namespace CppSharp // // Implements the visitor pattern for the generated expr bindings. // - public abstract class ExprVisitor where TRet : class + public abstract class ExprVisitor + where TRet : class { public abstract TRet VisitConstantExpr(ConstantExpr expr); public abstract TRet VisitOpaqueValueExpr(OpaqueValueExpr expr); diff --git a/src/Parser/ASTConverter.Stmt.cs b/src/Parser/ASTConverter.Stmt.cs index 1de6d26e..58228e4b 100644 --- a/src/Parser/ASTConverter.Stmt.cs +++ b/src/Parser/ASTConverter.Stmt.cs @@ -6,6 +6,7 @@ // ---------------------------------------------------------------------------- using CppSharp.Parser.AST; + using static CppSharp.ConversionUtils; namespace CppSharp @@ -13,7 +14,8 @@ namespace CppSharp // // Implements the visitor pattern for the generated stmt bindings. // - public abstract class StmtVisitor where TRet : class + public abstract class StmtVisitor + where TRet : class { public abstract TRet VisitDeclStmt(DeclStmt stmt); public abstract TRet VisitNullStmt(NullStmt stmt);