1 // Written in the D programming language.
2 
3 /**
4  * This module defines an Abstract Syntax Tree for the D language
5  *
6  * Examples:
7  * ---
8  * // TODO
9  * ---
10  *
11  * Copyright: Brian Schott 2013
12  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt Boost, License 1.0)
13  * Authors: Brian Schott
14  */
15 
16 module dparse.ast;
17 
18 import dparse.lexer;
19 import std.traits;
20 import std.algorithm;
21 import std.array;
22 import std.string;
23 
24 private immutable uint[TypeInfo] typeMap;
25 
26 shared static this()
27 {
28     typeMap[typeid(AddExpression)] = 1;
29     typeMap[typeid(AndAndExpression)] = 2;
30     typeMap[typeid(AndExpression)] = 3;
31     typeMap[typeid(AsmAddExp)] = 4;
32     typeMap[typeid(AsmAndExp)] = 5;
33     typeMap[typeid(AsmBrExp)] = 6;
34     typeMap[typeid(AsmExp)] = 7;
35     typeMap[typeid(AsmEqualExp)] = 8;
36     typeMap[typeid(AsmLogAndExp)] = 9;
37     typeMap[typeid(AsmLogOrExp)] = 10;
38     typeMap[typeid(AsmMulExp)] = 11;
39     typeMap[typeid(AsmOrExp)] = 12;
40     typeMap[typeid(AsmRelExp)] = 13;
41     typeMap[typeid(AsmUnaExp)] = 14;
42     typeMap[typeid(AsmShiftExp)] = 15;
43     typeMap[typeid(AsmXorExp)] = 16;
44     typeMap[typeid(AssertExpression)] = 17;
45     typeMap[typeid(AssignExpression)] = 18;
46     typeMap[typeid(CmpExpression)] = 19;
47     typeMap[typeid(DeleteExpression)] = 20;
48     typeMap[typeid(EqualExpression)] = 21;
49     typeMap[typeid(Expression)] = 22;
50     typeMap[typeid(FunctionCallExpression)] = 23;
51     typeMap[typeid(FunctionLiteralExpression)] = 24;
52     typeMap[typeid(IdentityExpression)] = 25;
53     typeMap[typeid(ImportExpression)] = 26;
54     typeMap[typeid(IndexExpression)] = 27;
55     typeMap[typeid(InExpression)] = 28;
56     typeMap[typeid(IsExpression)] = 29;
57     typeMap[typeid(MixinExpression)] = 30;
58     typeMap[typeid(MulExpression)] = 31;
59     typeMap[typeid(NewAnonClassExpression)] = 32;
60     typeMap[typeid(NewExpression)] = 33;
61     typeMap[typeid(OrExpression)] = 34;
62     typeMap[typeid(OrOrExpression)] = 35;
63     typeMap[typeid(PowExpression)] = 36;
64     typeMap[typeid(PragmaExpression)] = 37;
65     typeMap[typeid(PrimaryExpression)] = 38;
66     typeMap[typeid(RelExpression)] = 39;
67     typeMap[typeid(ShiftExpression)] = 40;
68     typeMap[typeid(Index)] = 41;
69     typeMap[typeid(TemplateMixinExpression)] = 42;
70     typeMap[typeid(TernaryExpression)] = 43;
71     typeMap[typeid(TraitsExpression)] = 44;
72     typeMap[typeid(TypeidExpression)] = 45;
73     typeMap[typeid(TypeofExpression)] = 46;
74     typeMap[typeid(UnaryExpression)] = 47;
75     typeMap[typeid(XorExpression)] = 48;
76 }
77 
78 /**
79  * Implements the $(LINK2 http://en.wikipedia.org/wiki/Visitor_pattern, Visitor Pattern)
80  * for the various AST classes
81  */
82 abstract class ASTVisitor
83 {
84 public:
85 
86     /** */
87     void visit(const ExpressionNode n)
88     {
89         switch (typeMap[typeid(n)])
90         {
91         case 1: visit(cast(AddExpression) n); break;
92         case 2: visit(cast(AndAndExpression) n); break;
93         case 3: visit(cast(AndExpression) n); break;
94         case 4: visit(cast(AsmAddExp) n); break;
95         case 5: visit(cast(AsmAndExp) n); break;
96         case 6: visit(cast(AsmBrExp) n); break;
97         case 7: visit(cast(AsmExp) n); break;
98         case 8: visit(cast(AsmEqualExp) n); break;
99         case 9: visit(cast(AsmLogAndExp) n); break;
100         case 10: visit(cast(AsmLogOrExp) n); break;
101         case 11: visit(cast(AsmMulExp) n); break;
102         case 12: visit(cast(AsmOrExp) n); break;
103         case 13: visit(cast(AsmRelExp) n); break;
104         case 14: visit(cast(AsmUnaExp) n); break;
105         case 15: visit(cast(AsmShiftExp) n); break;
106         case 16: visit(cast(AsmXorExp) n); break;
107         case 17: visit(cast(AssertExpression) n); break;
108         case 18: visit(cast(AssignExpression) n); break;
109         case 19: visit(cast(CmpExpression) n); break;
110         case 20: visit(cast(DeleteExpression) n); break;
111         case 21: visit(cast(EqualExpression) n); break;
112         case 22: visit(cast(Expression) n); break;
113         case 23: visit(cast(FunctionCallExpression) n); break;
114         case 24: visit(cast(FunctionLiteralExpression) n); break;
115         case 25: visit(cast(IdentityExpression) n); break;
116         case 26: visit(cast(ImportExpression) n); break;
117         case 27: visit(cast(IndexExpression) n); break;
118         case 28: visit(cast(InExpression) n); break;
119         case 29: visit(cast(IsExpression) n); break;
120         case 30: visit(cast(MixinExpression) n); break;
121         case 31: visit(cast(MulExpression) n); break;
122         case 32: visit(cast(NewAnonClassExpression) n); break;
123         case 33: visit(cast(NewExpression) n); break;
124         case 34: visit(cast(OrExpression) n); break;
125         case 35: visit(cast(OrOrExpression) n); break;
126         case 36: visit(cast(PowExpression) n); break;
127         case 37: visit(cast(PragmaExpression) n); break;
128         case 38: visit(cast(PrimaryExpression) n); break;
129         case 39: visit(cast(RelExpression) n); break;
130         case 40: visit(cast(ShiftExpression) n); break;
131         case 41: visit(cast(Index) n); break;
132         case 42: visit(cast(TemplateMixinExpression) n); break;
133         case 43: visit(cast(TernaryExpression) n); break;
134         case 44: visit(cast(TraitsExpression) n); break;
135         case 45: visit(cast(TypeidExpression) n); break;
136         case 46: visit(cast(TypeofExpression) n); break;
137         case 47: visit(cast(UnaryExpression) n); break;
138         case 48: visit(cast(XorExpression) n); break;
139         default: assert(false, __MODULE__ ~ " has a bug");
140         }
141     }
142 
143     /** */ void visit(const AddExpression addExpression) { addExpression.accept(this); }
144     /** */ void visit(const AliasDeclaration aliasDeclaration) { aliasDeclaration.accept(this); }
145     /** */ void visit(const AliasInitializer aliasInitializer) { aliasInitializer.accept(this); }
146     /** */ void visit(const AliasThisDeclaration aliasThisDeclaration) { aliasThisDeclaration.accept(this); }
147     /** */ void visit(const AlignAttribute alignAttribute) { alignAttribute.accept(this); }
148     /** */ void visit(const AndAndExpression andAndExpression) { andAndExpression.accept(this); }
149     /** */ void visit(const AndExpression andExpression) { andExpression.accept(this); }
150     /** */ void visit(const AnonymousEnumDeclaration anonymousEnumDeclaration) { anonymousEnumDeclaration.accept(this); }
151     /** */ void visit(const AnonymousEnumMember anonymousEnumMember) { anonymousEnumMember.accept(this); }
152     /** */ void visit(const ArgumentList argumentList) { argumentList.accept(this); }
153     /** */ void visit(const Arguments arguments) { arguments.accept(this); }
154     /** */ void visit(const ArrayInitializer arrayInitializer) { arrayInitializer.accept(this); }
155     /** */ void visit(const ArrayLiteral arrayLiteral) { arrayLiteral.accept(this); }
156     /** */ void visit(const ArrayMemberInitialization arrayMemberInitialization) { arrayMemberInitialization.accept(this); }
157     /** */ void visit(const AsmAddExp asmAddExp) { asmAddExp.accept(this); }
158     /** */ void visit(const AsmAndExp asmAndExp) { asmAndExp.accept(this); }
159     /** */ void visit(const AsmBrExp asmBrExp) { asmBrExp.accept(this); }
160     /** */ void visit(const AsmEqualExp asmEqualExp) { asmEqualExp.accept(this); }
161     /** */ void visit(const AsmExp asmExp) { asmExp.accept(this); }
162     /** */ void visit(const AsmInstruction asmInstruction) { asmInstruction.accept(this); }
163     /** */ void visit(const AsmLogAndExp asmLogAndExp) { asmLogAndExp.accept(this); }
164     /** */ void visit(const AsmLogOrExp asmLogOrExp) { asmLogOrExp.accept(this); }
165     /** */ void visit(const AsmMulExp asmMulExp) { asmMulExp.accept(this); }
166     /** */ void visit(const AsmOrExp asmOrExp) { asmOrExp.accept(this); }
167     /** */ void visit(const AsmPrimaryExp asmPrimaryExp) { asmPrimaryExp.accept(this); }
168     /** */ void visit(const AsmRelExp asmRelExp) { asmRelExp.accept(this); }
169     /** */ void visit(const AsmShiftExp asmShiftExp) { asmShiftExp.accept(this); }
170     /** */ void visit(const AsmStatement asmStatement) { asmStatement.accept(this); }
171     /** */ void visit(const AsmTypePrefix asmTypePrefix) { asmTypePrefix.accept(this); }
172     /** */ void visit(const AsmUnaExp asmUnaExp) { asmUnaExp.accept(this); }
173     /** */ void visit(const AsmXorExp asmXorExp) { asmXorExp.accept(this); }
174     /** */ void visit(const AssertExpression assertExpression) { assertExpression.accept(this); }
175     /** */ void visit(const AssignExpression assignExpression) { assignExpression.accept(this); }
176     /** */ void visit(const AssocArrayLiteral assocArrayLiteral) { assocArrayLiteral.accept(this); }
177     /** */ void visit(const AtAttribute atAttribute) { atAttribute.accept(this); }
178     /** */ void visit(const Attribute attribute) { attribute.accept(this); }
179     /** */ void visit(const AttributeDeclaration attributeDeclaration) { attributeDeclaration.accept(this); }
180     /** */ void visit(const AutoDeclaration autoDeclaration) { autoDeclaration.accept(this); }
181     /** */ void visit(const AutoDeclarationPart autoDeclarationPart) { autoDeclarationPart.accept(this); }
182     /** */ void visit(const BlockStatement blockStatement) { blockStatement.accept(this); }
183     /** */ void visit(const BodyStatement bodyStatement) { bodyStatement.accept(this); }
184     /** */ void visit(const BreakStatement breakStatement) { breakStatement.accept(this); }
185     /** */ void visit(const BaseClass baseClass) { baseClass.accept(this); }
186     /** */ void visit(const BaseClassList baseClassList) { baseClassList.accept(this); }
187     /** */ void visit(const CaseRangeStatement caseRangeStatement) { caseRangeStatement.accept(this); }
188     /** */ void visit(const CaseStatement caseStatement) { caseStatement.accept(this); }
189     /** */ void visit(const CastExpression castExpression) { castExpression.accept(this); }
190     /** */ void visit(const CastQualifier castQualifier) { castQualifier.accept(this); }
191     /** */ void visit(const Catch catch_) { catch_.accept(this); }
192     /** */ void visit(const Catches catches) { catches.accept(this); }
193     /** */ void visit(const ClassDeclaration classDeclaration) { classDeclaration.accept(this); }
194     /** */ void visit(const CmpExpression cmpExpression) { cmpExpression.accept(this); }
195     /** */ void visit(const CompileCondition compileCondition) { compileCondition.accept(this); }
196     /** */ void visit(const ConditionalDeclaration conditionalDeclaration) { conditionalDeclaration.accept(this); }
197     /** */ void visit(const ConditionalStatement conditionalStatement) { conditionalStatement.accept(this); }
198     /** */ void visit(const Constraint constraint) { constraint.accept(this); }
199     /** */ void visit(const Constructor constructor) { constructor.accept(this); }
200     /** */ void visit(const ContinueStatement continueStatement) { continueStatement.accept(this); }
201     /** */ void visit(const DebugCondition debugCondition) { debugCondition.accept(this); }
202     /** */ void visit(const DebugSpecification debugSpecification) { debugSpecification.accept(this); }
203     /** */ void visit(const Declaration declaration) { declaration.accept(this); }
204     /** */ void visit(const DeclarationOrStatement declarationsOrStatement) { declarationsOrStatement.accept(this); }
205     /** */ void visit(const DeclarationsAndStatements declarationsAndStatements) { declarationsAndStatements.accept(this); }
206     /** */ void visit(const Declarator declarator) { declarator.accept(this); }
207     /** */ void visit(const DefaultStatement defaultStatement) { defaultStatement.accept(this); }
208     /** */ void visit(const DeleteExpression deleteExpression) { deleteExpression.accept(this); }
209     /** */ void visit(const DeleteStatement deleteStatement) { deleteStatement.accept(this); }
210     /** */ void visit(const Deprecated deprecated_) { deprecated_.accept(this); }
211     /** */ void visit(const Destructor destructor) { destructor.accept(this); }
212     /** */ void visit(const DoStatement doStatement) { doStatement.accept(this); }
213     /** */ void visit(const EnumBody enumBody) { enumBody.accept(this); }
214     /** */ void visit(const EnumDeclaration enumDeclaration) { enumDeclaration.accept(this); }
215     /** */ void visit(const EnumMember enumMember) { enumMember.accept(this); }
216     /** */ void visit(const EponymousTemplateDeclaration eponymousTemplateDeclaration) { eponymousTemplateDeclaration.accept(this); }
217     /** */ void visit(const EqualExpression equalExpression) { equalExpression.accept(this); }
218     /** */ void visit(const Expression expression) { expression.accept(this); }
219     /** */ void visit(const ExpressionStatement expressionStatement) { expressionStatement.accept(this); }
220     /** */ void visit(const FinalSwitchStatement finalSwitchStatement) { finalSwitchStatement.accept(this); }
221     /** */ void visit(const Finally finally_) { finally_.accept(this); }
222     /** */ void visit(const ForStatement forStatement) { forStatement.accept(this); }
223     /** */ void visit(const ForeachStatement foreachStatement) { foreachStatement.accept(this); }
224     /** */ void visit(const StaticForeachDeclaration staticForeachDeclaration) { staticForeachDeclaration.accept(this); }
225     /** */ void visit(const StaticForeachStatement staticForeachStatement) { staticForeachStatement.accept(this); }
226     /** */ void visit(const ForeachType foreachType) { foreachType.accept(this); }
227     /** */ void visit(const ForeachTypeList foreachTypeList) { foreachTypeList.accept(this); }
228     /** */ void visit(const FunctionAttribute functionAttribute) { functionAttribute.accept(this); }
229     /** */ void visit(const FunctionBody functionBody) { functionBody.accept(this); }
230     /** */ void visit(const FunctionCallExpression functionCallExpression) { functionCallExpression.accept(this); }
231     /** */ void visit(const FunctionDeclaration functionDeclaration) { functionDeclaration.accept(this); }
232     /** */ void visit(const FunctionLiteralExpression functionLiteralExpression) { functionLiteralExpression.accept(this); }
233     /** */ void visit(const GotoStatement gotoStatement) { gotoStatement.accept(this); }
234     /** */ void visit(const IdentifierChain identifierChain) { identifierChain.accept(this); }
235     /** */ void visit(const DeclaratorIdentifierList identifierList) { identifierList.accept(this); }
236     /** */ void visit(const IdentifierOrTemplateChain identifierOrTemplateChain) { identifierOrTemplateChain.accept(this); }
237     /** */ void visit(const IdentifierOrTemplateInstance identifierOrTemplateInstance) { identifierOrTemplateInstance.accept(this); }
238     /** */ void visit(const IdentityExpression identityExpression) { identityExpression.accept(this); }
239     /** */ void visit(const IfStatement ifStatement) { ifStatement.accept(this); }
240     /** */ void visit(const ImportBind importBind) { importBind.accept(this); }
241     /** */ void visit(const ImportBindings importBindings) { importBindings.accept(this); }
242     /** */ void visit(const ImportDeclaration importDeclaration) { importDeclaration.accept(this); }
243     /** */ void visit(const ImportExpression importExpression) { importExpression.accept(this); }
244     /** */ void visit(const IndexExpression indexExpression) { indexExpression.accept(this); }
245     /** */ void visit(const InExpression inExpression) { inExpression.accept(this); }
246     /** */ void visit(const InStatement inStatement) { inStatement.accept(this); }
247     /** */ void visit(const Initialize initialize) { initialize.accept(this); }
248     /** */ void visit(const Initializer initializer) { initializer.accept(this); }
249     /** */ void visit(const InterfaceDeclaration interfaceDeclaration) { interfaceDeclaration.accept(this); }
250     /** */ void visit(const Invariant invariant_) { invariant_.accept(this); }
251     /** */ void visit(const IsExpression isExpression) { isExpression.accept(this); }
252     /** */ void visit(const KeyValuePair keyValuePair) { keyValuePair.accept(this); }
253     /** */ void visit(const KeyValuePairs keyValuePairs) { keyValuePairs.accept(this); }
254     /** */ void visit(const LabeledStatement labeledStatement) { labeledStatement.accept(this); }
255     /** */ void visit(const LastCatch lastCatch) { lastCatch.accept(this); }
256     /** */ void visit(const LinkageAttribute linkageAttribute) { linkageAttribute.accept(this); }
257     /** */ void visit(const MemberFunctionAttribute memberFunctionAttribute) { memberFunctionAttribute.accept(this); }
258     /** */ void visit(const MixinDeclaration mixinDeclaration) { mixinDeclaration.accept(this); }
259     /** */ void visit(const MixinExpression mixinExpression) { mixinExpression.accept(this); }
260     /** */ void visit(const MixinTemplateDeclaration mixinTemplateDeclaration) { mixinTemplateDeclaration.accept(this); }
261     /** */ void visit(const MixinTemplateName mixinTemplateName) { mixinTemplateName.accept(this); }
262     /** */ void visit(const Module module_) { module_.accept(this); }
263     /** */ void visit(const ModuleDeclaration moduleDeclaration) { moduleDeclaration.accept(this); }
264     /** */ void visit(const MulExpression mulExpression) { mulExpression.accept(this); }
265     /** */ void visit(const NewAnonClassExpression newAnonClassExpression) { newAnonClassExpression.accept(this); }
266     /** */ void visit(const NewExpression newExpression) { newExpression.accept(this); }
267     /** */ void visit(const NonVoidInitializer nonVoidInitializer) { nonVoidInitializer.accept(this); }
268     /** */ void visit(const Operands operands) { operands.accept(this); }
269     /** */ void visit(const OrExpression orExpression) { orExpression.accept(this); }
270     /** */ void visit(const OrOrExpression orOrExpression) { orOrExpression.accept(this); }
271     /** */ void visit(const OutStatement outStatement) { outStatement.accept(this); }
272     /** */ void visit(const Parameter parameter) { parameter.accept(this); }
273     /** */ void visit(const Parameters parameters) { parameters.accept(this); }
274     /** */ void visit(const Postblit postblit) { postblit.accept(this); }
275     /** */ void visit(const PowExpression powExpression) { powExpression.accept(this); }
276     /** */ void visit(const PragmaDeclaration pragmaDeclaration) { pragmaDeclaration.accept(this); }
277     /** */ void visit(const PragmaStatement pragmaStatement) { pragmaStatement.accept(this); }
278     /** */ void visit(const PragmaExpression pragmaExpression) { pragmaExpression.accept(this); }
279     /** */ void visit(const PrimaryExpression primaryExpression) { primaryExpression.accept(this); }
280     /** */ void visit(const Register register) { register.accept(this); }
281     /** */ void visit(const RelExpression relExpression) { relExpression.accept(this); }
282     /** */ void visit(const ReturnStatement returnStatement) { returnStatement.accept(this); }
283     /** */ void visit(const ScopeGuardStatement scopeGuardStatement) { scopeGuardStatement.accept(this); }
284     /** */ void visit(const SharedStaticConstructor sharedStaticConstructor) { sharedStaticConstructor.accept(this); }
285     /** */ void visit(const SharedStaticDestructor sharedStaticDestructor) { sharedStaticDestructor.accept(this); }
286     /** */ void visit(const ShiftExpression shiftExpression) { shiftExpression.accept(this); }
287     /** */ void visit(const SingleImport singleImport) { singleImport.accept(this); }
288     /** */ void visit(const Index index) { index.accept(this); }
289     /** */ void visit(const Statement statement) { statement.accept(this); }
290     /** */ void visit(const StatementNoCaseNoDefault statementNoCaseNoDefault) { statementNoCaseNoDefault.accept(this); }
291     /** */ void visit(const StaticAssertDeclaration staticAssertDeclaration) { staticAssertDeclaration.accept(this); }
292     /** */ void visit(const StaticAssertStatement staticAssertStatement) { staticAssertStatement.accept(this); }
293     /** */ void visit(const StaticConstructor staticConstructor) { staticConstructor.accept(this); }
294     /** */ void visit(const StaticDestructor staticDestructor) { staticDestructor.accept(this); }
295     /** */ void visit(const StaticIfCondition staticIfCondition) { staticIfCondition.accept(this); }
296     /** */ void visit(const StorageClass storageClass) { storageClass.accept(this); }
297     /** */ void visit(const StructBody structBody) { structBody.accept(this); }
298     /** */ void visit(const StructDeclaration structDeclaration) { structDeclaration.accept(this); }
299     /** */ void visit(const StructInitializer structInitializer) { structInitializer.accept(this); }
300     /** */ void visit(const StructMemberInitializer structMemberInitializer) { structMemberInitializer.accept(this); }
301     /** */ void visit(const StructMemberInitializers structMemberInitializers) { structMemberInitializers.accept(this); }
302     /** */ void visit(const SwitchStatement switchStatement) { switchStatement.accept(this); }
303     /** */ void visit(const Symbol symbol) { symbol.accept(this); }
304     /** */ void visit(const SynchronizedStatement synchronizedStatement) { synchronizedStatement.accept(this); }
305     /** */ void visit(const TemplateAliasParameter templateAliasParameter) { templateAliasParameter.accept(this); }
306     /** */ void visit(const TemplateArgument templateArgument) { templateArgument.accept(this); }
307     /** */ void visit(const TemplateArgumentList templateArgumentList) { templateArgumentList.accept(this); }
308     /** */ void visit(const TemplateArguments templateArguments) { templateArguments.accept(this); }
309     /** */ void visit(const TemplateDeclaration templateDeclaration) { templateDeclaration.accept(this); }
310     /** */ void visit(const TemplateInstance templateInstance) { templateInstance.accept(this); }
311     /** */ void visit(const TemplateMixinExpression templateMixinExpression) { templateMixinExpression.accept(this); }
312     /** */ void visit(const TemplateParameter templateParameter) { templateParameter.accept(this); }
313     /** */ void visit(const TemplateParameterList templateParameterList) { templateParameterList.accept(this); }
314     /** */ void visit(const TemplateParameters templateParameters) { templateParameters.accept(this); }
315     /** */ void visit(const TemplateSingleArgument templateSingleArgument) { templateSingleArgument.accept(this); }
316     /** */ void visit(const TemplateThisParameter templateThisParameter) { templateThisParameter.accept(this); }
317     /** */ void visit(const TemplateTupleParameter templateTupleParameter) { templateTupleParameter.accept(this); }
318     /** */ void visit(const TemplateTypeParameter templateTypeParameter) { templateTypeParameter.accept(this); }
319     /** */ void visit(const TemplateValueParameter templateValueParameter) { templateValueParameter.accept(this); }
320     /** */ void visit(const TemplateValueParameterDefault templateValueParameterDefault) { templateValueParameterDefault.accept(this); }
321     /** */ void visit(const TernaryExpression ternaryExpression) { ternaryExpression.accept(this); }
322     /** */ void visit(const ThrowStatement throwStatement) { throwStatement.accept(this); }
323     /** */ void visit(const Token) { }
324     /** */ void visit(const TraitsExpression traitsExpression) { traitsExpression.accept(this); }
325     /** */ void visit(const TryStatement tryStatement) { tryStatement.accept(this); }
326     /** */ void visit(const Type type) { type.accept(this); }
327     /** */ void visit(const TypeIdentifierPart typeIdentChain) { typeIdentChain.accept(this); }
328     /** */ void visit(const Type2 type2) { type2.accept(this); }
329     /** */ void visit(const TypeSpecialization typeSpecialization) { typeSpecialization.accept(this); }
330     /** */ void visit(const TypeSuffix typeSuffix) { typeSuffix.accept(this); }
331     /** */ void visit(const TypeidExpression typeidExpression) { typeidExpression.accept(this); }
332     /** */ void visit(const TypeofExpression typeofExpression) { typeofExpression.accept(this); }
333     /** */ void visit(const UnaryExpression unaryExpression) { unaryExpression.accept(this); }
334     /** */ void visit(const UnionDeclaration unionDeclaration) { unionDeclaration.accept(this); }
335     /** */ void visit(const Unittest unittest_) { unittest_.accept(this); }
336     /** */ void visit(const VariableDeclaration variableDeclaration) { variableDeclaration.accept(this); }
337     /** */ void visit(const Vector vector) { vector.accept(this); }
338     /** */ void visit(const VersionCondition versionCondition) { versionCondition.accept(this); }
339     /** */ void visit(const VersionSpecification versionSpecification) { versionSpecification.accept(this); }
340     /** */ void visit(const WhileStatement whileStatement) { whileStatement.accept(this); }
341     /** */ void visit(const WithStatement withStatement) { withStatement.accept(this); }
342     /** */ void visit(const XorExpression xorExpression) { xorExpression.accept(this); }
343 }
344 
345 interface ASTNode
346 {
347 public:
348     /** */ void accept(ASTVisitor visitor) const;
349 }
350 
351 template visitIfNotNull(fields ...)
352 {
353     static if (fields.length > 1)
354         immutable visitIfNotNull = visitIfNotNull!(fields[0]) ~ visitIfNotNull!(fields[1..$]);
355     else
356     {
357         static if (typeof(fields[0]).stringof[$ - 2 .. $] == "[]")
358         {
359             static if (__traits(hasMember, typeof(fields[0][0]), "classinfo"))
360                 immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") if (i !is null) visitor.visit(i);\n";
361             else
362                 immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") visitor.visit(i);\n";
363         }
364         else static if (__traits(hasMember, typeof(fields[0]), "classinfo"))
365             immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ " !is null) visitor.visit(" ~ fields[0].stringof ~ ");\n";
366         else static if (is(Unqual!(typeof(fields[0])) == Token))
367             immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ ` != tok!""` ~ ") visitor.visit(" ~ fields[0].stringof ~ ");\n";
368         else
369             immutable visitIfNotNull = "visitor.visit(" ~ fields[0].stringof ~ ");\n";
370     }
371 }
372 
373 mixin template OpEquals(bool print = false)
374 {
375     override bool opEquals(Object other) const
376     {
377         static if (print)
378             pragma(msg, generateOpEquals!(typeof(this)));
379         mixin (generateOpEquals!(typeof(this)));
380     }
381 }
382 
383 template generateOpEquals(T)
384 {
385     template opEqualsPart(p ...)
386     {
387         import std.traits : isSomeFunction, isDynamicArray;
388         import std.algorithm : among;
389 
390         static if (p.length > 1)
391         {
392             enum opEqualsPart = opEqualsPart!(p[0 .. $/2]) ~ opEqualsPart!(p[$/2 .. $]);
393         }
394         else static if (p.length && !isSomeFunction!(typeof(__traits(getMember, T, p[0])))
395             && !p[0].among("comment", "line", "column", "endLocation", "startLocation", "index", "dotLocation"))
396         {
397             static if (isDynamicArray!(typeof(__traits(getMember, T, p[0]))))
398             {
399                 enum opEqualsPart = "\tif (obj." ~ p[0] ~ ".length != " ~ p[0] ~ ".length) return false;\n"
400                     ~ "\tforeach (i; 0 .. " ~ p[0]  ~ ".length)\n"
401                     ~ "\t\tif (" ~ p[0] ~ "[i] != obj." ~ p[0] ~ "[i]) return false;\n";
402             }
403             else
404                 enum opEqualsPart = "\tif (obj." ~ p[0] ~ " != " ~ p[0] ~ ") return false;\n";
405         }
406         else
407             enum opEqualsPart = "";
408     }
409     enum generateOpEquals = "if (auto obj = cast(" ~ T.stringof ~ ") other){\n"
410         ~ opEqualsPart!(__traits(derivedMembers, T))
411         ~ "\treturn true;\n}\nreturn false;";
412 }
413 
414 abstract class ExpressionNode : ASTNode
415 {
416 public:
417     override void accept(ASTVisitor visitor) const
418     {
419         assert (false);
420     }
421 }
422 
423 mixin template BinaryExpressionBody()
424 {
425     ExpressionNode left;
426     ExpressionNode right;
427     size_t line;
428     size_t column;
429 }
430 
431 ///
432 final class AddExpression : ExpressionNode
433 {
434 public:
435     override void accept(ASTVisitor visitor) const
436     {
437         mixin (visitIfNotNull!(left, right));
438     }
439     mixin OpEquals;
440     /** */ IdType operator;
441     mixin BinaryExpressionBody;
442 }
443 
444 ///
445 final class AliasDeclaration : ASTNode
446 {
447 public:
448     override void accept(ASTVisitor visitor) const
449     {
450         mixin (visitIfNotNull!(storageClasses, type, declaratorIdentifierList,
451             initializers, parameters, memberFunctionAttributes));
452     }
453     mixin OpEquals;
454     /** */ StorageClass[] storageClasses;
455     /** */ Type type;
456     /** */ DeclaratorIdentifierList declaratorIdentifierList;
457     /** */ AliasInitializer[] initializers;
458     /** */ string comment;
459     /** */ Parameters parameters;
460     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
461 }
462 
463 ///
464 final class AliasInitializer : ASTNode
465 {
466 public:
467     override void accept(ASTVisitor visitor) const
468     {
469         mixin (visitIfNotNull!(name, templateParameters, storageClasses, type,
470                 functionLiteralExpression));
471     }
472     mixin OpEquals;
473     /** */ Token name;
474     /** */ StorageClass[] storageClasses;
475     /** */ TemplateParameters templateParameters;
476     /** */ Type type;
477     /** */ FunctionLiteralExpression functionLiteralExpression;
478 }
479 
480 ///
481 final class AliasThisDeclaration : ASTNode
482 {
483 public:
484     override void accept(ASTVisitor visitor) const
485     {
486         mixin (visitIfNotNull!(identifier));
487     }
488     mixin OpEquals;
489     /** */ Token identifier;
490     /** */ string comment;
491 }
492 
493 ///
494 final class AlignAttribute : ASTNode
495 {
496 public:
497     override void accept(ASTVisitor visitor) const
498     {
499         mixin (visitIfNotNull!(assignExpression));
500     }
501     mixin OpEquals;
502     /** */ ExpressionNode assignExpression;
503 }
504 
505 ///
506 final class AndAndExpression : ExpressionNode
507 {
508 public:
509     override void accept(ASTVisitor visitor) const
510     {
511         mixin (visitIfNotNull!(left, right));
512     }
513     mixin OpEquals;
514     mixin BinaryExpressionBody;
515 }
516 
517 ///
518 final class AndExpression : ExpressionNode
519 {
520 public:
521     override void accept(ASTVisitor visitor) const
522     {
523         mixin (visitIfNotNull!(left, right));
524     }
525     mixin OpEquals;
526     mixin BinaryExpressionBody;
527 }
528 
529 ///
530 final class AnonymousEnumDeclaration : ASTNode
531 {
532     override void accept(ASTVisitor visitor) const
533     {
534         mixin (visitIfNotNull!(baseType, members));
535     }
536     mixin OpEquals;
537     /** */ Type baseType;
538     /** */ AnonymousEnumMember[] members;
539 }
540 
541 ///
542 final class AnonymousEnumMember : ASTNode
543 {
544     override void accept(ASTVisitor visitor) const
545     {
546         mixin (visitIfNotNull!(type, name, assignExpression));
547     }
548     /** */ Type type;
549     /** */ Token name;
550     /** */ ExpressionNode assignExpression;
551     /** */ string comment;
552 }
553 
554 ///
555 final class ArgumentList : ASTNode
556 {
557 public:
558     override void accept(ASTVisitor visitor) const
559     {
560         mixin (visitIfNotNull!(items));
561     }
562     mixin OpEquals;
563     /** */ ExpressionNode[] items;
564     /** */ size_t startLocation;
565     /** */ size_t endLocation;
566 }
567 
568 ///
569 final class Arguments : ASTNode
570 {
571 public:
572     override void accept(ASTVisitor visitor) const
573     {
574         mixin (visitIfNotNull!(argumentList));
575     }
576     mixin OpEquals;
577     /** */ ArgumentList argumentList;
578 }
579 
580 ///
581 final class ArrayInitializer : ASTNode
582 {
583 public:
584     override void accept(ASTVisitor visitor) const
585     {
586         mixin (visitIfNotNull!(arrayMemberInitializations));
587     }
588     mixin OpEquals;
589     /** */ size_t startLocation;
590     /** */ size_t endLocation;
591     /** */ ArrayMemberInitialization[] arrayMemberInitializations;
592 }
593 
594 ///
595 final class ArrayLiteral : ASTNode
596 {
597 public:
598     override void accept(ASTVisitor visitor) const
599     {
600         mixin (visitIfNotNull!(argumentList));
601     }
602     mixin OpEquals;
603     /** */ ArgumentList argumentList;
604 }
605 
606 ///
607 final class ArrayMemberInitialization : ASTNode
608 {
609 public:
610     override void accept(ASTVisitor visitor) const
611     {
612         mixin (visitIfNotNull!(assignExpression, nonVoidInitializer));
613     }
614     mixin OpEquals;
615     /** */ ExpressionNode assignExpression;
616     /** */ NonVoidInitializer nonVoidInitializer;
617 }
618 
619 ///
620 final class AsmAddExp : ExpressionNode
621 {
622 public:
623     override void accept(ASTVisitor visitor) const
624     {
625         mixin (visitIfNotNull!(left, right));
626     }
627     mixin OpEquals;
628     /** */ IdType operator;
629     mixin BinaryExpressionBody;
630 }
631 
632 ///
633 final class AsmAndExp : ExpressionNode
634 {
635 public:
636     override void accept(ASTVisitor visitor) const
637     {
638         mixin (visitIfNotNull!(left, right));
639     }
640     mixin OpEquals;
641     mixin BinaryExpressionBody;
642 }
643 
644 ///
645 final class AsmBrExp : ExpressionNode
646 {
647 public:
648     override void accept(ASTVisitor visitor) const
649     {
650         mixin (visitIfNotNull!(asmBrExp, asmExp, asmUnaExp));
651     }
652     mixin OpEquals;
653     size_t line;
654     size_t column;
655     /** */ AsmBrExp asmBrExp;
656     /** */ ExpressionNode asmExp;
657     /** */ AsmUnaExp asmUnaExp;
658 }
659 
660 ///
661 final class AsmEqualExp : ExpressionNode
662 {
663 public:
664     override void accept(ASTVisitor visitor) const
665     {
666         mixin (visitIfNotNull!(left, right));
667     }
668     mixin BinaryExpressionBody;
669     mixin OpEquals;
670     /** */ IdType operator;
671 }
672 
673 ///
674 final class AsmExp : ExpressionNode
675 {
676 public:
677     override void accept(ASTVisitor visitor) const
678     {
679         mixin (visitIfNotNull!(left, middle, right));
680     }
681     mixin OpEquals;
682     /** */ ExpressionNode left;
683     /** */ ExpressionNode middle;
684     /** */ ExpressionNode right;
685 }
686 
687 ///
688 final class AsmInstruction : ASTNode
689 {
690 public:
691     override void accept(ASTVisitor visitor) const
692     {
693         mixin (visitIfNotNull!(identifierOrIntegerOrOpcode, asmInstruction, operands));
694     }
695     mixin OpEquals;
696     /** */ Token identifierOrIntegerOrOpcode;
697     /** */ bool hasAlign;
698     /** */ AsmInstruction asmInstruction;
699     /** */ Operands operands;
700 }
701 
702 ///
703 final class AsmLogAndExp : ExpressionNode
704 {
705 public:
706     override void accept(ASTVisitor visitor) const
707     {
708         mixin (visitIfNotNull!(left, right));
709     }
710     mixin BinaryExpressionBody;
711     mixin OpEquals;
712 }
713 
714 ///
715 final class AsmLogOrExp : ExpressionNode
716 {
717 public:
718     override void accept(ASTVisitor visitor) const
719     {
720         mixin (visitIfNotNull!(left, right));
721     }
722     mixin BinaryExpressionBody;
723     mixin OpEquals;
724 }
725 
726 ///
727 final class AsmMulExp : ExpressionNode
728 {
729 public:
730     override void accept(ASTVisitor visitor) const
731     {
732         mixin (visitIfNotNull!(left, right));
733     }
734     /** */ IdType operator;
735     mixin BinaryExpressionBody;
736     mixin OpEquals;
737 
738 }
739 
740 ///
741 final class AsmOrExp : ExpressionNode
742 {
743 public:
744     override void accept(ASTVisitor visitor) const
745     {
746         mixin (visitIfNotNull!(left, right));
747     }
748     mixin BinaryExpressionBody;
749     mixin OpEquals;
750 }
751 
752 ///
753 final class AsmPrimaryExp : ASTNode
754 {
755 public:
756     override void accept(ASTVisitor visitor) const
757     {
758         mixin (visitIfNotNull!(token, register, asmExp, identifierChain,
759             segmentOverrideSuffix));
760     }
761     /** */ ExpressionNode asmExp;
762     /** */ IdentifierChain identifierChain;
763     /** */ Register register;
764     /** */ ExpressionNode segmentOverrideSuffix;
765     /** */ Token token;
766     mixin OpEquals;
767 }
768 
769 ///
770 final class AsmRelExp : ExpressionNode
771 {
772 public:
773     override void accept(ASTVisitor visitor) const
774     {
775         mixin (visitIfNotNull!(left, right));
776     }
777     mixin BinaryExpressionBody;
778     /** */ IdType operator;
779     mixin OpEquals;
780 }
781 
782 ///
783 final class AsmShiftExp : ExpressionNode
784 {
785 public:
786     override void accept(ASTVisitor visitor) const
787     {
788         mixin (visitIfNotNull!(left, right));
789     }
790     mixin BinaryExpressionBody;
791     /** */ IdType operator;
792     mixin OpEquals;
793 }
794 
795 ///
796 final class AsmStatement : ASTNode
797 {
798 public:
799     override void accept(ASTVisitor visitor) const
800     {
801         mixin (visitIfNotNull!asmInstructions);
802     }
803     /** */ AsmInstruction[] asmInstructions;
804     /** */ FunctionAttribute[] functionAttributes;
805     mixin OpEquals;
806 }
807 
808 ///
809 final class AsmTypePrefix : ASTNode
810 {
811 public:
812     override void accept(ASTVisitor visitor) const
813     {
814         mixin (visitIfNotNull!(left, right));
815     }
816     /** */ Token left;
817     /** */ Token right;
818     mixin OpEquals;
819 }
820 
821 ///
822 final class AsmUnaExp : ASTNode
823 {
824 public:
825     override void accept(ASTVisitor visitor) const
826     {
827         mixin (visitIfNotNull!(prefix, asmTypePrefix, asmExp, asmPrimaryExp, asmUnaExp));
828     }
829     /** */ AsmTypePrefix asmTypePrefix;
830     /** */ ExpressionNode asmExp;
831     /** */ Token prefix;
832     /** */ AsmPrimaryExp asmPrimaryExp;
833     /** */ AsmUnaExp asmUnaExp;
834     mixin OpEquals;
835 }
836 
837 ///
838 final class AsmXorExp : ExpressionNode
839 {
840 public:
841     override void accept(ASTVisitor visitor) const
842     {
843         mixin (visitIfNotNull!(left, right));
844     }
845     mixin BinaryExpressionBody;
846     mixin OpEquals;
847 }
848 
849 ///
850 final class AssertExpression : ExpressionNode
851 {
852 public:
853     override void accept(ASTVisitor visitor) const
854     {
855         mixin (visitIfNotNull!(assertion, message));
856     }
857     /** */ size_t line;
858     /** */ size_t column;
859     /** */ ExpressionNode assertion;
860     /** */ ExpressionNode message;
861     mixin OpEquals;
862 }
863 
864 ///
865 final class AssignExpression : ExpressionNode
866 {
867 public:
868     override void accept(ASTVisitor visitor) const
869     {
870         mixin (visitIfNotNull!(ternaryExpression, expression));
871     }
872     /** */ ExpressionNode ternaryExpression;
873     /** */ ExpressionNode expression;
874     /** */ IdType operator;
875     /** */ size_t line;
876     /** */ size_t column;
877     mixin OpEquals;
878 }
879 
880 ///
881 final class AssocArrayLiteral : ASTNode
882 {
883 public:
884     override void accept(ASTVisitor visitor) const
885     {
886         mixin (visitIfNotNull!(keyValuePairs));
887     }
888     /** */ KeyValuePairs keyValuePairs;
889     mixin OpEquals;
890 }
891 
892 ///
893 final class AtAttribute : ASTNode
894 {
895 public:
896     override void accept(ASTVisitor visitor) const
897     {
898         mixin (visitIfNotNull!(templateInstance, argumentList));
899     }
900     /** */ ArgumentList argumentList;
901     /** */ TemplateInstance templateInstance;
902     /** */ Token identifier;
903     /** */ size_t startLocation;
904     /** */ size_t endLocation;
905     mixin OpEquals;
906 }
907 
908 ///
909 final class Attribute : ASTNode
910 {
911 public:
912     override void accept(ASTVisitor visitor) const
913     {
914         mixin (visitIfNotNull!(pragmaExpression, deprecated_, atAttribute,
915             alignAttribute, identifierChain, linkageAttribute));
916     }
917     /** */ PragmaExpression pragmaExpression;
918     /** */ Deprecated deprecated_;
919     /** */ AtAttribute atAttribute;
920     /** */ AlignAttribute alignAttribute;
921     /** */ LinkageAttribute linkageAttribute;
922     /** */ Token attribute;
923     /** */ IdentifierChain identifierChain;
924     mixin OpEquals;
925 }
926 
927 ///
928 final class AttributeDeclaration : ASTNode
929 {
930     override void accept(ASTVisitor visitor) const
931     {
932         mixin (visitIfNotNull!(attribute));
933     }
934     /** */ Attribute attribute;
935     /** */ size_t line;
936     mixin OpEquals;
937 }
938 
939 ///
940 final class AutoDeclaration : ASTNode
941 {
942 public:
943     override void accept(ASTVisitor visitor) const
944     {
945         foreach (sc; storageClasses)
946             visitor.visit(sc);
947         foreach (part; parts)
948             visitor.visit(part);
949     }
950     /** */ AutoDeclarationPart[] parts;
951     /** */ StorageClass[] storageClasses;
952     /** */ string comment;
953     mixin OpEquals;
954 }
955 
956 final class AutoDeclarationPart : ASTNode
957 {
958     override void accept(ASTVisitor visitor) const
959     {
960         if (templateParameters !is null)
961             visitor.visit(templateParameters);
962         visitor.visit(initializer);
963     }
964 
965     /** */ Token identifier;
966     /** */ Initializer initializer;
967     /** */ TemplateParameters templateParameters;
968 }
969 
970 ///
971 final class BlockStatement : ASTNode
972 {
973 public:
974     override void accept(ASTVisitor visitor) const
975     {
976         mixin (visitIfNotNull!(declarationsAndStatements));
977     }
978 
979     /**
980      * Byte position of the opening brace
981      */
982     size_t startLocation;
983 
984     /**
985      * Byte position of the closing brace
986      */
987     size_t endLocation;
988 
989     /** */ DeclarationsAndStatements declarationsAndStatements;
990     mixin OpEquals;
991 }
992 
993 ///
994 final class BodyStatement : ASTNode
995 {
996 public:
997     override void accept(ASTVisitor visitor) const
998     {
999         mixin (visitIfNotNull!(blockStatement));
1000     }
1001     /** */ BlockStatement blockStatement;
1002     mixin OpEquals;
1003 }
1004 
1005 ///
1006 final class BreakStatement : ASTNode
1007 {
1008 public:
1009     override void accept(ASTVisitor visitor) const
1010     {
1011         mixin (visitIfNotNull!(label));
1012     }
1013     /** */ Token label;
1014     mixin OpEquals;
1015 }
1016 
1017 ///
1018 final class BaseClass : ASTNode
1019 {
1020 public:
1021     override void accept(ASTVisitor visitor) const
1022     {
1023         mixin (visitIfNotNull!(type2));
1024     }
1025     /** */ Type2 type2;
1026     mixin OpEquals;
1027 }
1028 
1029 ///
1030 final class BaseClassList : ASTNode
1031 {
1032 public:
1033     override void accept(ASTVisitor visitor) const
1034     {
1035         mixin (visitIfNotNull!(items));
1036     }
1037     /** */ BaseClass[] items;
1038     mixin OpEquals;
1039 }
1040 
1041 ///
1042 final class CaseRangeStatement : ASTNode
1043 {
1044 public:
1045     override void accept(ASTVisitor visitor) const
1046     {
1047         mixin (visitIfNotNull!(low, high, declarationsAndStatements));
1048     }
1049     /** */ ExpressionNode low;
1050     /** */ ExpressionNode high;
1051     /** */ DeclarationsAndStatements declarationsAndStatements;
1052     /** */ size_t colonLocation;
1053     mixin OpEquals;
1054 }
1055 
1056 ///
1057 final class CaseStatement: ASTNode
1058 {
1059 public:
1060     override void accept(ASTVisitor visitor) const
1061     {
1062         mixin (visitIfNotNull!(argumentList, declarationsAndStatements));
1063     }
1064     /** */ ArgumentList argumentList;
1065     /** */ DeclarationsAndStatements declarationsAndStatements;
1066     /** */ size_t colonLocation;
1067     mixin OpEquals;
1068 }
1069 
1070 ///
1071 final class CastExpression: ASTNode
1072 {
1073 public:
1074     override void accept(ASTVisitor visitor) const
1075     {
1076         mixin (visitIfNotNull!(type, castQualifier, unaryExpression));
1077     }
1078     /** */ Type type;
1079     /** */ CastQualifier castQualifier;
1080     /** */ UnaryExpression unaryExpression;
1081     mixin OpEquals;
1082 }
1083 
1084 ///
1085 final class CastQualifier: ASTNode
1086 {
1087 public:
1088     override void accept(ASTVisitor visitor) const
1089     {
1090         mixin (visitIfNotNull!(first, second));
1091     }
1092     /** */ Token first;
1093     /** */ Token second;
1094     mixin OpEquals;
1095 }
1096 
1097 ///
1098 final class Catches: ASTNode
1099 {
1100 public:
1101     override void accept(ASTVisitor visitor) const
1102     {
1103         mixin (visitIfNotNull!(catches, lastCatch));
1104     }
1105     /** */ Catch[] catches;
1106     /** */ LastCatch lastCatch;
1107     mixin OpEquals;
1108 }
1109 
1110 ///
1111 final class Catch: ASTNode
1112 {
1113 public:
1114     override void accept(ASTVisitor visitor) const
1115     {
1116         mixin (visitIfNotNull!(type, identifier, declarationOrStatement));
1117     }
1118     /** */ Type type;
1119     /** */ Token identifier;
1120     /** */ DeclarationOrStatement declarationOrStatement;
1121     mixin OpEquals;
1122 }
1123 
1124 ///
1125 final class ClassDeclaration: ASTNode
1126 {
1127 public:
1128     override void accept(ASTVisitor visitor) const
1129     {
1130         mixin (visitIfNotNull!(templateParameters, constraint, baseClassList,
1131             structBody));
1132     }
1133 
1134     /** */ Token name;
1135     /** */ TemplateParameters templateParameters;
1136     /** */ Constraint constraint;
1137     /** */ BaseClassList baseClassList;
1138     /** */ StructBody structBody;
1139     /** */ string comment;
1140     mixin OpEquals;
1141 }
1142 
1143 ///
1144 final class CmpExpression : ExpressionNode
1145 {
1146 public:
1147     override void accept(ASTVisitor visitor) const
1148     {
1149         mixin (visitIfNotNull!(shiftExpression, equalExpression,
1150             identityExpression, relExpression, inExpression));
1151     }
1152     /** */ ExpressionNode shiftExpression;
1153     /** */ ExpressionNode equalExpression;
1154     /** */ ExpressionNode identityExpression;
1155     /** */ ExpressionNode relExpression;
1156     /** */ ExpressionNode inExpression;
1157     mixin OpEquals;
1158 }
1159 
1160 ///
1161 final class CompileCondition : ASTNode
1162 {
1163 public:
1164     override void accept(ASTVisitor visitor) const
1165     {
1166         mixin (visitIfNotNull!(versionCondition, debugCondition, staticIfCondition));
1167     }
1168     /** */ VersionCondition versionCondition;
1169     /** */ DebugCondition debugCondition;
1170     /** */ StaticIfCondition staticIfCondition;
1171     mixin OpEquals;
1172 }
1173 
1174 ///
1175 final class ConditionalDeclaration : ASTNode
1176 {
1177 public:
1178     override void accept(ASTVisitor visitor) const
1179     {
1180         mixin (visitIfNotNull!(compileCondition, trueDeclarations, falseDeclarations));
1181     }
1182     /** */ CompileCondition compileCondition;
1183     /** */ Declaration[] trueDeclarations;
1184     /** */ Declaration[] falseDeclarations;
1185     /** */ bool hasElse;
1186     mixin OpEquals;
1187 }
1188 
1189 ///
1190 final class ConditionalStatement : ASTNode
1191 {
1192 public:
1193     override void accept(ASTVisitor visitor) const
1194     {
1195         mixin (visitIfNotNull!(compileCondition, trueStatement, falseStatement));
1196     }
1197     /** */ CompileCondition compileCondition;
1198     /** */ DeclarationOrStatement trueStatement;
1199     /** */ DeclarationOrStatement falseStatement;
1200     mixin OpEquals;
1201 }
1202 
1203 ///
1204 final class Constraint : ASTNode
1205 {
1206 public:
1207     override void accept(ASTVisitor visitor) const
1208     {
1209         mixin (visitIfNotNull!(expression));
1210     }
1211     /** */ Expression expression;
1212     /** */ size_t location;
1213     mixin OpEquals;
1214 }
1215 
1216 ///
1217 final class Constructor : ASTNode
1218 {
1219 public:
1220     override void accept(ASTVisitor visitor) const
1221     {
1222         mixin (visitIfNotNull!(parameters, templateParameters, constraint,
1223             memberFunctionAttributes, functionBody));
1224     }
1225     /** */ Parameters parameters;
1226     /** */ FunctionBody functionBody;
1227     /** */ Constraint constraint;
1228     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1229     /** */ TemplateParameters templateParameters;
1230     /** */ size_t location;
1231     /** */ size_t line;
1232     /** */ size_t column;
1233     /** */ string comment;
1234     mixin OpEquals;
1235 }
1236 
1237 ///
1238 final class ContinueStatement : ASTNode
1239 {
1240 public:
1241     override void accept(ASTVisitor visitor) const
1242     {
1243         mixin (visitIfNotNull!(label));
1244     }
1245     /** */ Token label;
1246     mixin OpEquals;
1247 }
1248 
1249 ///
1250 final class DebugCondition : ASTNode
1251 {
1252 public:
1253     override void accept(ASTVisitor visitor) const
1254     {
1255         mixin (visitIfNotNull!(identifierOrInteger));
1256     }
1257     /** */ size_t debugIndex;
1258     /** */ Token identifierOrInteger;
1259     mixin OpEquals;
1260 }
1261 
1262 ///
1263 final class DebugSpecification : ASTNode
1264 {
1265 public:
1266     override void accept(ASTVisitor visitor) const
1267     {
1268         mixin (visitIfNotNull!(identifierOrInteger));
1269     }
1270     /** */ Token identifierOrInteger;
1271     mixin OpEquals;
1272 }
1273 
1274 ///
1275 final class Declaration : ASTNode
1276 {
1277 public:
1278 
1279     override void accept(ASTVisitor visitor) const
1280     {
1281 
1282         foreach (attr; attributes)
1283             visitor.visit(attr);
1284         foreach (dec; declarations)
1285             visitor.visit(dec);
1286         foreach (Type; DeclarationTypes)
1287         {
1288             const(Type)* value = storage.peek!Type;
1289             if (value !is null)
1290             {
1291                 static if (isArray!Type)
1292                     foreach (item; *(cast(Type*) value))
1293                         visitor.visit(item);
1294                 else if (*value !is null)
1295                     visitor.visit(*(cast(Type*) value));
1296             }
1297         }
1298     }
1299 
1300     private import std.variant:Algebraic;
1301     private import std.typetuple:TypeTuple;
1302 
1303     alias DeclarationTypes = TypeTuple!(AliasDeclaration, AliasThisDeclaration,
1304         AnonymousEnumDeclaration, AttributeDeclaration,
1305         ClassDeclaration, ConditionalDeclaration, Constructor, DebugSpecification,
1306         Destructor, EnumDeclaration, EponymousTemplateDeclaration,
1307         FunctionDeclaration, ImportDeclaration, InterfaceDeclaration, Invariant,
1308         MixinDeclaration, MixinTemplateDeclaration, Postblit, PragmaDeclaration,
1309         SharedStaticConstructor, SharedStaticDestructor, StaticAssertDeclaration,
1310         StaticConstructor, StaticDestructor, StructDeclaration,
1311         TemplateDeclaration, UnionDeclaration, Unittest, VariableDeclaration,
1312         VersionSpecification, StaticForeachDeclaration);
1313 
1314     private Algebraic!(DeclarationTypes) storage;
1315 
1316     private static string generateProperty(string type, string name)
1317     {
1318         return "const(" ~ type ~ ") " ~ name ~ "() const @property { auto p = storage.peek!" ~ type ~ "; return p is null? null : *p;}\n"
1319             ~ "const(" ~ type ~ ") " ~ name ~ "(" ~ type ~ " node) @property { storage = node; return node; }";
1320     }
1321 
1322     /** */ Attribute[] attributes;
1323     /** */ Declaration[] declarations;
1324 
1325     mixin(generateProperty("AliasDeclaration", "aliasDeclaration"));
1326     mixin(generateProperty("AliasThisDeclaration", "aliasThisDeclaration"));
1327     mixin(generateProperty("AnonymousEnumDeclaration", "anonymousEnumDeclaration"));
1328     mixin(generateProperty("AttributeDeclaration", "attributeDeclaration"));
1329     mixin(generateProperty("ClassDeclaration", "classDeclaration"));
1330     mixin(generateProperty("ConditionalDeclaration", "conditionalDeclaration"));
1331     mixin(generateProperty("Constructor", "constructor"));
1332     mixin(generateProperty("DebugSpecification", "debugSpecification"));
1333     mixin(generateProperty("Destructor", "destructor"));
1334     mixin(generateProperty("EnumDeclaration", "enumDeclaration"));
1335     mixin(generateProperty("EponymousTemplateDeclaration", "eponymousTemplateDeclaration"));
1336     mixin(generateProperty("FunctionDeclaration", "functionDeclaration"));
1337     mixin(generateProperty("ImportDeclaration", "importDeclaration"));
1338     mixin(generateProperty("InterfaceDeclaration", "interfaceDeclaration"));
1339     mixin(generateProperty("Invariant", "invariant_"));
1340     mixin(generateProperty("MixinDeclaration", "mixinDeclaration"));
1341     mixin(generateProperty("MixinTemplateDeclaration", "mixinTemplateDeclaration"));
1342     mixin(generateProperty("Postblit", "postblit"));
1343     mixin(generateProperty("PragmaDeclaration", "pragmaDeclaration"));
1344     mixin(generateProperty("SharedStaticConstructor", "sharedStaticConstructor"));
1345     mixin(generateProperty("SharedStaticDestructor", "sharedStaticDestructor"));
1346     mixin(generateProperty("StaticAssertDeclaration", "staticAssertDeclaration"));
1347     mixin(generateProperty("StaticConstructor", "staticConstructor"));
1348     mixin(generateProperty("StaticDestructor", "staticDestructor"));
1349     mixin(generateProperty("StructDeclaration", "structDeclaration"));
1350     mixin(generateProperty("TemplateDeclaration", "templateDeclaration"));
1351     mixin(generateProperty("UnionDeclaration", "unionDeclaration"));
1352     mixin(generateProperty("Unittest", "unittest_"));
1353     mixin(generateProperty("VariableDeclaration", "variableDeclaration"));
1354     mixin(generateProperty("VersionSpecification", "versionSpecification"));
1355     mixin(generateProperty("StaticForeachDeclaration", "staticForeachDeclaration"));
1356 
1357     override bool opEquals(Object other) const
1358     {
1359         auto otherDeclaration = cast(Declaration) other;
1360         if (otherDeclaration is null)
1361             return false;
1362         return attributes == otherDeclaration.attributes
1363             && declarations == otherDeclaration.declarations
1364             && storage == otherDeclaration.storage;
1365     }
1366 }
1367 
1368 ///
1369 final class DeclarationsAndStatements : ASTNode
1370 {
1371     override void accept(ASTVisitor visitor) const
1372     {
1373         mixin (visitIfNotNull!(declarationsAndStatements));
1374     }
1375 
1376     /** */ DeclarationOrStatement[] declarationsAndStatements;
1377     mixin OpEquals;
1378 }
1379 
1380 ///
1381 final class DeclarationOrStatement : ASTNode
1382 {
1383 public:
1384     override void accept(ASTVisitor visitor) const
1385     {
1386         mixin (visitIfNotNull!(declaration, statement));
1387     }
1388 
1389     /** */ Declaration declaration;
1390     /** */ Statement statement;
1391     /** */ size_t startLocation;
1392     /** */ size_t endLocation;
1393     mixin OpEquals;
1394 }
1395 
1396 ///
1397 final class Declarator : ASTNode
1398 {
1399 public:
1400     override void accept(ASTVisitor visitor) const
1401     {
1402         mixin (visitIfNotNull!(templateParameters, initializer));
1403     }
1404     /** */ Token name;
1405     /** */ TemplateParameters templateParameters;
1406     /** */ Initializer initializer;
1407     /** */ TypeSuffix[] cstyle;
1408     /** */ string comment;
1409     mixin OpEquals;
1410 }
1411 
1412 ///
1413 final class DeclaratorIdentifierList : ASTNode
1414 {
1415 public:
1416     override void accept(ASTVisitor visitor) const
1417     {
1418         mixin (visitIfNotNull!(identifiers));
1419     }
1420     /** */ Token[] identifiers;
1421     mixin OpEquals;
1422 }
1423 
1424 ///
1425 final class DefaultStatement : ASTNode
1426 {
1427 public:
1428     override void accept(ASTVisitor visitor) const
1429     {
1430         mixin (visitIfNotNull!(declarationsAndStatements));
1431     }
1432     /** */ DeclarationsAndStatements declarationsAndStatements;
1433     /** */ size_t colonLocation;
1434     mixin OpEquals;
1435 }
1436 
1437 ///
1438 final class DeleteExpression : ExpressionNode
1439 {
1440 public:
1441     override void accept(ASTVisitor visitor) const
1442     {
1443         mixin (visitIfNotNull!(unaryExpression));
1444     }
1445     /** */ UnaryExpression unaryExpression;
1446     /** */ size_t line;
1447     /** */ size_t column;
1448     mixin OpEquals;
1449 }
1450 
1451 ///
1452 final class DeleteStatement : ASTNode
1453 {
1454 public:
1455     override void accept(ASTVisitor visitor) const
1456     {
1457         mixin (visitIfNotNull!(deleteExpression));
1458     }
1459     /** */ DeleteExpression deleteExpression;
1460     mixin OpEquals;
1461 }
1462 
1463 ///
1464 final class Deprecated : ASTNode
1465 {
1466 public:
1467     override void accept(ASTVisitor visitor) const
1468     {
1469         mixin (visitIfNotNull!(assignExpression));
1470     }
1471     /** */ ExpressionNode assignExpression;
1472     mixin OpEquals;
1473 }
1474 
1475 ///
1476 final class Destructor : ASTNode
1477 {
1478 public:
1479     override void accept(ASTVisitor visitor) const
1480     {
1481         mixin (visitIfNotNull!(memberFunctionAttributes, functionBody));
1482     }
1483     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1484     /** */ FunctionBody functionBody;
1485     /** */ size_t line;
1486     /** */ size_t column;
1487     /** */ size_t index;
1488     /** */ string comment;
1489     mixin OpEquals;
1490 }
1491 
1492 ///
1493 final class DoStatement : ASTNode
1494 {
1495 public:
1496     override void accept(ASTVisitor visitor) const
1497     {
1498         mixin (visitIfNotNull!(expression, statementNoCaseNoDefault));
1499     }
1500     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
1501     /** */ Expression expression;
1502     mixin OpEquals;
1503 }
1504 
1505 ///
1506 final class EnumBody : ASTNode
1507 {
1508 public:
1509     override void accept(ASTVisitor visitor) const
1510     {
1511         mixin (visitIfNotNull!(enumMembers));
1512     }
1513     /** */ EnumMember[] enumMembers;
1514 
1515     /**
1516      * Byte position of the opening brace
1517      */
1518     size_t startLocation;
1519 
1520     /**
1521      * Byte position of the closing brace
1522      */
1523     size_t endLocation;
1524     mixin OpEquals;
1525 }
1526 
1527 ///
1528 final class EnumDeclaration : ASTNode
1529 {
1530 public:
1531     override void accept(ASTVisitor visitor) const
1532     {
1533         mixin (visitIfNotNull!(type, enumBody));
1534     }
1535     /** */ Token name;
1536     /** */ Type type;
1537     /** */ EnumBody enumBody;
1538     /** */ string comment;
1539     mixin OpEquals;
1540 }
1541 
1542 ///
1543 final class EnumMember : ASTNode
1544 {
1545 public:
1546     override void accept(ASTVisitor visitor) const
1547     {
1548         mixin (visitIfNotNull!(name, type, assignExpression));
1549     }
1550     /** */ Token name;
1551     /** */ Type type;
1552     /** */ ExpressionNode assignExpression;
1553     /** */ string comment;
1554     mixin OpEquals;
1555 }
1556 
1557 ///
1558 final class EponymousTemplateDeclaration : ASTNode
1559 {
1560 public:
1561     override void accept(ASTVisitor visitor) const
1562     {
1563         mixin (visitIfNotNull!(name, templateParameters, assignExpression));
1564     }
1565     /** */ Token name;
1566     /** */ TemplateParameters templateParameters;
1567     /** */ ExpressionNode assignExpression;
1568     /** */ Type type;
1569     /** */ string comment;
1570     mixin OpEquals;
1571 }
1572 
1573 ///
1574 final class EqualExpression : ExpressionNode
1575 {
1576 public:
1577     override void accept(ASTVisitor visitor) const
1578     {
1579         mixin (visitIfNotNull!(left, right));
1580     }
1581     /** */ IdType operator;
1582     mixin BinaryExpressionBody;
1583     mixin OpEquals;
1584 }
1585 
1586 ///
1587 final class Expression : ExpressionNode
1588 {
1589 public:
1590     override void accept(ASTVisitor visitor) const
1591     {
1592         mixin (visitIfNotNull!(items));
1593     }
1594     /** */ ExpressionNode[] items;
1595     /** */ size_t line;
1596     /** */ size_t column;
1597     mixin OpEquals;
1598 }
1599 
1600 ///
1601 final class ExpressionStatement : ASTNode
1602 {
1603 public:
1604     override void accept(ASTVisitor visitor) const
1605     {
1606         mixin (visitIfNotNull!(expression));
1607     }
1608     /** */ Expression expression;
1609     mixin OpEquals;
1610 }
1611 
1612 ///
1613 final class FinalSwitchStatement : ASTNode
1614 {
1615 public:
1616     override void accept(ASTVisitor visitor) const
1617     {
1618         mixin (visitIfNotNull!(switchStatement));
1619     }
1620     /** */ SwitchStatement switchStatement;
1621     mixin OpEquals;
1622 }
1623 
1624 ///
1625 final class Finally : ASTNode
1626 {
1627 public:
1628     override void accept(ASTVisitor visitor) const
1629     {
1630         mixin (visitIfNotNull!(declarationOrStatement));
1631     }
1632     /** */ DeclarationOrStatement declarationOrStatement;
1633     mixin OpEquals;
1634 }
1635 
1636 ///
1637 final class ForStatement : ASTNode
1638 {
1639 public:
1640     override void accept(ASTVisitor visitor) const
1641     {
1642         mixin (visitIfNotNull!(initialization, test, increment,
1643             declarationOrStatement));
1644     }
1645     /** */ DeclarationOrStatement initialization;
1646     /** */ Expression test;
1647     /** */ Expression increment;
1648     /** */ DeclarationOrStatement declarationOrStatement;
1649     /** */ size_t startIndex;
1650     mixin OpEquals;
1651 }
1652 
1653 
1654 ///
1655 final class Foreach(bool declOnly) : ASTNode
1656 {
1657 public:
1658     override void accept(ASTVisitor visitor) const
1659     {
1660         mixin (visitIfNotNull!(foreachType, foreachTypeList, low, high));
1661         static if (declOnly)
1662             mixin (visitIfNotNull!(declarations));
1663         else
1664             mixin (visitIfNotNull!(declarationOrStatement));
1665     }
1666     /** */ IdType type;
1667     /** */ ForeachTypeList foreachTypeList;
1668     /** */ ForeachType foreachType;
1669     /** */ Expression low;
1670     /** */ Expression high;
1671     /** */ size_t startIndex;
1672     static if (declOnly)
1673         /** */ Declaration[] declarations;
1674     else
1675         /** */ DeclarationOrStatement declarationOrStatement;
1676     mixin OpEquals;
1677 }
1678 
1679 ///
1680 alias StaticForeachDeclaration = Foreach!true;
1681 
1682 ///
1683 alias ForeachStatement = Foreach!false;
1684 
1685 ///
1686 final class StaticForeachStatement : ASTNode
1687 {
1688 public:
1689     override void accept(ASTVisitor visitor) const
1690     {
1691         mixin (visitIfNotNull!(foreachStatement));
1692     }
1693     /** */ ForeachStatement foreachStatement;
1694     mixin OpEquals;
1695 }
1696 
1697 ///
1698 final class ForeachType : ASTNode
1699 {
1700 public:
1701     override void accept(ASTVisitor visitor) const
1702     {
1703         mixin (visitIfNotNull!(type, identifier));
1704     }
1705     /** */ bool isAlias;
1706     /** */ bool isEnum;
1707     /** */ bool isRef;
1708     /** */ IdType[] typeConstructors;
1709     /** */ Type type;
1710     /** */ Token identifier;
1711     mixin OpEquals;
1712 }
1713 
1714 ///
1715 final class ForeachTypeList : ASTNode
1716 {
1717 public:
1718     override void accept(ASTVisitor visitor) const
1719     {
1720         mixin (visitIfNotNull!(items));
1721     }
1722     /** */ ForeachType[] items;
1723     mixin OpEquals;
1724 }
1725 
1726 ///
1727 final class FunctionAttribute : ASTNode
1728 {
1729 public:
1730     override void accept(ASTVisitor visitor) const
1731     {
1732         mixin (visitIfNotNull!(token, atAttribute));
1733     }
1734     /** */ Token token;
1735     /** */ AtAttribute atAttribute;
1736     mixin OpEquals;
1737 }
1738 
1739 ///
1740 final class FunctionBody : ASTNode
1741 {
1742 public:
1743     override void accept(ASTVisitor visitor) const
1744     {
1745         mixin (visitIfNotNull!(inStatement, outStatement, bodyStatement,
1746             blockStatement));
1747     }
1748 
1749     /** */ BlockStatement blockStatement;
1750     /** */ BodyStatement bodyStatement;
1751     /** */ OutStatement outStatement;
1752     /** */ InStatement inStatement;
1753     mixin OpEquals;
1754 }
1755 
1756 ///
1757 final class FunctionCallExpression : ExpressionNode
1758 {
1759 public:
1760     override void accept(ASTVisitor visitor) const
1761     {
1762         mixin (visitIfNotNull!(type, unaryExpression, templateArguments, arguments));
1763     }
1764     /** */ Type type;
1765     /** */ UnaryExpression unaryExpression;
1766     /** */ TemplateArguments templateArguments;
1767     /** */ Arguments arguments;
1768     mixin OpEquals;
1769 }
1770 
1771 ///
1772 final class FunctionDeclaration : ASTNode
1773 {
1774 public:
1775     override void accept(ASTVisitor visitor) const
1776     {
1777         mixin (visitIfNotNull!(attributes, storageClasses, returnType, parameters,
1778             templateParameters, constraint, memberFunctionAttributes,
1779             functionBody));
1780     }
1781     /** */ bool hasAuto;
1782     /** */ bool hasRef;
1783     /** */ Type returnType;
1784     /** */ Token name;
1785     /** */ TemplateParameters templateParameters;
1786     /** */ Parameters parameters;
1787     /** */ Constraint constraint;
1788     /** */ FunctionBody functionBody;
1789     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1790     /** */ string comment;
1791     /** */ Attribute[] attributes;
1792     /** */ StorageClass[] storageClasses;
1793     mixin OpEquals;
1794 }
1795 
1796 ///
1797 final class FunctionLiteralExpression : ExpressionNode
1798 {
1799 public:
1800     override void accept(ASTVisitor visitor) const
1801     {
1802         mixin (visitIfNotNull!(returnType, parameters, functionAttributes,
1803                 memberFunctionAttributes, functionBody, assignExpression));
1804     }
1805     /** */ ExpressionNode assignExpression;
1806     /** */ FunctionAttribute[] functionAttributes;
1807     /** */ FunctionBody functionBody;
1808     /** */ IdType functionOrDelegate;
1809     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1810     /** */ Parameters parameters;
1811     /** */ Token identifier;
1812     /** */ Type returnType;
1813     /** */ size_t line;
1814     /** */ size_t column;
1815     mixin OpEquals;
1816 }
1817 
1818 ///
1819 final class GotoStatement : ASTNode
1820 {
1821 public:
1822     override void accept(ASTVisitor visitor) const
1823     {
1824         mixin (visitIfNotNull!(label, expression));
1825     }
1826     /** */ Expression expression;
1827     /** */ Token label;
1828     mixin OpEquals;
1829 }
1830 
1831 ///
1832 final class IdentifierChain : ASTNode
1833 {
1834 public:
1835     override void accept(ASTVisitor visitor) const
1836     {
1837         mixin (visitIfNotNull!(identifiers));
1838     }
1839     /** */ Token[] identifiers;
1840     mixin OpEquals;
1841 }
1842 
1843 ///
1844 final class TypeIdentifierPart : ASTNode
1845 {
1846 public:
1847     override void accept(ASTVisitor visitor) const
1848     {
1849         mixin (visitIfNotNull!(identifierOrTemplateInstance, typeIdentifierPart,
1850             indexer));
1851     }
1852     /** */ bool dot;
1853     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
1854     /** */ TypeIdentifierPart typeIdentifierPart ;
1855     /** */ ExpressionNode indexer;
1856     mixin OpEquals;
1857 }
1858 
1859 ///
1860 final class IdentifierOrTemplateChain : ASTNode
1861 {
1862 public:
1863     override void accept(ASTVisitor visitor) const
1864     {
1865         mixin (visitIfNotNull!(identifiersOrTemplateInstances));
1866     }
1867 
1868     /** */ IdentifierOrTemplateInstance[] identifiersOrTemplateInstances;
1869     mixin OpEquals;
1870 }
1871 
1872 ///
1873 final class IdentifierOrTemplateInstance : ASTNode
1874 {
1875 public:
1876     override void accept(ASTVisitor visitor) const
1877     {
1878         mixin (visitIfNotNull!(identifier, templateInstance));
1879     }
1880 
1881     /** */ Token identifier;
1882     /** */ TemplateInstance templateInstance;
1883     mixin OpEquals;
1884 }
1885 
1886 ///
1887 final class IdentityExpression : ExpressionNode
1888 {
1889 public:
1890     override void accept(ASTVisitor visitor) const
1891     {
1892         mixin (visitIfNotNull!(left, right));
1893     }
1894     /** */ bool negated;
1895     mixin BinaryExpressionBody;
1896     mixin OpEquals;
1897 }
1898 
1899 ///
1900 final class IfStatement : ASTNode
1901 {
1902 public:
1903     override void accept(ASTVisitor visitor) const
1904     {
1905         mixin (visitIfNotNull!(identifier, type, expression, thenStatement,
1906             elseStatement));
1907     }
1908     /** */ Token identifier;
1909     /** */ Type type;
1910     /** */ Expression expression;
1911     /** */ DeclarationOrStatement thenStatement;
1912     /** */ DeclarationOrStatement elseStatement;
1913     /** */ size_t startIndex;
1914     /** */ size_t line;
1915     /** */ size_t column;
1916     mixin OpEquals;
1917 }
1918 
1919 ///
1920 final class ImportBind : ASTNode
1921 {
1922 public:
1923     override void accept(ASTVisitor visitor) const
1924     {
1925         mixin (visitIfNotNull!(left, right));
1926     }
1927     /** */ Token left;
1928     /** */ Token right;
1929     mixin OpEquals;
1930 }
1931 
1932 ///
1933 final class ImportBindings : ASTNode
1934 {
1935 public:
1936     override void accept(ASTVisitor visitor) const
1937     {
1938         mixin (visitIfNotNull!(singleImport, importBinds));
1939     }
1940     /** */ SingleImport singleImport;
1941     /** */ ImportBind[] importBinds;
1942     mixin OpEquals;
1943 }
1944 
1945 ///
1946 final class ImportDeclaration : ASTNode
1947 {
1948 public:
1949     override void accept(ASTVisitor visitor) const
1950     {
1951         mixin (visitIfNotNull!(singleImports, importBindings));
1952     }
1953     /** */ SingleImport[] singleImports;
1954     /** */ ImportBindings importBindings;
1955     /** */ size_t startIndex;
1956     /** */ size_t endIndex;
1957     mixin OpEquals;
1958 }
1959 
1960 ///
1961 final class ImportExpression : ExpressionNode
1962 {
1963 public:
1964     override void accept(ASTVisitor visitor) const
1965     {
1966         mixin (visitIfNotNull!(assignExpression));
1967     }
1968     /** */ ExpressionNode assignExpression;
1969     mixin OpEquals;
1970 }
1971 
1972 ///
1973 final class Index : ASTNode
1974 {
1975 public:
1976     override void accept(ASTVisitor visitor) const
1977     {
1978         mixin (visitIfNotNull!(low, high));
1979     }
1980     /** */ ExpressionNode low;
1981     /** */ ExpressionNode high;
1982     mixin OpEquals;
1983 }
1984 
1985 ///
1986 final class IndexExpression : ExpressionNode
1987 {
1988 public:
1989     override void accept(ASTVisitor visitor) const
1990     {
1991         mixin (visitIfNotNull!(unaryExpression, indexes));
1992     }
1993     /** */ UnaryExpression unaryExpression;
1994     /** */ Index[] indexes;
1995     mixin OpEquals;
1996 }
1997 
1998 ///
1999 final class InExpression : ExpressionNode
2000 {
2001 public:
2002     override void accept(ASTVisitor visitor) const
2003     {
2004         mixin (visitIfNotNull!(left, right));
2005     }
2006     mixin BinaryExpressionBody;
2007     bool negated;
2008     mixin OpEquals;
2009 }
2010 
2011 ///
2012 final class InStatement : ASTNode
2013 {
2014 public:
2015     override void accept(ASTVisitor visitor) const
2016     {
2017         mixin (visitIfNotNull!(blockStatement));
2018     }
2019     /** */ size_t inTokenLocation;
2020     /** */ BlockStatement blockStatement;
2021     mixin OpEquals;
2022 }
2023 
2024 ///
2025 final class Initialize : ASTNode
2026 {
2027 public:
2028     override void accept(ASTVisitor visitor) const
2029     {
2030         mixin (visitIfNotNull!(statementNoCaseNoDefault));
2031     }
2032     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2033     mixin OpEquals;
2034 }
2035 
2036 ///
2037 final class Initializer : ASTNode
2038 {
2039 public:
2040     override void accept(ASTVisitor visitor) const
2041     {
2042         mixin (visitIfNotNull!(nonVoidInitializer));
2043     }
2044     /** */ NonVoidInitializer nonVoidInitializer;
2045     mixin OpEquals;
2046 }
2047 
2048 ///
2049 final class InterfaceDeclaration : ASTNode
2050 {
2051 public:
2052     override void accept(ASTVisitor visitor) const
2053     {
2054         mixin (visitIfNotNull!(templateParameters, constraint, baseClassList,
2055             structBody));
2056     }
2057     /** */ Token name;
2058     /** */ TemplateParameters templateParameters;
2059     /** */ Constraint constraint;
2060     /** */ BaseClassList baseClassList;
2061     /** */ StructBody structBody;
2062     /** */ string comment;
2063     mixin OpEquals;
2064 }
2065 
2066 ///
2067 final class Invariant : ASTNode
2068 {
2069 public:
2070     override void accept(ASTVisitor visitor) const
2071     {
2072         mixin (visitIfNotNull!(blockStatement));
2073     }
2074     /** */ BlockStatement blockStatement;
2075     /** */ string comment;
2076     size_t line;
2077     size_t index;
2078     mixin OpEquals;
2079 }
2080 
2081 ///
2082 final class IsExpression : ExpressionNode
2083 {
2084 public:
2085     override void accept(ASTVisitor visitor) const
2086     {
2087         mixin (visitIfNotNull!(type, identifier, typeSpecialization,
2088             templateParameterList));
2089     }
2090     /** */ Type type;
2091     /** */ Token identifier;
2092     /** */ TypeSpecialization typeSpecialization;
2093     /** */ TemplateParameterList templateParameterList;
2094     /** */ IdType equalsOrColon;
2095     mixin OpEquals;
2096 }
2097 
2098 ///
2099 final class KeyValuePair : ASTNode
2100 {
2101 public:
2102     override void accept(ASTVisitor visitor) const
2103     {
2104         mixin (visitIfNotNull!(key, value));
2105     }
2106     /** */ ExpressionNode key;
2107     /** */ ExpressionNode value;
2108     mixin OpEquals;
2109 }
2110 
2111 ///
2112 final class KeyValuePairs : ASTNode
2113 {
2114 public:
2115     override void accept(ASTVisitor visitor) const
2116     {
2117         mixin (visitIfNotNull!(keyValuePairs));
2118     }
2119     /** */ KeyValuePair[] keyValuePairs;
2120     mixin OpEquals;
2121 }
2122 
2123 ///
2124 final class LabeledStatement : ASTNode
2125 {
2126 public:
2127     override void accept(ASTVisitor visitor) const
2128     {
2129         mixin (visitIfNotNull!(identifier, declarationOrStatement));
2130     }
2131     /** */ Token identifier;
2132     /** */ DeclarationOrStatement declarationOrStatement;
2133     mixin OpEquals;
2134 }
2135 
2136 ///
2137 final class LastCatch : ASTNode
2138 {
2139 public:
2140     override void accept(ASTVisitor visitor) const
2141     {
2142         mixin (visitIfNotNull!(statementNoCaseNoDefault));
2143     }
2144     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2145     size_t line;
2146     size_t column;
2147     mixin OpEquals;
2148 }
2149 
2150 ///
2151 final class LinkageAttribute : ASTNode
2152 {
2153 public:
2154     override void accept(ASTVisitor visitor) const
2155     {
2156         mixin (visitIfNotNull!(identifier, typeIdentifierPart));
2157     }
2158     /** */ Token identifier;
2159     /** */ bool hasPlusPlus;
2160     /** */ TypeIdentifierPart typeIdentifierPart;
2161     /** */ IdType classOrStruct;
2162     mixin OpEquals;
2163 }
2164 
2165 ///
2166 final class MemberFunctionAttribute : ASTNode
2167 {
2168 public:
2169     override void accept(ASTVisitor visitor) const
2170     {
2171         mixin (visitIfNotNull!(atAttribute));
2172     }
2173     /** */ IdType tokenType;
2174     /** */ AtAttribute atAttribute;
2175     mixin OpEquals;
2176 }
2177 
2178 ///
2179 final class MixinDeclaration : ASTNode
2180 {
2181 public:
2182     override void accept(ASTVisitor visitor) const
2183     {
2184         mixin (visitIfNotNull!(mixinExpression, templateMixinExpression));
2185     }
2186     /** */ MixinExpression mixinExpression;
2187     /** */ TemplateMixinExpression templateMixinExpression;
2188     mixin OpEquals;
2189 }
2190 
2191 ///
2192 final class MixinExpression : ExpressionNode
2193 {
2194 public:
2195     override void accept(ASTVisitor visitor) const
2196     {
2197         mixin (visitIfNotNull!(assignExpression));
2198     }
2199     /** */ ExpressionNode assignExpression;
2200     mixin OpEquals;
2201 }
2202 
2203 ///
2204 final class MixinTemplateDeclaration : ASTNode
2205 {
2206 public:
2207     override void accept(ASTVisitor visitor) const
2208     {
2209         mixin (visitIfNotNull!(templateDeclaration));
2210     }
2211     /** */ TemplateDeclaration templateDeclaration;
2212     mixin OpEquals;
2213 }
2214 
2215 ///
2216 final class MixinTemplateName : ASTNode
2217 {
2218 public:
2219     override void accept(ASTVisitor visitor) const
2220     {
2221         mixin (visitIfNotNull!(symbol, typeofExpression, identifierOrTemplateChain));
2222     }
2223     /** */ Symbol symbol;
2224     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
2225     /** */ TypeofExpression typeofExpression;
2226     mixin OpEquals;
2227 }
2228 
2229 ///
2230 final class Module : ASTNode
2231 {
2232 public:
2233     override void accept(ASTVisitor visitor) const
2234     {
2235         mixin (visitIfNotNull!(scriptLine, moduleDeclaration, declarations));
2236     }
2237     /** */ Token scriptLine;
2238     /** */ ModuleDeclaration moduleDeclaration;
2239     /** */ Declaration[] declarations;
2240     mixin OpEquals;
2241 }
2242 
2243 ///
2244 final class ModuleDeclaration : ASTNode
2245 {
2246 public:
2247     override void accept(ASTVisitor visitor) const
2248     {
2249         mixin (visitIfNotNull!(moduleName, deprecated_));
2250     }
2251     /** */ Deprecated deprecated_;
2252     /** */ IdentifierChain moduleName;
2253     /** */ size_t startLocation;
2254     /** */ size_t endLocation;
2255     /** */ string comment;
2256     mixin OpEquals;
2257 }
2258 
2259 
2260 ///
2261 final class MulExpression : ExpressionNode
2262 {
2263 public:
2264     override void accept(ASTVisitor visitor) const
2265     {
2266         mixin (visitIfNotNull!(left, right));
2267     }
2268     /** */ IdType operator;
2269     mixin BinaryExpressionBody;
2270     mixin OpEquals;
2271 }
2272 
2273 ///
2274 final class NewAnonClassExpression : ExpressionNode
2275 {
2276 public:
2277     override void accept(ASTVisitor visitor) const
2278     {
2279         mixin (visitIfNotNull!(allocatorArguments, constructorArguments,
2280             baseClassList, structBody));
2281     }
2282     /** */ Arguments allocatorArguments;
2283     /** */ Arguments constructorArguments;
2284     /** */ BaseClassList baseClassList;
2285     /** */ StructBody structBody;
2286     mixin OpEquals;
2287 }
2288 
2289 ///
2290 final class NewExpression : ExpressionNode
2291 {
2292 public:
2293     override void accept(ASTVisitor visitor) const
2294     {
2295         mixin (visitIfNotNull!(newAnonClassExpression, type, arguments,
2296             assignExpression));
2297     }
2298     /** */ Type type;
2299     /** */ NewAnonClassExpression newAnonClassExpression;
2300     /** */ Arguments arguments;
2301     /** */ ExpressionNode assignExpression;
2302     mixin OpEquals;
2303 }
2304 
2305 
2306 ///
2307 final class StatementNoCaseNoDefault : ASTNode
2308 {
2309 public:
2310     override void accept(ASTVisitor visitor) const
2311     {
2312         mixin (visitIfNotNull!(labeledStatement, blockStatement, ifStatement,
2313             whileStatement, doStatement, forStatement, foreachStatement,
2314             switchStatement, finalSwitchStatement, continueStatement,
2315             breakStatement, returnStatement, gotoStatement, withStatement,
2316             synchronizedStatement, tryStatement, throwStatement,
2317             scopeGuardStatement, asmStatement, pragmaStatement,
2318             conditionalStatement, staticAssertStatement, versionSpecification,
2319             debugSpecification, expressionStatement, staticForeachStatement));
2320     }
2321     /** */ LabeledStatement labeledStatement;
2322     /** */ BlockStatement blockStatement;
2323     /** */ IfStatement ifStatement;
2324     /** */ WhileStatement whileStatement;
2325     /** */ DoStatement doStatement;
2326     /** */ ForStatement forStatement;
2327     /** */ ForeachStatement foreachStatement;
2328     /** */ StaticForeachStatement staticForeachStatement;
2329     /** */ SwitchStatement switchStatement;
2330     /** */ FinalSwitchStatement finalSwitchStatement;
2331     /** */ ContinueStatement continueStatement;
2332     /** */ BreakStatement breakStatement;
2333     /** */ ReturnStatement returnStatement;
2334     /** */ GotoStatement gotoStatement;
2335     /** */ WithStatement withStatement;
2336     /** */ SynchronizedStatement synchronizedStatement;
2337     /** */ TryStatement tryStatement;
2338     /** */ ThrowStatement throwStatement;
2339     /** */ ScopeGuardStatement scopeGuardStatement;
2340     /** */ AsmStatement asmStatement;
2341     /** */ PragmaStatement pragmaStatement;
2342     /** */ ConditionalStatement conditionalStatement;
2343     /** */ StaticAssertStatement staticAssertStatement;
2344     /** */ VersionSpecification versionSpecification;
2345     /** */ DebugSpecification debugSpecification;
2346     /** */ ExpressionStatement expressionStatement;
2347     /** */ size_t startLocation;
2348     /** */ size_t endLocation;
2349     mixin OpEquals;
2350 }
2351 
2352 ///
2353 final class NonVoidInitializer : ASTNode
2354 {
2355 public:
2356     override void accept(ASTVisitor visitor) const
2357     {
2358         mixin (visitIfNotNull!(assignExpression, arrayInitializer,
2359             structInitializer));
2360     }
2361     /** */ ExpressionNode assignExpression;
2362     /** */ ArrayInitializer arrayInitializer;
2363     /** */ StructInitializer structInitializer;
2364 
2365     mixin OpEquals;
2366 }
2367 
2368 ///
2369 final class Operands : ASTNode
2370 {
2371 public:
2372     override void accept(ASTVisitor visitor) const
2373     {
2374         mixin (visitIfNotNull!(operands));
2375     }
2376     /** */ ExpressionNode[] operands;
2377     mixin OpEquals;
2378 }
2379 
2380 ///
2381 final class OrExpression : ExpressionNode
2382 {
2383 public:
2384     override void accept(ASTVisitor visitor) const
2385     {
2386         mixin (visitIfNotNull!(left, right));
2387     }
2388     mixin BinaryExpressionBody;
2389     mixin OpEquals;
2390 }
2391 
2392 ///
2393 final class OrOrExpression : ExpressionNode
2394 {
2395 public:
2396     override void accept(ASTVisitor visitor) const
2397     {
2398         mixin (visitIfNotNull!(left, right));
2399     }
2400     mixin BinaryExpressionBody;
2401     mixin OpEquals;
2402 }
2403 
2404 ///
2405 final class OutStatement : ASTNode
2406 {
2407 public:
2408     override void accept(ASTVisitor visitor) const
2409     {
2410         mixin (visitIfNotNull!(parameter, blockStatement));
2411     }
2412     /** */ size_t outTokenLocation;
2413     /** */ Token parameter;
2414     /** */ BlockStatement blockStatement;
2415     mixin OpEquals;
2416 }
2417 
2418 ///
2419 final class Parameter : ASTNode
2420 {
2421 public:
2422     override void accept(ASTVisitor visitor) const
2423     {
2424         mixin (visitIfNotNull!(type, name, default_));
2425     }
2426 
2427     /** */ IdType[] parameterAttributes;
2428     /** */ Type type;
2429     /** */ Token name;
2430     /** */ bool vararg;
2431     /** */ ExpressionNode default_;
2432     /** */ TypeSuffix[] cstyle;
2433 
2434     mixin OpEquals;
2435 }
2436 
2437 ///
2438 final class Parameters : ASTNode
2439 {
2440 public:
2441     override void accept(ASTVisitor visitor) const
2442     {
2443         mixin (visitIfNotNull!(parameters));
2444     }
2445 
2446     /** */ Parameter[] parameters;
2447     /** */ bool hasVarargs;
2448     mixin OpEquals;
2449 }
2450 
2451 ///
2452 final class Postblit : ASTNode
2453 {
2454 public:
2455     override void accept(ASTVisitor visitor) const
2456     {
2457         mixin (visitIfNotNull!(functionBody));
2458     }
2459     /** */ FunctionBody functionBody;
2460     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
2461     /** */ size_t location;
2462     /** */ size_t line;
2463     /** */ size_t column;
2464     mixin OpEquals;
2465 }
2466 
2467 ///
2468 final class PowExpression : ExpressionNode
2469 {
2470 public:
2471     override void accept(ASTVisitor visitor) const
2472     {
2473         mixin (visitIfNotNull!(left, right));
2474     }
2475     mixin BinaryExpressionBody;
2476     mixin OpEquals;
2477 }
2478 
2479 ///
2480 final class PragmaDeclaration : ASTNode
2481 {
2482 public:
2483     override void accept(ASTVisitor visitor) const
2484     {
2485         mixin (visitIfNotNull!(pragmaExpression));
2486     }
2487     /** */ PragmaExpression pragmaExpression;
2488     mixin OpEquals;
2489 }
2490 
2491 ///
2492 final class PragmaExpression : ExpressionNode
2493 {
2494 public:
2495     override void accept(ASTVisitor visitor) const
2496     {
2497         mixin (visitIfNotNull!(identifier, argumentList));
2498     }
2499     /** */ Token identifier;
2500     /** */ ArgumentList argumentList;
2501     mixin OpEquals;
2502 }
2503 
2504 ///
2505 final class PragmaStatement : ASTNode
2506 {
2507 public:
2508     override void accept(ASTVisitor visitor) const
2509     {
2510         mixin (visitIfNotNull!(pragmaExpression, statement, blockStatement));
2511     }
2512     /** */ PragmaExpression pragmaExpression;
2513     /** */ Statement statement;
2514     /** */ BlockStatement blockStatement;
2515     mixin OpEquals;
2516 }
2517 
2518 ///
2519 final class PrimaryExpression : ExpressionNode
2520 {
2521 public:
2522     override void accept(ASTVisitor visitor) const
2523     {
2524         mixin(visitIfNotNull!(basicType, typeConstructor, type, primary,
2525                 typeofExpression, typeidExpression, arrayLiteral, assocArrayLiteral,
2526                 expression, dot, identifierOrTemplateInstance, isExpression,
2527                 functionLiteralExpression,traitsExpression, mixinExpression,
2528                 importExpression, vector, arguments));
2529     }
2530     /** */ Token dot;
2531     /** */ Token primary;
2532     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
2533     /** */ Token basicType;
2534     /** */ TypeofExpression typeofExpression;
2535     /** */ TypeidExpression typeidExpression;
2536     /** */ ArrayLiteral arrayLiteral;
2537     /** */ AssocArrayLiteral assocArrayLiteral;
2538     /** */ Expression expression;
2539     /** */ IsExpression isExpression;
2540     /** */ FunctionLiteralExpression functionLiteralExpression;
2541     /** */ TraitsExpression traitsExpression;
2542     /** */ MixinExpression mixinExpression;
2543     /** */ ImportExpression importExpression;
2544     /** */ Vector vector;
2545     /** */ Type type;
2546     /** */ Token typeConstructor;
2547     /** */ Arguments arguments;
2548     mixin OpEquals;
2549 }
2550 
2551 ///
2552 final class Register : ASTNode
2553 {
2554 public:
2555     override void accept(ASTVisitor visitor) const
2556     {
2557         mixin (visitIfNotNull!(identifier, intLiteral));
2558     }
2559     /** */ Token identifier;
2560     /** */ Token intLiteral;
2561     /** */ bool hasIntegerLiteral;
2562     mixin OpEquals;
2563 }
2564 
2565 ///
2566 final class RelExpression : ExpressionNode
2567 {
2568 public:
2569     override void accept(ASTVisitor visitor) const
2570     {
2571         mixin (visitIfNotNull!(left, right));
2572     }
2573     /** */ IdType operator;
2574     mixin BinaryExpressionBody;
2575     mixin OpEquals;
2576 }
2577 
2578 ///
2579 final class ReturnStatement : ASTNode
2580 {
2581 public:
2582     override void accept(ASTVisitor visitor) const
2583     {
2584         mixin (visitIfNotNull!(expression));
2585     }
2586     /** */ Expression expression;
2587     /** */ size_t startLocation;
2588     /** */ size_t endLocation;
2589     mixin OpEquals;
2590 }
2591 
2592 ///
2593 final class ScopeGuardStatement : ASTNode
2594 {
2595 public:
2596     override void accept(ASTVisitor visitor) const
2597     {
2598         mixin (visitIfNotNull!(identifier, statementNoCaseNoDefault));
2599     }
2600     /** */ Token identifier;
2601     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2602     mixin OpEquals;
2603 }
2604 
2605 ///
2606 final class SharedStaticConstructor : ASTNode
2607 {
2608 public:
2609     override void accept(ASTVisitor visitor) const
2610     {
2611         mixin (visitIfNotNull!(memberFunctionAttributes, functionBody));
2612     }
2613     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
2614     /** */ FunctionBody functionBody;
2615     /** */ size_t location;
2616     /** */ size_t line;
2617     /** */ size_t column;
2618     /** */ string comment;
2619     mixin OpEquals;
2620 }
2621 
2622 ///
2623 final class SharedStaticDestructor : ASTNode
2624 {
2625 public:
2626     override void accept(ASTVisitor visitor) const
2627     {
2628         mixin (visitIfNotNull!(memberFunctionAttributes, functionBody));
2629     }
2630     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
2631     /** */ FunctionBody functionBody;
2632     /** */ size_t location;
2633     /** */ size_t line;
2634     /** */ size_t column;
2635     /** */ string comment;
2636     mixin OpEquals;
2637 }
2638 
2639 ///
2640 final class ShiftExpression : ExpressionNode
2641 {
2642 public:
2643     override void accept(ASTVisitor visitor) const
2644     {
2645         mixin (visitIfNotNull!(left, right));
2646     }
2647     /** */ IdType operator;
2648     mixin BinaryExpressionBody;
2649     mixin OpEquals;
2650 }
2651 
2652 ///
2653 final class SingleImport : ASTNode
2654 {
2655 public:
2656     override void accept(ASTVisitor visitor) const
2657     {
2658         mixin (visitIfNotNull!(rename, identifierChain));
2659     }
2660     /** */ Token rename;
2661     /** */ IdentifierChain identifierChain;
2662     mixin OpEquals;
2663 }
2664 
2665 ///
2666 final class Statement : ASTNode
2667 {
2668 public:
2669     override void accept(ASTVisitor visitor) const
2670     {
2671         mixin (visitIfNotNull!(statementNoCaseNoDefault, caseStatement,
2672             caseRangeStatement, defaultStatement));
2673     }
2674     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2675     /** */ CaseStatement caseStatement;
2676     /** */ CaseRangeStatement caseRangeStatement;
2677     /** */ DefaultStatement defaultStatement;
2678     mixin OpEquals;
2679 }
2680 
2681 ///
2682 final class StaticAssertDeclaration : ASTNode
2683 {
2684 public:
2685     override void accept(ASTVisitor visitor) const
2686     {
2687         mixin (visitIfNotNull!(staticAssertStatement));
2688     }
2689     /** */ StaticAssertStatement staticAssertStatement;
2690     mixin OpEquals;
2691 }
2692 
2693 ///
2694 final class StaticAssertStatement : ASTNode
2695 {
2696 public:
2697     override void accept(ASTVisitor visitor) const
2698     {
2699         mixin (visitIfNotNull!(assertExpression));
2700     }
2701     /** */ AssertExpression assertExpression;
2702     mixin OpEquals;
2703 }
2704 
2705 ///
2706 final class StaticConstructor : ASTNode
2707 {
2708 public:
2709     override void accept(ASTVisitor visitor) const
2710     {
2711         mixin (visitIfNotNull!(memberFunctionAttributes, functionBody));
2712     }
2713     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
2714     /** */ FunctionBody functionBody;
2715     /** */ size_t location;
2716     /** */ size_t line;
2717     /** */ size_t column;
2718     /** */ string comment;
2719     mixin OpEquals;
2720 }
2721 
2722 ///
2723 final class StaticDestructor : ASTNode
2724 {
2725 public:
2726     override void accept(ASTVisitor visitor) const
2727     {
2728         mixin (visitIfNotNull!(memberFunctionAttributes, functionBody));
2729     }
2730     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
2731     /** */ FunctionBody functionBody;
2732     /** */ size_t location;
2733     /** */ size_t line;
2734     /** */ size_t column;
2735     /** */ string comment;
2736     mixin OpEquals;
2737 }
2738 
2739 ///
2740 final class StaticIfCondition : ASTNode
2741 {
2742 public:
2743     override void accept(ASTVisitor visitor) const
2744     {
2745         mixin (visitIfNotNull!(assignExpression));
2746     }
2747     /** */ ExpressionNode assignExpression;
2748     mixin OpEquals;
2749 }
2750 
2751 ///
2752 final class StorageClass : ASTNode
2753 {
2754 public:
2755     override void accept(ASTVisitor visitor) const
2756     {
2757         mixin (visitIfNotNull!(token, alignAttribute, linkageAttribute,
2758             atAttribute, deprecated_));
2759     }
2760     /** */ AlignAttribute alignAttribute;
2761     /** */ LinkageAttribute linkageAttribute;
2762     /** */ AtAttribute atAttribute;
2763     /** */ Deprecated deprecated_;
2764     /** */ Token token;
2765     mixin OpEquals;
2766 }
2767 
2768 ///
2769 final class StructBody : ASTNode
2770 {
2771 public:
2772     override void accept(ASTVisitor visitor) const
2773     {
2774         mixin (visitIfNotNull!(declarations));
2775     }
2776 
2777     /**
2778      * Byte position of the opening brace
2779      */
2780     size_t startLocation;
2781 
2782     /**
2783      * Byte position of the closing brace
2784      */
2785     size_t endLocation;
2786     /** */ Declaration[] declarations;
2787     mixin OpEquals;
2788 }
2789 
2790 ///
2791 final class StructDeclaration : ASTNode
2792 {
2793 public:
2794     override void accept(ASTVisitor visitor) const
2795     {
2796         mixin (visitIfNotNull!(templateParameters, constraint, structBody));
2797     }
2798     /** */ Token name;
2799     /** */ TemplateParameters templateParameters;
2800     /** */ Constraint constraint;
2801     /** */ StructBody structBody;
2802     /** */ string comment;
2803     mixin OpEquals;
2804 }
2805 
2806 ///
2807 final class StructInitializer : ASTNode
2808 {
2809 public:
2810     override void accept(ASTVisitor visitor) const
2811     {
2812         mixin (visitIfNotNull!(structMemberInitializers));
2813     }
2814     /** */ StructMemberInitializers structMemberInitializers;
2815     /** */ size_t startLocation;
2816     /** */ size_t endLocation;
2817     mixin OpEquals;
2818 }
2819 
2820 ///
2821 final class StructMemberInitializer : ASTNode
2822 {
2823 public:
2824     override void accept(ASTVisitor visitor) const
2825     {
2826         mixin (visitIfNotNull!(identifier, nonVoidInitializer));
2827     }
2828     /** */ Token identifier;
2829     /** */ NonVoidInitializer nonVoidInitializer;
2830     mixin OpEquals;
2831 }
2832 
2833 ///
2834 final class StructMemberInitializers : ASTNode
2835 {
2836 public:
2837     override void accept(ASTVisitor visitor) const
2838     {
2839         mixin (visitIfNotNull!(structMemberInitializers));
2840     }
2841     /** */ StructMemberInitializer[] structMemberInitializers;
2842     mixin OpEquals;
2843 }
2844 
2845 ///
2846 final class SwitchStatement : ASTNode
2847 {
2848 public:
2849     override void accept(ASTVisitor visitor) const
2850     {
2851         mixin (visitIfNotNull!(expression, statement));
2852     }
2853     /** */ Expression expression;
2854     /** */ Statement statement;
2855     mixin OpEquals;
2856 }
2857 
2858 ///
2859 final class Symbol : ASTNode
2860 {
2861 public:
2862     override void accept(ASTVisitor visitor) const
2863     {
2864         mixin (visitIfNotNull!(identifierOrTemplateChain));
2865     }
2866 
2867     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
2868     /** */ bool dot;
2869     mixin OpEquals;
2870 }
2871 
2872 ///
2873 final class SynchronizedStatement : ASTNode
2874 {
2875 public:
2876     override void accept(ASTVisitor visitor) const
2877     {
2878         mixin (visitIfNotNull!(expression, statementNoCaseNoDefault));
2879     }
2880     /** */ Expression expression;
2881     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2882     mixin OpEquals;
2883 }
2884 
2885 ///
2886 final class TemplateAliasParameter : ASTNode
2887 {
2888 public:
2889     override void accept(ASTVisitor visitor) const
2890     {
2891         mixin (visitIfNotNull!(type, identifier, colonType, colonExpression,
2892             assignType, assignExpression));
2893     }
2894     /** */ Type type;
2895     /** */ Token identifier;
2896     /** */ Type colonType;
2897     /** */ ExpressionNode colonExpression;
2898     /** */ Type assignType;
2899     /** */ ExpressionNode assignExpression;
2900     mixin OpEquals;
2901 }
2902 
2903 ///
2904 final class TemplateArgument : ASTNode
2905 {
2906 public:
2907     override void accept(ASTVisitor visitor) const
2908     {
2909         mixin (visitIfNotNull!(type, assignExpression));
2910     }
2911     /** */ Type type;
2912     /** */ ExpressionNode assignExpression;
2913     mixin OpEquals;
2914 }
2915 
2916 ///
2917 final class TemplateArgumentList : ASTNode
2918 {
2919 public:
2920     override void accept(ASTVisitor visitor) const
2921     {
2922         mixin (visitIfNotNull!(items));
2923     }
2924     /** */ TemplateArgument[] items;
2925     mixin OpEquals;
2926 }
2927 
2928 ///
2929 final class TemplateArguments : ASTNode
2930 {
2931 public:
2932     override void accept(ASTVisitor visitor) const
2933     {
2934         mixin (visitIfNotNull!(templateArgumentList, templateSingleArgument));
2935     }
2936     /** */ TemplateArgumentList templateArgumentList;
2937     /** */ TemplateSingleArgument templateSingleArgument;
2938     mixin OpEquals;
2939 }
2940 
2941 ///
2942 final class TemplateDeclaration : ASTNode
2943 {
2944 public:
2945     override void accept(ASTVisitor visitor) const
2946     {
2947         mixin (visitIfNotNull!(name, templateParameters, constraint,
2948             declarations));
2949     }
2950     /** */ Token name;
2951     /** */ TemplateParameters templateParameters;
2952     /** */ Constraint constraint;
2953     /** */ Declaration[] declarations;
2954     /** */ string comment;
2955     /**
2956      * Byte position of the opening brace
2957      */
2958     size_t startLocation;
2959 
2960     /**
2961      * Byte position of the closing brace
2962      */
2963     size_t endLocation;
2964     mixin OpEquals;
2965 }
2966 
2967 ///
2968 final class TemplateInstance : ASTNode
2969 {
2970 public:
2971     override void accept(ASTVisitor visitor) const
2972     {
2973         mixin (visitIfNotNull!(identifier, templateArguments));
2974     }
2975     /** */ Token identifier;
2976     /** */ TemplateArguments templateArguments;
2977     mixin OpEquals;
2978 }
2979 
2980 ///
2981 final class TemplateMixinExpression : ExpressionNode
2982 {
2983 public:
2984     override void accept(ASTVisitor visitor) const
2985     {
2986         mixin (visitIfNotNull!(identifier, templateArguments, mixinTemplateName));
2987     }
2988     /** */ Token identifier;
2989     /** */ TemplateArguments templateArguments;
2990     /** */ MixinTemplateName mixinTemplateName;
2991     mixin OpEquals;
2992 }
2993 
2994 ///
2995 final class TemplateParameter : ASTNode
2996 {
2997 public:
2998     override void accept(ASTVisitor visitor) const
2999     {
3000         mixin (visitIfNotNull!(templateTypeParameter, templateValueParameter,
3001             templateAliasParameter, templateTupleParameter,
3002             templateThisParameter));
3003     }
3004     /** */ TemplateTypeParameter templateTypeParameter;
3005     /** */ TemplateValueParameter templateValueParameter;
3006     /** */ TemplateAliasParameter templateAliasParameter;
3007     /** */ TemplateTupleParameter templateTupleParameter;
3008     /** */ TemplateThisParameter templateThisParameter;
3009     mixin OpEquals;
3010 }
3011 
3012 ///
3013 final class TemplateParameterList : ASTNode
3014 {
3015 public:
3016     override void accept(ASTVisitor visitor) const
3017     {
3018         mixin (visitIfNotNull!(items));
3019     }
3020     /** */ TemplateParameter[] items;
3021     mixin OpEquals;
3022 }
3023 
3024 ///
3025 final class TemplateParameters : ASTNode
3026 {
3027 public:
3028     override void accept(ASTVisitor visitor) const
3029     {
3030         mixin (visitIfNotNull!(templateParameterList));
3031     }
3032     /** */ TemplateParameterList templateParameterList;
3033     mixin OpEquals;
3034 }
3035 
3036 ///
3037 final class TemplateSingleArgument : ASTNode
3038 {
3039 public:
3040     override void accept(ASTVisitor visitor) const
3041     {
3042         mixin (visitIfNotNull!(token));
3043     }
3044     /** */ Token token;
3045     mixin OpEquals;
3046 }
3047 
3048 ///
3049 final class TemplateThisParameter : ASTNode
3050 {
3051 public:
3052     override void accept(ASTVisitor visitor) const
3053     {
3054         mixin (visitIfNotNull!(templateTypeParameter));
3055     }
3056     /** */ TemplateTypeParameter templateTypeParameter;
3057     mixin OpEquals;
3058 }
3059 
3060 ///
3061 final class TemplateTupleParameter : ASTNode
3062 {
3063 public:
3064     override void accept(ASTVisitor visitor) const
3065     {
3066         mixin (visitIfNotNull!(identifier));
3067     }
3068     /** */ Token identifier;
3069     mixin OpEquals;
3070 }
3071 
3072 ///
3073 final class TemplateTypeParameter : ASTNode
3074 {
3075 public:
3076     override void accept(ASTVisitor visitor) const
3077     {
3078         mixin (visitIfNotNull!(identifier, colonType, assignType));
3079     }
3080     /** */ Token identifier;
3081     /** */ Type colonType;
3082     /** */ Type assignType;
3083     mixin OpEquals;
3084 }
3085 
3086 ///
3087 final class TemplateValueParameter : ASTNode
3088 {
3089 public:
3090     override void accept(ASTVisitor visitor) const
3091     {
3092         mixin (visitIfNotNull!(type, identifier, assignExpression,
3093             templateValueParameterDefault));
3094     }
3095     /** */ Type type;
3096     /** */ Token identifier;
3097     /** */ ExpressionNode assignExpression;
3098     /** */ TemplateValueParameterDefault templateValueParameterDefault;
3099     mixin OpEquals;
3100 }
3101 
3102 ///
3103 final class TemplateValueParameterDefault : ASTNode
3104 {
3105 public:
3106     override void accept(ASTVisitor visitor) const
3107     {
3108         mixin (visitIfNotNull!(token, assignExpression));
3109     }
3110     /** */ ExpressionNode assignExpression;
3111     /** */ Token token;
3112     mixin OpEquals;
3113 }
3114 
3115 ///
3116 final class TernaryExpression : ExpressionNode
3117 {
3118 public:
3119     override void accept(ASTVisitor visitor) const
3120     {
3121         mixin (visitIfNotNull!(orOrExpression, expression, ternaryExpression));
3122     }
3123     /** */ ExpressionNode orOrExpression;
3124     /** */ ExpressionNode expression;
3125     /** */ ExpressionNode ternaryExpression;
3126     /// Store this so that we know where the ':' is
3127     Token colon;
3128     mixin OpEquals;
3129 }
3130 
3131 ///
3132 final class ThrowStatement : ASTNode
3133 {
3134 public:
3135     override void accept(ASTVisitor visitor) const
3136     {
3137         mixin (visitIfNotNull!(expression));
3138     }
3139     /** */ Expression expression;
3140     mixin OpEquals;
3141 }
3142 
3143 ///
3144 final class TraitsExpression : ExpressionNode
3145 {
3146 public:
3147     override void accept(ASTVisitor visitor) const
3148     {
3149         mixin (visitIfNotNull!(identifier, templateArgumentList));
3150     }
3151     /** */ Token identifier;
3152     /** */ TemplateArgumentList templateArgumentList;
3153     mixin OpEquals;
3154 }
3155 
3156 ///
3157 final class TryStatement : ASTNode
3158 {
3159 public:
3160     override void accept(ASTVisitor visitor) const
3161     {
3162         mixin (visitIfNotNull!(declarationOrStatement, catches, finally_));
3163     }
3164     /** */ DeclarationOrStatement declarationOrStatement;
3165     /** */ Catches catches;
3166     /** */ Finally finally_;
3167     mixin OpEquals;
3168 }
3169 
3170 ///
3171 final class Type : ASTNode
3172 {
3173 public:
3174     override void accept(ASTVisitor visitor) const
3175     {
3176         mixin (visitIfNotNull!(type2, typeSuffixes));
3177     }
3178 
3179     /** */ IdType[] typeConstructors;
3180     /** */ TypeSuffix[] typeSuffixes;
3181     /** */ Type2 type2;
3182     mixin OpEquals;
3183 }
3184 
3185 ///
3186 final class Type2 : ASTNode
3187 {
3188 public:
3189     override void accept(ASTVisitor visitor) const
3190     {
3191         mixin (visitIfNotNull!(typeofExpression, typeIdentifierPart, type, vector));
3192     }
3193 
3194     /** */ IdType builtinType;
3195     /** */ alias superOrThis = builtinType;
3196     /** */ TypeofExpression typeofExpression;
3197     /** */ TypeIdentifierPart typeIdentifierPart;
3198     /** */ IdType typeConstructor;
3199     /** */ Type type;
3200     /** */ Vector vector;
3201     mixin OpEquals;
3202 }
3203 
3204 ///
3205 final class TypeSpecialization : ASTNode
3206 {
3207 public:
3208     override void accept(ASTVisitor visitor) const
3209     {
3210         mixin (visitIfNotNull!(token, type));
3211     }
3212     /** */ Token token;
3213     /** */ Type type;
3214     mixin OpEquals;
3215 }
3216 
3217 ///
3218 final class TypeSuffix : ASTNode
3219 {
3220 public:
3221     override void accept(ASTVisitor visitor) const
3222     {
3223         mixin (visitIfNotNull!(type, low, high, delegateOrFunction, parameters,
3224             memberFunctionAttributes));
3225     }
3226 
3227     /** */ Token delegateOrFunction;
3228     /** */ Token star;
3229     /** */ bool array;
3230     /** */ Type type;
3231     /** */ ExpressionNode low;
3232     /** */ ExpressionNode high;
3233     /** */ Parameters parameters;
3234     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
3235     mixin OpEquals;
3236 }
3237 
3238 ///
3239 final class TypeidExpression : ExpressionNode
3240 {
3241 public:
3242     override void accept(ASTVisitor visitor) const
3243     {
3244         mixin (visitIfNotNull!(type, expression));
3245     }
3246     /** */ Type type;
3247     /** */ Expression expression;
3248     mixin OpEquals;
3249 }
3250 
3251 ///
3252 final class TypeofExpression : ExpressionNode
3253 {
3254 public:
3255     override void accept(ASTVisitor visitor) const
3256     {
3257         mixin (visitIfNotNull!(expression, return_));
3258     }
3259     /** */ Expression expression;
3260     /** */ Token return_;
3261     mixin OpEquals;
3262 }
3263 
3264 ///
3265 final class UnaryExpression : ExpressionNode
3266 {
3267 public:
3268     override void accept(ASTVisitor visitor) const
3269     {
3270         // TODO prefix, postfix, unary
3271         mixin (visitIfNotNull!(primaryExpression, newExpression, deleteExpression,
3272             castExpression, functionCallExpression, argumentList, unaryExpression,
3273             type, identifierOrTemplateInstance, assertExpression, indexExpression));
3274     }
3275 
3276     /** */ Type type;
3277     /** */ PrimaryExpression primaryExpression;
3278     /** */ Token prefix;
3279     /** */ Token suffix;
3280     /** */ UnaryExpression unaryExpression;
3281     /** */ NewExpression newExpression;
3282     /** */ DeleteExpression deleteExpression;
3283     /** */ CastExpression castExpression;
3284     /** */ FunctionCallExpression functionCallExpression;
3285     /** */ ArgumentList argumentList;
3286     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
3287     /** */ AssertExpression assertExpression;
3288     /** */ IndexExpression indexExpression;
3289     /** */ size_t dotLocation;
3290     mixin OpEquals;
3291 }
3292 
3293 ///
3294 final class UnionDeclaration : ASTNode
3295 {
3296 public:
3297     override void accept(ASTVisitor visitor) const
3298     {
3299         mixin (visitIfNotNull!(name, templateParameters, constraint, structBody));
3300     }
3301 
3302     /** */ Token name;
3303     /** */ TemplateParameters templateParameters;
3304     /** */ Constraint constraint;
3305     /** */ StructBody structBody;
3306     /** */ string comment;
3307     mixin OpEquals;
3308 }
3309 
3310 ///
3311 final class Unittest : ASTNode
3312 {
3313 public:
3314     override void accept(ASTVisitor visitor) const
3315     {
3316         mixin (visitIfNotNull!(blockStatement));
3317     }
3318     /** */ BlockStatement blockStatement;
3319     /** */ string comment;
3320     /** */ size_t location;
3321     /** */ size_t line;
3322     /** */ size_t column;
3323     mixin OpEquals;
3324 }
3325 
3326 ///
3327 final class VariableDeclaration : ASTNode
3328 {
3329 public:
3330     override void accept(ASTVisitor visitor) const
3331     {
3332         mixin (visitIfNotNull!(storageClasses, type, declarators, autoDeclaration));
3333     }
3334     /** */ Type type;
3335     /** */ Declarator[] declarators;
3336     /** */ StorageClass[] storageClasses;
3337     /** */ AutoDeclaration autoDeclaration;
3338     /** */ string comment;
3339     mixin OpEquals;
3340 }
3341 
3342 ///
3343 final class Vector : ASTNode
3344 {
3345 public:
3346     override void accept(ASTVisitor visitor) const
3347     {
3348         mixin (visitIfNotNull!(type));
3349     }
3350     /** */ Type type;
3351     mixin OpEquals;
3352 }
3353 
3354 ///
3355 final class VersionCondition : ASTNode
3356 {
3357 public:
3358     override void accept(ASTVisitor visitor) const
3359     {
3360         mixin (visitIfNotNull!(token));
3361     }
3362     /** */ size_t versionIndex;
3363     /** */ Token token;
3364     mixin OpEquals;
3365 }
3366 
3367 ///
3368 final class VersionSpecification : ASTNode
3369 {
3370 public:
3371     override void accept(ASTVisitor visitor) const
3372     {
3373         mixin (visitIfNotNull!(token));
3374     }
3375     /** */ Token token;
3376     mixin OpEquals;
3377 }
3378 
3379 ///
3380 final class WhileStatement : ASTNode
3381 {
3382 public:
3383     override void accept(ASTVisitor visitor) const
3384     {
3385         mixin (visitIfNotNull!(expression, declarationOrStatement));
3386     }
3387 
3388     /** */ Expression expression;
3389     /** */ DeclarationOrStatement declarationOrStatement;
3390     /** */ size_t startIndex;
3391     mixin OpEquals;
3392 }
3393 
3394 ///
3395 final class WithStatement : ASTNode
3396 {
3397 public:
3398     override void accept(ASTVisitor visitor) const
3399     {
3400         mixin (visitIfNotNull!(expression, declarationOrStatement));
3401     }
3402 
3403     /** */ Expression expression;
3404     /** */ DeclarationOrStatement declarationOrStatement;
3405     mixin OpEquals;
3406 }
3407 
3408 ///
3409 final class XorExpression : ExpressionNode
3410 {
3411 public:
3412     override void accept(ASTVisitor visitor) const
3413     {
3414         mixin (visitIfNotNull!(left, right));
3415     }
3416     mixin BinaryExpressionBody;
3417     mixin OpEquals;
3418 }
3419 
3420 unittest // issue #133
3421 {
3422     import dparse.lexer, dparse.parser, dparse.rollback_allocator;
3423     string src = q{module test133; void main(){}};
3424     final class TkTest : ASTVisitor
3425     {
3426         alias visit = ASTVisitor.visit;
3427         override void visit(const Token t){assert(t.text.length);}
3428     }
3429     RollbackAllocator ra;
3430     LexerConfig cf = LexerConfig("", StringBehavior.source);
3431     StringCache ca = StringCache(16);
3432     Module m = parseModule(getTokensForParser(src, cf, &ca), "", &ra);
3433     TkTest t = new TkTest;
3434     t.visit(m);
3435 }
3436 
3437 unittest // issue #165
3438 {
3439     import dparse.lexer, dparse.parser, dparse.rollback_allocator;
3440     string src = q{module test165; enum foo(T) = bar!T;};
3441     final class EpoTest : ASTVisitor
3442     {
3443         bool visited;
3444         alias visit = ASTVisitor.visit;
3445         override void visit(const EponymousTemplateDeclaration){visited = true;}
3446     }
3447     RollbackAllocator ra;
3448     LexerConfig cf = LexerConfig("", StringBehavior.source);
3449     StringCache ca = StringCache(16);
3450     Module m = parseModule(getTokensForParser(src, cf, &ca), "", &ra);
3451     EpoTest et = new EpoTest;
3452     et.visit(m);
3453     assert(et.visited);
3454 }
3455 
3456 unittest // issue #156
3457 {
3458     import dparse.lexer, dparse.parser, dparse.rollback_allocator;
3459 
3460     final class Test : ASTVisitor
3461     {
3462         bool arrIndex, arrValue, arrValueOnly, aaLiteral;
3463         alias visit = ASTVisitor.visit;
3464         override void visit(const ArrayInitializer ai)
3465         {
3466             if (ai.arrayMemberInitializations.length == 1)
3467             {
3468                 arrIndex = ai.arrayMemberInitializations[0].assignExpression !is null;
3469                 arrValue = ai.arrayMemberInitializations[0].nonVoidInitializer !is null;
3470                 arrValueOnly = arrValue && !arrIndex;
3471             }
3472         }
3473         override void visit(const AssocArrayLiteral aal)
3474         {
3475             aaLiteral = true;
3476         }
3477     }
3478 
3479     RollbackAllocator ra;
3480     LexerConfig cf = LexerConfig("", StringBehavior.source);
3481     StringCache ca = StringCache(16);
3482 
3483     {
3484         // no colon so array.
3485         string src1 = q{void main(){const arr = [[0]];}};
3486         Module m = parseModule(getTokensForParser(src1, cf, &ca), "", &ra);
3487         Test t = new Test;
3488         t.visit(m);
3489         assert(t.arrValueOnly);
3490     }
3491     {
3492         // simple primary before colon, assume array.
3493         string src2 = q{void main(){const arr = [0:0];}};
3494         Module m = parseModule(getTokensForParser(src2, cf, &ca), "", &ra);
3495         Test t = new Test;
3496         t.visit(m);
3497         assert(t.arrIndex);
3498         assert(t.arrValue);
3499         assert(!t.aaLiteral);
3500     }
3501     {
3502         // more complex exp before colon, assume AA.
3503         string src3 = q{void main(){const arr = [[0]:0];}};
3504         Module m = parseModule(getTokensForParser(src3, cf, &ca), "", &ra);
3505         Test t = new Test;
3506         t.visit(m);
3507         assert(!t.arrIndex);
3508         assert(!t.arrValue);
3509         assert(t.aaLiteral);
3510     }
3511 }
3512 
3513 unittest // issue #170
3514 {
3515     import dparse.lexer, dparse.parser, dparse.rollback_allocator;
3516 
3517     final class Test170_F : ASTVisitor
3518     {
3519         static string src = q{void function() a = {call();};};
3520         bool visited;
3521         alias visit = ASTVisitor.visit;
3522         override void visit(const FunctionLiteralExpression){visited = true;}
3523     }
3524 
3525     final class Test170_S : ASTVisitor
3526     {
3527         static string src = q{A a = {member : call()};};
3528         bool visited;
3529         alias visit = ASTVisitor.visit;
3530         override void visit(const StructInitializer){visited = true;}
3531     }
3532 
3533     RollbackAllocator ra;
3534     LexerConfig cf = LexerConfig("", StringBehavior.source);
3535     StringCache ca = StringCache(16);
3536 
3537     Module m = parseModule(getTokensForParser(Test170_F.src, cf, &ca), "", &ra);
3538     Test170_F t170_f = new Test170_F;
3539     t170_f.visit(m);
3540     assert(t170_f.visited);
3541 
3542     m = parseModule(getTokensForParser(Test170_S.src, cf, &ca), "", &ra);
3543     Test170_S t170_s = new Test170_S;
3544     t170_s.visit(m);
3545     assert(t170_s.visited);
3546 }
3547 
3548 unittest // issue #193
3549 {
3550     import dparse.lexer, dparse.parser, dparse.rollback_allocator;
3551 
3552     final class Test193 : ASTVisitor
3553     {
3554         static string src = q{const(Type1[immutable(Type2)]) qualAarray;};
3555         size_t tc;
3556         alias visit = ASTVisitor.visit;
3557         override void visit(const TypeIdentifierPart tip)
3558         {
3559             tip.accept(this);
3560             assert(tip.indexer is null);
3561         }
3562         override void visit(const Type type)
3563         {
3564             tc++;
3565             if (tc == 1) //const(
3566             {
3567                 assert(type.type2.typeConstructor == tok!"const");
3568                 assert(type.type2.typeIdentifierPart is null);
3569             }
3570             else if (tc == 2) //const(Type1
3571             {
3572                 assert(type.typeConstructors.length == 0);
3573                 assert(type.type2.typeIdentifierPart.identifierOrTemplateInstance
3574                     .identifier.text == "Type1");
3575                 assert(type.typeSuffixes.length == 1);
3576             }
3577             else if (tc == 3) // immutable(
3578             {
3579                 assert(type.type2.typeConstructor == tok!"immutable");
3580                 assert(type.type2.typeIdentifierPart is null);
3581             }
3582             else if (tc == 4) // immutable(Type2
3583             {
3584                 assert(type.typeConstructors.length == 0);
3585                 assert(type.type2.typeIdentifierPart.identifierOrTemplateInstance
3586                     .identifier.text == "Type2");
3587                 assert(type.typeSuffixes.length == 0);
3588             }
3589             type.accept(this);
3590         }
3591     }
3592 
3593     RollbackAllocator ra;
3594     LexerConfig cf = LexerConfig("", StringBehavior.source);
3595     StringCache ca = StringCache(16);
3596 
3597     Module m = parseModule(getTokensForParser(Test193.src, cf, &ca), "", &ra);
3598     Test193 t193 = new Test193;
3599     t193.visit(m);
3600 }
3601