Skip to content

#1363 Async for-in test updated according to the current specification #1379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import 'dart:async';
import '../../../../Utils/expect.dart';


Future test1() async {
List log = [];
StreamController<String> streamController = new StreamController<String>();
Expand All @@ -33,7 +32,6 @@ Future test1() async {
Expect.listEquals(['a', 'a1', 'a2', '1', '11', '12', '2', '21', '22'], log);
}


Future test2() async {
List log = [];
StreamController<String> streamController = new StreamController<String>();
Expand All @@ -47,7 +45,7 @@ Future test2() async {
} else if (!streamController.isClosed) {
streamController.close();
}
await new Future.delayed(new Duration(microseconds: 100));
await null;
}
}
Expect.listEquals(['a', 'a1', 'a2', '1', '11', '12', '2', '21', '22'], log);
Expand Down
73 changes: 73 additions & 0 deletions Language/Statements/For/Asynchronous_For_in/execution_A01_t01.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2015, 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.

/// @assertion Let `D` be derived from <finalConstVarOrType>?. Execution of a
/// for-in statement, `f`, of the form `await for (D id in e) s` proceeds as
/// follows:
///
/// The expression `e` is evaluated to an object `o`. It is a dynamic type error
/// if `o` is not an instance of a class that implements [Stream]. It is a
/// compile-time error if `D` is empty and `id` is a final variable.
///
/// The stream associated with the innermost enclosing asynchronous for loop,
/// if any, is paused. The stream `o` is listened to, producing a stream
/// subscription `u`, and execution of the asynchronous for-in loop is suspended
/// until a stream event is available.
///
/// Pausing an asynchronous for loop means pausing the associated stream
/// subscription. A stream subscription is paused by calling its pause method.
/// If the subscription is already paused, an implementation may omit further
/// calls to pause.
///
/// For each data event from `u`, the statement `s` is executed with `id` bound
/// to the value of the current data event.
///
/// If execution of `s` continues without a label, or to a label that prefixes
/// the asynchronous for statement, then the execution of `s` is treated as if
/// it had completed normally.
///
/// If execution of `s` otherwise does not complete normally, the subscription
/// `u` is canceled by evaluating `await v.cancel()` where `v` is a fresh
/// variable referencing the stream subscription `u`. If that evaluation throws,
/// execution of `f` throws the same exception and stack trace. Otherwise
/// execution of `f` completes in the same way as the execution of `s`.
/// Otherwise the execution of `f` is suspended again, waiting for the next
/// stream subscription event, and `u` is resumed if it has been paused.
///
/// On an error event from `u`, with error object `e` and stack trace `st`, the
/// subscription `u` is canceled by evaluating `await v.cancel()` where `v` is a
/// fresh variable referencing the stream subscription `u`. If that evaluation
/// throws, execution of `f` throws the same exception object and stack trace.
/// Otherwise execution of `f` throws with `e` as exception object and `st` as
/// stack trace.
///
/// When `u` is done, execution of `f` completes normally.
///
/// @description Check that a compile error occurs if o is not an instance
/// of a class that implements [Stream]
///
/// @author [email protected]

import 'dart:async';

Future test1() async {
await for (var i in new Object()) {
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}

Future test2() async {
await for (int i in [1, 2, 3]) {
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}

main() {
test1();
test2();
}
66 changes: 66 additions & 0 deletions Language/Statements/For/Asynchronous_For_in/execution_A01_t02.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) 2022, 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.

/// @assertion Let `D` be derived from <finalConstVarOrType>?. Execution of a
/// for-in statement, `f`, of the form `await for (D id in e) s` proceeds as
/// follows:
///
/// The expression `e` is evaluated to an object `o`. It is a dynamic type error
/// if `o` is not an instance of a class that implements [Stream]. It is a
/// compile-time error if `D` is empty and `id` is a final variable.
///
/// The stream associated with the innermost enclosing asynchronous for loop,
/// if any, is paused. The stream `o` is listened to, producing a stream
/// subscription `u`, and execution of the asynchronous for-in loop is suspended
/// until a stream event is available.
///
/// Pausing an asynchronous for loop means pausing the associated stream
/// subscription. A stream subscription is paused by calling its pause method.
/// If the subscription is already paused, an implementation may omit further
/// calls to pause.
///
/// For each data event from `u`, the statement `s` is executed with `id` bound
/// to the value of the current data event.
///
/// If execution of `s` continues without a label, or to a label that prefixes
/// the asynchronous for statement, then the execution of `s` is treated as if
/// it had completed normally.
///
/// If execution of `s` otherwise does not complete normally, the subscription
/// `u` is canceled by evaluating `await v.cancel()` where `v` is a fresh
/// variable referencing the stream subscription `u`. If that evaluation throws,
/// execution of `f` throws the same exception and stack trace. Otherwise
/// execution of `f` completes in the same way as the execution of `s`.
/// Otherwise the execution of `f` is suspended again, waiting for the next
/// stream subscription event, and `u` is resumed if it has been paused.
///
/// On an error event from `u`, with error object `e` and stack trace `st`, the
/// subscription `u` is canceled by evaluating `await v.cancel()` where `v` is a
/// fresh variable referencing the stream subscription `u`. If that evaluation
/// throws, execution of `f` throws the same exception object and stack trace.
/// Otherwise execution of `f` throws with `e` as exception object and `st` as
/// stack trace.
///
/// When `u` is done, execution of `f` completes normally.
///
/// @description Check that it is a dynamic type error if `o` is not an instance
/// of a class that implements [Stream]
///
/// @author [email protected]

import '../../../../Utils/expect.dart';

main() async {
bool wasException = false;
dynamic collection = [1, 2, 3];
try {
await for (var i in collection) {
Expect.fail("Dynamic error expected");
print(i);
}
} catch (_) {
wasException = true;
}
Expect.isTrue(wasException);
}
60 changes: 60 additions & 0 deletions Language/Statements/For/Asynchronous_For_in/execution_A01_t03.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2022, 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.

/// @assertion Let `D` be derived from <finalConstVarOrType>?. Execution of a
/// for-in statement, `f`, of the form `await for (D id in e) s` proceeds as
/// follows:
///
/// The expression `e` is evaluated to an object `o`. It is a dynamic type error
/// if `o` is not an instance of a class that implements [Stream]. It is a
/// compile-time error if `D` is empty and `id` is a final variable.
///
/// The stream associated with the innermost enclosing asynchronous for loop,
/// if any, is paused. The stream `o` is listened to, producing a stream
/// subscription `u`, and execution of the asynchronous for-in loop is suspended
/// until a stream event is available.
///
/// Pausing an asynchronous for loop means pausing the associated stream
/// subscription. A stream subscription is paused by calling its pause method.
/// If the subscription is already paused, an implementation may omit further
/// calls to pause.
///
/// For each data event from `u`, the statement `s` is executed with `id` bound
/// to the value of the current data event.
///
/// If execution of `s` continues without a label, or to a label that prefixes
/// the asynchronous for statement, then the execution of `s` is treated as if
/// it had completed normally.
///
/// If execution of `s` otherwise does not complete normally, the subscription
/// `u` is canceled by evaluating `await v.cancel()` where `v` is a fresh
/// variable referencing the stream subscription `u`. If that evaluation throws,
/// execution of `f` throws the same exception and stack trace. Otherwise
/// execution of `f` completes in the same way as the execution of `s`.
/// Otherwise the execution of `f` is suspended again, waiting for the next
/// stream subscription event, and `u` is resumed if it has been paused.
///
/// On an error event from `u`, with error object `e` and stack trace `st`, the
/// subscription `u` is canceled by evaluating `await v.cancel()` where `v` is a
/// fresh variable referencing the stream subscription `u`. If that evaluation
/// throws, execution of `f` throws the same exception object and stack trace.
/// Otherwise execution of `f` throws with `e` as exception object and `st` as
/// stack trace.
///
/// When `u` is done, execution of `f` completes normally.
///
/// @description Check that it is a compile-time error if `D` is empty and id is
/// a final variable.
///
/// @author [email protected]
/// @issue 49495

main() async {
final i;
await for (i in Stream.fromIterable(['one', 'two', 'three'])) {
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
63 changes: 63 additions & 0 deletions Language/Statements/For/Asynchronous_For_in/execution_A02_t01.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) 2022, 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.

/// @assertion Let `D` be derived from <finalConstVarOrType>?. Execution of a
/// for-in statement, `f`, of the form `await for (D id in e) s` proceeds as
/// follows:
///
/// The expression `e` is evaluated to an object `o`. It is a dynamic type error
/// if `o` is not an instance of a class that implements [Stream]. It is a
/// compile-time error if `D` is empty and `id` is a final variable.
///
/// The stream associated with the innermost enclosing asynchronous for loop,
/// if any, is paused. The stream `o` is listened to, producing a stream
/// subscription `u`, and execution of the asynchronous for-in loop is suspended
/// until a stream event is available.
///
/// Pausing an asynchronous for loop means pausing the associated stream
/// subscription. A stream subscription is paused by calling its pause method.
/// If the subscription is already paused, an implementation may omit further
/// calls to pause.
///
/// For each data event from `u`, the statement `s` is executed with `id` bound
/// to the value of the current data event.
///
/// If execution of `s` continues without a label, or to a label that prefixes
/// the asynchronous for statement, then the execution of `s` is treated as if
/// it had completed normally.
///
/// If execution of `s` otherwise does not complete normally, the subscription
/// `u` is canceled by evaluating `await v.cancel()` where `v` is a fresh
/// variable referencing the stream subscription `u`. If that evaluation throws,
/// execution of `f` throws the same exception and stack trace. Otherwise
/// execution of `f` completes in the same way as the execution of `s`.
/// Otherwise the execution of `f` is suspended again, waiting for the next
/// stream subscription event, and `u` is resumed if it has been paused.
///
/// On an error event from `u`, with error object `e` and stack trace `st`, the
/// subscription `u` is canceled by evaluating `await v.cancel()` where `v` is a
/// fresh variable referencing the stream subscription `u`. If that evaluation
/// throws, execution of `f` throws the same exception object and stack trace.
/// Otherwise execution of `f` throws with `e` as exception object and `st` as
/// stack trace.
///
/// When `u` is done, execution of `f` completes normally.
///
/// @description Check that the stream associated with the innermost enclosing
/// asynchronous for loop is paused
///
/// @author [email protected]

import 'dart:async';
import '../../../../Utils/expect.dart';

main() async {
StreamController<int> sc = StreamController<int>();
sc.addStream(Stream<int>.fromIterable([1, 2, 3]));
await for (var i in sc.stream) {
await for (var j in Stream.fromIterable(['one', 'two', 'three'])) {
Expect.isTrue(sc.isPaused);
}
}
}
63 changes: 63 additions & 0 deletions Language/Statements/For/Asynchronous_For_in/execution_A02_t02.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) 2022, 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.

/// @assertion Let `D` be derived from <finalConstVarOrType>?. Execution of a
/// for-in statement, `f`, of the form `await for (D id in e) s` proceeds as
/// follows:
///
/// The expression `e` is evaluated to an object `o`. It is a dynamic type error
/// if `o` is not an instance of a class that implements [Stream]. It is a
/// compile-time error if `D` is empty and `id` is a final variable.
///
/// The stream associated with the innermost enclosing asynchronous for loop,
/// if any, is paused. The stream `o` is listened to, producing a stream
/// subscription `u`, and execution of the asynchronous for-in loop is suspended
/// until a stream event is available.
///
/// Pausing an asynchronous for loop means pausing the associated stream
/// subscription. A stream subscription is paused by calling its pause method.
/// If the subscription is already paused, an implementation may omit further
/// calls to pause.
///
/// For each data event from `u`, the statement `s` is executed with `id` bound
/// to the value of the current data event.
///
/// If execution of `s` continues without a label, or to a label that prefixes
/// the asynchronous for statement, then the execution of `s` is treated as if
/// it had completed normally.
///
/// If execution of `s` otherwise does not complete normally, the subscription
/// `u` is canceled by evaluating `await v.cancel()` where `v` is a fresh
/// variable referencing the stream subscription `u`. If that evaluation throws,
/// execution of `f` throws the same exception and stack trace. Otherwise
/// execution of `f` completes in the same way as the execution of `s`.
/// Otherwise the execution of `f` is suspended again, waiting for the next
/// stream subscription event, and `u` is resumed if it has been paused.
///
/// On an error event from `u`, with error object `e` and stack trace `st`, the
/// subscription `u` is canceled by evaluating `await v.cancel()` where `v` is a
/// fresh variable referencing the stream subscription `u`. If that evaluation
/// throws, execution of `f` throws the same exception object and stack trace.
/// Otherwise execution of `f` throws with `e` as exception object and `st` as
/// stack trace.
///
/// When `u` is done, execution of `f` completes normally.
///
/// @description Check that execution of the asynchronous for-in loop is
/// suspended until a stream event is available but not paused
///
/// @author [email protected]

import 'dart:async';
import '../../../../Utils/expect.dart';

main() async {
StreamController<int> sc = StreamController<int>();
sc.addStream(Stream<int>.fromIterable([1, 2, 3]));
await for (var j in Stream.fromIterable(['one', 'two', 'three'])) {
await for (var i in sc.stream) {
Expect.isFalse(sc.isPaused);
}
}
}
Loading