Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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.task.strong_mode; | 5 library analyzer.src.task.strong_mode; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/generated/ast.dart'; | 9 import 'package:analyzer/src/generated/ast.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/src/generated/element.dart'; |
| 11 import 'package:analyzer/src/generated/engine.dart'; | |
| 12 import 'package:analyzer/src/generated/java_engine.dart'; | |
| 11 import 'package:analyzer/src/generated/resolver.dart'; | 13 import 'package:analyzer/src/generated/resolver.dart'; |
| 12 import 'package:analyzer/src/generated/utilities_dart.dart'; | 14 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 13 | 15 |
| 14 /** | 16 /** |
| 17 * A function that returns `true` if the given [variable] passes the filter. | |
| 18 */ | |
| 19 typedef bool VariableFilter(VariableElement element); | |
| 20 | |
| 21 /** | |
| 22 * A visitor that will locate the declaration of a specific variable within an | |
| 23 * AST structure. | |
| 24 */ | |
| 25 class DeclarationFinder extends RecursiveAstVisitor { | |
|
Paul Berry
2015/08/27 18:56:07
I'm concerned about the execution speed of this cl
Brian Wilkerson
2015/08/27 20:43:54
Because I didn't think of it. You're right, it wou
| |
| 26 /** | |
| 27 * The element representing the variable whose declaration is to be found. | |
| 28 */ | |
| 29 final VariableElement targetElement; | |
| 30 | |
| 31 /** | |
| 32 * The declaration of the variable, or `null` if the AST structure did not | |
| 33 * contain a declaration of the variable. | |
| 34 */ | |
| 35 VariableDeclaration declaration = null; | |
| 36 | |
| 37 /** | |
| 38 * Initialize a newly created finder to search for the given [targetElement]. | |
| 39 */ | |
| 40 DeclarationFinder(this.targetElement); | |
| 41 | |
| 42 @override | |
| 43 void visitVariableDeclaration(VariableDeclaration node) { | |
| 44 if (node.name.staticElement == targetElement) { | |
| 45 declaration = node; | |
| 46 } | |
|
Paul Berry
2015/08/27 18:56:07
Were you intending to add:
throw new DeclarationF
Brian Wilkerson
2015/08/27 20:43:54
moot
| |
| 47 } | |
| 48 | |
| 49 /** | |
| 50 * Search inside the given AST [node] for the declaration of the variable with | |
| 51 * the given [element]. | |
| 52 */ | |
| 53 static VariableDeclaration find(AstNode node, VariableElement element) { | |
|
Paul Berry
2015/08/27 18:56:08
I'm not comfortable with the way this function is
Brian Wilkerson
2015/08/27 20:43:54
moot
| |
| 54 DeclarationFinder finder = new DeclarationFinder(element); | |
| 55 try { | |
| 56 node.accept(finder); | |
| 57 } on DeclarationFoundException { | |
| 58 // A declaration of the element was found | |
| 59 } catch (exception, stackTrace) { | |
| 60 AnalysisEngine.instance.logger.logInformation( | |
| 61 "Unable to locate declaration of $element", | |
| 62 new CaughtException(exception, stackTrace)); | |
| 63 return null; | |
| 64 } | |
| 65 return finder.declaration; | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 /** | |
| 70 * An exception used by a [DeclarationFinder] to cancel visiting after a | |
| 71 * declaration has been found. | |
| 72 */ | |
| 73 class DeclarationFoundException extends Error {} | |
| 74 | |
| 75 /** | |
| 15 * An object used to find static variables whose types should be inferred and | 76 * An object used to find static variables whose types should be inferred and |
| 16 * classes whose members should have types inferred. Clients are expected to | 77 * classes whose members should have types inferred. Clients are expected to |
| 17 * visit a [CompilationUnit]. | 78 * visit a [CompilationUnit]. |
| 18 */ | 79 */ |
| 19 class InferrenceFinder extends SimpleAstVisitor { | 80 class InferrenceFinder extends SimpleAstVisitor { |
| 20 /** | 81 /** |
| 21 * The static variables that should have types inferred for them. | 82 * The static variables that should have types inferred for them. |
| 22 */ | 83 */ |
| 23 final List<VariableElement> staticVariables = <VariableElement>[]; | 84 final List<VariableElement> staticVariables = <VariableElement>[]; |
| 24 | 85 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 /** | 133 /** |
| 73 * Add all of the [variables] with initializers to the list of variables whose | 134 * Add all of the [variables] with initializers to the list of variables whose |
| 74 * type can be inferred. Technically, we only infer the types of variables | 135 * type can be inferred. Technically, we only infer the types of variables |
| 75 * that do not have a static type, but all variables with initializers | 136 * that do not have a static type, but all variables with initializers |
| 76 * potentially need to be re-resolved after inference because they might | 137 * potentially need to be re-resolved after inference because they might |
| 77 * refer to fields whose type was inferred. | 138 * refer to fields whose type was inferred. |
| 78 */ | 139 */ |
| 79 void _addVariables(NodeList<VariableDeclaration> variables) { | 140 void _addVariables(NodeList<VariableDeclaration> variables) { |
| 80 for (VariableDeclaration variable in variables) { | 141 for (VariableDeclaration variable in variables) { |
| 81 if (variable.initializer != null) { | 142 if (variable.initializer != null) { |
| 82 staticVariables.add(variable.element); | 143 VariableElement element = variable.element; |
| 144 if (element.hasImplicitType) { | |
| 145 staticVariables.add(element); | |
| 146 } | |
| 83 } | 147 } |
| 84 } | 148 } |
| 85 } | 149 } |
| 86 } | 150 } |
| 87 | 151 |
| 88 /** | 152 /** |
| 89 * An object used to infer the type of instance fields and the return types of | 153 * An object used to infer the type of instance fields and the return types of |
| 90 * instance methods within a single compilation unit. | 154 * instance methods within a single compilation unit. |
| 91 */ | 155 */ |
| 92 class InstanceMemberInferrer { | 156 class InstanceMemberInferrer { |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 FunctionType functionType = element.type; | 586 FunctionType functionType = element.type; |
| 523 if (functionType is FunctionTypeImpl) { | 587 if (functionType is FunctionTypeImpl) { |
| 524 element.type = | 588 element.type = |
| 525 new FunctionTypeImpl(element, functionType.prunedTypedefs); | 589 new FunctionTypeImpl(element, functionType.prunedTypedefs); |
| 526 } | 590 } |
| 527 } | 591 } |
| 528 } | 592 } |
| 529 } | 593 } |
| 530 | 594 |
| 531 /** | 595 /** |
| 596 * A visitor that will gather all of the variables referenced within a given | |
| 597 * AST structure. The collection can be restricted to contain only those | |
| 598 * variables that pass a specified filter. | |
| 599 */ | |
| 600 class VariableGatherer extends RecursiveAstVisitor { | |
| 601 /** | |
| 602 * The filter used to limit which variables are gathered, or `null` if no | |
| 603 * filtering is to be performed. | |
| 604 */ | |
| 605 final VariableFilter filter; | |
| 606 | |
| 607 /** | |
| 608 * The variables that were found. | |
| 609 */ | |
| 610 final Set<VariableElement> results = new HashSet<VariableElement>(); | |
| 611 | |
| 612 /** | |
| 613 * Initialize a newly created gatherer to gather all of the variables that | |
| 614 * pass the given [filter] (or all variables if no filter is provided). | |
| 615 */ | |
| 616 VariableGatherer([this.filter = null]); | |
| 617 | |
| 618 @override | |
| 619 void visitSimpleIdentifier(SimpleIdentifier node) { | |
| 620 if (!node.inDeclarationContext()) { | |
| 621 Element element = node.staticElement; | |
| 622 if (element is PropertyAccessorElement && element.isSynthetic) { | |
| 623 element = (element as PropertyAccessorElement).variable; | |
| 624 } | |
| 625 if (element is VariableElement && (filter == null || filter(element))) { | |
| 626 results.add(element); | |
| 627 } | |
| 628 } | |
| 629 } | |
| 630 } | |
| 631 | |
| 632 /** | |
| 532 * A class of exception that is not used anywhere else. | 633 * A class of exception that is not used anywhere else. |
| 533 */ | 634 */ |
| 534 class _CycleException implements Exception {} | 635 class _CycleException implements Exception {} |
| OLD | NEW |