Skip to content

Commit

Permalink
dart-lang#1401. Async for-in tests added
Browse files Browse the repository at this point in the history
  • Loading branch information
sgrekhov committed May 1, 2023
1 parent be5c6fa commit 1d7920b
Show file tree
Hide file tree
Showing 8 changed files with 678 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (c) 2023, 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 It is a compile-time error if an asynchronous for-in statement
/// appears inside a synchronous function
///
/// @description Checks that it is a compile-time error if an asynchronous
/// for-in statement appears inside a synchronous function
/// @author [email protected]
/// @issue 52228
// SharedOptions=--enable-experiment=patterns,records

import "patterns_lib.dart";

test1() {
await for (var (v1 && v2) in Stream.fromIterable([1, 2, 3])) {
// ^^
// [analyzer] unspecified
// [cfe] unspecified
print(v1);
print(v2);
}
}

test2() {
await for (final (num v) in Stream.fromIterable([1, 2, 3])) {
// ^^
// [analyzer] unspecified
// [cfe] unspecified
print(v);
}
}

test3() {
await for (var (v) in Stream.fromIterable([1, 2, 3])) {
// ^^
// [analyzer] unspecified
// [cfe] unspecified
print(v);
}
}

test4() {
await for (final [v] in Stream.fromIterable([[1], [2], [3]])) {
// ^^
// [analyzer] unspecified
// [cfe] unspecified
print(v);
}
}

test5() {
await for (var {"k": v} in Stream.fromIterable([{"k": 1}])) {
// ^^
// [analyzer] unspecified
// [cfe] unspecified
print(v);
}
}

test6() {
await for (final (v1, n: v2) in Stream.fromIterable([(1, n: 2)])) {
// ^^
// [analyzer] unspecified
// [cfe] unspecified
print(v1);
print(v2);
}
}

test7() {
await for (var Square(area: v) in Stream.fromIterable([Square(1)])) {
// ^^
// [analyzer] unspecified
// [cfe] unspecified
print(v);
}
}

main() async {
test1();
test2();
test3();
test4();
test5();
test6();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Copyright (c) 2023, 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
/// A statement of the form:
///
/// for (<keyword> <pattern> in <expression>) <statement>
///
/// Where <keyword> is var or final is treated like so:
/// 1. Let I be the static type of <expression>, inferred using context type
/// schema Iterable<P> where P is the context type schema of <pattern>.
/// 2. Calculate the element type of I:
/// i. If I implements Iterable<T> for some T then E is T.
/// ii. Else if I is dynamic then E is dynamic.
/// iii. Else it is a compile-time error.
/// 3. Type check <pattern> with matched value type E.
/// 4. If there are no compile-time errors, then execution proceeds as the
/// following code, where id1 and id2 are fresh identifiers:
/// ```dart
/// var id1 = <expression>;
/// var id2 = id1.iterator;
/// while (id2.moveNext()) {
/// <keyword> <pattern> = id2.current;
/// { <statement> }
/// }
/// ```
/// @description Checks that in an async for-in loop if `I` implements
/// `Stream<T>` for some `T` then `E` is `T`. Test `T` inferred from `<pattern>`
/// to `<expression>` and from `<expression>` to `<pattern>`
/// @author [email protected]
// SharedOptions=--enable-experiment=patterns,records

import "../../Utils/expect.dart";
import "../../Utils/static_type_helper.dart";
import "patterns_lib.dart";

extension Storing on Object? {
static dynamic stored;
void get store => stored = this;
}

main() async {
String log = "";
await for (var (num v1) in Stream.fromIterable([1, 2, 3])..store) {
v1.expectStaticType<Exactly<num>>();
log += "$v1;";
}
Expect.equals("1;2;3;", log);
Expect.isTrue(Storing.stored is Stream<num>);

log = "";
await for (final (v2) in Stream<num>.fromIterable([1, 2, 3])) {
v2.expectStaticType<Exactly<num>>();
log += "$v2;";
}
Expect.equals("1;2;3;", log);
log = "";

log = "";
await for (var <num>[v3] in Stream.fromIterable([
[1],
[2],
[3]
])..store) {
v3.expectStaticType<Exactly<num>>();
log += "$v3;";
}
Expect.equals("1;2;3;", log);
Expect.isTrue(Storing.stored is Stream<List<num>>);

log = "";
await for (final [v4] in Stream<List<num>>.fromIterable([
[1],
[2],
[3]
])) {
v4.expectStaticType<Exactly<num>>();
log += "$v4;";
}
Expect.equals("1;2;3;", log);

log = "";
await for (var <String, num>{"k1": v5} in Stream.fromIterable([
{"k1": 1}
])..store) {
v5.expectStaticType<Exactly<num>>();
log += "$v5;";
}
Expect.equals("1;", log);
Expect.isTrue(Storing.stored is Stream<Map<String, num>>);

log = "";
await for (final {"k1": v6} in Stream<Map<String, num>>.fromIterable([
{"k1": 1}
])) {
v6.expectStaticType<Exactly<num>>();
log += "$v6;";
}
Expect.equals("1;", log);

log = "";
await for (var (num v7, n: num v8) in Stream.fromIterable([(1, n: 2)])
..store) {
v7.expectStaticType<Exactly<num>>();
v8.expectStaticType<Exactly<num>>();
log += "$v7;$v8;";
}
Expect.equals("1;2;", log);
Expect.isTrue(Storing.stored is Stream<(num, {num n})>);

log = "";
await for (final (v9, n: v10)
in Stream<(num, {num n})>.fromIterable([(1, n: 2)])) {
v9.expectStaticType<Exactly<num>>();
v10.expectStaticType<Exactly<num>>();
log += "$v9;$v10;";
}
Expect.equals("1;2;", log);

log = "";
await for (var Square<Centimeter>(area: v11)
in Stream.fromIterable([Square(1)])..store) {
v11.expectStaticType<Exactly<Unit<Centimeter>>>();
log += "$v11;";
}
Expect.equals("1;", log);
Expect.isTrue(Storing.stored is Stream<Square<Centimeter>>);

log = "";
await for (final Square(area: v12)
in Stream<Square<Centimeter>>.fromIterable([Square<Centimeter>(1)])) {
v12.expectStaticType<Exactly<Unit<Centimeter>>>();
log += "$v12;";
}
Expect.equals("1;", log);

log = "";
await for (var (num v1 && v2) in Stream.fromIterable([1, 2, 3])..store) {
v1.expectStaticType<Exactly<num>>();
v2.expectStaticType<Exactly<num>>();
log += "$v1&&$v2;";
}
Expect.equals("1&&1;2&&2;3&&3;", log);
Expect.isTrue(Storing.stored is Stream<num>);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Copyright (c) 2023, 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
/// A statement of the form:
///
/// for (<keyword> <pattern> in <expression>) <statement>
///
/// Where <keyword> is var or final is treated like so:
/// 1. Let I be the static type of <expression>, inferred using context type
/// schema Iterable<P> where P is the context type schema of <pattern>.
/// 2. Calculate the element type of I:
/// i. If I implements Iterable<T> for some T then E is T.
/// ii. Else if I is dynamic then E is dynamic.
/// iii. Else it is a compile-time error.
/// 3. Type check <pattern> with matched value type E.
/// 4. If there are no compile-time errors, then execution proceeds as the
/// following code, where id1 and id2 are fresh identifiers:
/// ```dart
/// var id1 = <expression>;
/// var id2 = id1.iterator;
/// while (id2.moveNext()) {
/// <keyword> <pattern> = id2.current;
/// { <statement> }
/// }
/// ```
/// @description Checks that in an async for-in loop if `I` is `dynamic` and
/// runtime type of `I` is `Stream<T>` where `T` is assignable to `<pattern>`
/// required type then for-in statement works as expected. In particular, if `I`
/// is `dynamic` then element type is `dynamic` and execution of the body does
/// take place
/// @author [email protected]
// SharedOptions=--enable-experiment=patterns,records

import "../../Utils/expect.dart";
import "../../Utils/static_type_helper.dart";
import "patterns_lib.dart";

main() async {
String log = "";
await for (var (num v1) in Stream.fromIterable([1, 2, 3]) as dynamic) {
v1.expectStaticType<Exactly<num>>();
log += "$v1;";
}
Expect.equals("1;2;3;", log);

log = "";
await for (final (v2) in Stream<num>.fromIterable([1, 2, 3]) as dynamic) {
Expect.throws(() {
v2.whatever;
}); // v2 is dynamic
log += "$v2;";
}
Expect.equals("1;2;3;", log);
log = "";

log = "";
await for (var <num>[v3] in Stream.fromIterable([
[1],
[2],
[3]
]) as dynamic) {
v3.expectStaticType<Exactly<num>>();
log += "$v3;";
}
Expect.equals("1;2;3;", log);

log = "";
await for (final [v4] in Stream<List<num>>.fromIterable([
[1],
[2],
[3]
]) as dynamic) {
Expect.throws(() {
v4.whatever;
});
log += "$v4;";
}
Expect.equals("1;2;3;", log);

log = "";
await for (var <String, num>{"k1": v5} in Stream.fromIterable([
{"k1": 1}
]) as dynamic) {
v5.expectStaticType<Exactly<num>>();
log += "$v5;";
}
Expect.equals("1;", log);

log = "";
await for (final {"k1": v6} in Stream<Map<String, num>>.fromIterable([
{"k1": 1}
]) as dynamic) {
Expect.throws(() {
v6.whatever;
});
log += "$v6;";
}
Expect.equals("1;", log);

log = "";
await for (var (num v7, n: num v8)
in Stream.fromIterable([(1, n: 2)]) as dynamic) {
v7.expectStaticType<Exactly<num>>();
v8.expectStaticType<Exactly<num>>();
log += "$v7;$v8;";
}
Expect.equals("1;2;", log);

log = "";
await for (final (v9, n: v10)
in Stream<(num, {num n})>.fromIterable([(1, n: 2)]) as dynamic) {
Expect.throws(() {
v9.whatever;
});
Expect.throws(() {
v10.whatever;
});
log += "$v9;$v10;";
}
Expect.equals("1;2;", log);

log = "";
await for (var Square<Centimeter>(area: v11)
in Stream.fromIterable([Square<Centimeter>(1)]) as dynamic) {
v11.expectStaticType<Exactly<Unit<Centimeter>>>();
log += "$v11;";
}
Expect.equals("1;", log);

log = "";
await for (final Square(area: v12)
in Stream<Square<Centimeter>>.fromIterable([Square<Centimeter>(1)])
as dynamic) {
v12.expectStaticType<Exactly<Unit<MetricUnits>>>();
log += "$v12;";
}
Expect.equals("1;", log);
}
Loading

0 comments on commit 1d7920b

Please sign in to comment.