mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:47:13 +00:00
cd3f54621a
These tests verify that the static type of an async function/method, the reified type of a tear-off of that function/method, and the runtime type of the future it returns, are all consistent with each other. Change-Id: Idf1fb77c5ae9445a36e18d2acc15fd45aa3411e5 Reviewed-on: https://dart-review.googlesource.com/19063 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Leaf Petersen <leafp@google.com>
133 lines
3.5 KiB
Dart
133 lines
3.5 KiB
Dart
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// This test verifies that for an unnamed async closure, the following three
|
|
// types are all appropriately matched:
|
|
// - The static return type
|
|
// - The return type of reified runtime type of a tearoff of the function or
|
|
// method
|
|
// - The reified type of the future returned by the function or method
|
|
//
|
|
// Specific attention is paid to the following conditions:
|
|
// - The static return type is determined by type inference
|
|
// - The static return type is `dynamic`
|
|
// - The function or method immediately returns a value or future with a
|
|
// different type (possibly using `=>` syntax)
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
class A {}
|
|
|
|
class B extends A {}
|
|
|
|
class B2 extends A {}
|
|
|
|
Future quick() async {}
|
|
|
|
Future<A> futureA() => new Future<A>.value(new A());
|
|
|
|
Future<B> futureB() => new Future<B>.value(new B());
|
|
|
|
void checkFutureDynamic(dynamic tearoff) {
|
|
Expect.isTrue(tearoff is Future<dynamic> Function());
|
|
Expect.isFalse(tearoff is Future<A> Function());
|
|
dynamic f = tearoff();
|
|
Expect.isTrue(f is Future<dynamic>);
|
|
Expect.isFalse(f is Future<A>);
|
|
}
|
|
|
|
void checkFutureA(dynamic tearoff) {
|
|
Expect.isTrue(tearoff is Future<A> Function());
|
|
Expect.isFalse(tearoff is Future<B> Function());
|
|
dynamic f = tearoff();
|
|
Expect.isTrue(f is Future<A>);
|
|
Expect.isFalse(f is Future<B>);
|
|
}
|
|
|
|
main() {
|
|
var f_inferred_futureDynamic = () async {
|
|
await quick();
|
|
if (false) {
|
|
return 0;
|
|
} else {
|
|
return new A();
|
|
}
|
|
};
|
|
|
|
var f_inferred_A = () async {
|
|
await quick();
|
|
if (false) {
|
|
return new A();
|
|
} else {
|
|
return new B();
|
|
}
|
|
};
|
|
|
|
Future<dynamic> Function() f_futureDynamic = () async {
|
|
await quick();
|
|
if (false) {
|
|
return 0;
|
|
} else {
|
|
return new B();
|
|
}
|
|
};
|
|
|
|
Future<A> Function() f_A = () async {
|
|
await quick();
|
|
if (false) {
|
|
return new A();
|
|
} else {
|
|
return new B();
|
|
}
|
|
};
|
|
|
|
Future<A> Function() f_immediateReturn_B = () async {
|
|
if (false) {
|
|
return new A();
|
|
} else {
|
|
return new B();
|
|
}
|
|
};
|
|
|
|
Future<A> Function() f_immediateReturn_FutureB = () async {
|
|
if (false) {
|
|
return new A();
|
|
} else {
|
|
return futureB();
|
|
}
|
|
};
|
|
|
|
Future<A> Function() f_expressionSyntax_B =
|
|
() async => false ? new A() : new B();
|
|
|
|
Future<A> Function() f_expressionSyntax_FutureB =
|
|
() async => false ? futureA() : futureB();
|
|
|
|
// Not executed
|
|
void checkStaticTypes() {
|
|
// Check that f_inferred_futureDynamic's static return type is
|
|
// `Future<dynamic>`, by verifying that its return value can be assigned to
|
|
// `Future<int>` but not `int`.
|
|
Future<int> v1 = f_inferred_futureDynamic();
|
|
int v2 = f_inferred_futureDynamic(); //# 01: compile-time error
|
|
|
|
// Check that f_inferred_A's static return type is `Future<A>`, by verifying
|
|
// that its return value can be assigned to `Future<B2>` but not
|
|
// `Future<int>`.
|
|
Future<B2> v3 = f_inferred_A();
|
|
Future<int> v4 = f_inferred_A(); //# 02: compile-time error
|
|
}
|
|
|
|
checkFutureDynamic(f_inferred_futureDynamic);
|
|
checkFutureA(f_inferred_A);
|
|
checkFutureDynamic(f_futureDynamic);
|
|
checkFutureA(f_A);
|
|
checkFutureA(f_immediateReturn_B);
|
|
checkFutureA(f_immediateReturn_FutureB);
|
|
checkFutureA(f_expressionSyntax_B);
|
|
checkFutureA(f_expressionSyntax_FutureB);
|
|
}
|