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("");
}