Version 2.17.0-97.0.dev
Merge commit 'd2e70942908390c47549a3592d44ca76ec145ff7' into 'dev'
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
index d87cbdc..0e8e42a 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
@@ -28,19 +28,19 @@
Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:717:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:717:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:717:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:753:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:753:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:753:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:776:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:776:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:776:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:680:13 -> SymbolConstant(#then)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:680:13 -> SymbolConstant(#onError)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:762:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:762:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:762:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:762:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:820:13 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:820:13 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:820:13 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:871:13 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:871:13 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:871:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:915:13 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:915:13 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:915:13 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:769:13 -> SymbolConstant(#then)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:769:13 -> SymbolConstant(#onError)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:880:13 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:880:13 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:880:13 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:880:13 -> MapConstant(const <Symbol*, dynamic>{})
Extra constant evaluation: evaluated: 61, effectively constant: 15
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index fdb4de0..06d63d9 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -53,7 +53,7 @@
/// ```dart
/// import 'dart:io';
///
-/// Future<void> main() async {
+/// void main() async {
/// var server = await HttpServer.bind(InternetAddress.anyIPv6, 80);
/// await server.forEach((HttpRequest request) {
/// request.response.write('Hello, world!');
@@ -82,7 +82,7 @@
/// ```dart
/// import 'dart:io';
///
-/// Future<void> main() async {
+/// void main() async {
/// var chain =
/// Platform.script.resolve('certificates/server_chain.pem').toFilePath();
/// var key = Platform.script.resolve('certificates/server_key.pem').toFilePath();
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 546f62d..05433e6 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -185,7 +185,7 @@
/// (the value handler) and using a second [catchError] for handling errors.
/// Each of these will forward the result that they don't handle
/// to their successors, and together they handle both value and error result.
-/// It also has the additional benefit of the [catchError] handling errors in the
+/// It has the additional benefit of the [catchError] handling errors in the
/// [then] value callback too.
/// Using sequential handlers instead of parallel ones often leads to code that
/// is easier to reason about.
@@ -291,6 +291,11 @@
///
/// If calling [computation] returns a non-future value,
/// a future is returned which has been completed with that value.
+ ///
+ /// Example:
+ /// ```dart
+ /// final result = await Future<int>.sync(() => 12);
+ /// ```
factory Future.sync(FutureOr<T> computation()) {
try {
var result = computation();
@@ -328,6 +333,15 @@
/// must be provided, otherwise the construction throws.
///
/// Use [Completer] to create a future now and complete it later.
+ ///
+ /// Example:
+ /// ```dart
+ /// Future<int> getFuture() {
+ /// return Future<int>.value(2021);
+ /// }
+ ///
+ /// final result = await getFuture();
+ /// ```
@pragma("vm:entry-point")
@pragma("vm:prefer-inline")
factory Future.value([FutureOr<T>? value]) {
@@ -342,6 +356,15 @@
/// will be considered unhandled.
///
/// Use [Completer] to create a future and complete it later.
+ ///
+ /// Example:
+ /// ```dart
+ /// Future<int> getFuture() {
+ /// return Future.error(Exception('Issue'));
+ /// }
+ ///
+ /// final error = await getFuture(); // Throws.
+ /// ```
factory Future.error(Object error, [StackTrace? stackTrace]) {
// TODO(40614): Remove once non-nullability is sound.
checkNotNullable(error, "error");
@@ -379,6 +402,13 @@
///
/// See also [Completer] for a way to create and complete a future at a
/// later time that isn't necessarily after a known fixed duration.
+ ///
+ /// Example:
+ /// ```dart
+ /// Future.delayed(const Duration(seconds: 1), () {
+ /// print('One second has passed.'); // Prints after 1 second.
+ /// });
+ /// ```
factory Future.delayed(Duration duration, [FutureOr<T> computation()?]) {
if (computation == null && !typeAcceptsNull<T>()) {
throw ArgumentError.value(
@@ -426,6 +456,24 @@
///
/// The call to [cleanUp] should not throw. If it does, the error will be an
/// uncaught asynchronous error.
+ ///
+ /// Example:
+ /// ```dart
+ /// void main() async {
+ /// var value = await Future.wait([delayedNumber(), delayedString()]);
+ /// print(value); // [2, result]
+ /// }
+ ///
+ /// Future<int> delayedNumber() async {
+ /// await Future.delayed(const Duration(seconds: 2));
+ /// return 2;
+ /// }
+ ///
+ /// Future<String> delayedString() async {
+ /// await Future.delayed(const Duration(seconds: 2));
+ /// return 'result';
+ /// }
+ /// ```
@pragma("vm:recognized", "other")
static Future<List<T>> wait<T>(Iterable<Future<T>> futures,
{bool eagerError = false, void cleanUp(T successValue)?}) {
@@ -534,6 +582,30 @@
///
/// If [futures] is empty, or if none of its futures complete,
/// the returned future never completes.
+ ///
+ /// Example:
+ /// ```dart
+ /// void main() async {
+ /// final result =
+ /// await Future.any([slowInt(), delayedString(), fastInt()]);
+ /// // The future of fastInt completes first, others are ignored.
+ /// print(result); // 3
+ /// }
+ /// Future<int> slowInt() async {
+ /// await Future.delayed(const Duration(seconds: 2));
+ /// return 2;
+ /// }
+ ///
+ /// Future<String> delayedString() async {
+ /// await Future.delayed(const Duration(seconds: 2));
+ /// throw TimeoutException('Time has passed');
+ /// }
+ ///
+ /// Future<int> fastInt() async {
+ /// await Future.delayed(const Duration(seconds: 1));
+ /// return 3;
+ /// }
+ /// ```
static Future<T> any<T>(Iterable<Future<T>> futures) {
var completer = new Completer<T>.sync();
void onValue(T value) {
@@ -599,6 +671,23 @@
/// The only restriction is a new call to [action] won't happen before
/// the previous call has returned, and if it returned a `Future<bool>`, not
/// until that future has completed.
+ ///
+ /// Example:
+ /// ```dart
+ /// void main() async {
+ /// var value = 0;
+ /// await Future.doWhile(() async {
+ /// value++;
+ /// await Future.delayed(const Duration(seconds: 1));
+ /// if (value == 3) {
+ /// print('Finished with $value');
+ /// return false;
+ /// }
+ /// return true;
+ /// });
+ /// }
+ /// // Outputs: 'Finished with 3'
+ /// ```
static Future doWhile(FutureOr<bool> action()) {
_Future<void> doneSignal = new _Future<void>();
late void Function(bool) nextIteration;
@@ -709,11 +798,25 @@
/// added. If the first `catchError` (or `then`) call happens after this future
/// has completed with an error then the error is reported as unhandled error.
/// See the description on [Future].
+ ///
+ /// Example:
+ /// ```dart
+ /// Future.delayed(
+ /// const Duration(seconds: 1),
+ /// () => throw 401,
+ /// ).then((value) {
+ /// throw 'Unreachable';
+ /// }).catchError((err) {
+ /// print('Error: $err'); // Prints 401.
+ /// }, test: (error) {
+ /// return error is int && error >= 400;
+ /// });
+ /// ```
// The `Function` below stands for one of two types:
// - (dynamic) -> FutureOr<T>
// - (dynamic, StackTrace) -> FutureOr<T>
// Given that there is a `test` function that is usually used to do an
- // `isCheck` we should also expect functions that take a specific argument.
+ // `is` check, we should also expect functions that take a specific argument.
Future<T> catchError(Function onError, {bool test(Object error)?});
/// Registers a function to be called when this future completes.
@@ -750,6 +853,21 @@
/// });
/// }
/// ```
+ /// Example:
+ /// ```dart
+ /// void main() async {
+ /// var value =
+ /// await waitTask().whenComplete(() => print('do something here'));
+ /// // Prints "do something here" after waitTask() completed.
+ /// print(value); // Prints "done"
+ /// }
+ ///
+ /// Future<String> waitTask() {
+ /// Future.delayed(const Duration(seconds: 5));
+ /// return Future.value('done');
+ /// }
+ /// // Outputs: 'do some work here' after waitTask is completed.
+ /// ```
Future<T> whenComplete(FutureOr<void> action());
/// Creates a [Stream] containing the result of this future.
@@ -773,6 +891,27 @@
///
/// If `onTimeout` is omitted, a timeout will cause the returned future to
/// complete with a [TimeoutException].
+ ///
+ /// Example:
+ /// ```dart
+ /// void main() async {
+ /// var result = await waitTask()
+ /// .timeout(const Duration(seconds: 10));
+ /// print(result); // 'completed'
+ ///
+ /// result = await waitTask()
+ /// .timeout(const Duration(seconds: 1), onTimeout: () => 'timeout');
+ /// print(result); // 'timeout'
+ ///
+ /// result = await waitTask()
+ /// .timeout(const Duration(seconds: 2)); // Throws.
+ /// }
+ ///
+ /// Future<String> waitTask() async {
+ /// await Future.delayed(const Duration(seconds: 5));
+ /// return 'completed';
+ /// }
+ /// ```
Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()?});
}
diff --git a/tools/VERSION b/tools/VERSION
index 19760f9..96f8bba 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 96
+PRERELEASE 97
PRERELEASE_PATCH 0
\ No newline at end of file