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 |