Chromium Code Reviews| Index: pkg/analyzer/lib/src/task/strong_mode.dart |
| diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart |
| index 823319893f36c3e1831fe4786ed144c8a8f823e0..728a45fe16efc6494dda2ca9cab85cd44c24cb18 100644 |
| --- a/pkg/analyzer/lib/src/task/strong_mode.dart |
| +++ b/pkg/analyzer/lib/src/task/strong_mode.dart |
| @@ -8,10 +8,71 @@ import 'dart:collection'; |
| import 'package:analyzer/src/generated/ast.dart'; |
| import 'package:analyzer/src/generated/element.dart'; |
| +import 'package:analyzer/src/generated/engine.dart'; |
| +import 'package:analyzer/src/generated/java_engine.dart'; |
| import 'package:analyzer/src/generated/resolver.dart'; |
| import 'package:analyzer/src/generated/utilities_dart.dart'; |
| /** |
| + * A function that returns `true` if the given [variable] passes the filter. |
| + */ |
| +typedef bool VariableFilter(VariableElement element); |
| + |
| +/** |
| + * A visitor that will locate the declaration of a specific variable within an |
| + * AST structure. |
| + */ |
| +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
|
| + /** |
| + * The element representing the variable whose declaration is to be found. |
| + */ |
| + final VariableElement targetElement; |
| + |
| + /** |
| + * The declaration of the variable, or `null` if the AST structure did not |
| + * contain a declaration of the variable. |
| + */ |
| + VariableDeclaration declaration = null; |
| + |
| + /** |
| + * Initialize a newly created finder to search for the given [targetElement]. |
| + */ |
| + DeclarationFinder(this.targetElement); |
| + |
| + @override |
| + void visitVariableDeclaration(VariableDeclaration node) { |
| + if (node.name.staticElement == targetElement) { |
| + declaration = node; |
| + } |
|
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
|
| + } |
| + |
| + /** |
| + * Search inside the given AST [node] for the declaration of the variable with |
| + * the given [element]. |
| + */ |
| + 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
|
| + DeclarationFinder finder = new DeclarationFinder(element); |
| + try { |
| + node.accept(finder); |
| + } on DeclarationFoundException { |
| + // A declaration of the element was found |
| + } catch (exception, stackTrace) { |
| + AnalysisEngine.instance.logger.logInformation( |
| + "Unable to locate declaration of $element", |
| + new CaughtException(exception, stackTrace)); |
| + return null; |
| + } |
| + return finder.declaration; |
| + } |
| +} |
| + |
| +/** |
| + * An exception used by a [DeclarationFinder] to cancel visiting after a |
| + * declaration has been found. |
| + */ |
| +class DeclarationFoundException extends Error {} |
| + |
| +/** |
| * An object used to find static variables whose types should be inferred and |
| * classes whose members should have types inferred. Clients are expected to |
| * visit a [CompilationUnit]. |
| @@ -79,7 +140,10 @@ class InferrenceFinder extends SimpleAstVisitor { |
| void _addVariables(NodeList<VariableDeclaration> variables) { |
| for (VariableDeclaration variable in variables) { |
| if (variable.initializer != null) { |
| - staticVariables.add(variable.element); |
| + VariableElement element = variable.element; |
| + if (element.hasImplicitType) { |
| + staticVariables.add(element); |
| + } |
| } |
| } |
| } |
| @@ -529,6 +593,43 @@ class InstanceMemberInferrer { |
| } |
| /** |
| + * A visitor that will gather all of the variables referenced within a given |
| + * AST structure. The collection can be restricted to contain only those |
| + * variables that pass a specified filter. |
| + */ |
| +class VariableGatherer extends RecursiveAstVisitor { |
| + /** |
| + * The filter used to limit which variables are gathered, or `null` if no |
| + * filtering is to be performed. |
| + */ |
| + final VariableFilter filter; |
| + |
| + /** |
| + * The variables that were found. |
| + */ |
| + final Set<VariableElement> results = new HashSet<VariableElement>(); |
| + |
| + /** |
| + * Initialize a newly created gatherer to gather all of the variables that |
| + * pass the given [filter] (or all variables if no filter is provided). |
| + */ |
| + VariableGatherer([this.filter = null]); |
| + |
| + @override |
| + void visitSimpleIdentifier(SimpleIdentifier node) { |
| + if (!node.inDeclarationContext()) { |
| + Element element = node.staticElement; |
| + if (element is PropertyAccessorElement && element.isSynthetic) { |
| + element = (element as PropertyAccessorElement).variable; |
| + } |
| + if (element is VariableElement && (filter == null || filter(element))) { |
| + results.add(element); |
| + } |
| + } |
| + } |
| +} |
| + |
| +/** |
| * A class of exception that is not used anywhere else. |
| */ |
| class _CycleException implements Exception {} |