Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(643)

Unified Diff: pkg/analyzer/lib/src/generated/static_type_analyzer.dart

Issue 1724543002: fix #25487, infer block lambdas from return statements (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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) {

Powered by Google App Engine
This is Rietveld 408576698