| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |