| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 /** | 5 /** |
| 6 * This library is capable of producing linked summaries from unlinked | 6 * This library is capable of producing linked summaries from unlinked |
| 7 * ones (or prelinked ones). It functions by building a miniature | 7 * ones (or prelinked ones). It functions by building a miniature |
| 8 * element model to represent the contents of the summaries, and then | 8 * element model to represent the contents of the summaries, and then |
| 9 * scanning the element model to gather linked information and adding | 9 * scanning the element model to gather linked information and adding |
| 10 * it to the summary data structures. | 10 * it to the summary data structures. |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 _storeTypeArguments( | 211 _storeTypeArguments( |
| 212 type.typeArguments, result, compilationUnit, typeParameterContext); | 212 type.typeArguments, result, compilationUnit, typeParameterContext); |
| 213 return result; | 213 return result; |
| 214 } | 214 } |
| 215 if (element is FunctionTypeAliasElementForLink) { | 215 if (element is FunctionTypeAliasElementForLink) { |
| 216 result.reference = compilationUnit.addReference(element); | 216 result.reference = compilationUnit.addReference(element); |
| 217 _storeTypeArguments( | 217 _storeTypeArguments( |
| 218 type.typeArguments, result, compilationUnit, typeParameterContext); | 218 type.typeArguments, result, compilationUnit, typeParameterContext); |
| 219 return result; | 219 return result; |
| 220 } | 220 } |
| 221 if (element is FunctionElement) { | 221 if (element is FunctionElement && element.enclosingElement == null) { |
| 222 // Element is a FunctionElement but not a TopLevelFunctionElementForLink | 222 // Element is a synthetic function element that was generated on the fly |
| 223 // or a MethodElementForLink. This means that it's a synthetic function | 223 // to represent a type that has no associated source code location. |
| 224 // element that was generated on the fly to represent a type that has no | |
| 225 // associated source code location. | |
| 226 assert(element.enclosingElement == null); | |
| 227 result.syntheticReturnType = _createLinkedType( | 224 result.syntheticReturnType = _createLinkedType( |
| 228 element.returnType, compilationUnit, typeParameterContext); | 225 element.returnType, compilationUnit, typeParameterContext); |
| 229 result.syntheticParams = element.parameters | 226 result.syntheticParams = element.parameters |
| 230 .map((ParameterElement param) => _serializeSyntheticParam( | 227 .map((ParameterElement param) => _serializeSyntheticParam( |
| 231 param, compilationUnit, typeParameterContext)) | 228 param, compilationUnit, typeParameterContext)) |
| 232 .toList(); | 229 .toList(); |
| 233 return result; | 230 return result; |
| 234 } | 231 } |
| 232 if (element is FunctionElement) { |
| 233 // Element is a local function inside another executable. |
| 234 result.reference = compilationUnit.addReference(element); |
| 235 // TODO(paulberry): do I need to store type arguments? |
| 236 return result; |
| 237 } |
| 235 // TODO(paulberry): implement other cases. | 238 // TODO(paulberry): implement other cases. |
| 236 throw new UnimplementedError('${element.runtimeType}'); | 239 throw new UnimplementedError('${element.runtimeType}'); |
| 237 } | 240 } |
| 238 // TODO(paulberry): implement other cases. | 241 // TODO(paulberry): implement other cases. |
| 239 throw new UnimplementedError('${type.runtimeType}'); | 242 throw new UnimplementedError('${type.runtimeType}'); |
| 240 } | 243 } |
| 241 | 244 |
| 242 /** | 245 /** |
| 243 * Create an [UnlinkedParam] representing the given [parameter], which should be | 246 * Create an [UnlinkedParam] representing the given [parameter], which should be |
| 244 * a parameter of a synthetic function type (e.g. one produced during type | 247 * a parameter of a synthetic function type (e.g. one produced during type |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 * If this compilation unit already has a reference in its references table | 1071 * If this compilation unit already has a reference in its references table |
| 1069 * matching [dependency], [name], [numTypeParameters], [unitNum], | 1072 * matching [dependency], [name], [numTypeParameters], [unitNum], |
| 1070 * [containingReference], and [kind], return its index. Otherwise add a new r
eference to | 1073 * [containingReference], and [kind], return its index. Otherwise add a new r
eference to |
| 1071 * the table and return its index. | 1074 * the table and return its index. |
| 1072 */ | 1075 */ |
| 1073 int addRawReference(String name, | 1076 int addRawReference(String name, |
| 1074 {int dependency: 0, | 1077 {int dependency: 0, |
| 1075 int numTypeParameters: 0, | 1078 int numTypeParameters: 0, |
| 1076 int unitNum: 0, | 1079 int unitNum: 0, |
| 1077 int containingReference: 0, | 1080 int containingReference: 0, |
| 1081 int localIndex: 0, |
| 1078 ReferenceKind kind: ReferenceKind.classOrEnum}) { | 1082 ReferenceKind kind: ReferenceKind.classOrEnum}) { |
| 1079 List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references; | 1083 List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references; |
| 1080 List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references; | 1084 List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references; |
| 1081 for (int i = 0; i < linkedReferences.length; i++) { | 1085 for (int i = 0; i < linkedReferences.length; i++) { |
| 1082 LinkedReferenceBuilder linkedReference = linkedReferences[i]; | 1086 LinkedReferenceBuilder linkedReference = linkedReferences[i]; |
| 1083 int candidateContainingReference = i < unlinkedReferences.length | 1087 int candidateContainingReference = i < unlinkedReferences.length |
| 1084 ? unlinkedReferences[i].prefixReference | 1088 ? unlinkedReferences[i].prefixReference |
| 1085 : linkedReference.containingReference; | 1089 : linkedReference.containingReference; |
| 1086 if (candidateContainingReference != 0 && | 1090 if (candidateContainingReference != 0 && |
| 1087 linkedReferences[candidateContainingReference].kind == | 1091 linkedReferences[candidateContainingReference].kind == |
| 1088 ReferenceKind.prefix) { | 1092 ReferenceKind.prefix) { |
| 1089 // We don't need to match containing references when they are prefixes, | 1093 // We don't need to match containing references when they are prefixes, |
| 1090 // since the relevant information is in linkedReference.dependency. | 1094 // since the relevant information is in linkedReference.dependency. |
| 1091 candidateContainingReference = 0; | 1095 candidateContainingReference = 0; |
| 1092 } | 1096 } |
| 1093 if (linkedReference.dependency == dependency && | 1097 if (linkedReference.dependency == dependency && |
| 1094 (i < unlinkedReferences.length | 1098 (i < unlinkedReferences.length |
| 1095 ? unlinkedReferences[i].name | 1099 ? unlinkedReferences[i].name |
| 1096 : linkedReference.name) == | 1100 : linkedReference.name) == |
| 1097 name && | 1101 name && |
| 1098 linkedReference.numTypeParameters == numTypeParameters && | 1102 linkedReference.numTypeParameters == numTypeParameters && |
| 1099 linkedReference.unit == unitNum && | 1103 linkedReference.unit == unitNum && |
| 1100 candidateContainingReference == containingReference && | 1104 candidateContainingReference == containingReference && |
| 1101 linkedReference.kind == kind) { | 1105 linkedReference.kind == kind && |
| 1106 linkedReference.localIndex == localIndex) { |
| 1102 return i; | 1107 return i; |
| 1103 } | 1108 } |
| 1104 } | 1109 } |
| 1105 int result = linkedReferences.length; | 1110 int result = linkedReferences.length; |
| 1106 linkedReferences.add(new LinkedReferenceBuilder( | 1111 linkedReferences.add(new LinkedReferenceBuilder( |
| 1107 dependency: dependency, | 1112 dependency: dependency, |
| 1108 name: name, | 1113 name: name, |
| 1109 numTypeParameters: numTypeParameters, | 1114 numTypeParameters: numTypeParameters, |
| 1110 unit: unitNum, | 1115 unit: unitNum, |
| 1111 containingReference: containingReference, | 1116 containingReference: containingReference, |
| 1112 kind: kind)); | 1117 kind: kind, |
| 1118 localIndex: localIndex)); |
| 1113 return result; | 1119 return result; |
| 1114 } | 1120 } |
| 1115 | 1121 |
| 1116 /** | 1122 /** |
| 1117 * If this compilation unit already has a reference in its references table | 1123 * If this compilation unit already has a reference in its references table |
| 1118 * to [element], return its index. Otherwise add a new reference to the table | 1124 * to [element], return its index. Otherwise add a new reference to the table |
| 1119 * and return its index. | 1125 * and return its index. |
| 1120 */ | 1126 */ |
| 1121 int addReference(Element element) { | 1127 int addReference(Element element) { |
| 1122 if (element is ClassElementForLink) { | 1128 if (element is ClassElementForLink) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1144 break; | 1150 break; |
| 1145 default: | 1151 default: |
| 1146 // TODO(paulberry): implement other cases as necessary | 1152 // TODO(paulberry): implement other cases as necessary |
| 1147 throw new UnimplementedError('${element._unlinkedExecutable.kind}'); | 1153 throw new UnimplementedError('${element._unlinkedExecutable.kind}'); |
| 1148 } | 1154 } |
| 1149 return addRawReference(element.name, | 1155 return addRawReference(element.name, |
| 1150 numTypeParameters: element.typeParameters.length, | 1156 numTypeParameters: element.typeParameters.length, |
| 1151 containingReference: | 1157 containingReference: |
| 1152 enclosingClass != null ? addReference(enclosingClass) : null, | 1158 enclosingClass != null ? addReference(enclosingClass) : null, |
| 1153 kind: kind); | 1159 kind: kind); |
| 1160 } else if (element is FunctionElementForLink_Local) { |
| 1161 FunctionElementImpl parent = element.enclosingElement; |
| 1162 int localIndex = parent.functions.indexOf(element); |
| 1163 assert(localIndex != -1); |
| 1164 return addRawReference(element.name, |
| 1165 containingReference: addReference(parent), |
| 1166 kind: ReferenceKind.function, |
| 1167 localIndex: localIndex); |
| 1168 } else if (element is FunctionElementForLink_Initializer) { |
| 1169 return addRawReference('', |
| 1170 containingReference: addReference(element.enclosingElement), |
| 1171 kind: ReferenceKind.function); |
| 1172 } else if (element is TopLevelVariableElementForLink) { |
| 1173 return addRawReference(element.name, |
| 1174 kind: ReferenceKind.topLevelPropertyAccessor); |
| 1175 } else if (element is FieldElementForLink_ClassField) { |
| 1176 ClassElementForLink_Class enclosingClass = element.enclosingElement; |
| 1177 // TODO(paulberry): do we need to set numTypeParameters to nonzero if the |
| 1178 // class has type parameters? |
| 1179 return addRawReference(element.name, |
| 1180 containingReference: addReference(enclosingClass), |
| 1181 kind: ReferenceKind.propertyAccessor); |
| 1154 } | 1182 } |
| 1155 // TODO(paulberry): implement other cases | 1183 // TODO(paulberry): implement other cases |
| 1156 throw new UnimplementedError('${element.runtimeType}'); | 1184 throw new UnimplementedError('${element.runtimeType}'); |
| 1157 } | 1185 } |
| 1158 | 1186 |
| 1159 @override | 1187 @override |
| 1160 DartType getLinkedType( | 1188 DartType getLinkedType( |
| 1161 int slot, TypeParameterizedElementForLink typeParameterContext) { | 1189 int slot, TypeParameterizedElementForLink typeParameterContext) { |
| 1162 // This method should only be called on compilation units that come from | 1190 // This method should only be called on compilation units that come from |
| 1163 // dependencies, never on compilation units that are part of the current | 1191 // dependencies, never on compilation units that are part of the current |
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 // considered to return `void`. | 1937 // considered to return `void`. |
| 1910 return VoidTypeImpl.instance; | 1938 return VoidTypeImpl.instance; |
| 1911 } else { | 1939 } else { |
| 1912 return DynamicTypeImpl.instance; | 1940 return DynamicTypeImpl.instance; |
| 1913 } | 1941 } |
| 1914 } | 1942 } |
| 1915 } | 1943 } |
| 1916 | 1944 |
| 1917 class ExprTypeComputer { | 1945 class ExprTypeComputer { |
| 1918 VariableElementForLink variable; | 1946 VariableElementForLink variable; |
| 1947 FunctionElementForLink_Initializer initializer; |
| 1919 CompilationUnitElementForLink unit; | 1948 CompilationUnitElementForLink unit; |
| 1920 LibraryElementForLink library; | 1949 LibraryElementForLink library; |
| 1921 Linker linker; | 1950 Linker linker; |
| 1922 TypeProvider typeProvider; | 1951 TypeProvider typeProvider; |
| 1923 UnlinkedConst unlinkedConst; | 1952 UnlinkedConst unlinkedConst; |
| 1924 | 1953 |
| 1925 final List<DartType> stack = <DartType>[]; | 1954 final List<DartType> stack = <DartType>[]; |
| 1926 int intPtr = 0; | 1955 int intPtr = 0; |
| 1927 int refPtr = 0; | 1956 int refPtr = 0; |
| 1928 int strPtr = 0; | 1957 int strPtr = 0; |
| 1929 int assignmentOperatorPtr = 0; | 1958 int assignmentOperatorPtr = 0; |
| 1930 | 1959 |
| 1931 ExprTypeComputer(VariableElementForLink variableElement) { | 1960 ExprTypeComputer(VariableElementForLink variableElement) { |
| 1932 this.variable = variableElement; | 1961 this.variable = variableElement; |
| 1962 initializer = variableElement.initializer; |
| 1933 unit = variableElement.compilationUnit; | 1963 unit = variableElement.compilationUnit; |
| 1934 library = unit.enclosingElement; | 1964 library = unit.enclosingElement; |
| 1935 linker = library._linker; | 1965 linker = library._linker; |
| 1936 typeProvider = linker.typeProvider; | 1966 typeProvider = linker.typeProvider; |
| 1937 unlinkedConst = variableElement.unlinkedVariable.constExpr; | 1967 unlinkedConst = variableElement.unlinkedVariable.constExpr; |
| 1938 } | 1968 } |
| 1939 | 1969 |
| 1940 DartType compute() { | 1970 DartType compute() { |
| 1941 // Perform RPN evaluation of the constant, using a stack of inferred types. | 1971 // Perform RPN evaluation of the constant, using a stack of inferred types. |
| 1942 for (UnlinkedConstOperation operation in unlinkedConst.operations) { | 1972 for (UnlinkedConstOperation operation in unlinkedConst.operations) { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 break; | 2119 break; |
| 2090 case UnlinkedConstOperation.typeCheck: | 2120 case UnlinkedConstOperation.typeCheck: |
| 2091 stack.removeLast(); | 2121 stack.removeLast(); |
| 2092 refPtr++; | 2122 refPtr++; |
| 2093 stack.add(typeProvider.boolType); | 2123 stack.add(typeProvider.boolType); |
| 2094 break; | 2124 break; |
| 2095 case UnlinkedConstOperation.throwException: | 2125 case UnlinkedConstOperation.throwException: |
| 2096 stack.removeLast(); | 2126 stack.removeLast(); |
| 2097 stack.add(BottomTypeImpl.instance); | 2127 stack.add(BottomTypeImpl.instance); |
| 2098 break; | 2128 break; |
| 2129 case UnlinkedConstOperation.pushLocalFunctionReference: |
| 2130 int popCount = _getNextInt(); |
| 2131 assert(popCount == 0); // TODO(paulberry): handle the nonzero case. |
| 2132 stack.add(initializer.functions[_getNextInt()].type); |
| 2133 break; |
| 2099 default: | 2134 default: |
| 2100 // TODO(paulberry): implement. | 2135 // TODO(paulberry): implement. |
| 2101 throw new UnimplementedError('$operation'); | 2136 throw new UnimplementedError('$operation'); |
| 2102 } | 2137 } |
| 2103 } | 2138 } |
| 2104 assert(intPtr == unlinkedConst.ints.length); | 2139 assert(intPtr == unlinkedConst.ints.length); |
| 2105 assert(refPtr == unlinkedConst.references.length); | 2140 assert(refPtr == unlinkedConst.references.length); |
| 2106 assert(strPtr == unlinkedConst.strings.length); | 2141 assert(strPtr == unlinkedConst.strings.length); |
| 2107 assert(assignmentOperatorPtr == unlinkedConst.assignmentOperators.length); | 2142 assert(assignmentOperatorPtr == unlinkedConst.assignmentOperators.length); |
| 2108 assert(stack.length == 1); | 2143 assert(stack.length == 1); |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 | 2727 |
| 2693 /** | 2728 /** |
| 2694 * Element representing the initializer expression of a variable. | 2729 * Element representing the initializer expression of a variable. |
| 2695 */ | 2730 */ |
| 2696 class FunctionElementForLink_Initializer implements FunctionElementImpl { | 2731 class FunctionElementForLink_Initializer implements FunctionElementImpl { |
| 2697 /** | 2732 /** |
| 2698 * The variable for which this element is the initializer. | 2733 * The variable for which this element is the initializer. |
| 2699 */ | 2734 */ |
| 2700 final VariableElementForLink _variable; | 2735 final VariableElementForLink _variable; |
| 2701 | 2736 |
| 2737 List<FunctionElementForLink_Local> _functions; |
| 2738 |
| 2702 FunctionElementForLink_Initializer(this._variable); | 2739 FunctionElementForLink_Initializer(this._variable); |
| 2703 | 2740 |
| 2704 @override | 2741 @override |
| 2742 VariableElementForLink get enclosingElement => _variable; |
| 2743 |
| 2744 @override |
| 2745 List<FunctionElementForLink_Local> get functions => _functions ??= _variable |
| 2746 .unlinkedVariable.initializer.localFunctions |
| 2747 .map( |
| 2748 (UnlinkedExecutable ex) => new FunctionElementForLink_Local(this, ex)) |
| 2749 .toList(); |
| 2750 |
| 2751 @override |
| 2705 DartType get returnType { | 2752 DartType get returnType { |
| 2706 // If this is a variable whose type needs inferring, infer it. | 2753 // If this is a variable whose type needs inferring, infer it. |
| 2707 if (_variable.hasImplicitType) { | 2754 if (_variable.hasImplicitType) { |
| 2708 return _variable.inferredType; | 2755 return _variable.inferredType; |
| 2709 } else { | 2756 } else { |
| 2710 // There's no reason linking should need to access the type of | 2757 // There's no reason linking should need to access the type of |
| 2711 // this FunctionElement, since the variable doesn't need its | 2758 // this FunctionElement, since the variable doesn't need its |
| 2712 // type inferred. | 2759 // type inferred. |
| 2713 assert(false); | 2760 assert(false); |
| 2714 // But for robustness, return the dynamic type. | 2761 // But for robustness, return the dynamic type. |
| 2715 return DynamicTypeImpl.instance; | 2762 return DynamicTypeImpl.instance; |
| 2716 } | 2763 } |
| 2717 } | 2764 } |
| 2718 | 2765 |
| 2719 @override | 2766 @override |
| 2720 void set returnType(DartType newType) { | 2767 void set returnType(DartType newType) { |
| 2721 // InstanceMemberInferrer stores the new type both here and on the variable | 2768 // InstanceMemberInferrer stores the new type both here and on the variable |
| 2722 // element. We don't need to record both values, so we ignore it here. | 2769 // element. We don't need to record both values, so we ignore it here. |
| 2723 } | 2770 } |
| 2724 | 2771 |
| 2725 @override | 2772 @override |
| 2726 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 2773 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 2727 } | 2774 } |
| 2728 | 2775 |
| 2729 /** | 2776 /** |
| 2777 * Element representing a local function (possibly a closure) inside another |
| 2778 * executable. |
| 2779 */ |
| 2780 class FunctionElementForLink_Local implements FunctionElementImpl { |
| 2781 /** |
| 2782 * The unlinked representation of the local function in the summary. |
| 2783 */ |
| 2784 final UnlinkedExecutable _executable; |
| 2785 |
| 2786 @override |
| 2787 final FunctionElementImpl enclosingElement; |
| 2788 |
| 2789 DartType _type; |
| 2790 |
| 2791 FunctionElementForLink_Local(this.enclosingElement, this._executable); |
| 2792 |
| 2793 @override |
| 2794 String get name => _executable.name; |
| 2795 |
| 2796 @override |
| 2797 DartType get type => _type ??= new FunctionTypeImpl(this); |
| 2798 |
| 2799 @override |
| 2800 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 2801 } |
| 2802 |
| 2803 /** |
| 2730 * Element representing a typedef resynthesized from a summary during linking. | 2804 * Element representing a typedef resynthesized from a summary during linking. |
| 2731 */ | 2805 */ |
| 2732 class FunctionTypeAliasElementForLink extends Object | 2806 class FunctionTypeAliasElementForLink extends Object |
| 2733 with TypeParameterizedElementForLink, ParameterParentElementForLink | 2807 with TypeParameterizedElementForLink, ParameterParentElementForLink |
| 2734 implements | 2808 implements |
| 2735 FunctionTypeAliasElement, | 2809 FunctionTypeAliasElement, |
| 2736 ReferenceableElementForLink, | 2810 ReferenceableElementForLink, |
| 2737 ElementImpl { | 2811 ElementImpl { |
| 2738 @override | 2812 @override |
| 2739 final CompilationUnitElementForLink enclosingElement; | 2813 final CompilationUnitElementForLink enclosingElement; |
| (...skipping 2011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4751 * there are no type parameters in scope. | 4825 * there are no type parameters in scope. |
| 4752 */ | 4826 */ |
| 4753 TypeParameterizedElementForLink get _typeParameterContext; | 4827 TypeParameterizedElementForLink get _typeParameterContext; |
| 4754 | 4828 |
| 4755 @override | 4829 @override |
| 4756 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 4830 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 4757 | 4831 |
| 4758 @override | 4832 @override |
| 4759 String toString() => '$enclosingElement.$name'; | 4833 String toString() => '$enclosingElement.$name'; |
| 4760 } | 4834 } |
| OLD | NEW |