| 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 * | 139 * |
| 140 * The libraries are prelinked, and a map is returned whose keys are the URIs of | 140 * The libraries are prelinked, and a map is returned whose keys are the URIs of |
| 141 * the libraries in this build unit, and whose values are the corresponding | 141 * the libraries in this build unit, and whose values are the corresponding |
| 142 * [LinkedLibraryBuilder]s. | 142 * [LinkedLibraryBuilder]s. |
| 143 */ | 143 */ |
| 144 Map<String, LinkedLibraryBuilder> setupForLink(Set<String> libraryUris, | 144 Map<String, LinkedLibraryBuilder> setupForLink(Set<String> libraryUris, |
| 145 GetUnitCallback getUnit, GetDeclaredVariable getDeclaredVariable) { | 145 GetUnitCallback getUnit, GetDeclaredVariable getDeclaredVariable) { |
| 146 Map<String, LinkedLibraryBuilder> linkedLibraries = | 146 Map<String, LinkedLibraryBuilder> linkedLibraries = |
| 147 <String, LinkedLibraryBuilder>{}; | 147 <String, LinkedLibraryBuilder>{}; |
| 148 for (String absoluteUri in libraryUris) { | 148 for (String absoluteUri in libraryUris) { |
| 149 Uri uri = Uri.parse(absoluteUri); | |
| 150 linkedLibraries[absoluteUri] = prelink( | 149 linkedLibraries[absoluteUri] = prelink( |
| 151 absoluteUri, | 150 absoluteUri, |
| 152 getUnit(absoluteUri), | 151 getUnit(absoluteUri), |
| 153 getUnit, | 152 getUnit, |
| 154 (String absoluteUri) => getUnit(absoluteUri)?.publicNamespace, | 153 (String absoluteUri) => getUnit(absoluteUri)?.publicNamespace, |
| 155 getDeclaredVariable); | 154 getDeclaredVariable); |
| 156 } | 155 } |
| 157 return linkedLibraries; | 156 return linkedLibraries; |
| 158 } | 157 } |
| 159 | 158 |
| (...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 'Linker tried to access linked type from current build unit'); | 1281 'Linker tried to access linked type from current build unit'); |
| 1283 } | 1282 } |
| 1284 | 1283 |
| 1285 /** | 1284 /** |
| 1286 * Perform type inference and const cycle detection on this | 1285 * Perform type inference and const cycle detection on this |
| 1287 * compilation unit. | 1286 * compilation unit. |
| 1288 */ | 1287 */ |
| 1289 void link() { | 1288 void link() { |
| 1290 if (library._linker.strongMode) { | 1289 if (library._linker.strongMode) { |
| 1291 new InstanceMemberInferrer(enclosingElement._linker.typeProvider, | 1290 new InstanceMemberInferrer(enclosingElement._linker.typeProvider, |
| 1292 enclosingElement.inheritanceManager) | 1291 enclosingElement.inheritanceManager, new Set<FieldElement>()) |
| 1293 .inferCompilationUnit(this); | 1292 .inferCompilationUnit(this); |
| 1294 for (TopLevelVariableElementForLink variable in topLevelVariables) { | 1293 for (TopLevelVariableElementForLink variable in topLevelVariables) { |
| 1295 variable.link(this); | 1294 variable.link(this); |
| 1296 } | 1295 } |
| 1297 } | 1296 } |
| 1298 for (ClassElementForLink classElement in types) { | 1297 for (ClassElementForLink classElement in types) { |
| 1299 classElement.link(this); | 1298 classElement.link(this); |
| 1300 } | 1299 } |
| 1301 } | 1300 } |
| 1302 | 1301 |
| (...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1976 final Linker linker; | 1975 final Linker linker; |
| 1977 final TypeProvider typeProvider; | 1976 final TypeProvider typeProvider; |
| 1978 final UnlinkedExpr unlinkedConst; | 1977 final UnlinkedExpr unlinkedConst; |
| 1979 | 1978 |
| 1980 final List<DartType> stack = <DartType>[]; | 1979 final List<DartType> stack = <DartType>[]; |
| 1981 int intPtr = 0; | 1980 int intPtr = 0; |
| 1982 int refPtr = 0; | 1981 int refPtr = 0; |
| 1983 int strPtr = 0; | 1982 int strPtr = 0; |
| 1984 int assignmentOperatorPtr = 0; | 1983 int assignmentOperatorPtr = 0; |
| 1985 | 1984 |
| 1985 bool hasError = false; |
| 1986 |
| 1986 factory ExprTypeComputer(FunctionElementForLink_Local functionElement) { | 1987 factory ExprTypeComputer(FunctionElementForLink_Local functionElement) { |
| 1987 CompilationUnitElementForLink unit = functionElement.compilationUnit; | 1988 CompilationUnitElementForLink unit = functionElement.compilationUnit; |
| 1988 LibraryElementForLink library = unit.enclosingElement; | 1989 LibraryElementForLink library = unit.enclosingElement; |
| 1989 Linker linker = library._linker; | 1990 Linker linker = library._linker; |
| 1990 TypeProvider typeProvider = linker.typeProvider; | 1991 TypeProvider typeProvider = linker.typeProvider; |
| 1991 UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr; | 1992 UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr; |
| 1992 return new ExprTypeComputer._( | 1993 return new ExprTypeComputer._( |
| 1993 functionElement, unit, library, linker, typeProvider, unlinkedConst); | 1994 functionElement, unit, library, linker, typeProvider, unlinkedConst); |
| 1994 } | 1995 } |
| 1995 | 1996 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 case UnlinkedExprOperation.pushNull: | 2041 case UnlinkedExprOperation.pushNull: |
| 2041 stack.add(typeProvider.nullType); | 2042 stack.add(typeProvider.nullType); |
| 2042 break; | 2043 break; |
| 2043 case UnlinkedExprOperation.pushSuper: | 2044 case UnlinkedExprOperation.pushSuper: |
| 2044 stack.add(DynamicTypeImpl.instance); | 2045 stack.add(DynamicTypeImpl.instance); |
| 2045 break; | 2046 break; |
| 2046 case UnlinkedExprOperation.pushThis: | 2047 case UnlinkedExprOperation.pushThis: |
| 2047 stack.add(DynamicTypeImpl.instance); | 2048 stack.add(DynamicTypeImpl.instance); |
| 2048 break; | 2049 break; |
| 2049 case UnlinkedExprOperation.pushReference: | 2050 case UnlinkedExprOperation.pushReference: |
| 2050 _doPushReference(); | 2051 try { |
| 2052 _doPushReference(); |
| 2053 } on _InferenceFailedError { |
| 2054 hasError = true; |
| 2055 return DynamicTypeImpl.instance; |
| 2056 } |
| 2051 break; | 2057 break; |
| 2052 case UnlinkedExprOperation.extractProperty: | 2058 case UnlinkedExprOperation.extractProperty: |
| 2053 _doExtractProperty(); | 2059 try { |
| 2060 _doExtractProperty(); |
| 2061 } on _InferenceFailedError { |
| 2062 hasError = true; |
| 2063 return DynamicTypeImpl.instance; |
| 2064 } |
| 2054 break; | 2065 break; |
| 2055 case UnlinkedExprOperation.invokeConstructor: | 2066 case UnlinkedExprOperation.invokeConstructor: |
| 2056 _doInvokeConstructor(); | 2067 _doInvokeConstructor(); |
| 2057 break; | 2068 break; |
| 2058 case UnlinkedExprOperation.makeUntypedList: | 2069 case UnlinkedExprOperation.makeUntypedList: |
| 2059 _doMakeUntypedList(); | 2070 _doMakeUntypedList(); |
| 2060 break; | 2071 break; |
| 2061 case UnlinkedExprOperation.makeUntypedMap: | 2072 case UnlinkedExprOperation.makeUntypedMap: |
| 2062 _doMakeUntypedMap(); | 2073 _doMakeUntypedMap(); |
| 2063 break; | 2074 break; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2125 break; | 2136 break; |
| 2126 case UnlinkedExprOperation.lessEqual: | 2137 case UnlinkedExprOperation.lessEqual: |
| 2127 _computeBinaryExpressionType(TokenType.LT_EQ); | 2138 _computeBinaryExpressionType(TokenType.LT_EQ); |
| 2128 break; | 2139 break; |
| 2129 case UnlinkedExprOperation.modulo: | 2140 case UnlinkedExprOperation.modulo: |
| 2130 _computeBinaryExpressionType(TokenType.PERCENT); | 2141 _computeBinaryExpressionType(TokenType.PERCENT); |
| 2131 break; | 2142 break; |
| 2132 case UnlinkedExprOperation.conditional: | 2143 case UnlinkedExprOperation.conditional: |
| 2133 _doConditional(); | 2144 _doConditional(); |
| 2134 break; | 2145 break; |
| 2146 case UnlinkedExprOperation.assignToIndex: |
| 2147 case UnlinkedExprOperation.assignToProperty: |
| 2135 case UnlinkedExprOperation.assignToRef: | 2148 case UnlinkedExprOperation.assignToRef: |
| 2136 _doAssignToRef(); | 2149 hasError = true; |
| 2137 break; | 2150 return DynamicTypeImpl.instance; |
| 2138 case UnlinkedExprOperation.assignToProperty: | |
| 2139 _doAssignToProperty(); | |
| 2140 break; | |
| 2141 case UnlinkedExprOperation.assignToIndex: | |
| 2142 _doAssignToIndex(); | |
| 2143 break; | |
| 2144 case UnlinkedExprOperation.await: | 2151 case UnlinkedExprOperation.await: |
| 2145 _doAwait(); | 2152 _doAwait(); |
| 2146 break; | 2153 break; |
| 2147 case UnlinkedExprOperation.extractIndex: | 2154 case UnlinkedExprOperation.extractIndex: |
| 2148 _doExtractIndex(); | 2155 _doExtractIndex(); |
| 2149 break; | 2156 break; |
| 2150 case UnlinkedExprOperation.invokeMethodRef: | 2157 case UnlinkedExprOperation.invokeMethodRef: |
| 2151 _doInvokeMethodRef(); | 2158 try { |
| 2159 _doInvokeMethodRef(); |
| 2160 } on _InferenceFailedError { |
| 2161 hasError = true; |
| 2162 return DynamicTypeImpl.instance; |
| 2163 } |
| 2152 break; | 2164 break; |
| 2153 case UnlinkedExprOperation.invokeMethod: | 2165 case UnlinkedExprOperation.invokeMethod: |
| 2154 _doInvokeMethod(); | 2166 _doInvokeMethod(); |
| 2155 break; | 2167 break; |
| 2156 case UnlinkedExprOperation.cascadeSectionBegin: | 2168 case UnlinkedExprOperation.cascadeSectionBegin: |
| 2157 stack.add(stack.last); | 2169 stack.add(stack.last); |
| 2158 break; | 2170 break; |
| 2159 case UnlinkedExprOperation.cascadeSectionEnd: | 2171 case UnlinkedExprOperation.cascadeSectionEnd: |
| 2160 stack.removeLast(); | 2172 stack.removeLast(); |
| 2161 break; | 2173 break; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2210 operand.lookUpInheritedMethod(operatorName, library: library); | 2222 operand.lookUpInheritedMethod(operatorName, library: library); |
| 2211 if (method != null) { | 2223 if (method != null) { |
| 2212 DartType type = method.returnType; | 2224 DartType type = method.returnType; |
| 2213 stack.add(type); | 2225 stack.add(type); |
| 2214 return; | 2226 return; |
| 2215 } | 2227 } |
| 2216 } | 2228 } |
| 2217 stack.add(DynamicTypeImpl.instance); | 2229 stack.add(DynamicTypeImpl.instance); |
| 2218 } | 2230 } |
| 2219 | 2231 |
| 2220 void _doAssignToIndex() { | |
| 2221 stack.removeLast(); | |
| 2222 stack.removeLast(); | |
| 2223 UnlinkedExprAssignOperator operator = | |
| 2224 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; | |
| 2225 if (operator == UnlinkedExprAssignOperator.assign) { | |
| 2226 // The type of the assignment is the type of the value, | |
| 2227 // which is already in the stack. | |
| 2228 } else if (isIncrementOrDecrement(operator)) { | |
| 2229 // TODO(scheglov) implement | |
| 2230 stack.add(DynamicTypeImpl.instance); | |
| 2231 } else { | |
| 2232 stack.removeLast(); | |
| 2233 // TODO(scheglov) implement | |
| 2234 stack.add(DynamicTypeImpl.instance); | |
| 2235 } | |
| 2236 } | |
| 2237 | |
| 2238 void _doAssignToProperty() { | |
| 2239 DartType targetType = stack.removeLast(); | |
| 2240 String propertyName = _getNextString(); | |
| 2241 UnlinkedExprAssignOperator assignOperator = | |
| 2242 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; | |
| 2243 if (assignOperator == UnlinkedExprAssignOperator.assign) { | |
| 2244 // The type of the assignment is the type of the value, | |
| 2245 // which is already in the stack. | |
| 2246 } else if (assignOperator == UnlinkedExprAssignOperator.postfixDecrement || | |
| 2247 assignOperator == UnlinkedExprAssignOperator.postfixIncrement) { | |
| 2248 DartType propertyType = _getPropertyType(targetType, propertyName); | |
| 2249 stack.add(propertyType); | |
| 2250 } else if (assignOperator == UnlinkedExprAssignOperator.prefixDecrement) { | |
| 2251 _pushPropertyBinaryExpression( | |
| 2252 targetType, propertyName, TokenType.MINUS, typeProvider.intType); | |
| 2253 } else if (assignOperator == UnlinkedExprAssignOperator.prefixIncrement) { | |
| 2254 _pushPropertyBinaryExpression( | |
| 2255 targetType, propertyName, TokenType.PLUS, typeProvider.intType); | |
| 2256 } else { | |
| 2257 TokenType binaryOperator = | |
| 2258 _convertAssignOperatorToTokenType(assignOperator); | |
| 2259 DartType operandType = stack.removeLast(); | |
| 2260 _pushPropertyBinaryExpression( | |
| 2261 targetType, propertyName, binaryOperator, operandType); | |
| 2262 } | |
| 2263 } | |
| 2264 | |
| 2265 void _doAssignToRef() { | |
| 2266 refPtr++; | |
| 2267 UnlinkedExprAssignOperator operator = | |
| 2268 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; | |
| 2269 if (operator == UnlinkedExprAssignOperator.assign) { | |
| 2270 // The type of the assignment is the type of the value, | |
| 2271 // which is already in the stack. | |
| 2272 } else if (isIncrementOrDecrement(operator)) { | |
| 2273 // TODO(scheglov) implement | |
| 2274 stack.add(DynamicTypeImpl.instance); | |
| 2275 } else { | |
| 2276 stack.removeLast(); | |
| 2277 // TODO(scheglov) implement | |
| 2278 stack.add(DynamicTypeImpl.instance); | |
| 2279 } | |
| 2280 } | |
| 2281 | |
| 2282 void _doAwait() { | 2232 void _doAwait() { |
| 2283 DartType type = stack.removeLast(); | 2233 DartType type = stack.removeLast(); |
| 2284 DartType typeArgument = type?.flattenFutures(linker.typeSystem); | 2234 DartType typeArgument = type?.flattenFutures(linker.typeSystem); |
| 2285 typeArgument = _dynamicIfNull(typeArgument); | 2235 typeArgument = _dynamicIfNull(typeArgument); |
| 2286 stack.add(typeArgument); | 2236 stack.add(typeArgument); |
| 2287 } | 2237 } |
| 2288 | 2238 |
| 2289 void _doConditional() { | 2239 void _doConditional() { |
| 2290 DartType elseType = stack.removeLast(); | 2240 DartType elseType = stack.removeLast(); |
| 2291 DartType thenType = stack.removeLast(); | 2241 DartType thenType = stack.removeLast(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2314 DartType target = stack.removeLast(); | 2264 DartType target = stack.removeLast(); |
| 2315 if (target.isDynamic) { | 2265 if (target.isDynamic) { |
| 2316 target = typeProvider.objectType; | 2266 target = typeProvider.objectType; |
| 2317 } | 2267 } |
| 2318 String propertyName = _getNextString(); | 2268 String propertyName = _getNextString(); |
| 2319 stack.add(() { | 2269 stack.add(() { |
| 2320 if (target is InterfaceType) { | 2270 if (target is InterfaceType) { |
| 2321 ExecutableElement element = target | 2271 ExecutableElement element = target |
| 2322 .lookUpInheritedGetterOrMethod(propertyName, library: library); | 2272 .lookUpInheritedGetterOrMethod(propertyName, library: library); |
| 2323 if (element != null) { | 2273 if (element != null) { |
| 2274 _throwIfInstanceFieldOrAccessor(element); |
| 2324 if (element is PropertyAccessorElement) { | 2275 if (element is PropertyAccessorElement) { |
| 2325 return element.returnType; | 2276 return element.returnType; |
| 2326 } else { | 2277 } else { |
| 2327 // Method tear-off | 2278 // Method tear-off |
| 2328 return element.type; | 2279 return element.type; |
| 2329 } | 2280 } |
| 2330 } | 2281 } |
| 2331 } | 2282 } |
| 2332 return DynamicTypeImpl.instance; | 2283 return DynamicTypeImpl.instance; |
| 2333 }()); | 2284 }()); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2429 } | 2380 } |
| 2430 | 2381 |
| 2431 void _doInvokeMethodRef() { | 2382 void _doInvokeMethodRef() { |
| 2432 int numNamed = _getNextInt(); | 2383 int numNamed = _getNextInt(); |
| 2433 int numPositional = _getNextInt(); | 2384 int numPositional = _getNextInt(); |
| 2434 List<String> namedArgNames = _getNextStrings(numNamed); | 2385 List<String> namedArgNames = _getNextStrings(numNamed); |
| 2435 List<DartType> namedArgTypeList = _popList(numNamed); | 2386 List<DartType> namedArgTypeList = _popList(numNamed); |
| 2436 List<DartType> positionalArgTypes = _popList(numPositional); | 2387 List<DartType> positionalArgTypes = _popList(numPositional); |
| 2437 EntityRef ref = _getNextRef(); | 2388 EntityRef ref = _getNextRef(); |
| 2438 ReferenceableElementForLink element = unit.resolveRef(ref.reference); | 2389 ReferenceableElementForLink element = unit.resolveRef(ref.reference); |
| 2390 _throwIfInstanceFieldOrAccessor(element); |
| 2439 List<DartType> typeArguments = _getTypeArguments(); | 2391 List<DartType> typeArguments = _getTypeArguments(); |
| 2440 stack.add(() { | 2392 stack.add(() { |
| 2441 DartType rawType = element.asStaticType; | 2393 DartType rawType = element.asStaticType; |
| 2442 if (rawType is FunctionType) { | 2394 if (rawType is FunctionType) { |
| 2443 FunctionType inferredType = _inferExecutableType( | 2395 FunctionType inferredType = _inferExecutableType( |
| 2444 rawType, | 2396 rawType, |
| 2445 numNamed, | 2397 numNamed, |
| 2446 numPositional, | 2398 numPositional, |
| 2447 namedArgNames, | 2399 namedArgNames, |
| 2448 namedArgTypeList, | 2400 namedArgTypeList, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2502 if (ref.paramReference != 0) { | 2454 if (ref.paramReference != 0) { |
| 2503 stack.add(typeProvider.typeType); | 2455 stack.add(typeProvider.typeType); |
| 2504 } else { | 2456 } else { |
| 2505 // Synthetic function types can't be directly referred | 2457 // Synthetic function types can't be directly referred |
| 2506 // to by expressions. | 2458 // to by expressions. |
| 2507 assert(ref.syntheticReturnType == null); | 2459 assert(ref.syntheticReturnType == null); |
| 2508 // Nor can implicit function types derived from | 2460 // Nor can implicit function types derived from |
| 2509 // function-typed parameters. | 2461 // function-typed parameters. |
| 2510 assert(ref.implicitFunctionTypeIndices.isEmpty); | 2462 assert(ref.implicitFunctionTypeIndices.isEmpty); |
| 2511 ReferenceableElementForLink element = unit.resolveRef(ref.reference); | 2463 ReferenceableElementForLink element = unit.resolveRef(ref.reference); |
| 2464 _throwIfInstanceFieldOrAccessor(element); |
| 2512 stack.add(element.asStaticType); | 2465 stack.add(element.asStaticType); |
| 2513 } | 2466 } |
| 2514 } | 2467 } |
| 2515 | 2468 |
| 2516 /** | 2469 /** |
| 2517 * Find the parameter in scope called [parameterName] and return its type. | 2470 * Find the parameter in scope called [parameterName] and return its type. |
| 2518 */ | 2471 */ |
| 2519 DartType _findParameterType(String parameterName) { | 2472 DartType _findParameterType(String parameterName) { |
| 2520 FunctionElementForLink_Local f = this.function; | 2473 FunctionElementForLink_Local f = this.function; |
| 2521 while (true) { | 2474 while (true) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2552 result[i] = _getNextString(); | 2505 result[i] = _getNextString(); |
| 2553 } | 2506 } |
| 2554 return result; | 2507 return result; |
| 2555 } | 2508 } |
| 2556 | 2509 |
| 2557 DartType _getNextTypeRef() { | 2510 DartType _getNextTypeRef() { |
| 2558 EntityRef ref = _getNextRef(); | 2511 EntityRef ref = _getNextRef(); |
| 2559 return unit.resolveTypeRef(ref, function.typeParameterContext); | 2512 return unit.resolveTypeRef(ref, function.typeParameterContext); |
| 2560 } | 2513 } |
| 2561 | 2514 |
| 2562 /** | |
| 2563 * Return the type of the property with the given [propertyName] in the | |
| 2564 * given [targetType]. May return `dynamic` if the property cannot be | |
| 2565 * resolved. | |
| 2566 */ | |
| 2567 DartType _getPropertyType(DartType targetType, String propertyName) { | |
| 2568 return targetType is InterfaceType | |
| 2569 ? targetType | |
| 2570 .lookUpInheritedGetter(propertyName, library: library) | |
| 2571 ?.returnType | |
| 2572 : DynamicTypeImpl.instance; | |
| 2573 } | |
| 2574 | |
| 2575 List<DartType> _getTypeArguments() { | 2515 List<DartType> _getTypeArguments() { |
| 2576 int numTypeArguments = _getNextInt(); | 2516 int numTypeArguments = _getNextInt(); |
| 2577 List<DartType> typeArguments = new List<DartType>(numTypeArguments); | 2517 List<DartType> typeArguments = new List<DartType>(numTypeArguments); |
| 2578 for (int i = 0; i < numTypeArguments; i++) { | 2518 for (int i = 0; i < numTypeArguments; i++) { |
| 2579 typeArguments[i] = _getNextTypeRef(); | 2519 typeArguments[i] = _getNextTypeRef(); |
| 2580 } | 2520 } |
| 2581 return typeArguments; | 2521 return typeArguments; |
| 2582 } | 2522 } |
| 2583 | 2523 |
| 2584 FunctionType _inferExecutableType( | 2524 FunctionType _inferExecutableType( |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2655 DartType type = method.returnType; | 2595 DartType type = method.returnType; |
| 2656 type = linker.typeSystem | 2596 type = linker.typeSystem |
| 2657 .refineBinaryExpressionType(left, operator, right, type); | 2597 .refineBinaryExpressionType(left, operator, right, type); |
| 2658 stack.add(type); | 2598 stack.add(type); |
| 2659 return; | 2599 return; |
| 2660 } | 2600 } |
| 2661 } | 2601 } |
| 2662 stack.add(DynamicTypeImpl.instance); | 2602 stack.add(DynamicTypeImpl.instance); |
| 2663 } | 2603 } |
| 2664 | 2604 |
| 2665 /** | 2605 void _throwIfInstanceFieldOrAccessor(Object element) { |
| 2666 * Extract the property with the given [propertyName], apply the operator | 2606 if (element is NonstaticMemberElementForLink && |
| 2667 * with the given [operandType], push the type of applying operand of the | 2607 element.hasInstanceGetterReference || |
| 2668 * given [operandType]. | 2608 element is FieldElement && !element.isStatic || |
| 2669 */ | 2609 element is PropertyAccessorElement && !element.isStatic) { |
| 2670 void _pushPropertyBinaryExpression(DartType targetType, String propertyName, | 2610 throw new _InferenceFailedError( |
| 2671 TokenType operator, DartType operandType) { | 2611 'Instance fields cannot be used for type inference.'); |
| 2672 DartType propertyType = _getPropertyType(targetType, propertyName); | |
| 2673 _pushBinaryOperatorType(propertyType, operator, operandType); | |
| 2674 } | |
| 2675 | |
| 2676 static TokenType _convertAssignOperatorToTokenType( | |
| 2677 UnlinkedExprAssignOperator o) { | |
| 2678 switch (o) { | |
| 2679 case UnlinkedExprAssignOperator.assign: | |
| 2680 return null; | |
| 2681 case UnlinkedExprAssignOperator.ifNull: | |
| 2682 return TokenType.QUESTION_QUESTION; | |
| 2683 case UnlinkedExprAssignOperator.multiply: | |
| 2684 return TokenType.STAR; | |
| 2685 case UnlinkedExprAssignOperator.divide: | |
| 2686 return TokenType.SLASH; | |
| 2687 case UnlinkedExprAssignOperator.floorDivide: | |
| 2688 return TokenType.TILDE_SLASH; | |
| 2689 case UnlinkedExprAssignOperator.modulo: | |
| 2690 return TokenType.PERCENT; | |
| 2691 case UnlinkedExprAssignOperator.plus: | |
| 2692 return TokenType.PLUS; | |
| 2693 case UnlinkedExprAssignOperator.minus: | |
| 2694 return TokenType.MINUS; | |
| 2695 case UnlinkedExprAssignOperator.shiftLeft: | |
| 2696 return TokenType.LT_LT; | |
| 2697 case UnlinkedExprAssignOperator.shiftRight: | |
| 2698 return TokenType.GT_GT; | |
| 2699 case UnlinkedExprAssignOperator.bitAnd: | |
| 2700 return TokenType.AMPERSAND; | |
| 2701 case UnlinkedExprAssignOperator.bitXor: | |
| 2702 return TokenType.CARET; | |
| 2703 case UnlinkedExprAssignOperator.bitOr: | |
| 2704 return TokenType.BAR; | |
| 2705 case UnlinkedExprAssignOperator.prefixIncrement: | |
| 2706 return TokenType.PLUS_PLUS; | |
| 2707 case UnlinkedExprAssignOperator.prefixDecrement: | |
| 2708 return TokenType.MINUS_MINUS; | |
| 2709 case UnlinkedExprAssignOperator.postfixIncrement: | |
| 2710 return TokenType.PLUS_PLUS; | |
| 2711 case UnlinkedExprAssignOperator.postfixDecrement: | |
| 2712 return TokenType.MINUS_MINUS; | |
| 2713 } | 2612 } |
| 2714 return null; | |
| 2715 } | 2613 } |
| 2716 } | 2614 } |
| 2717 | 2615 |
| 2718 /** | 2616 /** |
| 2719 * Element representing a field resynthesized from a summary during | 2617 * Element representing a field resynthesized from a summary during |
| 2720 * linking. | 2618 * linking. |
| 2721 */ | 2619 */ |
| 2722 abstract class FieldElementForLink implements FieldElement { | 2620 abstract class FieldElementForLink implements FieldElement { |
| 2723 @override | 2621 @override |
| 2724 PropertyAccessorElementForLink get getter; | 2622 PropertyAccessorElementForLink get getter; |
| (...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3926 * The name of the non-static members that is being accessed. | 3824 * The name of the non-static members that is being accessed. |
| 3927 */ | 3825 */ |
| 3928 final String _name; | 3826 final String _name; |
| 3929 | 3827 |
| 3930 /** | 3828 /** |
| 3931 * The library in which the access occurs. This determines whether private | 3829 * The library in which the access occurs. This determines whether private |
| 3932 * names are accessible. | 3830 * names are accessible. |
| 3933 */ | 3831 */ |
| 3934 final LibraryElementForLink _library; | 3832 final LibraryElementForLink _library; |
| 3935 | 3833 |
| 3834 /** |
| 3835 * Whether the [_element] was computed (even if to `null`). |
| 3836 */ |
| 3837 bool _elementReady = false; |
| 3838 |
| 3839 /** |
| 3840 * The cached [ExecutableElement] represented by this element. |
| 3841 */ |
| 3842 ExecutableElement _element; |
| 3843 |
| 3936 NonstaticMemberElementForLink(this._library, this._target, this._name); | 3844 NonstaticMemberElementForLink(this._library, this._target, this._name); |
| 3937 | 3845 |
| 3938 @override | 3846 @override |
| 3939 ConstVariableNode get asConstVariable => _target.asConstVariable; | 3847 ConstVariableNode get asConstVariable => _target.asConstVariable; |
| 3940 | 3848 |
| 3941 @override | 3849 /** |
| 3942 DartType get asStaticType { | 3850 * Return the [ExecutableElement] represented by this element. |
| 3943 if (_library._linker.strongMode) { | 3851 */ |
| 3852 ExecutableElement get asExecutableElement { |
| 3853 if (!_elementReady) { |
| 3854 _elementReady = true; |
| 3944 DartType targetType = _target.asStaticType; | 3855 DartType targetType = _target.asStaticType; |
| 3945 if (targetType.isDynamic) { | 3856 if (targetType.isDynamic) { |
| 3946 targetType = _library._linker.typeProvider.objectType; | 3857 targetType = _library._linker.typeProvider.objectType; |
| 3947 } | 3858 } |
| 3948 if (targetType is InterfaceType) { | 3859 if (targetType is InterfaceType) { |
| 3949 ExecutableElement element = | 3860 _element = |
| 3950 targetType.lookUpInheritedGetterOrMethod(_name, library: _library); | 3861 targetType.lookUpInheritedGetterOrMethod(_name, library: _library); |
| 3951 if (element != null) { | |
| 3952 if (element is PropertyAccessorElement) { | |
| 3953 return element.returnType; | |
| 3954 } else { | |
| 3955 // Method tear-off | |
| 3956 return element.type; | |
| 3957 } | |
| 3958 } | |
| 3959 } | 3862 } |
| 3960 // TODO(paulberry): handle .call on function types and .toString or | 3863 // TODO(paulberry): handle .call on function types and .toString or |
| 3961 // .hashCode on all types. | 3864 // .hashCode on all types. |
| 3962 } | 3865 } |
| 3866 return _element; |
| 3867 } |
| 3868 |
| 3869 @override |
| 3870 DartType get asStaticType { |
| 3871 if (_library._linker.strongMode) { |
| 3872 ExecutableElement element = asExecutableElement; |
| 3873 if (element != null) { |
| 3874 if (element is PropertyAccessorElement) { |
| 3875 return element.returnType; |
| 3876 } else { |
| 3877 // Method tear-off |
| 3878 return element.type; |
| 3879 } |
| 3880 } |
| 3881 } |
| 3963 return DynamicTypeImpl.instance; | 3882 return DynamicTypeImpl.instance; |
| 3964 } | 3883 } |
| 3965 | 3884 |
| 3966 @override | 3885 @override |
| 3967 TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode; | 3886 TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode; |
| 3968 | 3887 |
| 3888 /** |
| 3889 * Return `true` if this element is an instance getter, or its target |
| 3890 * is an instance getter (recursively). |
| 3891 */ |
| 3892 bool get hasInstanceGetterReference { |
| 3893 ExecutableElement element = asExecutableElement; |
| 3894 if (element is PropertyAccessorElement) { |
| 3895 return !element.isStatic; |
| 3896 } |
| 3897 ReferenceableElementForLink target = _target; |
| 3898 if (target is NonstaticMemberElementForLink) { |
| 3899 return target.hasInstanceGetterReference; |
| 3900 } |
| 3901 return false; |
| 3902 } |
| 3903 |
| 3969 @override | 3904 @override |
| 3970 ReferenceableElementForLink getContainedName(String name) { | 3905 ReferenceableElementForLink getContainedName(String name) { |
| 3971 return new NonstaticMemberElementForLink(_library, this, name); | 3906 return new NonstaticMemberElementForLink(_library, this, name); |
| 3972 } | 3907 } |
| 3973 | 3908 |
| 3974 @override | 3909 @override |
| 3975 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 3910 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 3976 | 3911 |
| 3977 @override | 3912 @override |
| 3978 String toString() => '$_target.(dynamic)$_name'; | 3913 String toString() => '$_target.(dynamic)$_name'; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4173 @override | 4108 @override |
| 4174 bool get isSynthetic => true; | 4109 bool get isSynthetic => true; |
| 4175 | 4110 |
| 4176 @override | 4111 @override |
| 4177 String get name => 'x'; | 4112 String get name => 'x'; |
| 4178 | 4113 |
| 4179 @override | 4114 @override |
| 4180 ParameterKind get parameterKind => ParameterKind.REQUIRED; | 4115 ParameterKind get parameterKind => ParameterKind.REQUIRED; |
| 4181 | 4116 |
| 4182 @override | 4117 @override |
| 4183 DartType get type => enclosingElement.computeVariableType(); | 4118 DartType get type => enclosingElement.variable.type; |
| 4184 | 4119 |
| 4185 @override | 4120 @override |
| 4186 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 4121 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 4187 } | 4122 } |
| 4188 | 4123 |
| 4189 /** | 4124 /** |
| 4190 * Mixin used by elements that can have parameters. | 4125 * Mixin used by elements that can have parameters. |
| 4191 */ | 4126 */ |
| 4192 abstract class ParameterParentElementForLink implements Element { | 4127 abstract class ParameterParentElementForLink implements Element { |
| 4193 List<ParameterElement> _parameters; | 4128 List<ParameterElement> _parameters; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4445 } | 4380 } |
| 4446 } | 4381 } |
| 4447 return _parameters; | 4382 return _parameters; |
| 4448 } | 4383 } |
| 4449 | 4384 |
| 4450 @override | 4385 @override |
| 4451 DartType get returnType { | 4386 DartType get returnType { |
| 4452 if (isSetter) { | 4387 if (isSetter) { |
| 4453 return VoidTypeImpl.instance; | 4388 return VoidTypeImpl.instance; |
| 4454 } else { | 4389 } else { |
| 4455 return computeVariableType(); | 4390 return variable.type; |
| 4456 } | 4391 } |
| 4457 } | 4392 } |
| 4458 | 4393 |
| 4459 @override | 4394 @override |
| 4460 FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this); | 4395 FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this); |
| 4461 | 4396 |
| 4462 @override | 4397 @override |
| 4463 List<TypeParameterElement> get typeParameters { | 4398 List<TypeParameterElement> get typeParameters { |
| 4464 // TODO(paulberry): is this correct for fields in generic classes? | 4399 // TODO(paulberry): is this correct for fields in generic classes? |
| 4465 return const []; | 4400 return const []; |
| 4466 } | 4401 } |
| 4467 | 4402 |
| 4468 /** | |
| 4469 * Compute the type of the corresponding variable, which may depend on the | |
| 4470 * progress of type inference. | |
| 4471 */ | |
| 4472 DartType computeVariableType() { | |
| 4473 if (variable.hasImplicitType && | |
| 4474 !isStatic && | |
| 4475 !variable.compilationUnit.isTypeInferenceComplete) { | |
| 4476 // This is an instance field and we are currently inferring types in the | |
| 4477 // library cycle containing it. So we shouldn't use the inferred type | |
| 4478 // (even if we have already computed it), since that would lead to | |
| 4479 // non-deterministic type inference results. | |
| 4480 return DynamicTypeImpl.instance; | |
| 4481 } else { | |
| 4482 return variable.type; | |
| 4483 } | |
| 4484 } | |
| 4485 | |
| 4486 @override | 4403 @override |
| 4487 ReferenceableElementForLink getContainedName(String name) { | 4404 ReferenceableElementForLink getContainedName(String name) { |
| 4488 return new NonstaticMemberElementForLink(library, this, name); | 4405 return new NonstaticMemberElementForLink(library, this, name); |
| 4489 } | 4406 } |
| 4490 | 4407 |
| 4491 @override | 4408 @override |
| 4492 FunctionElementForLink_Local getLocalFunction(int index) { | 4409 FunctionElementForLink_Local getLocalFunction(int index) { |
| 4493 if (index == 0) { | 4410 if (index == 0) { |
| 4494 return variable.initializer; | 4411 return variable.initializer; |
| 4495 } else { | 4412 } else { |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4840 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[]; | 4757 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[]; |
| 4841 collectDependencies(dependencies, functionElement._unlinkedExecutable, | 4758 collectDependencies(dependencies, functionElement._unlinkedExecutable, |
| 4842 functionElement.compilationUnit); | 4759 functionElement.compilationUnit); |
| 4843 return dependencies; | 4760 return dependencies; |
| 4844 } | 4761 } |
| 4845 | 4762 |
| 4846 void evaluate(bool inCycle) { | 4763 void evaluate(bool inCycle) { |
| 4847 if (inCycle) { | 4764 if (inCycle) { |
| 4848 functionElement._setInferredType(DynamicTypeImpl.instance); | 4765 functionElement._setInferredType(DynamicTypeImpl.instance); |
| 4849 } else { | 4766 } else { |
| 4850 var bodyType = new ExprTypeComputer(functionElement).compute(); | 4767 var computer = new ExprTypeComputer(functionElement); |
| 4851 if (functionElement.isAsynchronous) { | 4768 DartType bodyType = computer.compute(); |
| 4852 var linker = functionElement.compilationUnit.library._linker; | 4769 if (computer.hasError) { |
| 4853 var typeProvider = linker.typeProvider; | 4770 functionElement._setInferredType(DynamicTypeImpl.instance); |
| 4854 var typeSystem = linker.typeSystem; | 4771 } else { |
| 4855 if (bodyType.isDartAsyncFutureOr) { | 4772 if (functionElement.isAsynchronous) { |
| 4856 bodyType = (bodyType as InterfaceType).typeArguments[0]; | 4773 var linker = functionElement.compilationUnit.library._linker; |
| 4774 var typeProvider = linker.typeProvider; |
| 4775 var typeSystem = linker.typeSystem; |
| 4776 if (bodyType.isDartAsyncFutureOr) { |
| 4777 bodyType = (bodyType as InterfaceType).typeArguments[0]; |
| 4778 } |
| 4779 bodyType = typeProvider.futureType |
| 4780 .instantiate([bodyType.flattenFutures(typeSystem)]); |
| 4857 } | 4781 } |
| 4858 bodyType = typeProvider.futureType | 4782 functionElement._setInferredType(bodyType); |
| 4859 .instantiate([bodyType.flattenFutures(typeSystem)]); | |
| 4860 } | 4783 } |
| 4861 functionElement._setInferredType(bodyType); | |
| 4862 } | 4784 } |
| 4863 } | 4785 } |
| 4864 | 4786 |
| 4865 @override | 4787 @override |
| 4866 String toString() => 'TypeInferenceNode($functionElement)'; | 4788 String toString() => 'TypeInferenceNode($functionElement)'; |
| 4867 } | 4789 } |
| 4868 | 4790 |
| 4869 class TypeProviderForLink extends TypeProviderBase { | 4791 class TypeProviderForLink extends TypeProviderBase { |
| 4870 final Linker _linker; | 4792 final Linker _linker; |
| 4871 | 4793 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5183 * there are no type parameters in scope. | 5105 * there are no type parameters in scope. |
| 5184 */ | 5106 */ |
| 5185 TypeParameterizedElementMixin get _typeParameterContext; | 5107 TypeParameterizedElementMixin get _typeParameterContext; |
| 5186 | 5108 |
| 5187 @override | 5109 @override |
| 5188 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 5110 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 5189 | 5111 |
| 5190 @override | 5112 @override |
| 5191 String toString() => '$enclosingElement.$name'; | 5113 String toString() => '$enclosingElement.$name'; |
| 5192 } | 5114 } |
| 5115 |
| 5116 /** |
| 5117 * This exception is thrown when [ExprTypeComputer] cannot inference the type. |
| 5118 */ |
| 5119 class _InferenceFailedError { |
| 5120 final String message; |
| 5121 |
| 5122 _InferenceFailedError(this.message); |
| 5123 } |
| OLD | NEW |