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

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

Issue 2676633005: Temporarily restore ad hoc Future.then inference (Closed)
Patch Set: Created 3 years, 11 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 a2aeae15c7741c74e7444e1ef09841ccf790c371..b5de145803aaac7959c414093deef9295659130a 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -1967,6 +1967,49 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
argTypes.add(argumentList.arguments[i].staticType);
}
}
+
+ // TODO(leafp): remove this again after code has been updated to
+ // use FutureOr on classes that implement Future
+ // Special case Future<T>.then upwards inference. It has signature:
+ //
+ // <S>(T -> (S | Future<S>)) -> Future<S>
+ //
+ // Based on the first argument type, we'll pick one of these signatures:
+ //
+ // <S>(T -> S) -> Future<S>
+ // <S>(T -> Future<S>) -> Future<S>
+ //
+ // ... and finish the inference using that.
+ if (argTypes.isNotEmpty &&
+ argTypes[0].isDartAsyncFutureOr &&
Jennifer Messerly 2017/02/03 18:31:51 I'm not sure this check will be satisfied? it look
Leaf 2017/02/03 21:28:56 Yeesh. Totally borked. I guess the downwards inf
+ _resolver.isFutureThen(fnType.element)) {
+ var firstArgType = argTypes[0];
+ var firstParamType = paramTypes[0] as FunctionType;
+ if (firstArgType is FunctionType) {
Jennifer Messerly 2017/02/03 18:31:52 if firstArgType was a FutureOr, then it's not a Fu
Leaf 2017/02/03 21:28:56 Done.
+ var argReturnType = firstArgType.returnType;
+ // Skip the inference if we have the top type. It can only lead to
+ // worse inference. For example, this happens when the lambda returns
+ // S or Future<S> in a conditional.
+ if (!argReturnType.isObject && !argReturnType.isDynamic) {
+ DartType paramReturnType = fnType.typeFormals[0].type;
Jennifer Messerly 2017/02/03 18:31:51 rather than this line and the following if stateme
Leaf 2017/02/03 21:28:56 Done.
+ if (_resolver.isSubtypeOfFuture(argReturnType)) {
+ // Given an argument of (T) -> Future<S>, instantiate with <S>
+ paramReturnType =
+ _typeProvider.futureType.instantiate([paramReturnType]);
+ }
+
+ // Adjust the expected parameter type to have this return type.
+ var function = new FunctionElementImpl(firstParamType.name, -1)
+ ..isSynthetic = true
+ ..shareParameters(firstParamType.parameters)
+ ..returnType = paramReturnType;
+ function.type = new FunctionTypeImpl(function);
+ // Use this as the expected 1st parameter type.
+ paramTypes[0] = function.type;
+ }
+ }
+ }
+
return ts.inferGenericFunctionCall(fnType, paramTypes, argTypes,
fnType.returnType, InferenceContext.getContext(node),
errorReporter: _resolver.errorReporter, errorNode: errorNode);

Powered by Google App Engine
This is Rietveld 408576698