comparison src/dil/ast/DefaultVisitor.d @ 806:bcb74c9b895c

Moved out files in the trunk folder to the root.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sun, 09 Mar 2008 00:12:19 +0100
parents trunk/src/dil/ast/DefaultVisitor.d@9e6c6bb73e5f
children
comparison
equal deleted inserted replaced
805:a3fab8b74a7d 806:bcb74c9b895c
1 /++
2 Author: Aziz Köksal
3 License: GPL3
4 +/
5 module dil.ast.DefaultVisitor;
6
7 import dil.ast.Visitor;
8
9 import dil.ast.Node;
10 import dil.ast.Declarations,
11 dil.ast.Expressions,
12 dil.ast.Statements,
13 dil.ast.Types,
14 dil.ast.Parameters;
15 import common;
16
17 /// This huge template function, when instantiated for a certain node class,
18 /// generates a body of calls to visit() on the subnodes.
19 returnType!(T.stringof) visitDefault(T)(T t)
20 {
21 assert(t !is null, "node passed to visitDefault() is null");
22 //Stdout(t).newline;
23
24 alias t d, s, e, n; // Variable aliases of t.
25
26 static if (is(T : Declaration))
27 {
28 alias T D;
29 static if (is(D == CompoundDeclaration))
30 foreach (decl; d.decls)
31 visitD(decl);
32 //EmptyDeclaration,
33 //IllegalDeclaration,
34 //ModuleDeclaration have no subnodes.
35 static if (is(D == AliasDeclaration) ||
36 is(D == TypedefDeclaration))
37 visitD(d.decl);
38 static if (is(D == EnumDeclaration))
39 {
40 d.baseType && visitT(d.baseType);
41 foreach (member; d.members)
42 visitD(member);
43 }
44 static if (is(D == EnumMemberDeclaration))
45 d.value && visitE(d.value);
46 static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration))
47 {
48 // visitN(d.tparams);
49 foreach (base; d.bases)
50 visitT(base);
51 d.decls && visitD(d.decls);
52 }
53 static if (is(D == StructDeclaration) || is(D == UnionDeclaration))
54 // visitN(d.tparams),
55 d.decls && visitD(d.decls);
56 static if (is(D == ConstructorDeclaration))
57 visitN(d.params), visitS(d.funcBody);
58 static if (is(D == StaticConstructorDeclaration) ||
59 is(D == DestructorDeclaration) ||
60 is(D == StaticDestructorDeclaration) ||
61 is(D == InvariantDeclaration) ||
62 is(D == UnittestDeclaration))
63 visitS(d.funcBody);
64 static if (is(D == FunctionDeclaration))
65 visitT(d.returnType),
66 // visitN(d.tparams),
67 visitN(d.params),
68 visitS(d.funcBody);
69 static if (is(D == VariablesDeclaration))
70 {
71 d.typeNode && visitT(d.typeNode);
72 foreach(init; d.inits)
73 init && visitE(init);
74 }
75 static if (is(D == DebugDeclaration) || is(D == VersionDeclaration))
76 d.decls && visitD(d.decls),
77 d.elseDecls && visitD(d.elseDecls);
78 static if (is(D == StaticIfDeclaration))
79 visitE(d.condition),
80 visitD(d.ifDecls),
81 d.elseDecls && visitD(d.elseDecls);
82 static if (is(D == StaticAssertDeclaration))
83 visitE(d.condition),
84 d.message && visitE(d.message);
85 static if (is(D == TemplateDeclaration))
86 visitN(d.tparams),
87 visitD(d.decls);
88 static if (is(D == NewDeclaration) || is(D == DeleteDeclaration))
89 visitN(d.params),
90 visitS(d.funcBody);
91 static if (is(D == ProtectionDeclaration) ||
92 is(D == StorageClassDeclaration) ||
93 is(D == LinkageDeclaration) ||
94 is(D == AlignDeclaration))
95 visitD(d.decls);
96 static if (is(D == PragmaDeclaration))
97 {
98 foreach (arg; d.args)
99 visitE(arg);
100 visitD(d.decls);
101 }
102 static if (is(D == MixinDeclaration))
103 d.templateExpr ? visitE(d.templateExpr) : visitE(d.argument);
104 }
105 else
106 static if (is(T : Expression))
107 {
108 alias T E;
109 static if (is(E == IllegalExpression))
110 {}
111 else
112 static if (is(E == CondExpression))
113 visitE(e.condition), visitE(e.lhs), visitE(e.rhs);
114 else
115 static if (is(E : BinaryExpression))
116 visitE(e.lhs), visitE(e.rhs);
117 else
118 static if (is(E : UnaryExpression))
119 {
120 static if (is(E == CastExpression))
121 visitT(e.type);
122 visitE(e.e); // Visit member in base class UnaryExpression.
123 static if (is(E == IndexExpression))
124 foreach (arg; e.args)
125 visitE(arg);
126 static if (is(E == SliceExpression))
127 e.left && (visitE(e.left), visitE(e.right));
128 static if (is(E == AsmPostBracketExpression))
129 visitE(e.e2);
130 }
131 else
132 {
133 static if (is(E == NewExpression))
134 {
135 foreach (arg; e.newArgs)
136 visitE(arg);
137 visitT(e.type);
138 foreach (arg; e.ctorArgs)
139 visitE(arg);
140 }
141 static if (is(E == NewAnonClassExpression))
142 {
143 foreach (arg; e.newArgs)
144 visitE(arg);
145 foreach (base; e.bases)
146 visitT(base);
147 foreach (arg; e.ctorArgs)
148 visitE(arg);
149 visitD(e.decls);
150 }
151 static if (is(E == AsmBracketExpression))
152 visitE(e.e);
153 static if (is(E == TemplateInstanceExpression))
154 e.targs && visitN(e.targs);
155 static if (is(E == ArrayLiteralExpression))
156 foreach (value; e.values)
157 visitE(value);
158 static if (is(E == AArrayLiteralExpression))
159 foreach (i, key; e.keys)
160 visitE(key), visitE(e.values[i]);
161 static if (is(E == AssertExpression))
162 visitE(e.expr), e.msg && visitE(e.msg);
163 static if (is(E == MixinExpression) ||
164 is(E == ImportExpression))
165 visitE(e.expr);
166 static if (is(E == TypeofExpression) ||
167 is(E == TypeDotIdExpression) ||
168 is(E == TypeidExpression))
169 visitT(e.type);
170 static if (is(E == IsExpression))
171 visitT(e.type), e.specType && visitT(e.specType),
172 e.tparams && visitN(e.tparams);
173 static if (is(E == FunctionLiteralExpression))
174 e.returnType && visitT(e.returnType),
175 e.params && visitN(e.params),
176 visitS(e.funcBody);
177 static if (is(E == ParenExpression))
178 visitE(e.next);
179 static if (is(E == TraitsExpression))
180 visitN(e.targs);
181 // VoidInitializer has no subnodes.
182 static if (is(E == ArrayInitExpression))
183 foreach (i, key; e.keys)
184 key && visitE(key), visitE(e.values[i]);
185 static if (is(E == StructInitExpression))
186 foreach (value; e.values)
187 visitE(value);
188 }
189 }
190 else
191 static if (is(T : Statement))
192 {
193 alias T S;
194 static if (is(S == CompoundStatement))
195 foreach (stmnt; s.stmnts)
196 visitS(stmnt);
197 //IllegalStatement has no subnodes.
198 static if (is(S == FuncBodyStatement))
199 s.funcBody && visitS(s.funcBody),
200 s.inBody && visitS(s.inBody),
201 s.outBody && visitS(s.outBody);
202 static if (is(S == ScopeStatement) || is(S == LabeledStatement))
203 visitS(s.s);
204 static if (is(S == ExpressionStatement))
205 visitE(s.e);
206 static if (is(S == DeclarationStatement))
207 visitD(s.decl);
208 static if (is(S == IfStatement))
209 {
210 s.variable ? cast(Node)visitS(s.variable) : visitE(s.condition);
211 visitS(s.ifBody), s.elseBody && visitS(s.elseBody);
212 }
213 static if (is(S == WhileStatement))
214 visitE(s.condition), visitS(s.whileBody);
215 static if (is(S == DoWhileStatement))
216 visitS(s.doBody), visitE(s.condition);
217 static if (is(S == ForStatement))
218 s.init && visitS(s.init),
219 s.condition && visitE(s.condition),
220 s.increment && visitE(s.increment),
221 visitS(s.forBody);
222 static if (is(S == ForeachStatement))
223 visitN(s.params), visitE(s.aggregate), visitS(s.forBody);
224 static if (is(S == ForeachRangeStatement))
225 visitN(s.params), visitE(s.lower), visitE(s.upper), visitS(s.forBody);
226 static if (is(S == SwitchStatement))
227 visitE(s.condition), visitS(s.switchBody);
228 static if (is(S == CaseStatement))
229 {
230 foreach (value; s.values)
231 visitE(value);
232 visitS(s.caseBody);
233 }
234 static if (is(S == DefaultStatement))
235 visitS(s.defaultBody);
236 //ContinueStatement,
237 //BreakStatement have no subnodes.
238 static if (is(S == ReturnStatement))
239 s.e && visitE(s.e);
240 static if (is(S == GotoStatement))
241 s.caseExpr && visitE(s.caseExpr);
242 static if (is(S == WithStatement))
243 visitE(s.e), visitS(s.withBody);
244 static if (is(S == SynchronizedStatement))
245 s.e && visitE(s.e), visitS(s.syncBody);
246 static if (is(S == TryStatement))
247 {
248 visitS(s.tryBody);
249 foreach (catchBody; s.catchBodies)
250 visitS(catchBody);
251 s.finallyBody && visitS(s.finallyBody);
252 }
253 static if (is(S == CatchStatement))
254 s.param && visitN(s.param), visitS(s.catchBody);
255 static if (is(S == FinallyStatement))
256 visitS(s.finallyBody);
257 static if (is(S == ScopeGuardStatement))
258 visitS(s.scopeBody);
259 static if (is(S == ThrowStatement))
260 visitE(s.e);
261 static if (is(S == VolatileStatement))
262 s.volatileBody && visitS(s.volatileBody);
263 static if (is(S == AsmBlockStatement))
264 visitS(s.statements);
265 static if (is(S == AsmStatement))
266 foreach (op; s.operands)
267 visitE(op);
268 //AsmAlignStatement,
269 //IllegalAsmStatement have no subnodes.
270 static if (is(S == PragmaStatement))
271 {
272 foreach (arg; s.args)
273 visitE(arg);
274 visitS(s.pragmaBody);
275 }
276 static if (is(S == MixinStatement))
277 visitE(s.templateExpr);
278 static if (is(S == StaticIfStatement))
279 visitE(s.condition), visitS(s.ifBody), s.elseBody && visitS(s.elseBody);
280 static if (is(S == StaticAssertStatement))
281 visitE(s.condition), s.message && visitE(s.message);
282 static if (is(S == DebugStatement) || is(S == VersionStatement))
283 visitS(s.mainBody), s.elseBody && visitS(s.elseBody);
284 }
285 else
286 static if (is(T : TypeNode))
287 {
288 //IllegalType,
289 //IntegralType,
290 //ModuleScopeType,
291 //IdentifierType have no subnodes.
292 static if (is(T == QualifiedType))
293 visitT(t.lhs), visitT(t.rhs);
294 static if (is(T == TypeofType))
295 visitE(t.e);
296 static if (is(T == TemplateInstanceType))
297 t.targs && visitN(t.targs);
298 static if (is(T == PointerType))
299 visitT(t.next);
300 static if (is(T == ArrayType))
301 {
302 visitT(t.next);
303 if (t.assocType)
304 visitT(t.assocType);
305 else if (t.e1)
306 visitE(t.e1), t.e2 && visitE(t.e2);
307 }
308 static if (is(T == FunctionType) || is(T == DelegateType))
309 visitT(t.returnType), visitN(t.params);
310 static if (is(T == CFuncPointerType))
311 visitT(t.next), t.params && visitN(t.params);
312 static if (is(T == BaseClassType) ||
313 is(T == ConstType) ||
314 is(T == InvariantType))
315 visitT(t.next);
316 }
317 else
318 static if (is(T == Parameter))
319 {
320 n.type && visitT(n.type);
321 n.defValue && visitE(n.defValue);
322 }
323 else
324 static if (is(T == Parameters) ||
325 is(T == TemplateParameters) ||
326 is(T == TemplateArguments))
327 {
328 foreach (node; n.children)
329 visitN(node);
330 }
331 else
332 static if (is(T : TemplateParameter))
333 {
334 static if (is(N == TemplateAliasParameter) ||
335 is(N == TemplateTypeParameter) ||
336 is(N == TemplateThisParameter))
337 n.specType && visitN(n.specType),
338 n.defType && visitN(n.defType);
339 static if (is(N == TemplateValueParameter))
340 visitT(n.valueType),
341 n.specValue && visitN(n.specValue),
342 n.defValue && visitN(n.defValue);
343 //TemplateTupleParameter has no subnodes.
344 }
345 else
346 static assert(0, "Missing default visit method for: "~typeof(t).stringof);
347 return t;
348 }
349
350 /// Generates the default visit methods.
351 ///
352 /// E.g:
353 /// ---
354 /// private mixin .visitDefault!(ClassDeclaration) _ClassDeclaration;
355 /// override returnType!("ClassDeclaration") visit(ClassDeclaration node)
356 /// { return _ClassDeclaration.visitDefault(node); }
357 /// ---
358 char[] generateDefaultVisitMethods()
359 {
360 char[] text;
361 foreach (className; g_classNames)
362 text ~= "private mixin .visitDefault!("~className~") _"~className~";\n"
363 "override returnType!(\""~className~"\") visit("~className~" node)"
364 "{return _"~className~".visitDefault(node);}\n";
365 return text;
366 }
367 // pragma(msg, generateDefaultVisitMethods());
368
369 /// This class provides default methods for
370 /// traversing nodes and their sub-nodes.
371 class DefaultVisitor : Visitor
372 {
373 // Comment out if too many errors are shown.
374 mixin(generateDefaultVisitMethods());
375 }