| 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'; |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 definingClass, new SymbolState(argumentValue)); | 421 definingClass, new SymbolState(argumentValue)); |
| 422 } | 422 } |
| 423 // Either it's an external const factory constructor that we can't | 423 // Either it's an external const factory constructor that we can't |
| 424 // emulate, or an error occurred (a cycle, or a const constructor trying | 424 // emulate, or an error occurred (a cycle, or a const constructor trying |
| 425 // to delegate to a non-const constructor). | 425 // to delegate to a non-const constructor). |
| 426 // In the former case, the best we can do is consider it an unknown value. | 426 // In the former case, the best we can do is consider it an unknown value. |
| 427 // In the latter case, the error has already been reported, so considering | 427 // In the latter case, the error has already been reported, so considering |
| 428 // it an unknown value will suppress further errors. | 428 // it an unknown value will suppress further errors. |
| 429 return new DartObjectImpl.validWithUnknownValue(definingClass); | 429 return new DartObjectImpl.validWithUnknownValue(definingClass); |
| 430 } | 430 } |
| 431 validator.beforeGetConstantInitializers(constructor); | |
| 432 ConstructorElementImpl constructorBase = _getConstructorBase(constructor); | 431 ConstructorElementImpl constructorBase = _getConstructorBase(constructor); |
| 432 validator.beforeGetConstantInitializers(constructorBase); |
| 433 List<ConstructorInitializer> initializers = | 433 List<ConstructorInitializer> initializers = |
| 434 constructorBase.constantInitializers; | 434 constructorBase.constantInitializers; |
| 435 if (initializers == null) { | 435 if (initializers == null) { |
| 436 // This can happen in some cases where there are compile errors in the | 436 // This can happen in some cases where there are compile errors in the |
| 437 // code being analyzed (for example if the code is trying to create a | 437 // code being analyzed (for example if the code is trying to create a |
| 438 // const instance using a non-const constructor, or the node we're | 438 // const instance using a non-const constructor, or the node we're |
| 439 // visiting is involved in a cycle). The error has already been reported, | 439 // visiting is involved in a cycle). The error has already been reported, |
| 440 // so consider it an unknown value to suppress further errors. | 440 // so consider it an unknown value to suppress further errors. |
| 441 return new DartObjectImpl.validWithUnknownValue(definingClass); | 441 return new DartObjectImpl.validWithUnknownValue(definingClass); |
| 442 } | 442 } |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 } | 695 } |
| 696 } | 696 } |
| 697 | 697 |
| 698 /** | 698 /** |
| 699 * Interface used by unit tests to verify correct dependency analysis during | 699 * Interface used by unit tests to verify correct dependency analysis during |
| 700 * constant evaluation. | 700 * constant evaluation. |
| 701 */ | 701 */ |
| 702 abstract class ConstantEvaluationValidator { | 702 abstract class ConstantEvaluationValidator { |
| 703 /** | 703 /** |
| 704 * This method is called just before computing the constant value associated | 704 * This method is called just before computing the constant value associated |
| 705 * with [constNode]. Unit tests will override this method to introduce | 705 * with [element]. Unit tests will override this method to introduce |
| 706 * additional error checking. | 706 * additional error checking. |
| 707 */ | 707 */ |
| 708 void beforeComputeValue(AstNode constNode); | 708 void beforeComputeValue(Element element); |
| 709 | 709 |
| 710 /** | 710 /** |
| 711 * This method is called just before getting the constant initializers | 711 * This method is called just before getting the constant initializers |
| 712 * associated with the [constructor]. Unit tests will override this method to | 712 * associated with the [constructor]. Unit tests will override this method to |
| 713 * introduce additional error checking. | 713 * introduce additional error checking. |
| 714 */ | 714 */ |
| 715 void beforeGetConstantInitializers(ConstructorElement constructor); | 715 void beforeGetConstantInitializers(ConstructorElement constructor); |
| 716 | 716 |
| 717 /** | 717 /** |
| 718 * This method is called just before retrieving an evaluation result from an | 718 * This method is called just before retrieving an evaluation result from an |
| 719 * AST node. Unit tests will override it to introduce additional error | 719 * element. Unit tests will override it to introduce additional error |
| 720 * checking. | 720 * checking. |
| 721 */ | 721 */ |
| 722 void beforeGetEvaluationResult(AstNode node); | 722 void beforeGetEvaluationResult(Element element); |
| 723 | 723 |
| 724 /** | 724 /** |
| 725 * This method is called just before getting the constant value of a field | 725 * This method is called just before getting the constant value of a field |
| 726 * with an initializer. Unit tests will override this method to introduce | 726 * with an initializer. Unit tests will override this method to introduce |
| 727 * additional error checking. | 727 * additional error checking. |
| 728 */ | 728 */ |
| 729 void beforeGetFieldEvaluationResult(FieldElementImpl field); | 729 void beforeGetFieldEvaluationResult(FieldElementImpl field); |
| 730 | 730 |
| 731 /** | 731 /** |
| 732 * This method is called just before getting a parameter's default value. Unit | 732 * This method is called just before getting a parameter's default value. Unit |
| 733 * tests will override this method to introduce additional error checking. | 733 * tests will override this method to introduce additional error checking. |
| 734 */ | 734 */ |
| 735 void beforeGetParameterDefault(ParameterElement parameter); | 735 void beforeGetParameterDefault(ParameterElement parameter); |
| 736 } | 736 } |
| 737 | 737 |
| 738 /** | 738 /** |
| 739 * Implementation of [ConstantEvaluationValidator] used in production; does no | 739 * Implementation of [ConstantEvaluationValidator] used in production; does no |
| 740 * validation. | 740 * validation. |
| 741 */ | 741 */ |
| 742 class ConstantEvaluationValidator_ForProduction | 742 class ConstantEvaluationValidator_ForProduction |
| 743 implements ConstantEvaluationValidator { | 743 implements ConstantEvaluationValidator { |
| 744 @override | 744 @override |
| 745 void beforeComputeValue(AstNode constNode) {} | 745 void beforeComputeValue(Element element) {} |
| 746 | 746 |
| 747 @override | 747 @override |
| 748 void beforeGetConstantInitializers(ConstructorElement constructor) {} | 748 void beforeGetConstantInitializers(ConstructorElement constructor) {} |
| 749 | 749 |
| 750 @override | 750 @override |
| 751 void beforeGetEvaluationResult(AstNode node) {} | 751 void beforeGetEvaluationResult(Element element) {} |
| 752 | 752 |
| 753 @override | 753 @override |
| 754 void beforeGetFieldEvaluationResult(FieldElementImpl field) {} | 754 void beforeGetFieldEvaluationResult(FieldElementImpl field) {} |
| 755 | 755 |
| 756 @override | 756 @override |
| 757 void beforeGetParameterDefault(ParameterElement parameter) {} | 757 void beforeGetParameterDefault(ParameterElement parameter) {} |
| 758 } | 758 } |
| 759 | 759 |
| 760 /** | 760 /** |
| 761 * Instances of the class `ConstantEvaluator` evaluate constant expressions to | 761 * Instances of the class `ConstantEvaluator` evaluate constant expressions to |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 } | 845 } |
| 846 | 846 |
| 847 /** | 847 /** |
| 848 * A visitor used to traverse the AST structures of all of the compilation units | 848 * A visitor used to traverse the AST structures of all of the compilation units |
| 849 * being resolved and build tables of the constant variables, constant | 849 * being resolved and build tables of the constant variables, constant |
| 850 * constructors, constant constructor invocations, and annotations found in | 850 * constructors, constant constructor invocations, and annotations found in |
| 851 * those compilation units. | 851 * those compilation units. |
| 852 */ | 852 */ |
| 853 class ConstantFinder extends RecursiveAstVisitor<Object> { | 853 class ConstantFinder extends RecursiveAstVisitor<Object> { |
| 854 /** | 854 /** |
| 855 * A table mapping constant variable elements to the declarations of those | 855 * The elements whose constant values need to be computed, with the exception |
| 856 * variables. | 856 * of annotations. |
| 857 */ | 857 */ |
| 858 final HashMap<PotentiallyConstVariableElement, VariableDeclaration> variableMa
p = | 858 HashSet<Element> constantsToCompute = new HashSet<Element>(); |
| 859 new HashMap<PotentiallyConstVariableElement, VariableDeclaration>(); | |
| 860 | |
| 861 /** | |
| 862 * A table mapping constant constructors to the declarations of those | |
| 863 * constructors. | |
| 864 */ | |
| 865 final HashMap<ConstructorElement, ConstructorDeclaration> constructorMap = | |
| 866 new HashMap<ConstructorElement, ConstructorDeclaration>(); | |
| 867 | 859 |
| 868 /** | 860 /** |
| 869 * A collection of annotations. | 861 * A collection of annotations. |
| 870 */ | 862 */ |
| 871 final List<Annotation> annotations = <Annotation>[]; | 863 final List<Annotation> annotations = <Annotation>[]; |
| 872 | 864 |
| 873 /** | 865 /** |
| 874 * True if instance variables marked as "final" should be treated as "const". | 866 * True if instance variables marked as "final" should be treated as "const". |
| 875 */ | 867 */ |
| 876 bool treatFinalInstanceVarAsConst = false; | 868 bool treatFinalInstanceVarAsConst = false; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 897 treatFinalInstanceVarAsConst = prevTreatFinalInstanceVarAsConst; | 889 treatFinalInstanceVarAsConst = prevTreatFinalInstanceVarAsConst; |
| 898 } | 890 } |
| 899 } | 891 } |
| 900 | 892 |
| 901 @override | 893 @override |
| 902 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 894 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 903 super.visitConstructorDeclaration(node); | 895 super.visitConstructorDeclaration(node); |
| 904 if (node.constKeyword != null) { | 896 if (node.constKeyword != null) { |
| 905 ConstructorElement element = node.element; | 897 ConstructorElement element = node.element; |
| 906 if (element != null) { | 898 if (element != null) { |
| 907 constructorMap[element] = node; | 899 constantsToCompute.add(element); |
| 900 constantsToCompute.addAll(element.parameters); |
| 908 } | 901 } |
| 909 } | 902 } |
| 910 return null; | 903 return null; |
| 911 } | 904 } |
| 912 | 905 |
| 913 @override | 906 @override |
| 914 Object visitVariableDeclaration(VariableDeclaration node) { | 907 Object visitVariableDeclaration(VariableDeclaration node) { |
| 915 super.visitVariableDeclaration(node); | 908 super.visitVariableDeclaration(node); |
| 916 Expression initializer = node.initializer; | 909 Expression initializer = node.initializer; |
| 917 VariableElement element = node.element; | 910 VariableElement element = node.element; |
| 918 if (initializer != null && | 911 if (initializer != null && |
| 919 (node.isConst || | 912 (node.isConst || |
| 920 treatFinalInstanceVarAsConst && | 913 treatFinalInstanceVarAsConst && |
| 921 element is FieldElement && | 914 element is FieldElement && |
| 922 node.isFinal && | 915 node.isFinal && |
| 923 !element.isStatic)) { | 916 !element.isStatic)) { |
| 924 if (node.element != null) { | 917 if (node.element != null) { |
| 925 variableMap[node.element as PotentiallyConstVariableElement] = node; | 918 constantsToCompute.add(node.element); |
| 926 } | 919 } |
| 927 } | 920 } |
| 928 return null; | 921 return null; |
| 929 } | 922 } |
| 930 } | 923 } |
| 931 | 924 |
| 932 /** | 925 /** |
| 933 * An object used to compute the values of constant variables and constant | 926 * An object used to compute the values of constant variables and constant |
| 934 * constructor invocations in one or more compilation units. The expected usage | 927 * constructor invocations in one or more compilation units. The expected usage |
| 935 * pattern is for the compilation units to be added to this computer using the | 928 * pattern is for the compilation units to be added to this computer using the |
| (...skipping 19 matching lines...) Expand all Loading... |
| 955 /** | 948 /** |
| 956 * The object used to find constant variables and constant constructor | 949 * The object used to find constant variables and constant constructor |
| 957 * invocations in the compilation units that were added. | 950 * invocations in the compilation units that were added. |
| 958 */ | 951 */ |
| 959 ConstantFinder _constantFinder = new ConstantFinder(); | 952 ConstantFinder _constantFinder = new ConstantFinder(); |
| 960 | 953 |
| 961 /** | 954 /** |
| 962 * A graph in which the nodes are the constants, and the edges are from each | 955 * A graph in which the nodes are the constants, and the edges are from each |
| 963 * constant to the other constants that are referenced by it. | 956 * constant to the other constants that are referenced by it. |
| 964 */ | 957 */ |
| 965 DirectedGraph<AstNode> referenceGraph = new DirectedGraph<AstNode>(); | 958 DirectedGraph<Element> referenceGraph = new DirectedGraph<Element>(); |
| 966 | 959 |
| 967 /** | 960 /** |
| 968 * A table mapping constant variables to the declarations of those variables. | 961 * The elements whose constant values need to be computed. Any elements |
| 962 * which appear in [referenceGraph] but not in this set either belong to a |
| 963 * different library cycle (and hence don't need to be recomputed) or were |
| 964 * computed during a previous stage of resolution stage (e.g. constants |
| 965 * associated with enums). |
| 969 */ | 966 */ |
| 970 HashMap<PotentiallyConstVariableElement, VariableDeclaration> _variableDeclara
tionMap; | 967 HashSet<Element> _constantsToCompute; |
| 971 | |
| 972 /** | |
| 973 * A table mapping constant constructors to the declarations of those | |
| 974 * constructors. | |
| 975 */ | |
| 976 HashMap<ConstructorElement, ConstructorDeclaration> constructorDeclarationMap; | |
| 977 | 968 |
| 978 /** | 969 /** |
| 979 * A collection of annotations. | 970 * A collection of annotations. |
| 980 */ | 971 */ |
| 981 List<Annotation> _annotations; | 972 List<Annotation> _annotations; |
| 982 | 973 |
| 983 /** | 974 /** |
| 984 * The evaluation engine that does the work of evaluating instance creation | 975 * The evaluation engine that does the work of evaluating instance creation |
| 985 * expressions. | 976 * expressions. |
| 986 */ | 977 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1003 */ | 994 */ |
| 1004 void add(CompilationUnit unit) { | 995 void add(CompilationUnit unit) { |
| 1005 unit.accept(_constantFinder); | 996 unit.accept(_constantFinder); |
| 1006 } | 997 } |
| 1007 | 998 |
| 1008 /** | 999 /** |
| 1009 * Compute values for all of the constants in the compilation units that were | 1000 * Compute values for all of the constants in the compilation units that were |
| 1010 * added. | 1001 * added. |
| 1011 */ | 1002 */ |
| 1012 void computeValues() { | 1003 void computeValues() { |
| 1013 _variableDeclarationMap = _constantFinder.variableMap; | 1004 _constantsToCompute = _constantFinder.constantsToCompute; |
| 1014 constructorDeclarationMap = _constantFinder.constructorMap; | |
| 1015 _annotations = _constantFinder.annotations; | 1005 _annotations = _constantFinder.annotations; |
| 1016 _variableDeclarationMap.values.forEach((VariableDeclaration declaration) { | 1006 for (Element element in _constantsToCompute) { |
| 1017 ReferenceFinder referenceFinder = new ReferenceFinder(declaration, | 1007 referenceGraph.addNode(element); |
| 1018 referenceGraph, _variableDeclarationMap, constructorDeclarationMap); | 1008 if (element is ParameterElement) { |
| 1019 referenceGraph.addNode(declaration); | 1009 if (element.initializer != null) { |
| 1020 declaration.initializer.accept(referenceFinder); | 1010 Expression defaultValue = |
| 1021 }); | 1011 (element as ConstVariableElement).constantInitializer; |
| 1022 constructorDeclarationMap.forEach((ConstructorElementImpl element, | |
| 1023 ConstructorDeclaration declaration) { | |
| 1024 element.isCycleFree = false; | |
| 1025 ConstructorElement redirectedConstructor = | |
| 1026 evaluationEngine.getConstRedirectedConstructor(element); | |
| 1027 if (redirectedConstructor != null) { | |
| 1028 ConstructorElement redirectedConstructorBase = | |
| 1029 ConstantEvaluationEngine._getConstructorBase(redirectedConstructor); | |
| 1030 ConstructorDeclaration redirectedConstructorDeclaration = | |
| 1031 findConstructorDeclaration(redirectedConstructorBase); | |
| 1032 referenceGraph.addEdge(declaration, redirectedConstructorDeclaration); | |
| 1033 return; | |
| 1034 } | |
| 1035 ReferenceFinder referenceFinder = new ReferenceFinder(declaration, | |
| 1036 referenceGraph, _variableDeclarationMap, constructorDeclarationMap); | |
| 1037 referenceGraph.addNode(declaration); | |
| 1038 bool superInvocationFound = false; | |
| 1039 NodeList<ConstructorInitializer> initializers = declaration.initializers; | |
| 1040 for (ConstructorInitializer initializer in initializers) { | |
| 1041 if (initializer is SuperConstructorInvocation) { | |
| 1042 superInvocationFound = true; | |
| 1043 } | |
| 1044 initializer.accept(referenceFinder); | |
| 1045 } | |
| 1046 if (!superInvocationFound) { | |
| 1047 // No explicit superconstructor invocation found, so we need to | |
| 1048 // manually insert a reference to the implicit superconstructor. | |
| 1049 InterfaceType superclass = | |
| 1050 (element.returnType as InterfaceType).superclass; | |
| 1051 if (superclass != null && !superclass.isObject) { | |
| 1052 ConstructorElement unnamedConstructor = | |
| 1053 superclass.element.unnamedConstructor; | |
| 1054 ConstructorDeclaration superConstructorDeclaration = | |
| 1055 findConstructorDeclaration(unnamedConstructor); | |
| 1056 if (superConstructorDeclaration != null) { | |
| 1057 referenceGraph.addEdge(declaration, superConstructorDeclaration); | |
| 1058 } | |
| 1059 } | |
| 1060 } | |
| 1061 for (FieldElement field in element.enclosingElement.fields) { | |
| 1062 // Note: non-static const isn't allowed but we handle it anyway so that | |
| 1063 // we won't be confused by incorrect code. | |
| 1064 if ((field.isFinal || field.isConst) && !field.isStatic) { | |
| 1065 VariableDeclaration fieldDeclaration = _variableDeclarationMap[field]; | |
| 1066 if (fieldDeclaration != null) { | |
| 1067 referenceGraph.addEdge(declaration, fieldDeclaration); | |
| 1068 } | |
| 1069 } | |
| 1070 } | |
| 1071 for (FormalParameter parameter in declaration.parameters.parameters) { | |
| 1072 referenceGraph.addNode(parameter); | |
| 1073 referenceGraph.addEdge(declaration, parameter); | |
| 1074 if (parameter is DefaultFormalParameter) { | |
| 1075 Expression defaultValue = parameter.defaultValue; | |
| 1076 if (defaultValue != null) { | 1012 if (defaultValue != null) { |
| 1077 ReferenceFinder parameterReferenceFinder = new ReferenceFinder( | 1013 ReferenceFinder parameterReferenceFinder = |
| 1078 parameter, referenceGraph, _variableDeclarationMap, | 1014 new ReferenceFinder(element, referenceGraph); |
| 1079 constructorDeclarationMap); | |
| 1080 defaultValue.accept(parameterReferenceFinder); | 1015 defaultValue.accept(parameterReferenceFinder); |
| 1081 } | 1016 } |
| 1082 } | 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}"); |
| 1083 } | 1074 } |
| 1084 }); | 1075 } |
| 1085 List<List<AstNode>> topologicalSort = | 1076 List<List<Element>> topologicalSort = |
| 1086 referenceGraph.computeTopologicalSort(); | 1077 referenceGraph.computeTopologicalSort(); |
| 1087 for (List<AstNode> constantsInCycle in topologicalSort) { | 1078 for (List<Element> constantsInCycle in topologicalSort) { |
| 1088 if (constantsInCycle.length == 1) { | 1079 if (constantsInCycle.length == 1) { |
| 1089 _computeValueFor(constantsInCycle[0]); | 1080 _computeValueFor(constantsInCycle[0]); |
| 1090 } else { | 1081 } else { |
| 1091 for (AstNode constant in constantsInCycle) { | 1082 for (Element constant in constantsInCycle) { |
| 1092 _generateCycleError(constantsInCycle, constant); | 1083 _generateCycleError(constantsInCycle, constant); |
| 1093 } | 1084 } |
| 1094 } | 1085 } |
| 1095 } | 1086 } |
| 1096 // Since no constant can depend on an annotation, we don't waste time | 1087 // Since no constant can depend on an annotation, we don't waste time |
| 1097 // including them in the topological sort. We just process all the | 1088 // including them in the topological sort. We just process all the |
| 1098 // annotations after all other constants are finished. | 1089 // annotations after all other constants are finished. |
| 1099 for (Annotation annotation in _annotations) { | 1090 for (Annotation annotation in _annotations) { |
| 1100 _computeValueFor(annotation); | 1091 _computeValueForAnnotation(annotation); |
| 1101 } | 1092 } |
| 1102 } | 1093 } |
| 1103 | 1094 |
| 1104 ConstructorDeclaration findConstructorDeclaration( | |
| 1105 ConstructorElement constructor) => constructorDeclarationMap[ | |
| 1106 ConstantEvaluationEngine._getConstructorBase(constructor)]; | |
| 1107 | |
| 1108 VariableDeclaration findVariableDeclaration( | |
| 1109 PotentiallyConstVariableElement variable) => | |
| 1110 _variableDeclarationMap[variable]; | |
| 1111 | |
| 1112 /** | 1095 /** |
| 1113 * Compute a value for the given [constNode]. | 1096 * Compute a value for the given [element]. |
| 1114 */ | 1097 */ |
| 1115 void _computeValueFor(AstNode constNode) { | 1098 void _computeValueFor(Element element) { |
| 1116 evaluationEngine.validator.beforeComputeValue(constNode); | 1099 if (!_constantsToCompute.contains(element)) { |
| 1117 if (constNode is VariableDeclaration) { | 1100 // Element is in the dependency graph but should have been computed by |
| 1118 VariableElement element = constNode.element; | 1101 // a previous stage of analysis. |
| 1102 return; |
| 1103 } |
| 1104 evaluationEngine.validator.beforeComputeValue(element); |
| 1105 if (element is ParameterElement) { |
| 1106 if (element.initializer != null) { |
| 1107 Expression defaultValue = |
| 1108 (element as PotentiallyConstVariableElement).constantInitializer; |
| 1109 if (defaultValue != null) { |
| 1110 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 1111 ErrorReporter errorReporter = |
| 1112 new ErrorReporter(errorListener, element.source); |
| 1113 DartObjectImpl dartObject = defaultValue |
| 1114 .accept(new ConstantVisitor(evaluationEngine, errorReporter)); |
| 1115 (element as ParameterElementImpl).evaluationResult = |
| 1116 new EvaluationResultImpl.con2(dartObject, errorListener.errors); |
| 1117 } |
| 1118 } |
| 1119 } else if (element is VariableElement) { |
| 1119 RecordingErrorListener errorListener = new RecordingErrorListener(); | 1120 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 1120 ErrorReporter errorReporter = | 1121 ErrorReporter errorReporter = |
| 1121 new ErrorReporter(errorListener, element.source); | 1122 new ErrorReporter(errorListener, element.source); |
| 1122 DartObjectImpl dartObject = | 1123 DartObjectImpl dartObject = |
| 1123 (element as PotentiallyConstVariableElement).constantInitializer | 1124 (element as PotentiallyConstVariableElement).constantInitializer |
| 1124 .accept(new ConstantVisitor(evaluationEngine, errorReporter)); | 1125 .accept(new ConstantVisitor(evaluationEngine, errorReporter)); |
| 1125 // Only check the type for truly const declarations (don't check final | 1126 // Only check the type for truly const declarations (don't check final |
| 1126 // fields with initializers, since their types may be generic. The type | 1127 // fields with initializers, since their types may be generic. The type |
| 1127 // of the final field will be checked later, when the constructor is | 1128 // of the final field will be checked later, when the constructor is |
| 1128 // invoked). | 1129 // invoked). |
| 1129 if (dartObject != null && constNode.isConst) { | 1130 if (dartObject != null && element.isConst) { |
| 1130 if (!evaluationEngine.runtimeTypeMatch(dartObject, element.type)) { | 1131 if (!evaluationEngine.runtimeTypeMatch(dartObject, element.type)) { |
| 1131 errorReporter.reportErrorForElement( | 1132 errorReporter.reportErrorForElement( |
| 1132 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, element, [ | 1133 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, element, [ |
| 1133 dartObject.type, | 1134 dartObject.type, |
| 1134 element.type | 1135 element.type |
| 1135 ]); | 1136 ]); |
| 1136 } | 1137 } |
| 1137 } | 1138 } |
| 1138 (element as VariableElementImpl).evaluationResult = | 1139 (element as VariableElementImpl).evaluationResult = |
| 1139 new EvaluationResultImpl.con2(dartObject, errorListener.errors); | 1140 new EvaluationResultImpl.con2(dartObject, errorListener.errors); |
| 1140 } else if (constNode is ConstructorDeclaration) { | 1141 } else if (element is ConstructorElement) { |
| 1141 // No evaluation needs to be done; constructor declarations are only in | 1142 // No evaluation needs to be done; constructor declarations are only in |
| 1142 // the dependency graph to ensure that any constants referred to in | 1143 // the dependency graph to ensure that any constants referred to in |
| 1143 // initializer lists and parameter defaults are evaluated before | 1144 // initializer lists and parameter defaults are evaluated before |
| 1144 // invocations of the constructor. However we do need to annotate the | 1145 // invocations of the constructor. However we do need to annotate the |
| 1145 // element as being free of constant evaluation cycles so that later code | 1146 // element as being free of constant evaluation cycles so that later code |
| 1146 // will know that it is safe to evaluate. | 1147 // will know that it is safe to evaluate. |
| 1147 ConstructorElementImpl constructor = constNode.element; | 1148 (element as ConstructorElementImpl).isCycleFree = true; |
| 1148 constructor.isCycleFree = true; | |
| 1149 } else if (constNode is FormalParameter) { | |
| 1150 if (constNode is DefaultFormalParameter) { | |
| 1151 ParameterElement element = constNode.element; | |
| 1152 Expression defaultValue = | |
| 1153 (element as PotentiallyConstVariableElement).constantInitializer; | |
| 1154 if (defaultValue != null) { | |
| 1155 RecordingErrorListener errorListener = new RecordingErrorListener(); | |
| 1156 ErrorReporter errorReporter = | |
| 1157 new ErrorReporter(errorListener, element.source); | |
| 1158 DartObjectImpl dartObject = defaultValue | |
| 1159 .accept(new ConstantVisitor(evaluationEngine, errorReporter)); | |
| 1160 (element as ParameterElementImpl).evaluationResult = | |
| 1161 new EvaluationResultImpl.con2(dartObject, errorListener.errors); | |
| 1162 } | |
| 1163 } | |
| 1164 } else if (constNode is Annotation) { | |
| 1165 ElementAnnotationImpl elementAnnotation = constNode.elementAnnotation; | |
| 1166 // elementAnnotation is null if the annotation couldn't be resolved, in | |
| 1167 // which case we skip it. | |
| 1168 if (elementAnnotation != null) { | |
| 1169 Element element = elementAnnotation.element; | |
| 1170 if (element is PropertyAccessorElement && | |
| 1171 element.variable is VariableElementImpl) { | |
| 1172 // The annotation is a reference to a compile-time constant variable. | |
| 1173 // Just copy the evaluation result. | |
| 1174 VariableElementImpl variableElement = | |
| 1175 element.variable as VariableElementImpl; | |
| 1176 elementAnnotation.evaluationResult = variableElement.evaluationResult; | |
| 1177 } else if (element is ConstructorElementImpl && | |
| 1178 constNode.arguments != null) { | |
| 1179 RecordingErrorListener errorListener = new RecordingErrorListener(); | |
| 1180 CompilationUnit sourceCompilationUnit = | |
| 1181 constNode.getAncestor((node) => node is CompilationUnit); | |
| 1182 ErrorReporter errorReporter = new ErrorReporter( | |
| 1183 errorListener, sourceCompilationUnit.element.source); | |
| 1184 ConstantVisitor constantVisitor = | |
| 1185 new ConstantVisitor(evaluationEngine, errorReporter); | |
| 1186 DartObjectImpl result = evaluationEngine.evaluateConstructorCall( | |
| 1187 constNode, constNode.arguments.arguments, element, | |
| 1188 constantVisitor, errorReporter); | |
| 1189 elementAnnotation.evaluationResult = | |
| 1190 new EvaluationResultImpl.con2(result, errorListener.errors); | |
| 1191 } else { | |
| 1192 // This may happen for invalid code (e.g. failing to pass arguments | |
| 1193 // to an annotation which references a const constructor). The error | |
| 1194 // is detected elsewhere, so just silently ignore it here. | |
| 1195 elementAnnotation.evaluationResult = | |
| 1196 new EvaluationResultImpl.con1(null); | |
| 1197 } | |
| 1198 } | |
| 1199 } else { | 1149 } else { |
| 1200 // Should not happen. | 1150 // Should not happen. |
| 1201 assert(false); | 1151 assert(false); |
| 1202 AnalysisEngine.instance.logger.logError( | 1152 AnalysisEngine.instance.logger.logError( |
| 1203 "Constant value computer trying to compute the value of a node which i
s not a VariableDeclaration, InstanceCreationExpression, FormalParameter, or Con
structorDeclaration"); | 1153 "Constant value computer trying to compute the value of a node of type
${element.runtimeType}"); |
| 1204 return; | 1154 return; |
| 1205 } | 1155 } |
| 1206 } | 1156 } |
| 1207 | 1157 |
| 1208 /** | 1158 /** |
| 1159 * Compute a value for the given annotation. |
| 1160 */ |
| 1161 void _computeValueForAnnotation(Annotation constNode) { |
| 1162 ElementAnnotationImpl elementAnnotation = constNode.elementAnnotation; |
| 1163 // elementAnnotation is null if the annotation couldn't be resolved, in |
| 1164 // which case we skip it. |
| 1165 if (elementAnnotation != null) { |
| 1166 Element element = elementAnnotation.element; |
| 1167 if (element is PropertyAccessorElement && |
| 1168 element.variable is VariableElementImpl) { |
| 1169 // The annotation is a reference to a compile-time constant variable. |
| 1170 // Just copy the evaluation result. |
| 1171 VariableElementImpl variableElement = |
| 1172 element.variable as VariableElementImpl; |
| 1173 elementAnnotation.evaluationResult = variableElement.evaluationResult; |
| 1174 } else if (element is ConstructorElementImpl && |
| 1175 constNode.arguments != null) { |
| 1176 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 1177 CompilationUnit sourceCompilationUnit = |
| 1178 constNode.getAncestor((node) => node is CompilationUnit); |
| 1179 ErrorReporter errorReporter = new ErrorReporter( |
| 1180 errorListener, sourceCompilationUnit.element.source); |
| 1181 ConstantVisitor constantVisitor = |
| 1182 new ConstantVisitor(evaluationEngine, errorReporter); |
| 1183 DartObjectImpl result = evaluationEngine.evaluateConstructorCall( |
| 1184 constNode, constNode.arguments.arguments, element, constantVisitor, |
| 1185 errorReporter); |
| 1186 elementAnnotation.evaluationResult = |
| 1187 new EvaluationResultImpl.con2(result, errorListener.errors); |
| 1188 } else { |
| 1189 // This may happen for invalid code (e.g. failing to pass arguments |
| 1190 // to an annotation which references a const constructor). The error |
| 1191 // is detected elsewhere, so just silently ignore it here. |
| 1192 elementAnnotation.evaluationResult = |
| 1193 new EvaluationResultImpl.con1(null); |
| 1194 } |
| 1195 } |
| 1196 } |
| 1197 |
| 1198 /** |
| 1209 * Generate an error indicating that the given [constNode] is not a valid | 1199 * Generate an error indicating that the given [constNode] is not a valid |
| 1210 * compile-time constant because it references at least one of the constants | 1200 * compile-time constant because it references at least one of the constants |
| 1211 * in the given [cycle], each of which directly or indirectly references the | 1201 * in the given [cycle], each of which directly or indirectly references the |
| 1212 * constant. | 1202 * constant. |
| 1213 */ | 1203 */ |
| 1214 void _generateCycleError(List<AstNode> cycle, AstNode constNode) { | 1204 void _generateCycleError(List<Element> cycle, Element element) { |
| 1215 if (constNode is VariableDeclaration) { | 1205 if (element is VariableElement) { |
| 1216 VariableElement element = constNode.element; | |
| 1217 RecordingErrorListener errorListener = new RecordingErrorListener(); | 1206 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 1218 ErrorReporter errorReporter = | 1207 ErrorReporter errorReporter = |
| 1219 new ErrorReporter(errorListener, element.source); | 1208 new ErrorReporter(errorListener, element.source); |
| 1220 // TODO(paulberry): It would be really nice if we could extract enough | 1209 // TODO(paulberry): It would be really nice if we could extract enough |
| 1221 // information from the 'cycle' argument to provide the user with a | 1210 // information from the 'cycle' argument to provide the user with a |
| 1222 // description of the cycle. | 1211 // description of the cycle. |
| 1223 errorReporter.reportErrorForElement( | 1212 errorReporter.reportErrorForElement( |
| 1224 CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, element, []); | 1213 CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, element, []); |
| 1225 (element as VariableElementImpl).evaluationResult = | 1214 (element as VariableElementImpl).evaluationResult = |
| 1226 new EvaluationResultImpl.con2(null, errorListener.errors); | 1215 new EvaluationResultImpl.con2(null, errorListener.errors); |
| 1227 } else if (constNode is ConstructorDeclaration) { | 1216 } else if (element is ConstructorElement) { |
| 1228 // We don't report cycle errors on constructor declarations since there | 1217 // We don't report cycle errors on constructor declarations since there |
| 1229 // is nowhere to put the error information. | 1218 // is nowhere to put the error information. |
| 1230 } else { | 1219 } else { |
| 1231 // Should not happen. Formal parameter defaults and annotations should | 1220 // Should not happen. Formal parameter defaults and annotations should |
| 1232 // never appear as part of a cycle because they can't be referred to. | 1221 // never appear as part of a cycle because they can't be referred to. |
| 1233 assert(false); | 1222 assert(false); |
| 1234 AnalysisEngine.instance.logger.logError( | 1223 AnalysisEngine.instance.logger.logError( |
| 1235 "Constant value computer trying to report a cycle error for a node of
type ${constNode.runtimeType}"); | 1224 "Constant value computer trying to report a cycle error for a node of
type ${element.runtimeType}"); |
| 1236 } | 1225 } |
| 1237 } | 1226 } |
| 1238 } | 1227 } |
| 1239 | 1228 |
| 1240 /** | 1229 /** |
| 1241 * A visitor used to evaluate constant expressions to produce their compile-time | 1230 * A visitor used to evaluate constant expressions to produce their compile-time |
| 1242 * value. According to the Dart Language Specification: <blockquote> A constant | 1231 * value. According to the Dart Language Specification: <blockquote> A constant |
| 1243 * expression is one of the following: | 1232 * expression is one of the following: |
| 1244 * | 1233 * |
| 1245 * * A literal number. | 1234 * * A literal number. |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1716 * Return the constant value of the static constant represented by the given | 1705 * Return the constant value of the static constant represented by the given |
| 1717 * [element]. The [node] is the node to be used if an error needs to be | 1706 * [element]. The [node] is the node to be used if an error needs to be |
| 1718 * reported. | 1707 * reported. |
| 1719 */ | 1708 */ |
| 1720 DartObjectImpl _getConstantValue(AstNode node, Element element) { | 1709 DartObjectImpl _getConstantValue(AstNode node, Element element) { |
| 1721 if (element is PropertyAccessorElement) { | 1710 if (element is PropertyAccessorElement) { |
| 1722 element = (element as PropertyAccessorElement).variable; | 1711 element = (element as PropertyAccessorElement).variable; |
| 1723 } | 1712 } |
| 1724 if (element is VariableElementImpl) { | 1713 if (element is VariableElementImpl) { |
| 1725 VariableElementImpl variableElementImpl = element; | 1714 VariableElementImpl variableElementImpl = element; |
| 1726 evaluationEngine.validator.beforeGetEvaluationResult(node); | 1715 evaluationEngine.validator.beforeGetEvaluationResult(element); |
| 1727 EvaluationResultImpl value = variableElementImpl.evaluationResult; | 1716 EvaluationResultImpl value = variableElementImpl.evaluationResult; |
| 1728 if (variableElementImpl.isConst && value != null) { | 1717 if (variableElementImpl.isConst && value != null) { |
| 1729 return value.value; | 1718 return value.value; |
| 1730 } | 1719 } |
| 1731 } else if (element is ExecutableElement) { | 1720 } else if (element is ExecutableElement) { |
| 1732 ExecutableElement function = element; | 1721 ExecutableElement function = element; |
| 1733 if (function.isStatic) { | 1722 if (function.isStatic) { |
| 1734 ParameterizedType functionType = function.type; | 1723 ParameterizedType functionType = function.type; |
| 1735 if (functionType == null) { | 1724 if (functionType == null) { |
| 1736 functionType = _typeProvider.functionType; | 1725 functionType = _typeProvider.functionType; |
| (...skipping 3134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4871 } | 4860 } |
| 4872 | 4861 |
| 4873 /** | 4862 /** |
| 4874 * An object used to add reference information for a given variable to the | 4863 * An object used to add reference information for a given variable to the |
| 4875 * bi-directional mapping used to order the evaluation of constants. | 4864 * bi-directional mapping used to order the evaluation of constants. |
| 4876 */ | 4865 */ |
| 4877 class ReferenceFinder extends RecursiveAstVisitor<Object> { | 4866 class ReferenceFinder extends RecursiveAstVisitor<Object> { |
| 4878 /** | 4867 /** |
| 4879 * The element representing the construct that will be visited. | 4868 * The element representing the construct that will be visited. |
| 4880 */ | 4869 */ |
| 4881 final AstNode _source; | 4870 final Element _source; |
| 4882 | 4871 |
| 4883 /** | 4872 /** |
| 4884 * A graph in which the nodes are the constant variables and the edges are | 4873 * A graph in which the nodes are the constant variables and the edges are |
| 4885 * from each variable to the other constant variables that are referenced in | 4874 * from each variable to the other constant variables that are referenced in |
| 4886 * the head's initializer. | 4875 * the head's initializer. |
| 4887 */ | 4876 */ |
| 4888 final DirectedGraph<AstNode> _referenceGraph; | 4877 final DirectedGraph<Element> _referenceGraph; |
| 4889 | |
| 4890 /** | |
| 4891 * A table mapping constant variables to the declarations of those variables. | |
| 4892 */ | |
| 4893 final HashMap<PotentiallyConstVariableElement, VariableDeclaration> _variableD
eclarationMap; | |
| 4894 | |
| 4895 /** | |
| 4896 * A table mapping constant constructors to the declarations of those | |
| 4897 * constructors. | |
| 4898 */ | |
| 4899 final HashMap<ConstructorElement, ConstructorDeclaration> _constructorDeclarat
ionMap; | |
| 4900 | 4878 |
| 4901 /** | 4879 /** |
| 4902 * Initialize a newly created reference finder to find references from a given | 4880 * Initialize a newly created reference finder to find references from a given |
| 4903 * variable to other variables and to add those references to the given graph. | 4881 * variable to other variables and to add those references to the given graph. |
| 4904 * The [source] is the element representing the variable whose initializer | 4882 * The [source] is the element representing the variable whose initializer |
| 4905 * will be visited. The [referenceGraph] is a graph recording which variables | 4883 * will be visited. The [referenceGraph] is a graph recording which variables |
| 4906 * (heads) reference which other variables (tails) in their initializers. The | 4884 * (heads) reference which other variables (tails) in their initializers. |
| 4907 * [variableDeclarationMap] is a table mapping constant variables to the | |
| 4908 * declarations of those variables. The [constructorDeclarationMap] is a table | |
| 4909 * mapping constant constructors to the declarations of those constructors. | |
| 4910 */ | 4885 */ |
| 4911 ReferenceFinder(this._source, this._referenceGraph, | 4886 ReferenceFinder(this._source, this._referenceGraph); |
| 4912 this._variableDeclarationMap, this._constructorDeclarationMap); | |
| 4913 | |
| 4914 ConstructorDeclaration findConstructorDeclaration( | |
| 4915 ConstructorElement constructor) => _constructorDeclarationMap[ | |
| 4916 ConstantEvaluationEngine._getConstructorBase(constructor)]; | |
| 4917 | 4887 |
| 4918 @override | 4888 @override |
| 4919 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 4889 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 4920 if (node.isConst) { | 4890 if (node.isConst) { |
| 4921 ConstructorElement constructor = node.staticElement; | 4891 ConstructorElement constructor = |
| 4892 ConstantEvaluationEngine._getConstructorBase(node.staticElement); |
| 4922 if (constructor != null) { | 4893 if (constructor != null) { |
| 4923 ConstructorDeclaration declaration = | 4894 _referenceGraph.addEdge(_source, constructor); |
| 4924 findConstructorDeclaration(constructor); | |
| 4925 if (declaration != null) { | |
| 4926 _referenceGraph.addEdge(_source, declaration); | |
| 4927 } | |
| 4928 } | 4895 } |
| 4929 } | 4896 } |
| 4930 return super.visitInstanceCreationExpression(node); | 4897 return super.visitInstanceCreationExpression(node); |
| 4931 } | 4898 } |
| 4932 | 4899 |
| 4933 @override | 4900 @override |
| 4934 Object visitRedirectingConstructorInvocation( | 4901 Object visitRedirectingConstructorInvocation( |
| 4935 RedirectingConstructorInvocation node) { | 4902 RedirectingConstructorInvocation node) { |
| 4936 super.visitRedirectingConstructorInvocation(node); | 4903 super.visitRedirectingConstructorInvocation(node); |
| 4937 ConstructorElement target = node.staticElement; | 4904 ConstructorElement target = |
| 4905 ConstantEvaluationEngine._getConstructorBase(node.staticElement); |
| 4938 if (target != null && target.isConst) { | 4906 if (target != null && target.isConst) { |
| 4939 ConstructorDeclaration targetDeclaration = | 4907 _referenceGraph.addEdge(_source, target); |
| 4940 _constructorDeclarationMap[target]; | |
| 4941 if (targetDeclaration != null) { | |
| 4942 _referenceGraph.addEdge(_source, targetDeclaration); | |
| 4943 } | |
| 4944 } | 4908 } |
| 4945 return null; | 4909 return null; |
| 4946 } | 4910 } |
| 4947 | 4911 |
| 4948 @override | 4912 @override |
| 4949 Object visitSimpleIdentifier(SimpleIdentifier node) { | 4913 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 4950 Element element = node.staticElement; | 4914 Element element = node.staticElement; |
| 4951 if (element is PropertyAccessorElement) { | 4915 if (element is PropertyAccessorElement) { |
| 4952 element = (element as PropertyAccessorElement).variable; | 4916 element = (element as PropertyAccessorElement).variable; |
| 4953 } | 4917 } |
| 4954 if (element is VariableElement) { | 4918 if (element is VariableElement) { |
| 4955 if (element.isConst) { | 4919 if (element.isConst) { |
| 4956 VariableDeclaration variableDeclaration = | 4920 _referenceGraph.addEdge(_source, element); |
| 4957 _variableDeclarationMap[element]; | |
| 4958 // The declaration will be null when the variable is not defined in the | |
| 4959 // compilation units that were used to produce the | |
| 4960 // variableDeclarationMap. In such cases, the variable should already | |
| 4961 // have a value associated with it, but we don't bother to check because | |
| 4962 // there's nothing we can do about it at this point. | |
| 4963 if (variableDeclaration != null) { | |
| 4964 _referenceGraph.addEdge(_source, variableDeclaration); | |
| 4965 } | |
| 4966 } | 4921 } |
| 4967 } | 4922 } |
| 4968 return null; | 4923 return null; |
| 4969 } | 4924 } |
| 4970 | 4925 |
| 4971 @override | 4926 @override |
| 4972 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 4927 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 4973 super.visitSuperConstructorInvocation(node); | 4928 super.visitSuperConstructorInvocation(node); |
| 4974 ConstructorElement constructor = node.staticElement; | 4929 ConstructorElement constructor = |
| 4930 ConstantEvaluationEngine._getConstructorBase(node.staticElement); |
| 4975 if (constructor != null && constructor.isConst) { | 4931 if (constructor != null && constructor.isConst) { |
| 4976 ConstructorDeclaration constructorDeclaration = | 4932 _referenceGraph.addEdge(_source, constructor); |
| 4977 _constructorDeclarationMap[constructor]; | |
| 4978 // The declaration will be null when the constructor is not defined in the | |
| 4979 // compilation units that were used to produce the | |
| 4980 // constructorDeclarationMap. In such cases, the constructor should | |
| 4981 // already have its initializer AST's stored in it, but we don't bother | |
| 4982 // to check because there's nothing we can do about it at this point. | |
| 4983 if (constructorDeclaration != null) { | |
| 4984 _referenceGraph.addEdge(_source, constructorDeclaration); | |
| 4985 } | |
| 4986 } | 4933 } |
| 4987 return null; | 4934 return null; |
| 4988 } | 4935 } |
| 4989 } | 4936 } |
| 4990 | 4937 |
| 4991 /** | 4938 /** |
| 4992 * The state of an object representing a string. | 4939 * The state of an object representing a string. |
| 4993 */ | 4940 */ |
| 4994 class StringState extends InstanceState { | 4941 class StringState extends InstanceState { |
| 4995 /** | 4942 /** |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5197 return BoolState.from(_element == rightElement); | 5144 return BoolState.from(_element == rightElement); |
| 5198 } else if (rightOperand is DynamicState) { | 5145 } else if (rightOperand is DynamicState) { |
| 5199 return BoolState.UNKNOWN_VALUE; | 5146 return BoolState.UNKNOWN_VALUE; |
| 5200 } | 5147 } |
| 5201 return BoolState.FALSE_STATE; | 5148 return BoolState.FALSE_STATE; |
| 5202 } | 5149 } |
| 5203 | 5150 |
| 5204 @override | 5151 @override |
| 5205 String toString() => _element == null ? "-unknown-" : _element.name; | 5152 String toString() => _element == null ? "-unknown-" : _element.name; |
| 5206 } | 5153 } |
| OLD | NEW |