| 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 1965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1976 final Linker linker; | 1976 final Linker linker; |
| 1977 final TypeProvider typeProvider; | 1977 final TypeProvider typeProvider; |
| 1978 final UnlinkedExpr unlinkedConst; | 1978 final UnlinkedExpr unlinkedConst; |
| 1979 | 1979 |
| 1980 final List<DartType> stack = <DartType>[]; | 1980 final List<DartType> stack = <DartType>[]; |
| 1981 int intPtr = 0; | 1981 int intPtr = 0; |
| 1982 int refPtr = 0; | 1982 int refPtr = 0; |
| 1983 int strPtr = 0; | 1983 int strPtr = 0; |
| 1984 int assignmentOperatorPtr = 0; | 1984 int assignmentOperatorPtr = 0; |
| 1985 | 1985 |
| 1986 bool hasError = false; |
| 1987 |
| 1986 factory ExprTypeComputer(FunctionElementForLink_Local functionElement) { | 1988 factory ExprTypeComputer(FunctionElementForLink_Local functionElement) { |
| 1987 CompilationUnitElementForLink unit = functionElement.compilationUnit; | 1989 CompilationUnitElementForLink unit = functionElement.compilationUnit; |
| 1988 LibraryElementForLink library = unit.enclosingElement; | 1990 LibraryElementForLink library = unit.enclosingElement; |
| 1989 Linker linker = library._linker; | 1991 Linker linker = library._linker; |
| 1990 TypeProvider typeProvider = linker.typeProvider; | 1992 TypeProvider typeProvider = linker.typeProvider; |
| 1991 UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr; | 1993 UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr; |
| 1992 return new ExprTypeComputer._( | 1994 return new ExprTypeComputer._( |
| 1993 functionElement, unit, library, linker, typeProvider, unlinkedConst); | 1995 functionElement, unit, library, linker, typeProvider, unlinkedConst); |
| 1994 } | 1996 } |
| 1995 | 1997 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 case UnlinkedExprOperation.pushNull: | 2042 case UnlinkedExprOperation.pushNull: |
| 2041 stack.add(typeProvider.nullType); | 2043 stack.add(typeProvider.nullType); |
| 2042 break; | 2044 break; |
| 2043 case UnlinkedExprOperation.pushSuper: | 2045 case UnlinkedExprOperation.pushSuper: |
| 2044 stack.add(DynamicTypeImpl.instance); | 2046 stack.add(DynamicTypeImpl.instance); |
| 2045 break; | 2047 break; |
| 2046 case UnlinkedExprOperation.pushThis: | 2048 case UnlinkedExprOperation.pushThis: |
| 2047 stack.add(DynamicTypeImpl.instance); | 2049 stack.add(DynamicTypeImpl.instance); |
| 2048 break; | 2050 break; |
| 2049 case UnlinkedExprOperation.pushReference: | 2051 case UnlinkedExprOperation.pushReference: |
| 2050 _doPushReference(); | 2052 try { |
| 2053 _doPushReference(); |
| 2054 } on _InferenceFailedError { |
| 2055 hasError = true; |
| 2056 return DynamicTypeImpl.instance; |
| 2057 } |
| 2051 break; | 2058 break; |
| 2052 case UnlinkedExprOperation.extractProperty: | 2059 case UnlinkedExprOperation.extractProperty: |
| 2053 _doExtractProperty(); | 2060 try { |
| 2061 _doExtractProperty(); |
| 2062 } on _InferenceFailedError { |
| 2063 hasError = true; |
| 2064 return DynamicTypeImpl.instance; |
| 2065 } |
| 2054 break; | 2066 break; |
| 2055 case UnlinkedExprOperation.invokeConstructor: | 2067 case UnlinkedExprOperation.invokeConstructor: |
| 2056 _doInvokeConstructor(); | 2068 _doInvokeConstructor(); |
| 2057 break; | 2069 break; |
| 2058 case UnlinkedExprOperation.makeUntypedList: | 2070 case UnlinkedExprOperation.makeUntypedList: |
| 2059 _doMakeUntypedList(); | 2071 _doMakeUntypedList(); |
| 2060 break; | 2072 break; |
| 2061 case UnlinkedExprOperation.makeUntypedMap: | 2073 case UnlinkedExprOperation.makeUntypedMap: |
| 2062 _doMakeUntypedMap(); | 2074 _doMakeUntypedMap(); |
| 2063 break; | 2075 break; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2126 case UnlinkedExprOperation.lessEqual: | 2138 case UnlinkedExprOperation.lessEqual: |
| 2127 _computeBinaryExpressionType(TokenType.LT_EQ); | 2139 _computeBinaryExpressionType(TokenType.LT_EQ); |
| 2128 break; | 2140 break; |
| 2129 case UnlinkedExprOperation.modulo: | 2141 case UnlinkedExprOperation.modulo: |
| 2130 _computeBinaryExpressionType(TokenType.PERCENT); | 2142 _computeBinaryExpressionType(TokenType.PERCENT); |
| 2131 break; | 2143 break; |
| 2132 case UnlinkedExprOperation.conditional: | 2144 case UnlinkedExprOperation.conditional: |
| 2133 _doConditional(); | 2145 _doConditional(); |
| 2134 break; | 2146 break; |
| 2135 case UnlinkedExprOperation.assignToRef: | 2147 case UnlinkedExprOperation.assignToRef: |
| 2136 _doAssignToRef(); | 2148 try { |
| 2149 _doAssignToRef(); |
| 2150 } on _InferenceFailedError { |
| 2151 hasError = true; |
| 2152 return DynamicTypeImpl.instance; |
| 2153 } |
| 2137 break; | 2154 break; |
| 2138 case UnlinkedExprOperation.assignToProperty: | 2155 case UnlinkedExprOperation.assignToProperty: |
| 2139 _doAssignToProperty(); | 2156 try { |
| 2157 _doAssignToProperty(); |
| 2158 } on _InferenceFailedError { |
| 2159 hasError = true; |
| 2160 return DynamicTypeImpl.instance; |
| 2161 } |
| 2140 break; | 2162 break; |
| 2141 case UnlinkedExprOperation.assignToIndex: | 2163 case UnlinkedExprOperation.assignToIndex: |
| 2142 _doAssignToIndex(); | 2164 _doAssignToIndex(); |
| 2143 break; | 2165 break; |
| 2144 case UnlinkedExprOperation.await: | 2166 case UnlinkedExprOperation.await: |
| 2145 _doAwait(); | 2167 _doAwait(); |
| 2146 break; | 2168 break; |
| 2147 case UnlinkedExprOperation.extractIndex: | 2169 case UnlinkedExprOperation.extractIndex: |
| 2148 _doExtractIndex(); | 2170 _doExtractIndex(); |
| 2149 break; | 2171 break; |
| 2150 case UnlinkedExprOperation.invokeMethodRef: | 2172 case UnlinkedExprOperation.invokeMethodRef: |
| 2151 _doInvokeMethodRef(); | 2173 try { |
| 2174 _doInvokeMethodRef(); |
| 2175 } on _InferenceFailedError { |
| 2176 hasError = true; |
| 2177 return DynamicTypeImpl.instance; |
| 2178 } |
| 2152 break; | 2179 break; |
| 2153 case UnlinkedExprOperation.invokeMethod: | 2180 case UnlinkedExprOperation.invokeMethod: |
| 2154 _doInvokeMethod(); | 2181 _doInvokeMethod(); |
| 2155 break; | 2182 break; |
| 2156 case UnlinkedExprOperation.cascadeSectionBegin: | 2183 case UnlinkedExprOperation.cascadeSectionBegin: |
| 2157 stack.add(stack.last); | 2184 stack.add(stack.last); |
| 2158 break; | 2185 break; |
| 2159 case UnlinkedExprOperation.cascadeSectionEnd: | 2186 case UnlinkedExprOperation.cascadeSectionEnd: |
| 2160 stack.removeLast(); | 2187 stack.removeLast(); |
| 2161 break; | 2188 break; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2228 } else if (isIncrementOrDecrement(operator)) { | 2255 } else if (isIncrementOrDecrement(operator)) { |
| 2229 // TODO(scheglov) implement | 2256 // TODO(scheglov) implement |
| 2230 stack.add(DynamicTypeImpl.instance); | 2257 stack.add(DynamicTypeImpl.instance); |
| 2231 } else { | 2258 } else { |
| 2232 stack.removeLast(); | 2259 stack.removeLast(); |
| 2233 // TODO(scheglov) implement | 2260 // TODO(scheglov) implement |
| 2234 stack.add(DynamicTypeImpl.instance); | 2261 stack.add(DynamicTypeImpl.instance); |
| 2235 } | 2262 } |
| 2236 } | 2263 } |
| 2237 | 2264 |
| 2265 void _throwIfInstanceFieldOrAccessor(Object element) { |
| 2266 // if (element is NonstaticMemberElementForLink) { |
| 2267 // element = (element as NonstaticMemberElementForLink).asExecutableElement
; |
| 2268 // } |
| 2269 if (element is NonstaticMemberElementForLink && |
| 2270 element.hasInstanceGetterReference || |
| 2271 element is FieldElement && !element.isStatic || |
| 2272 element is PropertyAccessorElement && !element.isStatic) { |
| 2273 throw new _InferenceFailedError( |
| 2274 'Instance fields cannot be used for type inference.'); |
| 2275 } |
| 2276 } |
| 2277 |
| 2238 void _doAssignToProperty() { | 2278 void _doAssignToProperty() { |
| 2279 // if (!element.isStatic) { |
| 2280 throw new _InferenceFailedError( |
| 2281 'Instance fields cannot be used for type inference.'); |
| 2282 // } |
| 2239 DartType targetType = stack.removeLast(); | 2283 DartType targetType = stack.removeLast(); |
| 2240 String propertyName = _getNextString(); | 2284 String propertyName = _getNextString(); |
| 2241 UnlinkedExprAssignOperator assignOperator = | 2285 UnlinkedExprAssignOperator assignOperator = |
| 2242 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; | 2286 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; |
| 2243 if (assignOperator == UnlinkedExprAssignOperator.assign) { | 2287 if (assignOperator == UnlinkedExprAssignOperator.assign) { |
| 2244 // The type of the assignment is the type of the value, | 2288 // The type of the assignment is the type of the value, |
| 2245 // which is already in the stack. | 2289 // which is already in the stack. |
| 2246 } else if (assignOperator == UnlinkedExprAssignOperator.postfixDecrement || | 2290 } else if (assignOperator == UnlinkedExprAssignOperator.postfixDecrement || |
| 2247 assignOperator == UnlinkedExprAssignOperator.postfixIncrement) { | 2291 assignOperator == UnlinkedExprAssignOperator.postfixIncrement) { |
| 2248 DartType propertyType = _getPropertyType(targetType, propertyName); | 2292 DartType propertyType = _getPropertyType(targetType, propertyName); |
| 2249 stack.add(propertyType); | 2293 stack.add(propertyType); |
| 2250 } else if (assignOperator == UnlinkedExprAssignOperator.prefixDecrement) { | 2294 } else if (assignOperator == UnlinkedExprAssignOperator.prefixDecrement) { |
| 2251 _pushPropertyBinaryExpression( | 2295 _pushPropertyBinaryExpression( |
| 2252 targetType, propertyName, TokenType.MINUS, typeProvider.intType); | 2296 targetType, propertyName, TokenType.MINUS, typeProvider.intType); |
| 2253 } else if (assignOperator == UnlinkedExprAssignOperator.prefixIncrement) { | 2297 } else if (assignOperator == UnlinkedExprAssignOperator.prefixIncrement) { |
| 2254 _pushPropertyBinaryExpression( | 2298 _pushPropertyBinaryExpression( |
| 2255 targetType, propertyName, TokenType.PLUS, typeProvider.intType); | 2299 targetType, propertyName, TokenType.PLUS, typeProvider.intType); |
| 2256 } else { | 2300 } else { |
| 2257 TokenType binaryOperator = | 2301 TokenType binaryOperator = |
| 2258 _convertAssignOperatorToTokenType(assignOperator); | 2302 _convertAssignOperatorToTokenType(assignOperator); |
| 2259 DartType operandType = stack.removeLast(); | 2303 DartType operandType = stack.removeLast(); |
| 2260 _pushPropertyBinaryExpression( | 2304 _pushPropertyBinaryExpression( |
| 2261 targetType, propertyName, binaryOperator, operandType); | 2305 targetType, propertyName, binaryOperator, operandType); |
| 2262 } | 2306 } |
| 2263 } | 2307 } |
| 2264 | 2308 |
| 2265 void _doAssignToRef() { | 2309 void _doAssignToRef() { |
| 2266 refPtr++; | 2310 EntityRef ref = _getNextRef(); |
| 2311 ReferenceableElementForLink element = unit.resolveRef(ref.reference); |
| 2312 _throwIfInstanceFieldOrAccessor(element); |
| 2267 UnlinkedExprAssignOperator operator = | 2313 UnlinkedExprAssignOperator operator = |
| 2268 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; | 2314 unlinkedConst.assignmentOperators[assignmentOperatorPtr++]; |
| 2269 if (operator == UnlinkedExprAssignOperator.assign) { | 2315 if (operator == UnlinkedExprAssignOperator.assign) { |
| 2270 // The type of the assignment is the type of the value, | 2316 // The type of the assignment is the type of the value, |
| 2271 // which is already in the stack. | 2317 // which is already in the stack. |
| 2272 } else if (isIncrementOrDecrement(operator)) { | 2318 } else if (isIncrementOrDecrement(operator)) { |
| 2273 // TODO(scheglov) implement | 2319 // TODO(scheglov) implement |
| 2274 stack.add(DynamicTypeImpl.instance); | 2320 stack.add(DynamicTypeImpl.instance); |
| 2275 } else { | 2321 } else { |
| 2276 stack.removeLast(); | 2322 stack.removeLast(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2314 DartType target = stack.removeLast(); | 2360 DartType target = stack.removeLast(); |
| 2315 if (target.isDynamic) { | 2361 if (target.isDynamic) { |
| 2316 target = typeProvider.objectType; | 2362 target = typeProvider.objectType; |
| 2317 } | 2363 } |
| 2318 String propertyName = _getNextString(); | 2364 String propertyName = _getNextString(); |
| 2319 stack.add(() { | 2365 stack.add(() { |
| 2320 if (target is InterfaceType) { | 2366 if (target is InterfaceType) { |
| 2321 ExecutableElement element = target | 2367 ExecutableElement element = target |
| 2322 .lookUpInheritedGetterOrMethod(propertyName, library: library); | 2368 .lookUpInheritedGetterOrMethod(propertyName, library: library); |
| 2323 if (element != null) { | 2369 if (element != null) { |
| 2370 _throwIfInstanceFieldOrAccessor(element); |
| 2324 if (element is PropertyAccessorElement) { | 2371 if (element is PropertyAccessorElement) { |
| 2325 return element.returnType; | 2372 return element.returnType; |
| 2326 } else { | 2373 } else { |
| 2327 // Method tear-off | 2374 // Method tear-off |
| 2328 return element.type; | 2375 return element.type; |
| 2329 } | 2376 } |
| 2330 } | 2377 } |
| 2331 } | 2378 } |
| 2332 return DynamicTypeImpl.instance; | 2379 return DynamicTypeImpl.instance; |
| 2333 }()); | 2380 }()); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2429 } | 2476 } |
| 2430 | 2477 |
| 2431 void _doInvokeMethodRef() { | 2478 void _doInvokeMethodRef() { |
| 2432 int numNamed = _getNextInt(); | 2479 int numNamed = _getNextInt(); |
| 2433 int numPositional = _getNextInt(); | 2480 int numPositional = _getNextInt(); |
| 2434 List<String> namedArgNames = _getNextStrings(numNamed); | 2481 List<String> namedArgNames = _getNextStrings(numNamed); |
| 2435 List<DartType> namedArgTypeList = _popList(numNamed); | 2482 List<DartType> namedArgTypeList = _popList(numNamed); |
| 2436 List<DartType> positionalArgTypes = _popList(numPositional); | 2483 List<DartType> positionalArgTypes = _popList(numPositional); |
| 2437 EntityRef ref = _getNextRef(); | 2484 EntityRef ref = _getNextRef(); |
| 2438 ReferenceableElementForLink element = unit.resolveRef(ref.reference); | 2485 ReferenceableElementForLink element = unit.resolveRef(ref.reference); |
| 2486 _throwIfInstanceFieldOrAccessor(element); |
| 2439 List<DartType> typeArguments = _getTypeArguments(); | 2487 List<DartType> typeArguments = _getTypeArguments(); |
| 2440 stack.add(() { | 2488 stack.add(() { |
| 2441 DartType rawType = element.asStaticType; | 2489 DartType rawType = element.asStaticType; |
| 2442 if (rawType is FunctionType) { | 2490 if (rawType is FunctionType) { |
| 2443 FunctionType inferredType = _inferExecutableType( | 2491 FunctionType inferredType = _inferExecutableType( |
| 2444 rawType, | 2492 rawType, |
| 2445 numNamed, | 2493 numNamed, |
| 2446 numPositional, | 2494 numPositional, |
| 2447 namedArgNames, | 2495 namedArgNames, |
| 2448 namedArgTypeList, | 2496 namedArgTypeList, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2502 if (ref.paramReference != 0) { | 2550 if (ref.paramReference != 0) { |
| 2503 stack.add(typeProvider.typeType); | 2551 stack.add(typeProvider.typeType); |
| 2504 } else { | 2552 } else { |
| 2505 // Synthetic function types can't be directly referred | 2553 // Synthetic function types can't be directly referred |
| 2506 // to by expressions. | 2554 // to by expressions. |
| 2507 assert(ref.syntheticReturnType == null); | 2555 assert(ref.syntheticReturnType == null); |
| 2508 // Nor can implicit function types derived from | 2556 // Nor can implicit function types derived from |
| 2509 // function-typed parameters. | 2557 // function-typed parameters. |
| 2510 assert(ref.implicitFunctionTypeIndices.isEmpty); | 2558 assert(ref.implicitFunctionTypeIndices.isEmpty); |
| 2511 ReferenceableElementForLink element = unit.resolveRef(ref.reference); | 2559 ReferenceableElementForLink element = unit.resolveRef(ref.reference); |
| 2560 _throwIfInstanceFieldOrAccessor(element); |
| 2512 stack.add(element.asStaticType); | 2561 stack.add(element.asStaticType); |
| 2513 } | 2562 } |
| 2514 } | 2563 } |
| 2515 | 2564 |
| 2516 /** | 2565 /** |
| 2517 * Find the parameter in scope called [parameterName] and return its type. | 2566 * Find the parameter in scope called [parameterName] and return its type. |
| 2518 */ | 2567 */ |
| 2519 DartType _findParameterType(String parameterName) { | 2568 DartType _findParameterType(String parameterName) { |
| 2520 FunctionElementForLink_Local f = this.function; | 2569 FunctionElementForLink_Local f = this.function; |
| 2521 while (true) { | 2570 while (true) { |
| (...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3926 * The name of the non-static members that is being accessed. | 3975 * The name of the non-static members that is being accessed. |
| 3927 */ | 3976 */ |
| 3928 final String _name; | 3977 final String _name; |
| 3929 | 3978 |
| 3930 /** | 3979 /** |
| 3931 * The library in which the access occurs. This determines whether private | 3980 * The library in which the access occurs. This determines whether private |
| 3932 * names are accessible. | 3981 * names are accessible. |
| 3933 */ | 3982 */ |
| 3934 final LibraryElementForLink _library; | 3983 final LibraryElementForLink _library; |
| 3935 | 3984 |
| 3985 bool _elementReady = false; |
| 3986 ExecutableElement _element; |
| 3987 |
| 3936 NonstaticMemberElementForLink(this._library, this._target, this._name); | 3988 NonstaticMemberElementForLink(this._library, this._target, this._name); |
| 3937 | 3989 |
| 3938 @override | 3990 @override |
| 3939 ConstVariableNode get asConstVariable => _target.asConstVariable; | 3991 ConstVariableNode get asConstVariable => _target.asConstVariable; |
| 3940 | 3992 |
| 3941 @override | 3993 /** |
| 3942 DartType get asStaticType { | 3994 * TODO(scheglov) document |
| 3943 if (_library._linker.strongMode) { | 3995 */ |
| 3996 bool get hasInstanceGetterReference { |
| 3997 ExecutableElement element = asExecutableElement; |
| 3998 if (element is PropertyAccessorElement) { |
| 3999 return !element.isStatic; |
| 4000 } |
| 4001 ReferenceableElementForLink target = _target; |
| 4002 if (target is NonstaticMemberElementForLink) { |
| 4003 return target.hasInstanceGetterReference; |
| 4004 } |
| 4005 return false; |
| 4006 } |
| 4007 |
| 4008 /** |
| 4009 * TODO((scheglov) document |
| 4010 */ |
| 4011 ExecutableElement get asExecutableElement { |
| 4012 if (!_elementReady) { |
| 4013 _elementReady = true; |
| 3944 DartType targetType = _target.asStaticType; | 4014 DartType targetType = _target.asStaticType; |
| 3945 if (targetType.isDynamic) { | 4015 if (targetType.isDynamic) { |
| 3946 targetType = _library._linker.typeProvider.objectType; | 4016 targetType = _library._linker.typeProvider.objectType; |
| 3947 } | 4017 } |
| 3948 if (targetType is InterfaceType) { | 4018 if (targetType is InterfaceType) { |
| 3949 ExecutableElement element = | 4019 _element = |
| 3950 targetType.lookUpInheritedGetterOrMethod(_name, library: _library); | 4020 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 } | 4021 } |
| 3960 // TODO(paulberry): handle .call on function types and .toString or | 4022 // TODO(paulberry): handle .call on function types and .toString or |
| 3961 // .hashCode on all types. | 4023 // .hashCode on all types. |
| 3962 } | 4024 } |
| 4025 return _element; |
| 4026 } |
| 4027 |
| 4028 @override |
| 4029 DartType get asStaticType { |
| 4030 if (_library._linker.strongMode) { |
| 4031 ExecutableElement element = asExecutableElement; |
| 4032 if (element != null) { |
| 4033 if (element is PropertyAccessorElement) { |
| 4034 return element.returnType; |
| 4035 } else { |
| 4036 // Method tear-off |
| 4037 return element.type; |
| 4038 } |
| 4039 } |
| 4040 } |
| 3963 return DynamicTypeImpl.instance; | 4041 return DynamicTypeImpl.instance; |
| 3964 } | 4042 } |
| 3965 | 4043 |
| 3966 @override | 4044 @override |
| 3967 TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode; | 4045 TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode; |
| 3968 | 4046 |
| 3969 @override | 4047 @override |
| 3970 ReferenceableElementForLink getContainedName(String name) { | 4048 ReferenceableElementForLink getContainedName(String name) { |
| 3971 return new NonstaticMemberElementForLink(_library, this, name); | 4049 return new NonstaticMemberElementForLink(_library, this, name); |
| 3972 } | 4050 } |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4463 List<TypeParameterElement> get typeParameters { | 4541 List<TypeParameterElement> get typeParameters { |
| 4464 // TODO(paulberry): is this correct for fields in generic classes? | 4542 // TODO(paulberry): is this correct for fields in generic classes? |
| 4465 return const []; | 4543 return const []; |
| 4466 } | 4544 } |
| 4467 | 4545 |
| 4468 /** | 4546 /** |
| 4469 * Compute the type of the corresponding variable, which may depend on the | 4547 * Compute the type of the corresponding variable, which may depend on the |
| 4470 * progress of type inference. | 4548 * progress of type inference. |
| 4471 */ | 4549 */ |
| 4472 DartType computeVariableType() { | 4550 DartType computeVariableType() { |
| 4473 if (variable.hasImplicitType && | 4551 // if (variable.hasImplicitType && |
| 4474 !isStatic && | 4552 // !isStatic && |
| 4475 !variable.compilationUnit.isTypeInferenceComplete) { | 4553 // !variable.compilationUnit.isTypeInferenceComplete) { |
| 4476 // This is an instance field and we are currently inferring types in the | 4554 // // 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 | 4555 // // 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 | 4556 // // (even if we have already computed it), since that would lead to |
| 4479 // non-deterministic type inference results. | 4557 // // non-deterministic type inference results. |
| 4480 return DynamicTypeImpl.instance; | 4558 // return DynamicTypeImpl.instance; |
| 4481 } else { | 4559 // } else { |
| 4482 return variable.type; | 4560 return variable.type; |
| 4483 } | 4561 // } |
| 4484 } | 4562 } |
| 4485 | 4563 |
| 4486 @override | 4564 @override |
| 4487 ReferenceableElementForLink getContainedName(String name) { | 4565 ReferenceableElementForLink getContainedName(String name) { |
| 4488 return new NonstaticMemberElementForLink(library, this, name); | 4566 return new NonstaticMemberElementForLink(library, this, name); |
| 4489 } | 4567 } |
| 4490 | 4568 |
| 4491 @override | 4569 @override |
| 4492 FunctionElementForLink_Local getLocalFunction(int index) { | 4570 FunctionElementForLink_Local getLocalFunction(int index) { |
| 4493 if (index == 0) { | 4571 if (index == 0) { |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4732 /** | 4810 /** |
| 4733 * Specialization of [Node] used to construct the type inference dependency | 4811 * Specialization of [Node] used to construct the type inference dependency |
| 4734 * graph. | 4812 * graph. |
| 4735 */ | 4813 */ |
| 4736 class TypeInferenceNode extends Node<TypeInferenceNode> { | 4814 class TypeInferenceNode extends Node<TypeInferenceNode> { |
| 4737 /** | 4815 /** |
| 4738 * The [FunctionElementForLink_Local] to which this node refers. | 4816 * The [FunctionElementForLink_Local] to which this node refers. |
| 4739 */ | 4817 */ |
| 4740 final FunctionElementForLink_Local functionElement; | 4818 final FunctionElementForLink_Local functionElement; |
| 4741 | 4819 |
| 4820 /** |
| 4821 * TODO(scheglov) document |
| 4822 */ |
| 4823 bool _hasError = false; |
| 4824 |
| 4742 TypeInferenceNode(this.functionElement); | 4825 TypeInferenceNode(this.functionElement); |
| 4743 | 4826 |
| 4744 @override | 4827 @override |
| 4745 bool get isEvaluated => functionElement._hasTypeBeenInferred; | 4828 bool get isEvaluated => functionElement._hasTypeBeenInferred; |
| 4746 | 4829 |
| 4747 /** | 4830 /** |
| 4748 * Collect the type inference dependencies in [unlinkedExecutable] (which | 4831 * Collect the type inference dependencies in [unlinkedExecutable] (which |
| 4749 * should be interpreted relative to [compilationUnit]) and store them in | 4832 * should be interpreted relative to [compilationUnit]) and store them in |
| 4750 * [dependencies]. | 4833 * [dependencies]. |
| 4751 */ | 4834 */ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4769 int numInts = unlinkedConst.ints[intPtr++]; | 4852 int numInts = unlinkedConst.ints[intPtr++]; |
| 4770 intPtr += numInts; | 4853 intPtr += numInts; |
| 4771 break; | 4854 break; |
| 4772 case UnlinkedExprOperation.concatenate: | 4855 case UnlinkedExprOperation.concatenate: |
| 4773 intPtr++; | 4856 intPtr++; |
| 4774 break; | 4857 break; |
| 4775 case UnlinkedExprOperation.pushReference: | 4858 case UnlinkedExprOperation.pushReference: |
| 4776 EntityRef ref = unlinkedConst.references[refPtr++]; | 4859 EntityRef ref = unlinkedConst.references[refPtr++]; |
| 4777 // TODO(paulberry): cache these resolved references for | 4860 // TODO(paulberry): cache these resolved references for |
| 4778 // later use by evaluate(). | 4861 // later use by evaluate(). |
| 4779 TypeInferenceNode dependency = | 4862 ReferenceableElementForLink element = |
| 4780 compilationUnit.resolveRef(ref.reference).asTypeInferenceNode; | 4863 compilationUnit.resolveRef(ref.reference); |
| 4864 // // Type inference using instance fields is not allowed. |
| 4865 // // So, we need to report an error and fail the inference. |
| 4866 // if (element is VariableElementForLink) { |
| 4867 // var variable = element as VariableElementForLink; |
| 4868 // if (!variable.isStatic) { |
| 4869 // _hasError = true; |
| 4870 // dependencies.clear(); |
| 4871 // return; |
| 4872 // } |
| 4873 // } |
| 4874 TypeInferenceNode dependency = element.asTypeInferenceNode; |
| 4781 if (dependency != null) { | 4875 if (dependency != null) { |
| 4782 dependencies.add(dependency); | 4876 dependencies.add(dependency); |
| 4783 } | 4877 } |
| 4784 break; | 4878 break; |
| 4785 case UnlinkedExprOperation.invokeConstructor: | 4879 case UnlinkedExprOperation.invokeConstructor: |
| 4786 refPtr++; | 4880 refPtr++; |
| 4787 intPtr += 2; | 4881 intPtr += 2; |
| 4788 break; | 4882 break; |
| 4789 case UnlinkedExprOperation.makeUntypedList: | 4883 case UnlinkedExprOperation.makeUntypedList: |
| 4790 case UnlinkedExprOperation.makeUntypedMap: | 4884 case UnlinkedExprOperation.makeUntypedMap: |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4840 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[]; | 4934 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[]; |
| 4841 collectDependencies(dependencies, functionElement._unlinkedExecutable, | 4935 collectDependencies(dependencies, functionElement._unlinkedExecutable, |
| 4842 functionElement.compilationUnit); | 4936 functionElement.compilationUnit); |
| 4843 return dependencies; | 4937 return dependencies; |
| 4844 } | 4938 } |
| 4845 | 4939 |
| 4846 void evaluate(bool inCycle) { | 4940 void evaluate(bool inCycle) { |
| 4847 if (inCycle) { | 4941 if (inCycle) { |
| 4848 functionElement._setInferredType(DynamicTypeImpl.instance); | 4942 functionElement._setInferredType(DynamicTypeImpl.instance); |
| 4849 } else { | 4943 } else { |
| 4850 var bodyType = new ExprTypeComputer(functionElement).compute(); | 4944 var computer = new ExprTypeComputer(functionElement); |
| 4851 if (functionElement.isAsynchronous) { | 4945 if (computer.hasError) { |
| 4852 var linker = functionElement.compilationUnit.library._linker; | 4946 functionElement._setInferredType(DynamicTypeImpl.instance); |
| 4853 var typeProvider = linker.typeProvider; | 4947 } else { |
| 4854 var typeSystem = linker.typeSystem; | 4948 DartType bodyType = computer.compute(); |
| 4855 if (bodyType.isDartAsyncFutureOr) { | 4949 if (functionElement.isAsynchronous) { |
| 4856 bodyType = (bodyType as InterfaceType).typeArguments[0]; | 4950 var linker = functionElement.compilationUnit.library._linker; |
| 4951 var typeProvider = linker.typeProvider; |
| 4952 var typeSystem = linker.typeSystem; |
| 4953 if (bodyType.isDartAsyncFutureOr) { |
| 4954 bodyType = (bodyType as InterfaceType).typeArguments[0]; |
| 4955 } |
| 4956 bodyType = typeProvider.futureType |
| 4957 .instantiate([bodyType.flattenFutures(typeSystem)]); |
| 4857 } | 4958 } |
| 4858 bodyType = typeProvider.futureType | 4959 functionElement._setInferredType(bodyType); |
| 4859 .instantiate([bodyType.flattenFutures(typeSystem)]); | |
| 4860 } | 4960 } |
| 4861 functionElement._setInferredType(bodyType); | |
| 4862 } | 4961 } |
| 4863 } | 4962 } |
| 4864 | 4963 |
| 4865 @override | 4964 @override |
| 4866 String toString() => 'TypeInferenceNode($functionElement)'; | 4965 String toString() => 'TypeInferenceNode($functionElement)'; |
| 4867 } | 4966 } |
| 4868 | 4967 |
| 4869 class TypeProviderForLink extends TypeProviderBase { | 4968 class TypeProviderForLink extends TypeProviderBase { |
| 4870 final Linker _linker; | 4969 final Linker _linker; |
| 4871 | 4970 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5183 * there are no type parameters in scope. | 5282 * there are no type parameters in scope. |
| 5184 */ | 5283 */ |
| 5185 TypeParameterizedElementMixin get _typeParameterContext; | 5284 TypeParameterizedElementMixin get _typeParameterContext; |
| 5186 | 5285 |
| 5187 @override | 5286 @override |
| 5188 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 5287 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 5189 | 5288 |
| 5190 @override | 5289 @override |
| 5191 String toString() => '$enclosingElement.$name'; | 5290 String toString() => '$enclosingElement.$name'; |
| 5192 } | 5291 } |
| 5292 |
| 5293 /** |
| 5294 * TODO(scheglov) document |
| 5295 */ |
| 5296 class _InferenceFailedError { |
| 5297 final String message; |
| 5298 |
| 5299 _InferenceFailedError(this.message); |
| 5300 } |
| OLD | NEW |