1 module dlangide.tools.d.dparser; 2 3 version(USE_LIBDPARSE): 4 5 import dlangui.core.logger; 6 7 import std.d.lexer; 8 import std.d.parser; 9 import std.d.ast; 10 import std.algorithm; 11 import std.string; 12 import std.path; 13 import std.file; 14 import std.conv; 15 16 string importDeclToModuleName(const IdentifierChain chain) { 17 char[] buf; 18 foreach(token; chain.identifiers) { 19 if (buf.length) 20 buf ~= '.'; 21 buf ~= token.text; 22 } 23 return buf.dup; 24 } 25 26 class DParsedModule { 27 protected string _moduleName; 28 protected string _moduleFile; 29 protected StringCache* _cache; 30 protected Module _ast; 31 protected string[] _imports; 32 protected const(Token)[] _tokens; 33 protected LexerConfig _lexerConfig; 34 protected ubyte[] _sourceCode; 35 36 @property string filename() { return _moduleFile; } 37 /// module name, e.g. "std.stdio" 38 @property string moduleName() { return _moduleName; } 39 40 this(StringCache* cache, string filename) { 41 _cache = cache; 42 _moduleFile = filename; 43 } 44 45 static void msgFunction(string fn, size_t line, size_t col, string msg, bool isError) { 46 debug(DParseErrors) Log.d("parser error: ", fn, "(", line, ":", col, ") : ", isError ? "Error: ": "Warning: ", msg); 47 } 48 49 static class ImportListIterator : ASTVisitor { 50 string[] _imports; 51 @property string[] imports() { 52 return _imports; 53 } 54 private void addImport(string m) { 55 foreach(imp; _imports) 56 if (imp.equal(m)) 57 return; 58 _imports ~= m; 59 } 60 61 alias visit = ASTVisitor.visit; 62 //override void visit(const Module module_) { 63 // super.visit(module_); 64 //} 65 override void visit(const ImportDeclaration importDeclaration) { 66 foreach(imp; importDeclaration.singleImports) { 67 addImport(importDeclToModuleName(imp.identifierChain)); 68 } 69 } 70 71 void run(Module ast) { 72 _imports.length = 0; 73 visit(ast); 74 } 75 } 76 private ImportListIterator _importIterator; 77 void scanImports() { 78 if (!_importIterator) 79 _importIterator = new ImportListIterator(); 80 _importIterator.run(_ast); 81 _imports = _importIterator.imports; 82 } 83 84 85 86 private IdentPositionIterator _identPositionIterator; 87 IdentDefinitionLookupResult findTokenNode(const(Token)* tokenToFindPositionFor, const(Token)* tokenToFindReferencesFor) { 88 if (!_identPositionIterator) 89 _identPositionIterator = new IdentPositionIterator(); 90 auto foundNode = _identPositionIterator.run(this, _ast, tokenToFindPositionFor, tokenToFindReferencesFor); 91 return foundNode; 92 } 93 94 95 void findDeclaration(int bytePosition, DParsedModule[string] scanned) { 96 const(Token) * token = findIdentTokenByBytePosition(bytePosition); 97 if (!token) 98 return; 99 100 Log.d("Identifier token found by position: ", token.text); 101 IdentDefinitionLookupResult res = findTokenNode(token, token); 102 if (!res.found) 103 return; 104 Log.d("Found in node:"); 105 res.found.dump(); 106 } 107 108 const(Token) * findIdentTokenByBytePosition(int bytePosition) { 109 const(Token) * res = null; 110 for(int i = 0; i < _tokens.length; i++) { 111 auto t = &_tokens[i]; 112 if (t.index >= bytePosition) { 113 if (res && *res == tok!"identifier") 114 return res; // return this or previous identifier token 115 if (t.index == bytePosition && (*t) == tok!"identifier") 116 return t; // return next identifier token 117 } 118 res = t; 119 } 120 return res; 121 } 122 123 void parse(ubyte[] sourceCode) { 124 _sourceCode = sourceCode; 125 _tokens = getTokensForParser(sourceCode, _lexerConfig, _cache); 126 uint errorCount; 127 uint warningCount; 128 _ast = parseModule(_tokens, _moduleFile, null, &msgFunction, &errorCount, &warningCount); 129 _moduleName = _ast.moduleDeclaration ? importDeclToModuleName(_ast.moduleDeclaration.moduleName) : null; 130 scanImports(); 131 } 132 133 private void addImport(string m) { 134 foreach(imp; _imports) 135 if (imp.equal(m)) 136 return; 137 _imports ~= m; 138 } 139 140 @property string[] imports() { 141 return _imports; 142 } 143 } 144 145 /// D source code parsing service 146 class DParsingService { 147 148 protected static __gshared DParsingService _instance; 149 /// singleton 150 static @property DParsingService instance() { 151 if (!_instance) { 152 _instance = new DParsingService(); 153 } 154 return _instance; 155 } 156 /// destroy singleton 157 static void shutdown() { 158 destroy(_instance); 159 _instance = null; 160 } 161 162 protected StringCache _cache; 163 protected string[] _importPaths; 164 protected DParsedModule[] _modules; 165 protected DParsedModule[string] _moduleByName; 166 protected DParsedModule[string] _moduleByFile; 167 protected bool[string] _notFoundModules; 168 protected DParsedModule _currentModule; // current module 169 170 this() { 171 _cache = StringCache(16); 172 } 173 174 void scanDeps(DParsedModule m, ref DParsedModule[string]scanned) { 175 foreach(imp; m.imports) { 176 if (imp !in scanned) { 177 DParsedModule impModule = getOrParseModule(imp); 178 scanned[imp] = impModule; 179 if (impModule) 180 scanDeps(impModule, scanned); 181 } 182 } 183 } 184 185 DParsedModule scan(ubyte[] sourceCode, string filename, ref DParsedModule[string] scanned) { 186 Log.d("scanning ", filename); 187 destroy(_notFoundModules); 188 DParsedModule res = new DParsedModule(&_cache, filename); 189 res.parse(sourceCode); 190 _currentModule = res; 191 Log.d("moduleName: ", res.moduleName, " imports: ", res.imports); 192 Log.d("deps:"); 193 scanned[res.moduleName] = res; 194 scanDeps(res, scanned); 195 foreach(key, value; scanned) { 196 Log.d(" module ", key, " : ", value ? value.filename : "NOT FOUND"); 197 } 198 return res; 199 } 200 201 DParsedModule findDeclaration(ubyte[] sourceCode, string filename, int bytePosition) { 202 DParsedModule[string] scanned; 203 DParsedModule m = scan(sourceCode, filename, scanned); 204 m.findDeclaration(bytePosition, scanned); 205 return m; 206 } 207 208 /// converts some.module.name to some/module/name.d 209 string moduleNameToPackagePath(string moduleName) { 210 string[] pathSegments = moduleName.split("."); 211 string normalized = buildNormalizedPath(pathSegments); 212 return normalized ~ ".d"; 213 } 214 215 string findModuleFile(string moduleName) { 216 string packagePath = moduleNameToPackagePath(moduleName); 217 foreach(ip; _importPaths) { 218 //Log.d("packagePath: ", packagePath, " importPath: ", ip); 219 string path = buildNormalizedPath(ip, packagePath); 220 if (path.exists && path.isFile) { 221 //Log.d("found ", path); 222 return path; 223 } 224 string pathImports = path ~ "i"; 225 if (pathImports.exists && pathImports.isFile) { 226 //Log.d("found ", pathImports); 227 return pathImports; 228 } 229 } 230 return null; 231 } 232 233 DParsedModule getOrParseModule(string moduleName) { 234 if (_currentModule) { 235 if (moduleName.equal(_currentModule.moduleName)) 236 return _currentModule; // module being scanned 237 } 238 if (auto m = moduleName in _moduleByName) { 239 return *m; 240 } 241 if (moduleName in _notFoundModules) { 242 Log.d("module is in not found: ", moduleName); 243 return null; // already listed as not found 244 } 245 string filename = findModuleFile(moduleName); 246 if (!filename) { 247 Log.d("module not found: ", moduleName); 248 _notFoundModules[moduleName] = true; 249 return null; 250 } 251 try { 252 DParsedModule res = new DParsedModule(&_cache, filename); 253 ubyte[] sourceCode = cast(ubyte[])read(filename); 254 res.parse(sourceCode); 255 _moduleByName[moduleName] = res; 256 _moduleByFile[filename] = res; 257 return res; 258 } catch (Exception e) { 259 Log.d("exception while parsing: ", moduleName, " : ", e); 260 _notFoundModules[moduleName] = true; 261 return null; 262 } 263 } 264 265 void addImportPaths(in string[] paths) { 266 Log.d("addImportPaths: ", paths); 267 foreach(p; paths) { 268 string ap = absolutePath(buildNormalizedPath(p)); 269 bool found = false; 270 foreach(ip; _importPaths) 271 if (ip.equal(ap)) { 272 found = true; 273 break; 274 } 275 if (!found) 276 _importPaths ~= ap; 277 } 278 } 279 } 280 281 282 static class ImportInfo { 283 string moduleName; 284 const ImportDeclaration decl; 285 this(const ImportDeclaration decl, string moduleName) { 286 this.decl = decl; 287 this.moduleName = moduleName; 288 } 289 } 290 enum DeclarationType { 291 none, 292 classVariableDeclaration, 293 structVariableDeclaration, 294 variableDeclaration, 295 classDeclaration, // class declaration 296 structDeclaration, // struct declaration 297 classFunctionDeclaration, // function inside class 298 structFunctionDeclaration, // function inside struct 299 functionDeclaration, // just function 300 functionParameter, // function parameter 301 functionTemplateTypeParameter, 302 classTemplateTypeParameter, 303 structTemplateTypeParameter, 304 templateTypeParameter, 305 } 306 static class IdentContext { 307 DParsedModule mod; 308 Token token; 309 ImportInfo[] imports; 310 const(ASTNode)[] stack; 311 ASTNode declarationNode; 312 ASTNode baseDeclarationNode; 313 DeclarationType declarationType = DeclarationType.none; 314 this(DParsedModule mod, const Token token, ImportInfo[] imports, const(ASTNode)[] stack) { 315 this.mod = mod; 316 this.token = token; 317 this.imports = imports; 318 this.stack = stack; 319 initDeclarationType(); 320 } 321 /// returns true if context ident token is the same as t 322 bool sametok(const Token t) { 323 return t.text.ptr is token.text.ptr; 324 } 325 /// casts top object on stack with specified offset to specified type and returns result 326 T match(T)(int offset = 0) { 327 if (offset < 0 || offset >= stack.length) 328 return null; 329 return cast(T)stack[$ - 1 - offset]; 330 } 331 /// returns true if top object on stack is T1 and second is T2 332 bool match(T1, T2)() { 333 if (stack.length < 2) 334 return false; 335 return cast(T1)stack[$ - 1] !is null && cast(T2)stack[$ - 2] !is null; 336 } 337 /// returns true if top object on stack is T1 and second is T2 338 bool match(T1, T2, T3)() { 339 if (stack.length < 3) 340 return false; 341 return cast(T1)stack[$ - 1] !is null && cast(T2)stack[$ - 2] !is null && cast(T3)stack[$ - 3] !is null; 342 } 343 bool initDeclarationType() { 344 if (match!(Declarator, VariableDeclaration) && sametok(match!Declarator.name)) { 345 if (match!StructBody(2) && match!ClassDeclaration(3)) { 346 declarationType = DeclarationType.classVariableDeclaration; 347 declarationNode = match!VariableDeclaration(1); 348 baseDeclarationNode = match!ClassDeclaration(3); 349 } else if (match!StructBody(2) && match!StructDeclaration(3)) { 350 declarationType = DeclarationType.structVariableDeclaration; 351 declarationNode = match!VariableDeclaration(1); 352 baseDeclarationNode = match!StructDeclaration(3); 353 } else { 354 declarationType = DeclarationType.variableDeclaration; 355 declarationNode = match!VariableDeclaration(1); 356 } 357 return true; 358 } else if (match!ClassDeclaration && sametok(match!ClassDeclaration.name)) { 359 declarationType = DeclarationType.classDeclaration; 360 declarationNode = match!ClassDeclaration; 361 return true; 362 } else if (match!StructDeclaration && sametok(match!StructDeclaration.name)) { 363 declarationType = DeclarationType.structDeclaration; 364 declarationNode = match!StructDeclaration; 365 return true; 366 } else if (match!FunctionDeclaration && sametok(match!FunctionDeclaration.name)) { 367 if (match!StructBody(1) && match!ClassDeclaration(2)) { 368 declarationType = DeclarationType.classFunctionDeclaration; 369 declarationNode = match!FunctionDeclaration; 370 baseDeclarationNode = match!ClassDeclaration(2); 371 } else if (match!StructBody(1) && match!StructDeclaration(2)) { 372 declarationType = DeclarationType.structFunctionDeclaration; 373 declarationNode = match!FunctionDeclaration; 374 baseDeclarationNode = match!StructDeclaration(2); 375 } else { 376 declarationType = DeclarationType.functionDeclaration; 377 declarationNode = match!FunctionDeclaration; 378 } 379 return true; 380 } else if (match!Parameter && sametok(match!Parameter.name) && match!Parameters(1)) { 381 if (match!FunctionDeclaration(2)) { 382 declarationType = DeclarationType.functionParameter; 383 declarationNode = match!Parameter; 384 baseDeclarationNode = match!FunctionDeclaration(2); 385 return true; 386 } 387 } else if (match!TemplateTypeParameter && sametok(match!TemplateTypeParameter.identifier) && match!TemplateParameter(1) && match!TemplateParameterList(2) && match!TemplateParameters(3)) { 388 if (match!FunctionDeclaration(4)) { 389 declarationType = DeclarationType.functionTemplateTypeParameter; 390 declarationNode = match!TemplateTypeParameter; 391 baseDeclarationNode = match!FunctionDeclaration(4); 392 return true; 393 } else if (match!ClassDeclaration(4)) { 394 declarationType = DeclarationType.classTemplateTypeParameter; 395 declarationNode = match!TemplateTypeParameter; 396 baseDeclarationNode = match!ClassDeclaration(4); 397 return true; 398 } else if (match!StructDeclaration(4)) { 399 declarationType = DeclarationType.structTemplateTypeParameter; 400 declarationNode = match!TemplateTypeParameter; 401 baseDeclarationNode = match!StructDeclaration(4); 402 return true; 403 } 404 declarationType = DeclarationType.templateTypeParameter; 405 declarationNode = match!TemplateTypeParameter; 406 return true; 407 } 408 return false; 409 } 410 void dump() { 411 Log.d("module: ", mod.moduleName, 412 "\n\ttoken: ", token.text, " [", token.line, ":", token.column, "-", token.index, "] declType: ", declarationType, 413 " declNode: ", declarationNode, " baseDeclNode: ", baseDeclarationNode, 414 "\n\timports: ", imports, "\n\tcontext: ", stack); 415 } 416 } 417 418 static class IdentDefinitionLookupResult { 419 DParsedModule mod; 420 const(Token) tokenToFind; 421 const(Token) tokenToFindReferences; 422 IdentContext found; 423 IdentContext[] references; 424 this(DParsedModule mod, const(Token) * tokenToFind, const(Token) * tokenToFindReferences, IdentContext found, IdentContext[] references) { 425 this.mod = mod; 426 this.tokenToFind = *tokenToFind; 427 this.tokenToFindReferences = *tokenToFindReferences; 428 this.found = found; 429 this.references = references; 430 } 431 } 432 433 static class IdentPositionIterator : ASTVisitor { 434 435 private const(Token) * _tokenToFind; 436 private const(Token) * _tokenToFindReferences; 437 private ImportInfo[] _scopedImportList; 438 private const(ASTNode)[] _stack; 439 private IdentContext _found; 440 private IdentContext[] _references; 441 private DParsedModule _mod; 442 443 444 private void addImport(const ImportDeclaration decl, string m) { 445 foreach(imp; _scopedImportList) 446 if (imp.moduleName.equal(m)) 447 return; 448 _scopedImportList ~= new ImportInfo(decl, m); 449 } 450 451 private void push(const ASTNode node) { 452 _stack ~= node; 453 } 454 455 private const(ASTNode)pop() { 456 assert(_stack.length > 0); 457 auto res = _stack[$ - 1]; 458 _stack.length--; 459 return res; 460 } 461 462 IdentDefinitionLookupResult run(DParsedModule mod, Module ast, const(Token) * tokenToFind, const(Token) * tokenToFindReferences) { 463 _mod = mod; 464 _stack.length = 0; 465 _references.length = 0; 466 _found = null; 467 _tokenToFind = tokenToFind; 468 _tokenToFindReferences = tokenToFindReferences; 469 visit(ast); 470 if (_references.length > 0) { 471 Log.d("References to the same ident found: "); 472 foreach(r; _references) 473 r.dump(); 474 } 475 return new IdentDefinitionLookupResult(_mod, _tokenToFind, _tokenToFindReferences, _found, _references); 476 } 477 478 //alias visit = ASTVisitor.visit; 479 static string def(string param) { 480 return "push(" ~ param ~ "); super.visit(" ~ param ~ "); pop();"; 481 } 482 /// for objects which contain token not covered by visit() 483 static string deftoken(string param, string tokenField) { 484 return "push(" ~ param ~ "); visit(" ~ param ~ '.' ~ tokenField ~ "); super.visit(" ~ param ~ "); pop();"; 485 } 486 /// for objects which can affect scope - save imports list, and restore after visiting 487 static string defblock(string param) { 488 return "size_t importPos = _scopedImportList.length; push(" ~ param ~ "); super.visit(" ~ param ~ "); pop(); _scopedImportList.length = importPos;"; 489 } 490 491 @property private const(ASTNode)[] copyStack() { 492 const(ASTNode)[] res; 493 foreach(n; _stack) 494 res ~= n; 495 return res; 496 } 497 498 @property private ImportInfo[] copyImports() { 499 ImportInfo[]res; 500 foreach(imp; _scopedImportList) 501 res ~= imp; 502 return res; 503 } 504 505 override void visit(const Token t) { 506 if (_tokenToFind && t.index == _tokenToFind.index) { 507 _found = new IdentContext(_mod, t, copyImports, copyStack); 508 } else if (_tokenToFindReferences && t.text.ptr is _tokenToFindReferences.text.ptr) { 509 _references ~= new IdentContext(_mod, t, copyImports, copyStack); 510 } 511 } 512 513 override void visit(const ExpressionNode n) { 514 //mixin(def("n")); 515 super.visit(n); 516 } 517 override void visit(const AddExpression addExpression) { mixin(def("addExpression")); } 518 override void visit(const AliasDeclaration aliasDeclaration) { mixin(def("aliasDeclaration")); } 519 override void visit(const AliasInitializer aliasInitializer) { mixin(def("aliasInitializer")); } 520 override void visit(const AliasThisDeclaration aliasThisDeclaration) { mixin(def("aliasThisDeclaration")); } 521 override void visit(const AlignAttribute alignAttribute) { mixin(def("alignAttribute")); } 522 override void visit(const AndAndExpression andAndExpression) { mixin(def("andAndExpression")); } 523 override void visit(const AndExpression andExpression) { mixin(def("andExpression")); } 524 override void visit(const AnonymousEnumDeclaration anonymousEnumDeclaration) { mixin(def("anonymousEnumDeclaration")); } 525 override void visit(const AnonymousEnumMember anonymousEnumMember) { mixin(def("anonymousEnumMember")); } 526 override void visit(const ArgumentList argumentList) { mixin(def("argumentList")); } 527 override void visit(const Arguments arguments) { mixin(def("arguments")); } 528 override void visit(const ArrayInitializer arrayInitializer) { mixin(def("arrayInitializer")); } 529 override void visit(const ArrayLiteral arrayLiteral) { mixin(def("arrayLiteral")); } 530 override void visit(const ArrayMemberInitialization arrayMemberInitialization) { mixin(def("arrayMemberInitialization")); } 531 override void visit(const AsmAddExp asmAddExp) { mixin(def("asmAddExp")); } 532 override void visit(const AsmAndExp asmAndExp) { mixin(def("asmAndExp")); } 533 override void visit(const AsmBrExp asmBrExp) { mixin(def("asmBrExp")); } 534 override void visit(const AsmEqualExp asmEqualExp) { mixin(def("asmEqualExp")); } 535 override void visit(const AsmExp asmExp) { mixin(def("asmExp")); } 536 override void visit(const AsmInstruction asmInstruction) { mixin(def("asmInstruction")); } 537 override void visit(const AsmLogAndExp asmLogAndExp) { mixin(def("asmLogAndExp")); } 538 override void visit(const AsmLogOrExp asmLogOrExp) { mixin(def("asmLogOrExp")); } 539 override void visit(const AsmMulExp asmMulExp) { mixin(def("asmMulExp")); } 540 override void visit(const AsmOrExp asmOrExp) { mixin(def("asmOrExp")); } 541 override void visit(const AsmPrimaryExp asmPrimaryExp) { mixin(def("asmPrimaryExp")); } 542 override void visit(const AsmRelExp asmRelExp) { mixin(def("asmRelExp")); } 543 override void visit(const AsmShiftExp asmShiftExp) { mixin(def("asmShiftExp")); } 544 override void visit(const AsmStatement asmStatement) { mixin(def("asmStatement")); } 545 override void visit(const AsmTypePrefix asmTypePrefix) { mixin(def("asmTypePrefix")); } 546 override void visit(const AsmUnaExp asmUnaExp) { mixin(def("asmUnaExp")); } 547 override void visit(const AsmXorExp asmXorExp) { mixin(def("asmXorExp")); } 548 override void visit(const AssertExpression assertExpression) { mixin(def("assertExpression")); } 549 override void visit(const AssignExpression assignExpression) { mixin(def("assignExpression")); } 550 override void visit(const AssocArrayLiteral assocArrayLiteral) { mixin(def("assocArrayLiteral")); } 551 override void visit(const AtAttribute atAttribute) { 552 mixin(deftoken("atAttribute", "identifier")); 553 } 554 override void visit(const Attribute attribute) { 555 mixin(deftoken("attribute", "attribute")); 556 } 557 override void visit(const AttributeDeclaration attributeDeclaration) { mixin(def("attributeDeclaration")); } 558 override void visit(const AutoDeclaration autoDeclaration) { mixin(def("autoDeclaration")); } 559 override void visit(const BlockStatement blockStatement) { 560 mixin(defblock("blockStatement")); 561 } 562 override void visit(const BodyStatement bodyStatement) { mixin(def("bodyStatement")); } 563 override void visit(const BreakStatement breakStatement) { mixin(def("breakStatement")); } 564 override void visit(const BaseClass baseClass) { mixin(def("baseClass")); } 565 override void visit(const BaseClassList baseClassList) { mixin(def("baseClassList")); } 566 override void visit(const CaseRangeStatement caseRangeStatement) { mixin(def("caseRangeStatement")); } 567 override void visit(const CaseStatement caseStatement) { mixin(def("caseStatement")); } 568 override void visit(const CastExpression castExpression) { mixin(def("castExpression")); } 569 override void visit(const CastQualifier castQualifier) { mixin(def("castQualifier")); } 570 override void visit(const Catch catch_) { mixin(def("catch_")); } 571 override void visit(const Catches catches) { mixin(def("catches")); } 572 override void visit(const ClassDeclaration classDeclaration) { 573 mixin(deftoken("classDeclaration", "name")); 574 } 575 override void visit(const CmpExpression cmpExpression) { mixin(def("cmpExpression")); } 576 override void visit(const CompileCondition compileCondition) { mixin(def("compileCondition")); } 577 override void visit(const ConditionalDeclaration conditionalDeclaration) { 578 super.visit(conditionalDeclaration); 579 // Don't put conditional decl into stack 580 // TODO: check conditional compilation conditions 581 //mixin(def("conditionalDeclaration")); 582 } 583 override void visit(const ConditionalStatement conditionalStatement) { mixin(def("conditionalStatement")); } 584 override void visit(const Constraint constraint) { mixin(def("constraint")); } 585 override void visit(const Constructor constructor) { mixin(def("constructor")); } 586 override void visit(const ContinueStatement continueStatement) { mixin(def("continueStatement")); } 587 override void visit(const DebugCondition debugCondition) { mixin(def("debugCondition")); } 588 override void visit(const DebugSpecification debugSpecification) { mixin(def("debugSpecification")); } 589 override void visit(const Declaration declaration) { 590 super.visit(declaration); 591 //mixin(def("declaration")); 592 } 593 override void visit(const DeclarationOrStatement declarationsOrStatement) { 594 super.visit(declarationsOrStatement); 595 //mixin(def("declarationsOrStatement")); 596 } 597 override void visit(const DeclarationsAndStatements declarationsAndStatements) { mixin(def("declarationsAndStatements")); } 598 override void visit(const Declarator declarator) { 599 mixin(deftoken("declarator", "name")); 600 } 601 override void visit(const DefaultStatement defaultStatement) { mixin(def("defaultStatement")); } 602 override void visit(const DeleteExpression deleteExpression) { mixin(def("deleteExpression")); } 603 override void visit(const DeleteStatement deleteStatement) { mixin(def("deleteStatement")); } 604 override void visit(const Deprecated deprecated_) { mixin(def("deprecated_")); } 605 override void visit(const Destructor destructor) { mixin(def("destructor")); } 606 override void visit(const DoStatement doStatement) { mixin(def("doStatement")); } 607 override void visit(const EnumBody enumBody) { mixin(def("enumBody")); } 608 override void visit(const EnumDeclaration enumDeclaration) { 609 mixin(deftoken("enumDeclaration", "name")); 610 } 611 override void visit(const EnumMember enumMember) { mixin(def("enumMember")); } 612 override void visit(const EponymousTemplateDeclaration eponymousTemplateDeclaration) { mixin(def("eponymousTemplateDeclaration")); } 613 override void visit(const EqualExpression equalExpression) { mixin(def("equalExpression")); } 614 override void visit(const Expression expression) { mixin(def("expression")); } 615 override void visit(const ExpressionStatement expressionStatement) { mixin(def("expressionStatement")); } 616 override void visit(const FinalSwitchStatement finalSwitchStatement) { mixin(def("finalSwitchStatement")); } 617 override void visit(const Finally finally_) { mixin(def("finally_")); } 618 override void visit(const ForStatement forStatement) { mixin(def("forStatement")); } 619 override void visit(const ForeachStatement foreachStatement) { mixin(def("foreachStatement")); } 620 override void visit(const ForeachType foreachType) { mixin(def("foreachType")); } 621 override void visit(const ForeachTypeList foreachTypeList) { mixin(def("foreachTypeList")); } 622 override void visit(const FunctionAttribute functionAttribute) { mixin(def("functionAttribute")); } 623 override void visit(const FunctionBody functionBody) { 624 mixin(defblock("functionBody")); 625 } 626 override void visit(const FunctionCallExpression functionCallExpression) { mixin(def("functionCallExpression")); } 627 override void visit(const FunctionDeclaration functionDeclaration) { 628 mixin(deftoken("functionDeclaration", "name")); 629 } 630 override void visit(const FunctionLiteralExpression functionLiteralExpression) { mixin(def("functionLiteralExpression")); } 631 override void visit(const GotoStatement gotoStatement) { mixin(def("gotoStatement")); } 632 override void visit(const IdentifierChain identifierChain) { mixin(def("identifierChain")); } 633 override void visit(const IdentifierList identifierList) { mixin(def("identifierList")); } 634 override void visit(const IdentifierOrTemplateChain identifierOrTemplateChain) { mixin(def("identifierOrTemplateChain")); } 635 override void visit(const IdentifierOrTemplateInstance identifierOrTemplateInstance) { mixin(def("identifierOrTemplateInstance")); } 636 override void visit(const IdentityExpression identityExpression) { mixin(def("identityExpression")); } 637 override void visit(const IfStatement ifStatement) { mixin(def("ifStatement")); } 638 override void visit(const ImportBind importBind) { mixin(def("importBind")); } 639 override void visit(const ImportBindings importBindings) { mixin(def("importBindings")); } 640 override void visit(const ImportDeclaration importDeclaration) { 641 foreach(imp; importDeclaration.singleImports) { 642 addImport(importDeclaration, importDeclToModuleName(imp.identifierChain)); 643 } 644 mixin(def("importDeclaration")); 645 } 646 override void visit(const ImportExpression importExpression) { mixin(def("importExpression")); } 647 override void visit(const IndexExpression indexExpression) { mixin(def("indexExpression")); } 648 override void visit(const InExpression inExpression) { mixin(def("inExpression")); } 649 override void visit(const InStatement inStatement) { mixin(def("inStatement")); } 650 override void visit(const Initialize initialize) { mixin(def("initialize")); } 651 override void visit(const Initializer initializer) { mixin(def("initializer")); } 652 override void visit(const InterfaceDeclaration interfaceDeclaration) { 653 mixin(deftoken("interfaceDeclaration", "name")); 654 } 655 override void visit(const Invariant invariant_) { mixin(def("invariant_")); } 656 override void visit(const IsExpression isExpression) { mixin(def("isExpression")); } 657 override void visit(const KeyValuePair keyValuePair) { mixin(def("keyValuePair")); } 658 override void visit(const KeyValuePairs keyValuePairs) { mixin(def("keyValuePairs")); } 659 override void visit(const LabeledStatement labeledStatement) { mixin(def("labeledStatement")); } 660 override void visit(const LambdaExpression lambdaExpression) { mixin(def("lambdaExpression")); } 661 override void visit(const LastCatch lastCatch) { mixin(def("lastCatch")); } 662 override void visit(const LinkageAttribute linkageAttribute) { mixin(def("linkageAttribute")); } 663 override void visit(const MemberFunctionAttribute memberFunctionAttribute) { mixin(def("memberFunctionAttribute")); } 664 override void visit(const MixinDeclaration mixinDeclaration) { mixin(def("mixinDeclaration")); } 665 override void visit(const MixinExpression mixinExpression) { mixin(def("mixinExpression")); } 666 override void visit(const MixinTemplateDeclaration mixinTemplateDeclaration) { mixin(def("mixinTemplateDeclaration")); } 667 override void visit(const MixinTemplateName mixinTemplateName) { mixin(def("mixinTemplateName")); } 668 override void visit(const Module module_) { mixin(def("module_")); } 669 override void visit(const ModuleDeclaration moduleDeclaration) { mixin(def("moduleDeclaration")); } 670 override void visit(const MulExpression mulExpression) { mixin(def("mulExpression")); } 671 override void visit(const NewAnonClassExpression newAnonClassExpression) { mixin(def("newAnonClassExpression")); } 672 override void visit(const NewExpression newExpression) { mixin(def("newExpression")); } 673 override void visit(const NonVoidInitializer nonVoidInitializer) { mixin(def("nonVoidInitializer")); } 674 override void visit(const Operands operands) { mixin(def("operands")); } 675 override void visit(const OrExpression orExpression) { mixin(def("orExpression")); } 676 override void visit(const OrOrExpression orOrExpression) { mixin(def("orOrExpression")); } 677 override void visit(const OutStatement outStatement) { mixin(def("outStatement")); } 678 override void visit(const Parameter parameter) { mixin(def("parameter")); } 679 override void visit(const Parameters parameters) { mixin(def("parameters")); } 680 override void visit(const Postblit postblit) { mixin(def("postblit")); } 681 override void visit(const PowExpression powExpression) { mixin(def("powExpression")); } 682 override void visit(const PragmaDeclaration pragmaDeclaration) { mixin(def("pragmaDeclaration")); } 683 override void visit(const PragmaExpression pragmaExpression) { mixin(def("pragmaExpression")); } 684 override void visit(const PrimaryExpression primaryExpression) { mixin(def("primaryExpression")); } 685 override void visit(const Register register) { mixin(def("register")); } 686 override void visit(const RelExpression relExpression) { mixin(def("relExpression")); } 687 override void visit(const ReturnStatement returnStatement) { mixin(def("returnStatement")); } 688 override void visit(const ScopeGuardStatement scopeGuardStatement) { mixin(def("scopeGuardStatement")); } 689 override void visit(const SharedStaticConstructor sharedStaticConstructor) { mixin(def("sharedStaticConstructor")); } 690 override void visit(const SharedStaticDestructor sharedStaticDestructor) { mixin(def("sharedStaticDestructor")); } 691 override void visit(const ShiftExpression shiftExpression) { mixin(def("shiftExpression")); } 692 override void visit(const SingleImport singleImport) { mixin(def("singleImport")); } 693 override void visit(const SliceExpression sliceExpression) { mixin(def("sliceExpression")); } 694 override void visit(const Statement statement) { 695 //mixin(def("statement")); 696 super.visit(statement); 697 } 698 override void visit(const StatementNoCaseNoDefault statementNoCaseNoDefault) { 699 super.visit(statementNoCaseNoDefault); 700 //mixin(def("statementNoCaseNoDefault")); 701 } 702 override void visit(const StaticAssertDeclaration staticAssertDeclaration) { mixin(def("staticAssertDeclaration")); } 703 override void visit(const StaticAssertStatement staticAssertStatement) { mixin(def("staticAssertStatement")); } 704 override void visit(const StaticConstructor staticConstructor) { mixin(def("staticConstructor")); } 705 override void visit(const StaticDestructor staticDestructor) { mixin(def("staticDestructor")); } 706 override void visit(const StaticIfCondition staticIfCondition) { mixin(def("staticIfCondition")); } 707 override void visit(const StorageClass storageClass) { mixin(def("storageClass")); } 708 override void visit(const StructBody structBody) { mixin(def("structBody")); } 709 override void visit(const StructDeclaration structDeclaration) { 710 mixin(deftoken("structDeclaration", "name")); 711 } 712 override void visit(const StructInitializer structInitializer) { mixin(def("structInitializer")); } 713 override void visit(const StructMemberInitializer structMemberInitializer) { mixin(def("structMemberInitializer")); } 714 override void visit(const StructMemberInitializers structMemberInitializers) { mixin(def("structMemberInitializers")); } 715 override void visit(const SwitchStatement switchStatement) { mixin(def("switchStatement")); } 716 override void visit(const Symbol symbol) { mixin(def("symbol")); } 717 override void visit(const SynchronizedStatement synchronizedStatement) { mixin(def("synchronizedStatement")); } 718 override void visit(const TemplateAliasParameter templateAliasParameter) { mixin(def("templateAliasParameter")); } 719 override void visit(const TemplateArgument templateArgument) { mixin(def("templateArgument")); } 720 override void visit(const TemplateArgumentList templateArgumentList) { mixin(def("templateArgumentList")); } 721 override void visit(const TemplateArguments templateArguments) { mixin(def("templateArguments")); } 722 override void visit(const TemplateDeclaration templateDeclaration) { mixin(def("templateDeclaration")); } 723 override void visit(const TemplateInstance templateInstance) { mixin(def("templateInstance")); } 724 override void visit(const TemplateMixinExpression templateMixinExpression) { mixin(def("templateMixinExpression")); } 725 override void visit(const TemplateParameter templateParameter) { mixin(def("templateParameter")); } 726 override void visit(const TemplateParameterList templateParameterList) { mixin(def("templateParameterList")); } 727 override void visit(const TemplateParameters templateParameters) { mixin(def("templateParameters")); } 728 override void visit(const TemplateSingleArgument templateSingleArgument) { mixin(def("templateSingleArgument")); } 729 override void visit(const TemplateThisParameter templateThisParameter) { mixin(def("templateThisParameter")); } 730 override void visit(const TemplateTupleParameter templateTupleParameter) { mixin(def("templateTupleParameter")); } 731 override void visit(const TemplateTypeParameter templateTypeParameter) { mixin(def("templateTypeParameter")); } 732 override void visit(const TemplateValueParameter templateValueParameter) { mixin(def("templateValueParameter")); } 733 override void visit(const TemplateValueParameterDefault templateValueParameterDefault) { mixin(def("templateValueParameterDefault")); } 734 override void visit(const TernaryExpression ternaryExpression) { mixin(def("ternaryExpression")); } 735 override void visit(const ThrowStatement throwStatement) { mixin(def("throwStatement")); } 736 override void visit(const TraitsExpression traitsExpression) { mixin(def("traitsExpression")); } 737 override void visit(const TryStatement tryStatement) { mixin(def("tryStatement")); } 738 override void visit(const Type type) { mixin(def("type")); } 739 override void visit(const Type2 type2) { mixin(def("type2")); } 740 override void visit(const TypeSpecialization typeSpecialization) { mixin(def("typeSpecialization")); } 741 override void visit(const TypeSuffix typeSuffix) { mixin(def("typeSuffix")); } 742 override void visit(const TypeidExpression typeidExpression) { mixin(def("typeidExpression")); } 743 override void visit(const TypeofExpression typeofExpression) { mixin(def("typeofExpression")); } 744 override void visit(const UnaryExpression unaryExpression) { 745 super.visit(unaryExpression); 746 //mixin(def("unaryExpression")); 747 } 748 override void visit(const UnionDeclaration unionDeclaration) { mixin(def("unionDeclaration")); } 749 override void visit(const Unittest unittest_) { mixin(def("unittest_")); } 750 override void visit(const VariableDeclaration variableDeclaration) { 751 mixin(def("variableDeclaration")); 752 } 753 override void visit(const Vector vector) { mixin(def("vector")); } 754 override void visit(const VersionCondition versionCondition) { mixin(def("versionCondition")); } 755 override void visit(const VersionSpecification versionSpecification) { mixin(def("versionSpecification")); } 756 override void visit(const WhileStatement whileStatement) { mixin(def("whileStatement")); } 757 override void visit(const WithStatement withStatement) { mixin(def("withStatement")); } 758 override void visit(const XorExpression xorExpression) { mixin(def("xorExpression")); } 759 }