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