| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.generated.declaration_resolver; | 5 library analyzer.src.generated.declaration_resolver; |
| 6 | 6 |
| 7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/ast/token.dart'; | 8 import 'package:analyzer/dart/ast/token.dart'; |
| 9 import 'package:analyzer/dart/ast/visitor.dart'; | 9 import 'package:analyzer/dart/ast/visitor.dart'; |
| 10 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 // in which case the elements are disconnected from the rest of the element | 58 // in which case the elements are disconnected from the rest of the element |
| 59 // model, thus we can't reconnect to them. To avoid crashes, just create | 59 // model, thus we can't reconnect to them. To avoid crashes, just create |
| 60 // fresh elements. | 60 // fresh elements. |
| 61 ElementHolder elementHolder = new ElementHolder(); | 61 ElementHolder elementHolder = new ElementHolder(); |
| 62 new ElementBuilder(elementHolder, _enclosingUnit).visitAnnotation(node); | 62 new ElementBuilder(elementHolder, _enclosingUnit).visitAnnotation(node); |
| 63 return null; | 63 return null; |
| 64 } | 64 } |
| 65 | 65 |
| 66 @override | 66 @override |
| 67 Object visitCatchClause(CatchClause node) { | 67 Object visitCatchClause(CatchClause node) { |
| 68 SimpleIdentifier exceptionParameter = node.exceptionParameter; | 68 _walker.elementBuilder.buildCatchVariableElements(node); |
| 69 if (exceptionParameter != null) { | |
| 70 _match(exceptionParameter, _walker.getVariable()); | |
| 71 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | |
| 72 if (stackTraceParameter != null) { | |
| 73 _match(stackTraceParameter, _walker.getVariable()); | |
| 74 } | |
| 75 } | |
| 76 return super.visitCatchClause(node); | 69 return super.visitCatchClause(node); |
| 77 } | 70 } |
| 78 | 71 |
| 79 @override | 72 @override |
| 80 Object visitClassDeclaration(ClassDeclaration node) { | 73 Object visitClassDeclaration(ClassDeclaration node) { |
| 81 ClassElement element = _match(node.name, _walker.getClass()); | 74 ClassElement element = _match(node.name, _walker.getClass()); |
| 82 _walk(new ElementWalker.forClass(element), () { | 75 _walk(new ElementWalker.forClass(element), () { |
| 83 super.visitClassDeclaration(node); | 76 super.visitClassDeclaration(node); |
| 84 }); | 77 }); |
| 85 _resolveMetadata(node, node.metadata, element); | 78 _resolveMetadata(node, node.metadata, element); |
| 86 return null; | 79 return null; |
| 87 } | 80 } |
| 88 | 81 |
| 89 @override | 82 @override |
| 90 Object visitClassTypeAlias(ClassTypeAlias node) { | 83 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 91 ClassElement element = _match(node.name, _walker.getClass()); | 84 ClassElement element = _match(node.name, _walker.getClass()); |
| 92 _walk(new ElementWalker.forClass(element), () { | 85 _walk(new ElementWalker.forClass(element), () { |
| 93 super.visitClassTypeAlias(node); | 86 super.visitClassTypeAlias(node); |
| 94 }); | 87 }); |
| 95 _resolveMetadata(node, node.metadata, element); | 88 _resolveMetadata(node, node.metadata, element); |
| 96 return null; | 89 return null; |
| 97 } | 90 } |
| 98 | 91 |
| 99 @override | 92 @override |
| 100 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 93 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 101 ConstructorElement element = _match(node.name, _walker.getConstructor()); | 94 ConstructorElement element = _match(node.name, _walker.getConstructor(), |
| 102 _walk(new ElementWalker.forExecutable(element), () { | 95 offset: node.name?.offset ?? node.returnType.offset); |
| 96 _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () { |
| 103 node.element = element; | 97 node.element = element; |
| 104 super.visitConstructorDeclaration(node); | 98 super.visitConstructorDeclaration(node); |
| 105 }); | 99 }); |
| 106 _resolveMetadata(node, node.metadata, element); | 100 _resolveMetadata(node, node.metadata, element); |
| 107 return null; | 101 return null; |
| 108 } | 102 } |
| 109 | 103 |
| 110 @override | 104 @override |
| 111 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 105 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 112 VariableElement element = _match(node.identifier, _walker.getVariable()); | 106 // Declared identifiers can only occur inside executable elements. |
| 113 super.visitDeclaredIdentifier(node); | 107 _walker.elementBuilder.visitDeclaredIdentifier(node); |
| 114 _resolveMetadata(node, node.metadata, element); | |
| 115 return null; | 108 return null; |
| 116 } | 109 } |
| 117 | 110 |
| 118 @override | 111 @override |
| 119 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 112 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 120 ParameterElement element = | 113 ParameterElement element = |
| 121 _match(node.parameter.identifier, _walker.getParameter()); | 114 _match(node.parameter.identifier, _walker.getParameter()); |
| 122 Expression defaultValue = node.defaultValue; | 115 Expression defaultValue = node.defaultValue; |
| 123 if (defaultValue != null) { | 116 if (defaultValue != null) { |
| 124 _walk(new ElementWalker.forExecutable(element.initializer), () { | 117 _walk( |
| 118 new ElementWalker.forExecutable(element.initializer, _enclosingUnit), |
| 119 () { |
| 125 defaultValue.accept(this); | 120 defaultValue.accept(this); |
| 126 }); | 121 }); |
| 127 } | 122 } |
| 128 _walk(new ElementWalker.forParameter(element), () { | 123 _walk(new ElementWalker.forParameter(element), () { |
| 129 node.parameter.accept(this); | 124 node.parameter.accept(this); |
| 130 }); | 125 }); |
| 131 _resolveMetadata(node, node.metadata, element); | 126 _resolveMetadata(node, node.metadata, element); |
| 132 return null; | 127 return null; |
| 133 } | 128 } |
| 134 | 129 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 element = _match(functionName, _walker.getFunction()); | 182 element = _match(functionName, _walker.getFunction()); |
| 188 } else if (property.keyword == Keyword.GET) { | 183 } else if (property.keyword == Keyword.GET) { |
| 189 element = _match(functionName, _walker.getAccessor()); | 184 element = _match(functionName, _walker.getAccessor()); |
| 190 } else { | 185 } else { |
| 191 assert(property.keyword == Keyword.SET); | 186 assert(property.keyword == Keyword.SET); |
| 192 element = _match(functionName, _walker.getAccessor(), | 187 element = _match(functionName, _walker.getAccessor(), |
| 193 elementName: functionName.name + '='); | 188 elementName: functionName.name + '='); |
| 194 } | 189 } |
| 195 } | 190 } |
| 196 node.functionExpression.element = element; | 191 node.functionExpression.element = element; |
| 197 _walk(new ElementWalker.forExecutable(element), () { | 192 _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () { |
| 198 super.visitFunctionDeclaration(node); | 193 super.visitFunctionDeclaration(node); |
| 199 }); | 194 }); |
| 200 _resolveMetadata(node, node.metadata, element); | 195 _resolveMetadata(node, node.metadata, element); |
| 201 return null; | 196 return null; |
| 202 } | 197 } |
| 203 | 198 |
| 204 @override | 199 @override |
| 205 Object visitFunctionExpression(FunctionExpression node) { | 200 Object visitFunctionExpression(FunctionExpression node) { |
| 206 if (node.parent is! FunctionDeclaration) { | 201 if (node.parent is! FunctionDeclaration) { |
| 207 FunctionElement element = _walker.getFunction(); | 202 FunctionElement element = _walker.getFunction(); |
| 203 _matchOffset(element, node.offset); |
| 208 node.element = element; | 204 node.element = element; |
| 209 _walk(new ElementWalker.forExecutable(element), () { | 205 _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () { |
| 210 super.visitFunctionExpression(node); | 206 super.visitFunctionExpression(node); |
| 211 }); | 207 }); |
| 212 return null; | 208 return null; |
| 213 } else { | 209 } else { |
| 214 return super.visitFunctionExpression(node); | 210 return super.visitFunctionExpression(node); |
| 215 } | 211 } |
| 216 } | 212 } |
| 217 | 213 |
| 218 @override | 214 @override |
| 219 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 215 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 243 @override | 239 @override |
| 244 Object visitImportDirective(ImportDirective node) { | 240 Object visitImportDirective(ImportDirective node) { |
| 245 super.visitImportDirective(node); | 241 super.visitImportDirective(node); |
| 246 _resolveAnnotations( | 242 _resolveAnnotations( |
| 247 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); | 243 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); |
| 248 return null; | 244 return null; |
| 249 } | 245 } |
| 250 | 246 |
| 251 @override | 247 @override |
| 252 Object visitLabeledStatement(LabeledStatement node) { | 248 Object visitLabeledStatement(LabeledStatement node) { |
| 253 for (Label label in node.labels) { | 249 bool onSwitchStatement = node.statement is SwitchStatement; |
| 254 _match(label.label, _walker.getLabel()); | 250 _walker.elementBuilder |
| 255 } | 251 .buildLabelElements(node.labels, onSwitchStatement, false); |
| 256 return super.visitLabeledStatement(node); | 252 return super.visitLabeledStatement(node); |
| 257 } | 253 } |
| 258 | 254 |
| 259 @override | 255 @override |
| 260 Object visitLibraryDirective(LibraryDirective node) { | 256 Object visitLibraryDirective(LibraryDirective node) { |
| 261 super.visitLibraryDirective(node); | 257 super.visitLibraryDirective(node); |
| 262 _resolveAnnotations( | 258 _resolveAnnotations( |
| 263 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); | 259 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); |
| 264 return null; | 260 return null; |
| 265 } | 261 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 280 _match(methodName, _walker.getFunction(), elementName: elementName); | 276 _match(methodName, _walker.getFunction(), elementName: elementName); |
| 281 } else { | 277 } else { |
| 282 if (property.keyword == Keyword.GET) { | 278 if (property.keyword == Keyword.GET) { |
| 283 element = _match(methodName, _walker.getAccessor()); | 279 element = _match(methodName, _walker.getAccessor()); |
| 284 } else { | 280 } else { |
| 285 assert(property.keyword == Keyword.SET); | 281 assert(property.keyword == Keyword.SET); |
| 286 element = _match(methodName, _walker.getAccessor(), | 282 element = _match(methodName, _walker.getAccessor(), |
| 287 elementName: nameOfMethod + '='); | 283 elementName: nameOfMethod + '='); |
| 288 } | 284 } |
| 289 } | 285 } |
| 290 _walk(new ElementWalker.forExecutable(element), () { | 286 _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () { |
| 291 super.visitMethodDeclaration(node); | 287 super.visitMethodDeclaration(node); |
| 292 }); | 288 }); |
| 293 _resolveMetadata(node, node.metadata, element); | 289 _resolveMetadata(node, node.metadata, element); |
| 294 return null; | 290 return null; |
| 295 } | 291 } |
| 296 | 292 |
| 297 @override | 293 @override |
| 298 Object visitPartDirective(PartDirective node) { | 294 Object visitPartDirective(PartDirective node) { |
| 299 super.visitPartDirective(node); | 295 super.visitPartDirective(node); |
| 300 _resolveAnnotations( | 296 _resolveAnnotations( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 318 }); | 314 }); |
| 319 _resolveMetadata(node, node.metadata, element); | 315 _resolveMetadata(node, node.metadata, element); |
| 320 return null; | 316 return null; |
| 321 } else { | 317 } else { |
| 322 return super.visitSimpleFormalParameter(node); | 318 return super.visitSimpleFormalParameter(node); |
| 323 } | 319 } |
| 324 } | 320 } |
| 325 | 321 |
| 326 @override | 322 @override |
| 327 Object visitSwitchCase(SwitchCase node) { | 323 Object visitSwitchCase(SwitchCase node) { |
| 328 for (Label label in node.labels) { | 324 _walker.elementBuilder.buildLabelElements(node.labels, false, true); |
| 329 _match(label.label, _walker.getLabel()); | |
| 330 } | |
| 331 return super.visitSwitchCase(node); | 325 return super.visitSwitchCase(node); |
| 332 } | 326 } |
| 333 | 327 |
| 334 @override | 328 @override |
| 335 Object visitSwitchDefault(SwitchDefault node) { | 329 Object visitSwitchDefault(SwitchDefault node) { |
| 336 for (Label label in node.labels) { | 330 _walker.elementBuilder.buildLabelElements(node.labels, false, true); |
| 337 _match(label.label, _walker.getLabel()); | |
| 338 } | |
| 339 return super.visitSwitchDefault(node); | 331 return super.visitSwitchDefault(node); |
| 340 } | 332 } |
| 341 | 333 |
| 342 @override | 334 @override |
| 343 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | 335 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 344 super.visitTopLevelVariableDeclaration(node); | 336 super.visitTopLevelVariableDeclaration(node); |
| 345 _resolveMetadata(node, node.metadata, node.variables.variables[0].element); | 337 _resolveMetadata(node, node.metadata, node.variables.variables[0].element); |
| 346 return null; | 338 return null; |
| 347 } | 339 } |
| 348 | 340 |
| 349 @override | 341 @override |
| 350 Object visitTypeParameter(TypeParameter node) { | 342 Object visitTypeParameter(TypeParameter node) { |
| 351 Element element = _match(node.name, _walker.getTypeParameter()); | 343 Element element = _match(node.name, _walker.getTypeParameter()); |
| 352 super.visitTypeParameter(node); | 344 super.visitTypeParameter(node); |
| 353 _resolveMetadata(node, node.metadata, element); | 345 _resolveMetadata(node, node.metadata, element); |
| 354 return null; | 346 return null; |
| 355 } | 347 } |
| 356 | 348 |
| 357 @override | 349 @override |
| 358 Object visitVariableDeclaration(VariableDeclaration node) { | 350 Object visitVariableDeclaration(VariableDeclaration node) { |
| 359 VariableElement element = _match(node.name, _walker.getVariable()); | 351 VariableElement element = _match(node.name, _walker.getVariable()); |
| 360 Expression initializer = node.initializer; | 352 Expression initializer = node.initializer; |
| 361 if (initializer != null) { | 353 if (initializer != null) { |
| 362 _walk(new ElementWalker.forExecutable(element.initializer), () { | 354 _walk( |
| 355 new ElementWalker.forExecutable(element.initializer, _enclosingUnit), |
| 356 () { |
| 363 super.visitVariableDeclaration(node); | 357 super.visitVariableDeclaration(node); |
| 364 }); | 358 }); |
| 365 return null; | 359 return null; |
| 366 } else { | 360 } else { |
| 367 return super.visitVariableDeclaration(node); | 361 return super.visitVariableDeclaration(node); |
| 368 } | 362 } |
| 369 } | 363 } |
| 370 | 364 |
| 371 @override | 365 @override |
| 372 Object visitVariableDeclarationList(VariableDeclarationList node) { | 366 Object visitVariableDeclarationList(VariableDeclarationList node) { |
| 373 super.visitVariableDeclarationList(node); | 367 if (_walker.elementBuilder != null) { |
| 374 if (node.parent is! FieldDeclaration && | 368 return _walker.elementBuilder.visitVariableDeclarationList(node); |
| 375 node.parent is! TopLevelVariableDeclaration) { | 369 } else { |
| 376 _resolveMetadata(node, node.metadata, node.variables[0].element); | 370 super.visitVariableDeclarationList(node); |
| 371 if (node.parent is! FieldDeclaration && |
| 372 node.parent is! TopLevelVariableDeclaration) { |
| 373 _resolveMetadata(node, node.metadata, node.variables[0].element); |
| 374 } |
| 375 return null; |
| 377 } | 376 } |
| 378 return null; | |
| 379 } | 377 } |
| 380 | 378 |
| 381 /** | 379 /** |
| 382 * Updates [identifier] to point to [element], after ensuring that the | 380 * Updates [identifier] to point to [element], after ensuring that the |
| 383 * element has the expected name. | 381 * element has the expected name. |
| 384 * | 382 * |
| 385 * If no [elementName] is given, it defaults to the name of the [identifier] | 383 * If no [elementName] is given, it defaults to the name of the [identifier] |
| 386 * (or the empty string if [identifier] is `null`). | 384 * (or the empty string if [identifier] is `null`). |
| 387 * | 385 * |
| 388 * If [identifier] is `null`, nothing is updated, but the element name is | 386 * If [identifier] is `null`, nothing is updated, but the element name is |
| 389 * still checked. | 387 * still checked. |
| 390 */ | 388 */ |
| 391 Element/*=E*/ _match/*<E extends Element>*/( | 389 Element/*=E*/ _match/*<E extends Element>*/( |
| 392 SimpleIdentifier identifier, Element/*=E*/ element, | 390 SimpleIdentifier identifier, Element/*=E*/ element, |
| 393 {String elementName}) { | 391 {String elementName, int offset}) { |
| 394 elementName ??= identifier?.name ?? ''; | 392 elementName ??= identifier?.name ?? ''; |
| 393 offset ??= identifier.offset; |
| 395 if (element.name != elementName) { | 394 if (element.name != elementName) { |
| 396 throw new StateError( | 395 throw new StateError( |
| 397 'Expected an element matching `$elementName`, got `${element.name}`'); | 396 'Expected an element matching `$elementName`, got `${element.name}`'); |
| 398 } | 397 } |
| 399 identifier?.staticElement = element; | 398 identifier?.staticElement = element; |
| 399 _matchOffset(element, offset); |
| 400 return element; | 400 return element; |
| 401 } | 401 } |
| 402 | 402 |
| 403 void _matchOffset(Element element, int offset) { |
| 404 if (element.nameOffset != 0 && element.nameOffset != offset) { |
| 405 throw new StateError('Element offset mismatch'); |
| 406 } else { |
| 407 (element as ElementImpl).nameOffset = offset; |
| 408 } |
| 409 } |
| 410 |
| 403 /** | 411 /** |
| 404 * Associate each of the annotation [nodes] with the corresponding | 412 * Associate each of the annotation [nodes] with the corresponding |
| 405 * [ElementAnnotation] in [annotations]. If there is a problem, report it | 413 * [ElementAnnotation] in [annotations]. If there is a problem, report it |
| 406 * against the given [parent] node. | 414 * against the given [parent] node. |
| 407 */ | 415 */ |
| 408 void _resolveAnnotations(AstNode parent, NodeList<Annotation> nodes, | 416 void _resolveAnnotations(AstNode parent, NodeList<Annotation> nodes, |
| 409 List<ElementAnnotation> annotations) { | 417 List<ElementAnnotation> annotations) { |
| 410 int nodeCount = nodes.length; | 418 int nodeCount = nodes.length; |
| 411 if (nodeCount != annotations.length) { | 419 if (nodeCount != annotations.length) { |
| 412 throw new StateError('Found $nodeCount annotation nodes and ' | 420 throw new StateError('Found $nodeCount annotation nodes and ' |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 /** | 462 /** |
| 455 * Keeps track of the set of non-synthetic child elements of an element, | 463 * Keeps track of the set of non-synthetic child elements of an element, |
| 456 * yielding them one at a time in response to "get" method calls. | 464 * yielding them one at a time in response to "get" method calls. |
| 457 */ | 465 */ |
| 458 class ElementWalker { | 466 class ElementWalker { |
| 459 /** | 467 /** |
| 460 * The element whose child elements are being walked. | 468 * The element whose child elements are being walked. |
| 461 */ | 469 */ |
| 462 final Element element; | 470 final Element element; |
| 463 | 471 |
| 472 /** |
| 473 * If [element] is an executable element, an element builder which is |
| 474 * accumulating the executable element's local variables and labels. |
| 475 * Otherwise `null`. |
| 476 */ |
| 477 LocalElementBuilder elementBuilder; |
| 478 |
| 479 /** |
| 480 * If [element] is an executable element, the element holder associated with |
| 481 * [elementBuilder]. Otherwise `null`. |
| 482 */ |
| 483 ElementHolder _elementHolder; |
| 484 |
| 464 List<PropertyAccessorElement> _accessors; | 485 List<PropertyAccessorElement> _accessors; |
| 465 int _accessorIndex = 0; | 486 int _accessorIndex = 0; |
| 466 List<ClassElement> _classes; | 487 List<ClassElement> _classes; |
| 467 int _classIndex = 0; | 488 int _classIndex = 0; |
| 468 List<ConstructorElement> _constructors; | 489 List<ConstructorElement> _constructors; |
| 469 int _constructorIndex = 0; | 490 int _constructorIndex = 0; |
| 470 List<ClassElement> _enums; | 491 List<ClassElement> _enums; |
| 471 int _enumIndex = 0; | 492 int _enumIndex = 0; |
| 472 List<ExecutableElement> _functions; | 493 List<ExecutableElement> _functions; |
| 473 int _functionIndex = 0; | 494 int _functionIndex = 0; |
| 474 List<LabelElement> _labels; | |
| 475 int _labelIndex = 0; | |
| 476 List<ParameterElement> _parameters; | 495 List<ParameterElement> _parameters; |
| 477 int _parameterIndex = 0; | 496 int _parameterIndex = 0; |
| 478 List<FunctionTypeAliasElement> _typedefs; | 497 List<FunctionTypeAliasElement> _typedefs; |
| 479 int _typedefIndex = 0; | 498 int _typedefIndex = 0; |
| 480 List<TypeParameterElement> _typeParameters; | 499 List<TypeParameterElement> _typeParameters; |
| 481 int _typeParameterIndex = 0; | 500 int _typeParameterIndex = 0; |
| 482 List<VariableElement> _variables; | 501 List<VariableElement> _variables; |
| 483 int _variableIndex = 0; | 502 int _variableIndex = 0; |
| 484 | 503 |
| 485 /** | 504 /** |
| (...skipping 21 matching lines...) Expand all Loading... |
| 507 _enums = compilationUnit.enums, | 526 _enums = compilationUnit.enums, |
| 508 _functions = compilationUnit.functions, | 527 _functions = compilationUnit.functions, |
| 509 _typedefs = compilationUnit.functionTypeAliases, | 528 _typedefs = compilationUnit.functionTypeAliases, |
| 510 _variables = | 529 _variables = |
| 511 compilationUnit.topLevelVariables.where(_isNotSynthetic).toList(); | 530 compilationUnit.topLevelVariables.where(_isNotSynthetic).toList(); |
| 512 | 531 |
| 513 /** | 532 /** |
| 514 * Creates an [ElementWalker] which walks the child elements of a compilation | 533 * Creates an [ElementWalker] which walks the child elements of a compilation |
| 515 * unit element. | 534 * unit element. |
| 516 */ | 535 */ |
| 517 ElementWalker.forExecutable(ExecutableElement element) | 536 ElementWalker.forExecutable( |
| 518 : element = element, | 537 ExecutableElement element, CompilationUnitElement compilationUnit) |
| 519 _functions = element.functions, | 538 : this._forExecutable(element, compilationUnit, new ElementHolder()); |
| 520 _labels = element.labels, | |
| 521 _parameters = element.parameters, | |
| 522 _typeParameters = element.typeParameters, | |
| 523 _variables = element.localVariables; | |
| 524 | 539 |
| 525 /** | 540 /** |
| 526 * Creates an [ElementWalker] which walks the child elements of a parameter | 541 * Creates an [ElementWalker] which walks the child elements of a parameter |
| 527 * element. | 542 * element. |
| 528 */ | 543 */ |
| 529 ElementWalker.forParameter(ParameterElement element) | 544 ElementWalker.forParameter(ParameterElement element) |
| 530 : element = element, | 545 : element = element, |
| 531 _parameters = element.parameters, | 546 _parameters = element.parameters, |
| 532 _typeParameters = element.typeParameters; | 547 _typeParameters = element.typeParameters; |
| 533 | 548 |
| 534 /** | 549 /** |
| 535 * Creates an [ElementWalker] which walks the child elements of a typedef | 550 * Creates an [ElementWalker] which walks the child elements of a typedef |
| 536 * element. | 551 * element. |
| 537 */ | 552 */ |
| 538 ElementWalker.forTypedef(FunctionTypeAliasElement element) | 553 ElementWalker.forTypedef(FunctionTypeAliasElement element) |
| 539 : element = element, | 554 : element = element, |
| 540 _parameters = element.parameters, | 555 _parameters = element.parameters, |
| 541 _typeParameters = element.typeParameters; | 556 _typeParameters = element.typeParameters; |
| 542 | 557 |
| 558 ElementWalker._forExecutable(ExecutableElement element, |
| 559 CompilationUnitElement compilationUnit, ElementHolder elementHolder) |
| 560 : element = element, |
| 561 elementBuilder = |
| 562 new LocalElementBuilder(elementHolder, compilationUnit), |
| 563 _elementHolder = elementHolder, |
| 564 _functions = element.functions, |
| 565 _parameters = element.parameters, |
| 566 _typeParameters = element.typeParameters; |
| 567 |
| 543 /** | 568 /** |
| 544 * Returns the next non-synthetic child of [element] which is an accessor; | 569 * Returns the next non-synthetic child of [element] which is an accessor; |
| 545 * throws an [IndexError] if there are no more. | 570 * throws an [IndexError] if there are no more. |
| 546 */ | 571 */ |
| 547 PropertyAccessorElement getAccessor() => _accessors[_accessorIndex++]; | 572 PropertyAccessorElement getAccessor() => _accessors[_accessorIndex++]; |
| 548 | 573 |
| 549 /** | 574 /** |
| 550 * Returns the next non-synthetic child of [element] which is a class; throws | 575 * Returns the next non-synthetic child of [element] which is a class; throws |
| 551 * an [IndexError] if there are no more. | 576 * an [IndexError] if there are no more. |
| 552 */ | 577 */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 565 ClassElement getEnum() => _enums[_enumIndex++]; | 590 ClassElement getEnum() => _enums[_enumIndex++]; |
| 566 | 591 |
| 567 /** | 592 /** |
| 568 * Returns the next non-synthetic child of [element] which is a top level | 593 * Returns the next non-synthetic child of [element] which is a top level |
| 569 * function, method, or local function; throws an [IndexError] if there are no | 594 * function, method, or local function; throws an [IndexError] if there are no |
| 570 * more. | 595 * more. |
| 571 */ | 596 */ |
| 572 ExecutableElement getFunction() => _functions[_functionIndex++]; | 597 ExecutableElement getFunction() => _functions[_functionIndex++]; |
| 573 | 598 |
| 574 /** | 599 /** |
| 575 * Returns the next non-synthetic child of [element] which is a label; throws | |
| 576 * an [IndexError] if there are no more. | |
| 577 */ | |
| 578 LabelElement getLabel() => _labels[_labelIndex++]; | |
| 579 | |
| 580 /** | |
| 581 * Returns the next non-synthetic child of [element] which is a parameter; | 600 * Returns the next non-synthetic child of [element] which is a parameter; |
| 582 * throws an [IndexError] if there are no more. | 601 * throws an [IndexError] if there are no more. |
| 583 */ | 602 */ |
| 584 ParameterElement getParameter() => _parameters[_parameterIndex++]; | 603 ParameterElement getParameter() => _parameters[_parameterIndex++]; |
| 585 | 604 |
| 586 /** | 605 /** |
| 587 * Returns the next non-synthetic child of [element] which is a typedef; | 606 * Returns the next non-synthetic child of [element] which is a typedef; |
| 588 * throws an [IndexError] if there are no more. | 607 * throws an [IndexError] if there are no more. |
| 589 */ | 608 */ |
| 590 FunctionTypeAliasElement getTypedef() => _typedefs[_typedefIndex++]; | 609 FunctionTypeAliasElement getTypedef() => _typedefs[_typedefIndex++]; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 613 throw new StateError( | 632 throw new StateError( |
| 614 'Unmatched ${elements[index].runtimeType} ${elements[index]}'); | 633 'Unmatched ${elements[index].runtimeType} ${elements[index]}'); |
| 615 } | 634 } |
| 616 } | 635 } |
| 617 | 636 |
| 618 check(_accessors, _accessorIndex); | 637 check(_accessors, _accessorIndex); |
| 619 check(_classes, _classIndex); | 638 check(_classes, _classIndex); |
| 620 check(_constructors, _constructorIndex); | 639 check(_constructors, _constructorIndex); |
| 621 check(_enums, _enumIndex); | 640 check(_enums, _enumIndex); |
| 622 check(_functions, _functionIndex); | 641 check(_functions, _functionIndex); |
| 623 check(_labels, _labelIndex); | |
| 624 check(_parameters, _parameterIndex); | 642 check(_parameters, _parameterIndex); |
| 625 check(_typedefs, _typedefIndex); | 643 check(_typedefs, _typedefIndex); |
| 626 check(_typeParameters, _typeParameterIndex); | 644 check(_typeParameters, _typeParameterIndex); |
| 627 check(_variables, _variableIndex); | 645 check(_variables, _variableIndex); |
| 646 Element element = this.element; |
| 647 if (element is ExecutableElementImpl) { |
| 648 element.labels = _elementHolder.labels; |
| 649 element.localVariables = _elementHolder.localVariables; |
| 650 } |
| 628 } | 651 } |
| 629 | 652 |
| 630 static bool _isNotSynthetic(Element e) => !e.isSynthetic; | 653 static bool _isNotSynthetic(Element e) => !e.isSynthetic; |
| 631 } | 654 } |
| 632 | 655 |
| 633 class _ElementMismatchException extends AnalysisException { | 656 class _ElementMismatchException extends AnalysisException { |
| 634 /** | 657 /** |
| 635 * Creates an exception to refer to the given [compilationUnit], [element], | 658 * Creates an exception to refer to the given [compilationUnit], [element], |
| 636 * and [cause]. | 659 * and [cause]. |
| 637 */ | 660 */ |
| 638 _ElementMismatchException( | 661 _ElementMismatchException( |
| 639 CompilationUnitElement compilationUnit, Element element, | 662 CompilationUnitElement compilationUnit, Element element, |
| 640 [CaughtException cause = null]) | 663 [CaughtException cause = null]) |
| 641 : super('Element mismatch in $compilationUnit at $element', cause); | 664 : super('Element mismatch in $compilationUnit at $element', cause); |
| 642 } | 665 } |
| OLD | NEW |