Browse Source

Abstract some `ASTConverterCodeGenerator` code

pull/1914/head
duckdoom5 4 months ago
parent
commit
14c15e432e
  1. 75
      src/CppParser/Bootstrap/Bootstrap.cs
  2. 96
      src/CppParser/Bootstrap/StmtCodeGenerators.cs
  3. 4
      src/Parser/ASTConverter.Expr.cs
  4. 4
      src/Parser/ASTConverter.Stmt.cs

75
src/CppParser/Bootstrap/Bootstrap.cs

@ -752,11 +752,14 @@ namespace CppSharp
internal abstract class ASTConverterCodeGenerator : ManagedParserCodeGenerator internal abstract class ASTConverterCodeGenerator : ManagedParserCodeGenerator
{ {
readonly Enumeration StmtClassEnum; public abstract string BaseTypeName { get; }
protected ASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations, Enumeration stmtClassEnum) public string ParamName => BaseTypeName.ToLowerInvariant();
public abstract bool IsAbstractASTNode(Class kind);
protected ASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
: base(context, declarations) : base(context, declarations)
{ {
StmtClassEnum = stmtClassEnum;
} }
public override void Process() public override void Process()
@ -765,6 +768,7 @@ namespace CppSharp
NewLine(); NewLine();
WriteLine("using CppSharp.Parser.AST;"); WriteLine("using CppSharp.Parser.AST;");
NewLine();
WriteLine("using static CppSharp.ConversionUtils;"); WriteLine("using static CppSharp.ConversionUtils;");
NewLine(); NewLine();
@ -779,11 +783,9 @@ namespace CppSharp
UnindentAndWriteCloseBrace(); UnindentAndWriteCloseBrace();
} }
public virtual string BaseTypeName { get; } protected abstract void GenerateVisitorSwitch(IEnumerable<string> classes);
public string ParamName => BaseTypeName.ToLowerInvariant(); protected virtual void GenerateVisitor()
private void GenerateVisitor()
{ {
var comment = new RawComment var comment = new RawComment
{ {
@ -792,12 +794,13 @@ namespace CppSharp
GenerateComment(comment); GenerateComment(comment);
WriteLine($"public abstract class {BaseTypeName}Visitor<TRet> where TRet : class"); WriteLine($"public abstract class {BaseTypeName}Visitor<TRet>");
WriteLineIndent("where TRet : class");
WriteOpenBraceAndIndent(); WriteOpenBraceAndIndent();
var classes = Declarations var classes = Declarations
.OfType<Class>() .OfType<Class>()
.Where(@class => !IsAbstractStmt(@class)) .Where(@class => !IsAbstractASTNode(@class))
.Select(@class => @class.Name) .Select(@class => @class.Name)
.ToArray(); .ToArray();
@ -812,62 +815,24 @@ namespace CppSharp
WriteLineIndent("return default(TRet);"); WriteLineIndent("return default(TRet);");
NewLine(); NewLine();
WriteLine($"switch({ParamName}.StmtClass)"); GenerateVisitorSwitch(classes);
WriteOpenBraceAndIndent();
var enumItems = StmtClassEnum != null ?
StmtClassEnum.Items.Where(item => item.IsGenerated)
.Select(item => RemoveFromEnd(item.Name, "Class"))
.Where(@class => !IsAbstractStmt(@class))
: new List<string>();
GenerateSwitchCases(StmtClassEnum != null ? enumItems : classes);
UnindentAndWriteCloseBrace(); UnindentAndWriteCloseBrace();
UnindentAndWriteCloseBrace(); UnindentAndWriteCloseBrace();
UnindentAndWriteCloseBrace();
}
public virtual void GenerateSwitchCases(IEnumerable<string> classes)
{
foreach (var className in classes)
{
WriteLine($"case StmtClass.{className}:");
WriteOpenBraceAndIndent();
WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);");
var isExpression = Declarations
.OfType<Class>()
.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() private void GenerateConverter()
{ {
WriteLine("public unsafe class {0}Converter : {0}Visitor<AST.{0}>", WriteLine("public unsafe class {0}Converter : {0}Visitor<AST.{0}>", BaseTypeName);
BaseTypeName);
WriteOpenBraceAndIndent(); WriteOpenBraceAndIndent();
foreach (var @class in Declarations.OfType<Class>()) foreach (var @class in Declarations.OfType<Class>())
{ {
if (IsAbstractStmt(@class)) if (IsAbstractASTNode(@class))
continue; continue;
PushBlock(); PushBlock();
WriteLine("public override AST.{0} Visit{1}({1} {2})", WriteLine("public override AST.{0} Visit{1}({1} {2})", BaseTypeName, @class.Name, ParamName);
BaseTypeName, @class.Name, ParamName);
WriteOpenBraceAndIndent(); WriteOpenBraceAndIndent();
var qualifiedName = $"{GetQualifiedName(@class)}"; var qualifiedName = $"{GetQualifiedName(@class)}";
@ -923,8 +888,7 @@ namespace CppSharp
public override bool VisitMethodDecl(Method method) public override bool VisitMethodDecl(Method method)
{ {
var managedName = GetDeclName(method, GeneratorKind.CSharp); var managedName = GetDeclName(method, GeneratorKind.CSharp);
var nativeName = CaseRenamePass.ConvertCaseString(method, var nativeName = CaseRenamePass.ConvertCaseString(method, RenameCasePattern.LowerCamelCase);
RenameCasePattern.LowerCamelCase);
WriteLine($"for (uint i = 0; i < {ParamName}.Get{nativeName}Count; i++)"); WriteLine($"for (uint i = 0; i < {ParamName}.Get{nativeName}Count; i++)");
WriteOpenBraceAndIndent(); WriteOpenBraceAndIndent();
@ -942,7 +906,7 @@ namespace CppSharp
return true; 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}"; var typeName = $"AST.{declTypeName}";
if (type.TryGetEnum(out Enumeration @enum)) if (type.TryGetEnum(out Enumeration @enum))
@ -975,8 +939,7 @@ namespace CppSharp
{ {
internal readonly IEnumerable<Declaration> Declarations; internal readonly IEnumerable<Declaration> Declarations;
public NativeParserCodeGenerator(BindingContext context, public NativeParserCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
IEnumerable<Declaration> declarations)
: base(context) : base(context)
{ {
Declarations = declarations; Declarations = declarations;

96
src/CppParser/Bootstrap/StmtCodeGenerators.cs

@ -445,13 +445,61 @@ namespace CppSharp
internal class StmtASTConverterCodeGenerator : ASTConverterCodeGenerator internal class StmtASTConverterCodeGenerator : ASTConverterCodeGenerator
{ {
public StmtASTConverterCodeGenerator(BindingContext context, private readonly Enumeration StmtClassEnum;
IEnumerable<Declaration> declarations, Enumeration stmtClassEnum)
: base(context, declarations, stmtClassEnum) public StmtASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations, Enumeration stmtClassEnum)
: base(context, declarations)
{ {
StmtClassEnum = stmtClassEnum;
} }
public override string BaseTypeName => "Stmt"; public override string BaseTypeName => "Stmt";
public override bool IsAbstractASTNode(Class kind)
{
return CodeGeneratorHelpers.IsAbstractStmt(kind);
}
protected override void GenerateVisitorSwitch(IEnumerable<string> 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<string>();
GenerateSwitchCases(StmtClassEnum != null ? enumItems : classes);
UnindentAndWriteCloseBrace();
}
private void GenerateSwitchCases(IEnumerable<string> classes)
{
foreach (var className in classes)
{
WriteLine($"case StmtClass.{className}:");
WriteOpenBraceAndIndent();
WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);");
var isExpression = Declarations
.OfType<Class>()
.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 internal class ExprDeclarationsCodeGenerator : StmtDeclarationsCodeGenerator
@ -513,7 +561,7 @@ namespace CppSharp
"AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)"; "AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)";
} }
internal class ExprASTConverterCodeGenerator : ASTConverterCodeGenerator internal class ExprASTConverterCodeGenerator : StmtASTConverterCodeGenerator
{ {
public ExprASTConverterCodeGenerator(BindingContext context, public ExprASTConverterCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations) IEnumerable<Declaration> declarations)
@ -522,5 +570,45 @@ namespace CppSharp
} }
public override string BaseTypeName => "Expr"; public override string BaseTypeName => "Expr";
public override bool IsAbstractASTNode(Class kind)
{
return CodeGeneratorHelpers.IsAbstractStmt(kind);
}
protected override void GenerateVisitorSwitch(IEnumerable<string> classes)
{
WriteLine($"switch({ParamName}.StmtClass)");
WriteOpenBraceAndIndent();
GenerateSwitchCases(classes);
UnindentAndWriteCloseBrace();
}
private void GenerateSwitchCases(IEnumerable<string> classes)
{
foreach (var className in classes)
{
WriteLine($"case StmtClass.{className}:");
WriteOpenBraceAndIndent();
WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);");
var isExpression = Declarations
.OfType<Class>()
.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());");
}
} }
} }

4
src/Parser/ASTConverter.Expr.cs

@ -6,6 +6,7 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
using CppSharp.Parser.AST; using CppSharp.Parser.AST;
using static CppSharp.ConversionUtils; using static CppSharp.ConversionUtils;
namespace CppSharp namespace CppSharp
@ -13,7 +14,8 @@ namespace CppSharp
// <summary> // <summary>
// <para>Implements the visitor pattern for the generated expr bindings.</para> // <para>Implements the visitor pattern for the generated expr bindings.</para>
// </summary> // </summary>
public abstract class ExprVisitor<TRet> where TRet : class public abstract class ExprVisitor<TRet>
where TRet : class
{ {
public abstract TRet VisitConstantExpr(ConstantExpr expr); public abstract TRet VisitConstantExpr(ConstantExpr expr);
public abstract TRet VisitOpaqueValueExpr(OpaqueValueExpr expr); public abstract TRet VisitOpaqueValueExpr(OpaqueValueExpr expr);

4
src/Parser/ASTConverter.Stmt.cs

@ -6,6 +6,7 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
using CppSharp.Parser.AST; using CppSharp.Parser.AST;
using static CppSharp.ConversionUtils; using static CppSharp.ConversionUtils;
namespace CppSharp namespace CppSharp
@ -13,7 +14,8 @@ namespace CppSharp
// <summary> // <summary>
// <para>Implements the visitor pattern for the generated stmt bindings.</para> // <para>Implements the visitor pattern for the generated stmt bindings.</para>
// </summary> // </summary>
public abstract class StmtVisitor<TRet> where TRet : class public abstract class StmtVisitor<TRet>
where TRet : class
{ {
public abstract TRet VisitDeclStmt(DeclStmt stmt); public abstract TRet VisitDeclStmt(DeclStmt stmt);
public abstract TRet VisitNullStmt(NullStmt stmt); public abstract TRet VisitNullStmt(NullStmt stmt);

Loading…
Cancel
Save