Chromium Code Reviews| Index: pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| index cc8e2f06e5ca9c4f409d14c684c20f332974cef1..82b3796c645d51ad12bfca232075775245660309 100644 |
| --- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| +++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| @@ -461,10 +461,21 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| // node. |
| return null; |
| } |
| + bool recordInference = false; |
| ExecutableElementImpl functionElement = |
| node.element as ExecutableElementImpl; |
| DartType computedType = _computeStaticReturnTypeOfFunctionExpression(node); |
| if (_strongMode) { |
| + // Strong mode can infer the type of a block function body. |
| + FunctionBody body = node.body; |
| + if (body is BlockFunctionBody) { |
| + DartType inferredType = InferenceContext.getType(body); |
|
Leaf
2016/02/23 02:17:47
It bothers me a little bit that this segment of co
Jennifer Messerly
2016/02/23 17:41:46
Yeah, makes sense. I was having the same thoughts
Jennifer Messerly
2016/02/23 22:16:21
Ah, I remembered one issue. This code isn't integr
Jennifer Messerly
2016/02/24 00:20:41
Done.
|
| + if (inferredType != null) { |
| + computedType = _computeReturnTypeOfFunction(body, inferredType); |
| + recordInference = true; |
| + } |
| + } |
| + |
| // In strong mode, we don't want to allow the function's return type to |
| // be bottom. If the surrounding context has a more precise type, we |
| // will push it down with inference, below. If not we want to use dynamic. |
| @@ -484,14 +495,17 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| if (computedType.isDynamic && |
| !(returnType.isDynamic || returnType.isBottom)) { |
| computedType = returnType; |
| - _resolver.inferenceContext.recordInference(node, functionType); |
| + recordInference = true; |
| } |
| } |
| } |
| } |
| functionElement.returnType = computedType; |
| _recordPropagatedTypeOfFunction(functionElement, node.body); |
| - _recordStaticType(node, node.element.type); |
| + _recordStaticType(node, functionElement.type); |
| + if (recordInference) { |
| + _resolver.inferenceContext.recordInference(node, functionElement.type); |
| + } |
| return null; |
| } |
| @@ -1473,6 +1487,27 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| } |
| /** |
| + * Given a function body and its return type, compute the return type of |
| + * the entire function, taking into account whether the function body |
| + * is `sync*`, `async` or `async*`. |
| + * |
| + * See also [FunctionBody.isAsynchronous], [FunctionBody.isGenerator]. |
| + */ |
| + DartType _computeReturnTypeOfFunction(FunctionBody body, DartType type) { |
| + if (body.isGenerator) { |
| + InterfaceType genericType = body.isAsynchronous |
| + ? _typeProvider.streamType |
| + : _typeProvider.iterableType; |
| + return genericType.substitute4(<DartType>[type]); |
| + } else if (body.isAsynchronous) { |
| + return _typeProvider.futureType |
| + .substitute4(<DartType>[type.flattenFutures(_typeSystem)]); |
| + } else { |
| + return type; |
| + } |
| + } |
| + |
| + /** |
| * Compute the static return type of the method or function represented by the given element. |
| * |
| * @param element the element representing the method or function invoked by the given node |
| @@ -1525,25 +1560,14 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| DartType _computeStaticReturnTypeOfFunctionExpression( |
| FunctionExpression node) { |
| FunctionBody body = node.body; |
| - if (body.isGenerator) { |
| - if (body.isAsynchronous) { |
| - return _typeProvider.streamDynamicType; |
| - } else { |
| - return _typeProvider.iterableDynamicType; |
| - } |
| - } |
| + |
| DartType type; |
| if (body is ExpressionFunctionBody) { |
| type = _getStaticType(body.expression); |
| } else { |
| type = _dynamicType; |
| } |
| - if (body.isAsynchronous) { |
| - return _typeProvider.futureType |
| - .substitute4(<DartType>[type.flattenFutures(_typeSystem)]); |
| - } else { |
| - return type; |
| - } |
| + return _computeReturnTypeOfFunction(body, type); |
| } |
| DartType _findIteratedType(DartType type, DartType targetType) { |