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

Side by Side Diff: pkg/analyzer/lib/src/generated/constant.dart

Issue 1131953004: Create a task in the new task model to compute constant dependencies. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 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 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine.constant; 8 library engine.constant;
9 9
10 import 'dart:collection'; 10 import 'dart:collection';
11 11
12 import 'package:analyzer/src/generated/utilities_general.dart'; 12 import 'package:analyzer/src/generated/utilities_general.dart';
13 13
14 import 'ast.dart'; 14 import 'ast.dart';
15 import 'element.dart'; 15 import 'element.dart';
16 import 'engine.dart' show AnalysisEngine, RecordingErrorListener; 16 import 'engine.dart' show AnalysisEngine, RecordingErrorListener;
17 import 'error.dart'; 17 import 'error.dart';
18 import 'java_core.dart'; 18 import 'java_core.dart';
19 import 'resolver.dart' show TypeProvider; 19 import 'resolver.dart' show TypeProvider;
20 import 'scanner.dart' show Token, TokenType; 20 import 'scanner.dart' show Token, TokenType;
21 import 'source.dart' show Source; 21 import 'source.dart' show Source;
22 import 'utilities_collection.dart'; 22 import 'utilities_collection.dart';
23 import 'utilities_dart.dart' show ParameterKind; 23 import 'utilities_dart.dart' show ParameterKind;
24 24
25 /** 25 /**
26 * Callback used by [ReferenceFinder] to report that a dependency was found.
27 */
28 typedef void ReferenceFinderCallback(Element dependency);
29
30 /**
26 * The state of an object representing a boolean value. 31 * The state of an object representing a boolean value.
27 */ 32 */
28 class BoolState extends InstanceState { 33 class BoolState extends InstanceState {
29 /** 34 /**
30 * An instance representing the boolean value 'false'. 35 * An instance representing the boolean value 'false'.
31 */ 36 */
32 static BoolState FALSE_STATE = new BoolState(false); 37 static BoolState FALSE_STATE = new BoolState(false);
33 38
34 /** 39 /**
35 * An instance representing the boolean value 'true'. 40 * An instance representing the boolean value 'true'.
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 SuperConstructorInvocation visitSuperConstructorInvocation( 184 SuperConstructorInvocation visitSuperConstructorInvocation(
180 SuperConstructorInvocation node) { 185 SuperConstructorInvocation node) {
181 SuperConstructorInvocation invocation = 186 SuperConstructorInvocation invocation =
182 super.visitSuperConstructorInvocation(node); 187 super.visitSuperConstructorInvocation(node);
183 invocation.staticElement = node.staticElement; 188 invocation.staticElement = node.staticElement;
184 return invocation; 189 return invocation;
185 } 190 }
186 } 191 }
187 192
188 /** 193 /**
189 * Helper class encapsulating the methods for evaluating constant instance 194 * Helper class encapsulating the methods for evaluating constants and
190 * constant instance creation expressions. 195 * constant instance creation expressions.
191 */ 196 */
192 class ConstantEvaluationEngine { 197 class ConstantEvaluationEngine {
193 /** 198 /**
194 * Parameter to "fromEnvironment" methods that denotes the default value. 199 * Parameter to "fromEnvironment" methods that denotes the default value.
195 */ 200 */
196 static String _DEFAULT_VALUE_PARAM = "defaultValue"; 201 static String _DEFAULT_VALUE_PARAM = "defaultValue";
197 202
198 /** 203 /**
199 * Source of RegExp matching any public identifier. 204 * Source of RegExp matching any public identifier.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 return false; 301 return false;
297 } 302 }
298 if (!identical(argumentValues[0].type, typeProvider.stringType)) { 303 if (!identical(argumentValues[0].type, typeProvider.stringType)) {
299 return false; 304 return false;
300 } 305 }
301 String name = argumentValues[0].stringValue; 306 String name = argumentValues[0].stringValue;
302 return isValidPublicSymbol(name); 307 return isValidPublicSymbol(name);
303 } 308 }
304 309
305 /** 310 /**
311 * Determine which constant elements need to have their values computed
312 * prior to computing the value of [element], and report them using
313 * [callback].
314 */
315 void computeDependencies(Element element, ReferenceFinderCallback callback) {
316 ReferenceFinder referenceFinder = new ReferenceFinder(callback);
317 if (element is ParameterElement) {
318 if (element.initializer != null) {
319 Expression defaultValue =
320 (element as ConstVariableElement).constantInitializer;
321 if (defaultValue != null) {
322 defaultValue.accept(referenceFinder);
323 }
324 }
325 } else if (element is PotentiallyConstVariableElement) {
326 element.constantInitializer.accept(referenceFinder);
327 } else if (element is ConstructorElementImpl) {
328 element.isCycleFree = false;
329 ConstructorElement redirectedConstructor =
330 getConstRedirectedConstructor(element);
331 if (redirectedConstructor != null) {
332 ConstructorElement redirectedConstructorBase =
333 ConstantEvaluationEngine._getConstructorBase(redirectedConstructor);
334 callback(redirectedConstructorBase);
335 return;
336 }
337 bool superInvocationFound = false;
338 List<ConstructorInitializer> initializers = element.constantInitializers;
339 for (ConstructorInitializer initializer in initializers) {
340 if (initializer is SuperConstructorInvocation) {
341 superInvocationFound = true;
342 }
343 initializer.accept(referenceFinder);
344 }
345 if (!superInvocationFound) {
346 // No explicit superconstructor invocation found, so we need to
347 // manually insert a reference to the implicit superconstructor.
348 InterfaceType superclass =
349 (element.returnType as InterfaceType).superclass;
350 if (superclass != null && !superclass.isObject) {
351 ConstructorElement unnamedConstructor = ConstantEvaluationEngine
352 ._getConstructorBase(superclass.element.unnamedConstructor);
353 if (unnamedConstructor != null) {
354 callback(unnamedConstructor);
355 }
356 }
357 }
358 for (FieldElement field in element.enclosingElement.fields) {
359 // Note: non-static const isn't allowed but we handle it anyway so that
360 // we won't be confused by incorrect code.
361 if ((field.isFinal || field.isConst) &&
362 !field.isStatic &&
363 field.initializer != null) {
364 callback(field);
365 }
366 }
367 for (ParameterElement parameterElement in element.parameters) {
368 callback(parameterElement);
369 }
370 } else {
371 // Should not happen.
372 assert(false);
373 AnalysisEngine.instance.logger.logError(
374 "Constant value computer trying to compute the value of a node of type ${element.runtimeType}");
375 }
376 }
377
378 /**
306 * Evaluate a call to fromEnvironment() on the bool, int, or String class. The 379 * Evaluate a call to fromEnvironment() on the bool, int, or String class. The
307 * [environmentValue] is the value fetched from the environment. The 380 * [environmentValue] is the value fetched from the environment. The
308 * [builtInDefaultValue] is the value that should be used as the default if no 381 * [builtInDefaultValue] is the value that should be used as the default if no
309 * "defaultValue" argument appears in [namedArgumentValues]. The 382 * "defaultValue" argument appears in [namedArgumentValues]. The
310 * [namedArgumentValues] are the values of the named parameters passed to 383 * [namedArgumentValues] are the values of the named parameters passed to
311 * fromEnvironment(). Return a [DartObjectImpl] object corresponding to the 384 * fromEnvironment(). Return a [DartObjectImpl] object corresponding to the
312 * evaluated result. 385 * evaluated result.
313 */ 386 */
314 DartObjectImpl computeValueFromEnvironment(DartObject environmentValue, 387 DartObjectImpl computeValueFromEnvironment(DartObject environmentValue,
315 DartObjectImpl builtInDefaultValue, 388 DartObjectImpl builtInDefaultValue,
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 1071
999 /** 1072 /**
1000 * Compute values for all of the constants in the compilation units that were 1073 * Compute values for all of the constants in the compilation units that were
1001 * added. 1074 * added.
1002 */ 1075 */
1003 void computeValues() { 1076 void computeValues() {
1004 _constantsToCompute = _constantFinder.constantsToCompute; 1077 _constantsToCompute = _constantFinder.constantsToCompute;
1005 _annotations = _constantFinder.annotations; 1078 _annotations = _constantFinder.annotations;
1006 for (Element element in _constantsToCompute) { 1079 for (Element element in _constantsToCompute) {
1007 referenceGraph.addNode(element); 1080 referenceGraph.addNode(element);
1008 if (element is ParameterElement) { 1081 evaluationEngine.computeDependencies(element, (Element dependency) {
1009 if (element.initializer != null) { 1082 referenceGraph.addEdge(element, dependency);
1010 Expression defaultValue = 1083 });
1011 (element as ConstVariableElement).constantInitializer;
1012 if (defaultValue != null) {
1013 ReferenceFinder parameterReferenceFinder =
1014 new ReferenceFinder(element, referenceGraph);
1015 defaultValue.accept(parameterReferenceFinder);
1016 }
1017 }
1018 } else if (element is PotentiallyConstVariableElement) {
1019 ReferenceFinder referenceFinder =
1020 new ReferenceFinder(element, referenceGraph);
1021 element.constantInitializer.accept(referenceFinder);
1022 } else if (element is ConstructorElementImpl) {
1023 element.isCycleFree = false;
1024 ConstructorElement redirectedConstructor =
1025 evaluationEngine.getConstRedirectedConstructor(element);
1026 if (redirectedConstructor != null) {
1027 ConstructorElement redirectedConstructorBase =
1028 ConstantEvaluationEngine
1029 ._getConstructorBase(redirectedConstructor);
1030 referenceGraph.addEdge(element, redirectedConstructorBase);
1031 continue;
1032 }
1033 ReferenceFinder referenceFinder =
1034 new ReferenceFinder(element, referenceGraph);
1035 bool superInvocationFound = false;
1036 List<ConstructorInitializer> initializers =
1037 element.constantInitializers;
1038 for (ConstructorInitializer initializer in initializers) {
1039 if (initializer is SuperConstructorInvocation) {
1040 superInvocationFound = true;
1041 }
1042 initializer.accept(referenceFinder);
1043 }
1044 if (!superInvocationFound) {
1045 // No explicit superconstructor invocation found, so we need to
1046 // manually insert a reference to the implicit superconstructor.
1047 InterfaceType superclass =
1048 (element.returnType as InterfaceType).superclass;
1049 if (superclass != null && !superclass.isObject) {
1050 ConstructorElement unnamedConstructor = ConstantEvaluationEngine
1051 ._getConstructorBase(superclass.element.unnamedConstructor);
1052 if (unnamedConstructor != null) {
1053 referenceGraph.addEdge(element, unnamedConstructor);
1054 }
1055 }
1056 }
1057 for (FieldElement field in element.enclosingElement.fields) {
1058 // Note: non-static const isn't allowed but we handle it anyway so tha t
1059 // we won't be confused by incorrect code.
1060 if ((field.isFinal || field.isConst) &&
1061 !field.isStatic &&
1062 field.initializer != null) {
1063 referenceGraph.addEdge(element, field);
1064 }
1065 }
1066 for (ParameterElement parameterElement in element.parameters) {
1067 referenceGraph.addEdge(element, parameterElement);
1068 }
1069 } else {
1070 // Should not happen.
1071 assert(false);
1072 AnalysisEngine.instance.logger.logError(
1073 "Constant value computer trying to compute the value of a node of ty pe ${element.runtimeType}");
1074 }
1075 } 1084 }
1076 List<List<Element>> topologicalSort = 1085 List<List<Element>> topologicalSort =
1077 referenceGraph.computeTopologicalSort(); 1086 referenceGraph.computeTopologicalSort();
1078 for (List<Element> constantsInCycle in topologicalSort) { 1087 for (List<Element> constantsInCycle in topologicalSort) {
1079 if (constantsInCycle.length == 1) { 1088 if (constantsInCycle.length == 1) {
1080 _computeValueFor(constantsInCycle[0]); 1089 _computeValueFor(constantsInCycle[0]);
1081 } else { 1090 } else {
1082 for (Element constant in constantsInCycle) { 1091 for (Element constant in constantsInCycle) {
1083 _generateCycleError(constantsInCycle, constant); 1092 _generateCycleError(constantsInCycle, constant);
1084 } 1093 }
(...skipping 3773 matching lines...) Expand 10 before | Expand all | Expand 10 after
4858 @override 4867 @override
4859 String toString() => "-unknown-"; 4868 String toString() => "-unknown-";
4860 } 4869 }
4861 4870
4862 /** 4871 /**
4863 * An object used to add reference information for a given variable to the 4872 * An object used to add reference information for a given variable to the
4864 * bi-directional mapping used to order the evaluation of constants. 4873 * bi-directional mapping used to order the evaluation of constants.
4865 */ 4874 */
4866 class ReferenceFinder extends RecursiveAstVisitor<Object> { 4875 class ReferenceFinder extends RecursiveAstVisitor<Object> {
4867 /** 4876 /**
4868 * The element representing the construct that will be visited. 4877 * The callback which should be used to report any dependencies that were
4878 * found.
4869 */ 4879 */
4870 final Element _source; 4880 final ReferenceFinderCallback _callback;
4871
4872 /**
4873 * A graph in which the nodes are the constant variables and the edges are
4874 * from each variable to the other constant variables that are referenced in
4875 * the head's initializer.
4876 */
4877 final DirectedGraph<Element> _referenceGraph;
4878 4881
4879 /** 4882 /**
4880 * Initialize a newly created reference finder to find references from a given 4883 * Initialize a newly created reference finder to find references from a given
4881 * variable to other variables and to add those references to the given graph. 4884 * variable to other variables and to add those references to the given graph.
4882 * The [source] is the element representing the variable whose initializer 4885 * The [_callback] will be invoked for every dependency found.
4883 * will be visited. The [referenceGraph] is a graph recording which variables
4884 * (heads) reference which other variables (tails) in their initializers.
4885 */ 4886 */
4886 ReferenceFinder(this._source, this._referenceGraph); 4887 ReferenceFinder(this._callback);
4887 4888
4888 @override 4889 @override
4889 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 4890 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
4890 if (node.isConst) { 4891 if (node.isConst) {
4891 ConstructorElement constructor = 4892 ConstructorElement constructor =
4892 ConstantEvaluationEngine._getConstructorBase(node.staticElement); 4893 ConstantEvaluationEngine._getConstructorBase(node.staticElement);
4893 if (constructor != null) { 4894 if (constructor != null) {
4894 _referenceGraph.addEdge(_source, constructor); 4895 _callback(constructor);
4895 } 4896 }
4896 } 4897 }
4897 return super.visitInstanceCreationExpression(node); 4898 return super.visitInstanceCreationExpression(node);
4898 } 4899 }
4899 4900
4900 @override 4901 @override
4901 Object visitRedirectingConstructorInvocation( 4902 Object visitRedirectingConstructorInvocation(
4902 RedirectingConstructorInvocation node) { 4903 RedirectingConstructorInvocation node) {
4903 super.visitRedirectingConstructorInvocation(node); 4904 super.visitRedirectingConstructorInvocation(node);
4904 ConstructorElement target = 4905 ConstructorElement target =
4905 ConstantEvaluationEngine._getConstructorBase(node.staticElement); 4906 ConstantEvaluationEngine._getConstructorBase(node.staticElement);
4906 if (target != null && target.isConst) { 4907 if (target != null && target.isConst) {
4907 _referenceGraph.addEdge(_source, target); 4908 _callback(target);
4908 } 4909 }
4909 return null; 4910 return null;
4910 } 4911 }
4911 4912
4912 @override 4913 @override
4913 Object visitSimpleIdentifier(SimpleIdentifier node) { 4914 Object visitSimpleIdentifier(SimpleIdentifier node) {
4914 Element element = node.staticElement; 4915 Element element = node.staticElement;
4915 if (element is PropertyAccessorElement) { 4916 if (element is PropertyAccessorElement) {
4916 element = (element as PropertyAccessorElement).variable; 4917 element = (element as PropertyAccessorElement).variable;
4917 } 4918 }
4918 if (element is VariableElement) { 4919 if (element is VariableElement) {
4919 if (element.isConst) { 4920 if (element.isConst) {
4920 _referenceGraph.addEdge(_source, element); 4921 _callback(element);
4921 } 4922 }
4922 } 4923 }
4923 return null; 4924 return null;
4924 } 4925 }
4925 4926
4926 @override 4927 @override
4927 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { 4928 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
4928 super.visitSuperConstructorInvocation(node); 4929 super.visitSuperConstructorInvocation(node);
4929 ConstructorElement constructor = 4930 ConstructorElement constructor =
4930 ConstantEvaluationEngine._getConstructorBase(node.staticElement); 4931 ConstantEvaluationEngine._getConstructorBase(node.staticElement);
4931 if (constructor != null && constructor.isConst) { 4932 if (constructor != null && constructor.isConst) {
4932 _referenceGraph.addEdge(_source, constructor); 4933 _callback(constructor);
4933 } 4934 }
4934 return null; 4935 return null;
4935 } 4936 }
4936 } 4937 }
4937 4938
4938 /** 4939 /**
4939 * The state of an object representing a string. 4940 * The state of an object representing a string.
4940 */ 4941 */
4941 class StringState extends InstanceState { 4942 class StringState extends InstanceState {
4942 /** 4943 /**
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
5144 return BoolState.from(_element == rightElement); 5145 return BoolState.from(_element == rightElement);
5145 } else if (rightOperand is DynamicState) { 5146 } else if (rightOperand is DynamicState) {
5146 return BoolState.UNKNOWN_VALUE; 5147 return BoolState.UNKNOWN_VALUE;
5147 } 5148 }
5148 return BoolState.FALSE_STATE; 5149 return BoolState.FALSE_STATE;
5149 } 5150 }
5150 5151
5151 @override 5152 @override
5152 String toString() => _element == null ? "-unknown-" : _element.name; 5153 String toString() => _element == null ? "-unknown-" : _element.name;
5153 } 5154 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/plugin/engine_plugin.dart » ('j') | pkg/analyzer/lib/src/task/dart.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698