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

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

Issue 2647833002: fix #28008, fix #28009 implement FutureOr<T> (Closed)
Patch Set: Merge remote-tracking branch 'origin/master' into 28008_futureort 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 8d9f708493ed2b2e974e86ca185e152cc8a40378..a86bcdefecee5fed63ab91bd425df6454e595f11 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -811,7 +811,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
Expression target = node.realTarget;
if (target != null) {
DartType targetType = target.bestType;
- if (_isAsyncFutureType(targetType)) {
+ if (targetType.isDartAsyncFuture) {
// Future.then(closure) return type is:
// 1) the returned Future type, if the closure returns a Future;
// 2) Future<valueType>, if the closure returns a value.
@@ -1418,11 +1418,11 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
// TODO(brianwilkerson) Determine whether this can still happen.
staticType2 = _dynamicType;
}
+
DartType staticType =
- _typeSystem.getLeastUpperBound(staticType1, staticType2);
- if (staticType == null) {
- staticType = _dynamicType;
- }
+ _typeSystem.getLeastUpperBound(staticType1, staticType2) ??
+ _dynamicType;
+
_recordStaticType(node, staticType);
DartType propagatedType1 = expr1.propagatedType;
DartType propagatedType2 = expr2.propagatedType;
@@ -1519,6 +1519,9 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
: _typeProvider.iterableType;
return genericType.instantiate(<DartType>[type]);
} else if (body.isAsynchronous) {
+ if (type.isDartAsyncFutureOr) {
+ type = (type as InterfaceType).typeArguments[0];
+ }
return _typeProvider.futureType
.instantiate(<DartType>[type.flattenFutures(_typeSystem)]);
} else {
@@ -1961,44 +1964,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
argTypes.add(argumentList.arguments[i].staticType);
}
}
-
- // 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] as FunctionType;
- if (firstArgType is FunctionType) {
- 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;
- 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);
@@ -2081,12 +2046,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
if (_strongMode &&
(computedType.isDartCoreNull || computedType.isDynamic)) {
DartType contextType = InferenceContext.getContext(body);
- if (contextType is FutureUnionType) {
- // TODO(jmesserly): can we do something better here?
- computedType = body.isAsynchronous ? contextType.type : _dynamicType;
- } else {
- computedType = contextType ?? _dynamicType;
- }
+ computedType = contextType ?? _dynamicType;
recordInference = !computedType.isDynamic;
}
@@ -2224,23 +2184,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
}
/**
- * Return `true` if the given [Type] is the `Future` form the 'dart:async'
- * library.
- */
- bool _isAsyncFutureType(DartType type) =>
- type is InterfaceType &&
- type.name == "Future" &&
- _isAsyncLibrary(type.element.library);
-
- /**
- * Return `true` if the given library is the 'dart:async' library.
- *
- * @param library the library being tested
- * @return `true` if the library is 'dart:async'
- */
- bool _isAsyncLibrary(LibraryElement library) => library.name == "dart.async";
-
- /**
* Return `true` if the given library is the 'dart:html' library.
*
* @param library the library being tested
« no previous file with comments | « pkg/analyzer/lib/src/generated/resolver.dart ('k') | pkg/analyzer/lib/src/generated/testing/element_factory.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698