mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:31:58 +00:00
Migration: fix handling of async functions that return FutureOr.
Change-Id: I613d0bfd8340062bb78b20a8fd035d24a4ccdf8d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155543 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
parent
f907e561c9
commit
2225b6f472
|
@ -2995,11 +2995,26 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType>
|
|||
/// upcast T to that type if possible, skipping the flatten when not
|
||||
/// necessary.
|
||||
DecoratedType _wrapFuture(DecoratedType type, AstNode node) {
|
||||
if (type.type.isDartCoreNull || type.type.isBottom) {
|
||||
var dartType = type.type;
|
||||
if (dartType.isDartCoreNull || dartType.isBottom) {
|
||||
return _futureOf(type, node);
|
||||
}
|
||||
|
||||
if (_typeSystem.isSubtypeOf(type.type, typeProvider.futureDynamicType)) {
|
||||
if (dartType is InterfaceType &&
|
||||
dartType.element == typeProvider.futureOrElement) {
|
||||
var typeArguments = type.typeArguments;
|
||||
if (typeArguments.length == 1) {
|
||||
// Wrapping FutureOr<T?1>?2 should produce Future<T?3>, where either 1
|
||||
// or 2 being nullable causes 3 to become nullable.
|
||||
var typeArgument = typeArguments[0];
|
||||
return _futureOf(
|
||||
typeArgument
|
||||
.withNode(NullabilityNode.forLUB(typeArgument.node, type.node)),
|
||||
node);
|
||||
}
|
||||
}
|
||||
|
||||
if (_typeSystem.isSubtypeOf(dartType, typeProvider.futureDynamicType)) {
|
||||
return _decoratedClassHierarchy.asInstanceOf(
|
||||
type, typeProvider.futureDynamicType.element);
|
||||
}
|
||||
|
|
|
@ -5583,6 +5583,20 @@ test() => C.one();
|
|||
await _checkSingleFileChanges(content, expected);
|
||||
}
|
||||
|
||||
Future<void> test_return_future_or_null_from_async_method() async {
|
||||
var content = '''
|
||||
import 'dart:async';
|
||||
Future<Null> f() async => g();
|
||||
FutureOr<Null> g() => null;
|
||||
''';
|
||||
var expected = '''
|
||||
import 'dart:async';
|
||||
Future<Null> f() async => g();
|
||||
FutureOr<Null> g() => null;
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected);
|
||||
}
|
||||
|
||||
Future<void> test_setter_overrides_implicit_setter() async {
|
||||
var content = '''
|
||||
class A {
|
||||
|
|
|
@ -6812,6 +6812,29 @@ int g() => 1;
|
|||
// No assertions; just checking that it doesn't crash.
|
||||
}
|
||||
|
||||
Future<void> test_return_from_async_futureOr_to_future() async {
|
||||
await analyze('''
|
||||
import 'dart:async';
|
||||
Future<Object> f(FutureOr<int> x) async => x;
|
||||
''');
|
||||
var lubNodeMatcher = anyNode;
|
||||
assertEdge(lubNodeMatcher, decoratedTypeAnnotation('Object').node,
|
||||
hard: false, checkable: false);
|
||||
var lubNode = lubNodeMatcher.matchingNode as NullabilityNodeForLUB;
|
||||
expect(lubNode.left, same(decoratedTypeAnnotation('int> x').node));
|
||||
expect(lubNode.right, same(decoratedTypeAnnotation('FutureOr<int>').node));
|
||||
}
|
||||
|
||||
Future<void> test_return_from_async_list_to_future() async {
|
||||
await analyze('''
|
||||
import 'dart:async';
|
||||
Future<Object> f(List<int> x) async => x;
|
||||
''');
|
||||
assertEdge(decoratedTypeAnnotation('List<int>').node,
|
||||
decoratedTypeAnnotation('Object').node,
|
||||
hard: false, checkable: false);
|
||||
}
|
||||
|
||||
Future<void> test_return_from_async_null() async {
|
||||
await analyze('''
|
||||
Future<int> f() async {
|
||||
|
|
Loading…
Reference in a new issue