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 library analyzer.src.generated.static_type_analyzer; | 5 library analyzer.src.generated.static_type_analyzer; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 computedType = _dynamicType; | 497 computedType = _dynamicType; |
498 } | 498 } |
499 | 499 |
500 // If we had a better type from the function body, use it. | 500 // If we had a better type from the function body, use it. |
501 // | 501 // |
502 // This helps in a few cases: | 502 // This helps in a few cases: |
503 // * ExpressionFunctionBody, when the surrounding context had a better type. | 503 // * ExpressionFunctionBody, when the surrounding context had a better type. |
504 // * BlockFunctionBody, if we inferred a type from yield/return. | 504 // * BlockFunctionBody, if we inferred a type from yield/return. |
505 // * we also normalize bottom to dynamic here. | 505 // * we also normalize bottom to dynamic here. |
506 if (_strongMode && (computedType.isBottom || computedType.isDynamic)) { | 506 if (_strongMode && (computedType.isBottom || computedType.isDynamic)) { |
507 computedType = InferenceContext.getType(body) ?? _dynamicType; | 507 DartType contextType = InferenceContext.getContext(body); |
| 508 if (contextType is FutureUnionType) { |
| 509 // TODO(jmesserly): can we do something better here? |
| 510 computedType = body.isAsynchronous ? contextType.type : _dynamicType; |
| 511 } else { |
| 512 computedType = contextType ?? _dynamicType; |
| 513 } |
508 recordInference = !computedType.isDynamic; | 514 recordInference = !computedType.isDynamic; |
509 } | 515 } |
510 | 516 |
511 computedType = _computeReturnTypeOfFunction(body, computedType); | 517 computedType = _computeReturnTypeOfFunction(body, computedType); |
512 | 518 |
513 functionElement.returnType = computedType; | 519 functionElement.returnType = computedType; |
514 _recordPropagatedTypeOfFunction(functionElement, node.body); | 520 _recordPropagatedTypeOfFunction(functionElement, node.body); |
515 _recordStaticType(node, functionElement.type); | 521 _recordStaticType(node, functionElement.type); |
516 if (recordInference) { | 522 if (recordInference) { |
517 _resolver.inferenceContext.recordInference(node, functionElement.type); | 523 _resolver.inferenceContext.recordInference(node, functionElement.type); |
(...skipping 1445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 List<DartType> paramTypes = <DartType>[]; | 1969 List<DartType> paramTypes = <DartType>[]; |
1964 List<DartType> argTypes = <DartType>[]; | 1970 List<DartType> argTypes = <DartType>[]; |
1965 for (int i = 0, length = rawParameters.length; i < length; i++) { | 1971 for (int i = 0, length = rawParameters.length; i < length; i++) { |
1966 ParameterElement parameter = rawParameters[i]; | 1972 ParameterElement parameter = rawParameters[i]; |
1967 if (parameter != null) { | 1973 if (parameter != null) { |
1968 paramTypes.add(parameter.type); | 1974 paramTypes.add(parameter.type); |
1969 argTypes.add(argumentList.arguments[i].staticType); | 1975 argTypes.add(argumentList.arguments[i].staticType); |
1970 } | 1976 } |
1971 } | 1977 } |
1972 | 1978 |
1973 return ts.inferGenericFunctionCall(_typeProvider, fnType, paramTypes, | 1979 DartType returnContext = InferenceContext.getContext(node); |
1974 argTypes, InferenceContext.getType(node)); | 1980 DartType returnType; |
| 1981 if (returnContext is FutureUnionType) { |
| 1982 returnType = fnType.returnType.isDartAsyncFuture |
| 1983 ? returnContext.futureOfType |
| 1984 : returnContext.type; |
| 1985 } else { |
| 1986 returnType = returnContext as DartType; |
| 1987 } |
| 1988 return ts.inferGenericFunctionCall( |
| 1989 _typeProvider, fnType, paramTypes, argTypes, returnType); |
1975 } | 1990 } |
1976 return null; | 1991 return null; |
1977 } | 1992 } |
1978 | 1993 |
1979 /** | 1994 /** |
1980 * Given an instance creation of a possibly generic type, infer the type | 1995 * Given an instance creation of a possibly generic type, infer the type |
1981 * arguments using the current context type as well as the argument types. | 1996 * arguments using the current context type as well as the argument types. |
1982 */ | 1997 */ |
1983 void _inferInstanceCreationExpression(InstanceCreationExpression node) { | 1998 void _inferInstanceCreationExpression(InstanceCreationExpression node) { |
1984 ConstructorName constructor = node.constructorName; | 1999 ConstructorName constructor = node.constructorName; |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2341 } | 2356 } |
2342 // merge types | 2357 // merge types |
2343 if (result == null) { | 2358 if (result == null) { |
2344 result = type; | 2359 result = type; |
2345 } else { | 2360 } else { |
2346 result = _typeSystem.getLeastUpperBound(_typeProvider, result, type); | 2361 result = _typeSystem.getLeastUpperBound(_typeProvider, result, type); |
2347 } | 2362 } |
2348 return null; | 2363 return null; |
2349 } | 2364 } |
2350 } | 2365 } |
OLD | NEW |