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 |