From edd03fa8cdc161751dfa75e6c697b2fd8f6fdb0b Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Thu, 23 Mar 2023 05:40:01 +0100 Subject: [PATCH] separate ASTVisitor.visit for ExpressionNode abstract classes should not have visitor functions, but rather only do dynamic dispatch. This becomes more important later with #409 --- src/dparse/ast.d | 33 +++++++++++++++--- src/dparse/astprinter.d | 76 ++++++++++++++++++++--------------------- 2 files changed, 67 insertions(+), 42 deletions(-) diff --git a/src/dparse/ast.d b/src/dparse/ast.d index c10f80c8..a76fda8b 100644 --- a/src/dparse/ast.d +++ b/src/dparse/ast.d @@ -92,11 +92,32 @@ enum DeclarationListStyle : ubyte */ abstract class ASTVisitor { - - /** */ + deprecated("Don't use or override visit(ExpressionNode). For usage: dynamicDispatch(ExpressionNode) is equivalent; " + ~ "for overriding: you should probably override more specific cases. If you need to override to inject some " + ~ "before/after code for all cases, make sure to call `super.dynamicDispatch(n)` instead of `n.accept(this)`!") void visit(const ExpressionNode n) { - switch (typeMap[typeid(n)]) + dynamicDispatch(n); + } + + /** + * Looks at the runtime type of `n`, then calls the appropriate `visit` + * method at runtime. + * + * Rule of thumb: when the type is an abstract class, use `dynamicDispatch`, + * otherwise use `visit`. + * + * For templated calls: + * --- + * static if (__traits(isAbstractClass, typeof(node))) + * visitor.dynamicDispatch(node); + * else + * visitor.visit(node); + * --- + */ + void dynamicDispatch(const ExpressionNode n) + { + switch (typeMap.get(typeid(n), 0)) { case 1: visit(cast(AddExpression) n); break; case 2: visit(cast(AndAndExpression) n); break; @@ -383,11 +404,15 @@ template visitIfNotNull(fields ...) { static if (typeof(fields[0]).stringof[$ - 2 .. $] == "[]") { - static if (__traits(hasMember, typeof(fields[0][0]), "classinfo")) + static if (__traits(isAbstractClass, typeof(fields[0][0]))) + immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") if (i !is null) visitor.dynamicDispatch(i);\n"; + else static if (__traits(hasMember, typeof(fields[0][0]), "classinfo")) immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") if (i !is null) visitor.visit(i);\n"; else immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") visitor.visit(i);\n"; } + else static if (__traits(isAbstractClass, typeof(fields[0]))) + immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ " !is null) visitor.dynamicDispatch(" ~ fields[0].stringof ~ ");\n"; else static if (__traits(hasMember, typeof(fields[0]), "classinfo")) immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ " !is null) visitor.visit(" ~ fields[0].stringof ~ ");\n"; else static if (is(Unqual!(typeof(fields[0])) == Token)) diff --git a/src/dparse/astprinter.d b/src/dparse/astprinter.d index a1f12085..f0fa5793 100644 --- a/src/dparse/astprinter.d +++ b/src/dparse/astprinter.d @@ -23,12 +23,12 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(addExpression.left); + dynamicDispatch(addExpression.left); output.writeln(""); if (addExpression.right !is null) { output.writeln(""); - visit(addExpression.right); + dynamicDispatch(addExpression.right); output.writeln(""); } output.writeln(""); @@ -58,12 +58,12 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(andAndExpression.left); + dynamicDispatch(andAndExpression.left); output.writeln(""); if (andAndExpression.right !is null) { output.writeln(""); - visit(andAndExpression.right); + dynamicDispatch(andAndExpression.right); output.writeln(""); } output.writeln(""); @@ -73,12 +73,12 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(andExpression.left); + dynamicDispatch(andExpression.left); output.writeln(""); if (andExpression.right !is null) { output.writeln(""); - visit(andExpression.right); + dynamicDispatch(andExpression.right); output.writeln(""); } output.writeln(""); @@ -191,13 +191,13 @@ class XMLPrinter : ASTVisitor if (caseRangeStatement.low !is null) { output.writeln(""); - visit(caseRangeStatement.low); + dynamicDispatch(caseRangeStatement.low); output.writeln(""); } if (caseRangeStatement.high !is null) { output.writeln(""); - visit(caseRangeStatement.high); + dynamicDispatch(caseRangeStatement.high); output.writeln(""); } if (caseRangeStatement.declarationsAndStatements !is null) @@ -295,7 +295,7 @@ class XMLPrinter : ASTVisitor if (deprecated_.assignExpression !is null) { output.writeln(""); - visit(deprecated_.assignExpression); + dynamicDispatch(deprecated_.assignExpression); output.writeln(""); } else @@ -320,7 +320,7 @@ class XMLPrinter : ASTVisitor visit(enumMember.type); output.write("", enumMember.name.text, ""); if (enumMember.assignExpression !is null) - visit(enumMember.assignExpression); + dynamicDispatch(enumMember.assignExpression); output.writeln(""); } @@ -336,10 +336,10 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(equalExpression.left); + dynamicDispatch(equalExpression.left); output.writeln(""); output.writeln(""); - visit(equalExpression.right); + dynamicDispatch(equalExpression.right); output.writeln(""); output.writeln(""); } @@ -475,10 +475,10 @@ class XMLPrinter : ASTVisitor else output.writeln(""); output.writeln(""); - visit(identityExpression.left); + dynamicDispatch(identityExpression.left); output.writeln(""); output.writeln(""); - visit(identityExpression.right); + dynamicDispatch(identityExpression.right); output.writeln(""); output.writeln(""); } @@ -541,10 +541,10 @@ class XMLPrinter : ASTVisitor else output.writeln(""); output.writeln(""); - visit(inExpression.left); + dynamicDispatch(inExpression.left); output.writeln(""); output.writeln(""); - visit(inExpression.right); + dynamicDispatch(inExpression.right); output.writeln(""); output.writeln(""); } @@ -613,10 +613,10 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(keyValuePair.key); + dynamicDispatch(keyValuePair.key); output.writeln(""); output.writeln(""); - visit(keyValuePair.value); + dynamicDispatch(keyValuePair.value); output.writeln(""); output.writeln(""); } @@ -676,12 +676,12 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(mulExpression.left); + dynamicDispatch(mulExpression.left); output.writeln(""); if (mulExpression.right !is null) { output.writeln(""); - visit(mulExpression.right); + dynamicDispatch(mulExpression.right); output.writeln(""); } output.writeln(""); @@ -691,12 +691,12 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(orOrExpression.left); + dynamicDispatch(orOrExpression.left); output.writeln(""); if (orOrExpression.right !is null) { output.writeln(""); - visit(orOrExpression.right); + dynamicDispatch(orOrExpression.right); output.writeln(""); } output.writeln(""); @@ -727,12 +727,12 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(powExpression.left); + dynamicDispatch(powExpression.left); output.writeln(""); if (powExpression.right !is null) { output.writeln(""); - visit(powExpression.right); + dynamicDispatch(powExpression.right); output.writeln(""); } output.writeln(""); @@ -743,10 +743,10 @@ class XMLPrinter : ASTVisitor output.writeln(""); output.writeln(""); - visit(relExpression.left); + dynamicDispatch(relExpression.left); output.writeln(""); output.writeln(""); - visit(relExpression.right); + dynamicDispatch(relExpression.right); output.writeln(""); output.writeln(""); } @@ -768,10 +768,10 @@ class XMLPrinter : ASTVisitor output.writeln(""); output.writeln(""); - visit(shiftExpression.left); + dynamicDispatch(shiftExpression.left); output.writeln(""); output.writeln(""); - visit(shiftExpression.right); + dynamicDispatch(shiftExpression.right); output.writeln(""); output.writeln(""); } @@ -804,7 +804,7 @@ class XMLPrinter : ASTVisitor if (templateAliasParameter.colonExpression !is null) { output.writeln(""); - visit(templateAliasParameter.colonExpression); + dynamicDispatch(templateAliasParameter.colonExpression); output.writeln(""); } else if (templateAliasParameter.colonType !is null) @@ -817,7 +817,7 @@ class XMLPrinter : ASTVisitor if (templateAliasParameter.assignExpression !is null) { output.writeln(""); - visit(templateAliasParameter.assignExpression); + dynamicDispatch(templateAliasParameter.assignExpression); output.writeln(""); } else if (templateAliasParameter.assignType !is null) @@ -962,14 +962,14 @@ class XMLPrinter : ASTVisitor if (typeSuffix.high !is null) { output.writeln(""); - visit(typeSuffix.low); + dynamicDispatch(typeSuffix.low); output.writeln(""); output.writeln(""); - visit(typeSuffix.high); + dynamicDispatch(typeSuffix.high); output.writeln(""); } else - visit(typeSuffix.low); + dynamicDispatch(typeSuffix.low); output.writeln(""); } } @@ -1041,12 +1041,12 @@ class XMLPrinter : ASTVisitor { output.writeln(""); output.writeln(""); - visit(xorExpression.left); + dynamicDispatch(xorExpression.left); output.writeln(""); if (xorExpression.right !is null) { output.writeln(""); - visit(xorExpression.right); + dynamicDispatch(xorExpression.right); output.writeln(""); } output.writeln(""); @@ -1058,15 +1058,15 @@ class XMLPrinter : ASTVisitor if (index.high) { output.writeln(""); - visit(index.low); + dynamicDispatch(index.low); output.writeln(""); output.writeln(""); - visit(index.high); + dynamicDispatch(index.high); output.writeln(""); } else - visit(index.low); + dynamicDispatch(index.low); output.writeln(""); }