Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: packages/analyzer/lib/src/dart/constant/utilities.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
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.
4
5 library analyzer.src.dart.constant.utilities;
6
7 import 'dart:collection';
8
9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/visitor.dart';
11 import 'package:analyzer/dart/element/element.dart';
12 import 'package:analyzer/src/dart/ast/utilities.dart';
13 import 'package:analyzer/src/dart/element/element.dart';
14 import 'package:analyzer/src/dart/element/handle.dart'
15 show ConstructorElementHandle;
16 import 'package:analyzer/src/dart/element/member.dart';
17 import 'package:analyzer/src/task/dart.dart';
18
19 ConstructorElementImpl getConstructorImpl(ConstructorElement constructor) {
20 while (constructor is ConstructorMember) {
21 constructor = (constructor as ConstructorMember).baseElement;
22 }
23 if (constructor is ConstructorElementHandle) {
24 constructor = (constructor as ConstructorElementHandle).actualElement;
25 }
26 return constructor;
27 }
28
29 /**
30 * Callback used by [ReferenceFinder] to report that a dependency was found.
31 */
32 typedef void ReferenceFinderCallback(ConstantEvaluationTarget dependency);
33
34 /**
35 * An [AstCloner] that copies the necessary information from the AST to allow
36 * constants to be evaluated.
37 */
38 class ConstantAstCloner extends AstCloner {
39 ConstantAstCloner() : super(true);
40
41 @override
42 ConstructorName visitConstructorName(ConstructorName node) {
43 ConstructorName name = super.visitConstructorName(node);
44 name.staticElement = node.staticElement;
45 return name;
46 }
47
48 @override
49 Annotation visitAnnotation(Annotation node) {
50 Annotation annotation = super.visitAnnotation(node);
51 annotation.element = node.element;
52 return annotation;
53 }
54
55 @override
56 FunctionExpression visitFunctionExpression(FunctionExpression node) {
57 FunctionExpression expression = super.visitFunctionExpression(node);
58 expression.element = node.element;
59 return expression;
60 }
61
62 @override
63 InstanceCreationExpression visitInstanceCreationExpression(
64 InstanceCreationExpression node) {
65 InstanceCreationExpression expression =
66 super.visitInstanceCreationExpression(node);
67 expression.staticElement = node.staticElement;
68 return expression;
69 }
70
71 @override
72 RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
73 RedirectingConstructorInvocation node) {
74 RedirectingConstructorInvocation invocation =
75 super.visitRedirectingConstructorInvocation(node);
76 invocation.staticElement = node.staticElement;
77 return invocation;
78 }
79
80 @override
81 SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
82 SimpleIdentifier identifier = super.visitSimpleIdentifier(node);
83 identifier.staticElement = node.staticElement;
84 return identifier;
85 }
86
87 @override
88 SuperConstructorInvocation visitSuperConstructorInvocation(
89 SuperConstructorInvocation node) {
90 SuperConstructorInvocation invocation =
91 super.visitSuperConstructorInvocation(node);
92 invocation.staticElement = node.staticElement;
93 return invocation;
94 }
95
96 @override
97 TypeName visitTypeName(TypeName node) {
98 TypeName typeName = super.visitTypeName(node);
99 typeName.type = node.type;
100 return typeName;
101 }
102 }
103
104 /**
105 * A visitor used to traverse the AST structures of all of the compilation units
106 * being resolved and build the full set of dependencies for all constant
107 * expressions.
108 */
109 class ConstantExpressionsDependenciesFinder extends RecursiveAstVisitor {
110 /**
111 * The constants whose values need to be computed.
112 */
113 HashSet<ConstantEvaluationTarget> dependencies =
114 new HashSet<ConstantEvaluationTarget>();
115
116 @override
117 void visitInstanceCreationExpression(InstanceCreationExpression node) {
118 if (node.isConst) {
119 _find(node);
120 } else {
121 super.visitInstanceCreationExpression(node);
122 }
123 }
124
125 @override
126 void visitListLiteral(ListLiteral node) {
127 if (node.constKeyword != null) {
128 _find(node);
129 } else {
130 super.visitListLiteral(node);
131 }
132 }
133
134 @override
135 void visitMapLiteral(MapLiteral node) {
136 if (node.constKeyword != null) {
137 _find(node);
138 } else {
139 super.visitMapLiteral(node);
140 }
141 }
142
143 @override
144 void visitSwitchCase(SwitchCase node) {
145 _find(node.expression);
146 node.statements.accept(this);
147 }
148
149 void _find(Expression node) {
150 if (node != null) {
151 ReferenceFinder referenceFinder = new ReferenceFinder(dependencies.add);
152 node.accept(referenceFinder);
153 }
154 }
155 }
156
157 /**
158 * A visitor used to traverse the AST structures of all of the compilation units
159 * being resolved and build tables of the constant variables, constant
160 * constructors, constant constructor invocations, and annotations found in
161 * those compilation units.
162 */
163 class ConstantFinder extends RecursiveAstVisitor<Object> {
164 /**
165 * The elements and AST nodes whose constant values need to be computed.
166 */
167 List<ConstantEvaluationTarget> constantsToCompute =
168 <ConstantEvaluationTarget>[];
169
170 /**
171 * A flag indicating whether instance variables marked as "final" should be
172 * treated as "const".
173 */
174 bool treatFinalInstanceVarAsConst = false;
175
176 @override
177 Object visitAnnotation(Annotation node) {
178 super.visitAnnotation(node);
179 ElementAnnotation elementAnnotation = node.elementAnnotation;
180 if (elementAnnotation == null) {
181 // Analyzer ignores annotations on "part of" directives and on enum
182 // constant declarations.
183 assert(node.parent is PartOfDirective ||
184 node.parent is EnumConstantDeclaration);
185 } else {
186 constantsToCompute.add(elementAnnotation);
187 }
188 return null;
189 }
190
191 @override
192 Object visitClassDeclaration(ClassDeclaration node) {
193 bool prevTreatFinalInstanceVarAsConst = treatFinalInstanceVarAsConst;
194 if (node.element.constructors.any((ConstructorElement e) => e.isConst)) {
195 // Instance vars marked "final" need to be included in the dependency
196 // graph, since constant constructors implicitly use the values in their
197 // initializers.
198 treatFinalInstanceVarAsConst = true;
199 }
200 try {
201 return super.visitClassDeclaration(node);
202 } finally {
203 treatFinalInstanceVarAsConst = prevTreatFinalInstanceVarAsConst;
204 }
205 }
206
207 @override
208 Object visitConstructorDeclaration(ConstructorDeclaration node) {
209 super.visitConstructorDeclaration(node);
210 if (node.constKeyword != null) {
211 ConstructorElement element = node.element;
212 if (element != null) {
213 constantsToCompute.add(element);
214 constantsToCompute.addAll(element.parameters);
215 }
216 }
217 return null;
218 }
219
220 @override
221 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
222 super.visitDefaultFormalParameter(node);
223 Expression defaultValue = node.defaultValue;
224 if (defaultValue != null && node.element != null) {
225 constantsToCompute.add(node.element);
226 }
227 return null;
228 }
229
230 @override
231 Object visitVariableDeclaration(VariableDeclaration node) {
232 super.visitVariableDeclaration(node);
233 Expression initializer = node.initializer;
234 VariableElement element = node.element;
235 if (initializer != null &&
236 (node.isConst ||
237 treatFinalInstanceVarAsConst &&
238 element is FieldElement &&
239 node.isFinal &&
240 !element.isStatic)) {
241 if (element != null) {
242 constantsToCompute.add(element);
243 }
244 }
245 return null;
246 }
247 }
248
249 /**
250 * An object used to add reference information for a given variable to the
251 * bi-directional mapping used to order the evaluation of constants.
252 */
253 class ReferenceFinder extends RecursiveAstVisitor<Object> {
254 /**
255 * The callback which should be used to report any dependencies that were
256 * found.
257 */
258 final ReferenceFinderCallback _callback;
259
260 /**
261 * Initialize a newly created reference finder to find references from a given
262 * variable to other variables and to add those references to the given graph.
263 * The [_callback] will be invoked for every dependency found.
264 */
265 ReferenceFinder(this._callback);
266
267 @override
268 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
269 if (node.isConst) {
270 ConstructorElement constructor = getConstructorImpl(node.staticElement);
271 if (constructor != null) {
272 _callback(constructor);
273 }
274 }
275 return super.visitInstanceCreationExpression(node);
276 }
277
278 @override
279 Object visitLabel(Label node) {
280 // We are visiting the "label" part of a named expression in a function
281 // call (presumably a constructor call), e.g. "const C(label: ...)". We
282 // don't want to visit the SimpleIdentifier for the label because that's a
283 // reference to a function parameter that needs to be filled in; it's not a
284 // constant whose value we depend on.
285 return null;
286 }
287
288 @override
289 Object visitRedirectingConstructorInvocation(
290 RedirectingConstructorInvocation node) {
291 super.visitRedirectingConstructorInvocation(node);
292 ConstructorElement target = getConstructorImpl(node.staticElement);
293 if (target != null) {
294 _callback(target);
295 }
296 return null;
297 }
298
299 @override
300 Object visitSimpleIdentifier(SimpleIdentifier node) {
301 Element staticElement = node.staticElement;
302 Element element = staticElement is PropertyAccessorElement
303 ? staticElement.variable
304 : staticElement;
305 if (element is VariableElement && element.isConst) {
306 _callback(element);
307 }
308 return null;
309 }
310
311 @override
312 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
313 super.visitSuperConstructorInvocation(node);
314 ConstructorElement constructor = getConstructorImpl(node.staticElement);
315 if (constructor != null) {
316 _callback(constructor);
317 }
318 return null;
319 }
320 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/dart/constant/evaluation.dart ('k') | packages/analyzer/lib/src/dart/constant/value.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698