1 /// Author: Aziz Köksal 2 /// License: GPL3 3 /// $(Maturity very high) 4 module dil.ast.DefaultVisitor; 5 6 import dil.ast.Visitor, 7 dil.ast.Node, 8 dil.ast.Declarations, 9 dil.ast.Expressions, 10 dil.ast.Statements, 11 dil.ast.Types, 12 dil.ast.Parameters; 13 import common; 14 15 /// Provides a visit() method which calls Visitor.visitN() on subnodes. 16 mixin template visitDefault(N, Ret = returnType!(N)) 17 { 18 override Ret visit(N n) 19 { 20 foreach (i, T; N.CTTI_Types) 21 { 22 auto member = __traits(getMember, n, N.CTTI_Members[i]); 23 static if (is(T : Node)) // A Node? 24 { 25 if (!N.CTTI_MayBeNull[i] || member !is null) 26 visitN(member); 27 } 28 else 29 static if (is(T : E[], E : Node)) // A Node array? 30 { 31 foreach (x; member) 32 if (!N.CTTI_MayBeNull[i] || x !is null) 33 visitN(x); 34 } 35 } 36 static if (!is(Ret : void)) 37 return n; 38 } 39 } 40 41 /// Generates the default visit methods. 42 /// 43 /// E.g.: 44 /// --- 45 /// mixin visitDefault!(ClassDecl); 46 /// mixin visitDefault!(InterfaceDecl); 47 /// --- 48 char[] generateDefaultVisitMethods() 49 { 50 char[] code; 51 foreach (className; NodeClassNames) 52 code ~= "mixin visitDefault!(" ~ className ~ ");\n"; 53 return code; 54 } 55 //pragma(msg, generateDefaultVisitMethods()); 56 57 /// Same as above but returns void. 58 char[] generateDefaultVisitMethods2() 59 { 60 char[] code; 61 foreach (className; NodeClassNames) 62 code ~= "mixin visitDefault!(" ~ className ~ ", void);\n"; 63 return code; 64 } 65 66 67 /// This class provides default methods for 68 /// traversing nodes and their subnodes. 69 class DefaultVisitor : Visitor 70 { 71 // Comment out if too many errors are shown. 72 mixin(generateDefaultVisitMethods()); 73 } 74 75 /// This class provides default methods for 76 /// traversing nodes and their subnodes. 77 class DefaultVisitor2 : Visitor2 78 { 79 // Comment out if too many errors are shown. 80 mixin(generateDefaultVisitMethods2()); 81 }