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

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

Issue 2676633005: Temporarily restore ad hoc Future.then inference (Closed)
Patch Set: Address comments Created 3 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 a2aeae15c7741c74e7444e1ef09841ccf790c371..b0d106c36809f8713c613da8044b90e7c4503d68 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -1967,6 +1967,45 @@ 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 && _resolver.isFutureThen(fnType.element)) {
+ var firstArgType = argTypes[0];
+ var firstParamType = paramTypes[0];
+ if (firstArgType is FunctionType &&
+ firstParamType is FunctionType &&
+ !firstParamType.returnType.isDartAsyncFutureOr) {
+ 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 = _typeProvider.futureOrType
+ .instantiate([fnType.typeFormals[0].type]);
+
+ // 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);
« no previous file with comments | « pkg/analyzer/lib/src/generated/resolver.dart ('k') | pkg/analyzer/test/src/task/strong/inferred_type_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698