diff --git a/Language/Functions/element_type_A01_t01.dart b/Language/Functions/element_type_A01_t01.dart new file mode 100644 index 0000000000..eac1944583 --- /dev/null +++ b/Language/Functions/element_type_A01_t01.dart @@ -0,0 +1,57 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. If +/// f is a synchronous generator and S implements Iterable for some U then +/// the element type of f is U. +/// +/// @description Check that if the declared return type of a synchronous +/// generator function `f` is `T`, and `S` is the union-free type derived from +/// `T`, and `S` is of the form `Iterable`, it is a compile-time error to +/// yield an expression whose static type isn't assignable to `U`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; + +Iterable? f1() sync* { + yield 1; + yield 3.14; + yield null; // Ok, element type is `num?` +} + +Iterable? f2() sync* { + yield 1; + yield null; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +FutureOr?> f3() sync* { + yield 1; + yield null; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + yield Future.value(null); +// ^^^^^^^^^^^^^^^^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + yield Future.value(1); +// ^^^^^^^^^^^^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + f1(); + f2(); + f3(); +} diff --git a/Language/Functions/element_type_A01_t02.dart b/Language/Functions/element_type_A01_t02.dart new file mode 100644 index 0000000000..17b39cc4e5 --- /dev/null +++ b/Language/Functions/element_type_A01_t02.dart @@ -0,0 +1,50 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. If +/// f is a synchronous generator and S implements Iterable for some U then +/// the element type of f is U. +/// +/// @description Check that if the declared return type of a synchronous +/// generator function `f` is `T`, and `S` is the union-free type derived from +/// `T`, and `S` is of the form `Iterable`, it is a compile-time error to +/// yield an expression whose static type isn't assignable to `U`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; + +Iterable? f1() sync* { + yield 1; + yield 3.14; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + yield "2"; +// ^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +FutureOr?> f2() sync* { + yield 1; + yield 3.14; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + yield "2"; +// ^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + f1(); + f2(); +} diff --git a/Language/Functions/element_type_A01_t03.dart b/Language/Functions/element_type_A01_t03.dart new file mode 100644 index 0000000000..b0276ff83a --- /dev/null +++ b/Language/Functions/element_type_A01_t03.dart @@ -0,0 +1,32 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. If +/// f is a synchronous generator and S implements Iterable for some U then +/// the element type of f is U. +/// +/// @description Check a run-time type of a return value of a synchronous +/// generator function +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../Utils/expect.dart"; + +FutureOr?> foo() sync* { + yield 1; + yield 2; + yield 3; +} + +main() { + FutureOr?> o = foo() as dynamic; + o as FutureOr>; + Expect.isRuntimeTypeImplementsIterable(o); +} diff --git a/Language/Functions/element_type_A01_t04.dart b/Language/Functions/element_type_A01_t04.dart new file mode 100644 index 0000000000..28b19d9d01 --- /dev/null +++ b/Language/Functions/element_type_A01_t04.dart @@ -0,0 +1,34 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. If +/// f is a synchronous generator and S implements Iterable for some U then +/// the element type of f is U. +/// +/// @description Let `f` be a synchronous generator function whose declared +/// return type derives the union-free type `S`, and assume that `S` implements +/// `Iterable`. Then check that the element type of `f` is `U`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../Utils/expect.dart"; +import "../../Utils/static_type_helper.dart"; + +FutureOr?> foo() sync* { + yield 1; + yield 2; + yield 3; +} + +main() { + var o = foo(); + o.expectStaticType?>>>(); + Expect.isRuntimeTypeImplementsIterable(o); +} diff --git a/Language/Functions/element_type_A01_t05.dart b/Language/Functions/element_type_A01_t05.dart new file mode 100644 index 0000000000..af13803086 --- /dev/null +++ b/Language/Functions/element_type_A01_t05.dart @@ -0,0 +1,37 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. If +/// f is a synchronous generator and S implements Iterable for some U then +/// the element type of f is U. +/// +/// @description Let `f` be a synchronous generator function whose declared +/// return type derives the union-free type `S`, and assume that `S` implements +/// `Iterable`. Then check that the element type of `f` is `U`. +/// @author sgrekhov22@gmail.com + +import "../../Utils/expect.dart"; + +Iterable? f1() sync* { + yield 1; + yield 2; + yield null; +} + +Iterable? f2() sync* { + yield 1; + yield 2; + yield 3; +} + +main() { + Expect.isRuntimeTypeImplementsIterable(f1()); + Expect.isRuntimeTypeImplementsIterable(f2()); +} diff --git a/Language/Functions/element_type_A01_t06.dart b/Language/Functions/element_type_A01_t06.dart new file mode 100644 index 0000000000..5423ca5645 --- /dev/null +++ b/Language/Functions/element_type_A01_t06.dart @@ -0,0 +1,38 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. If +/// f is a synchronous generator and S implements Iterable for some U then +/// the element type of f is U. +/// +/// @description Let `f` be a synchronous generator function whose declared +/// return type derives the union-free type `S`, and assume that `S` implements +/// `Iterable`. Then check that the element type of `f` is `U`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../Utils/expect.dart"; + +FutureOr?> f1() sync* { + yield 1; + yield 2; + yield null; +} + +FutureOr?>? f2() sync* { + yield 1; + yield 2; + yield 3; +} + +main() { + Expect.isRuntimeTypeImplementsIterable(f1()); + Expect.isRuntimeTypeImplementsIterable(f2()); +} diff --git a/Language/Functions/element_type_A02_t01.dart b/Language/Functions/element_type_A02_t01.dart new file mode 100644 index 0000000000..26f89b6126 --- /dev/null +++ b/Language/Functions/element_type_A02_t01.dart @@ -0,0 +1,58 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. +/// ... +/// If `f` is an asynchronous generator and `S` implements `Stream` for some +/// `U` then the element type of `f` is `U`. +/// +/// @description Check that if the declared return type of an asynchronous +/// generator function `f` is `T`, and `S` is the union-free type derived from +/// `T`, and `S` is of the form `Stream`, it is a compile-time error to +/// yield an expression whose static type isn't assignable to `U`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; + +Stream? f1() async* { + yield 1; + yield 3.14; + yield null; // Ok, element type is `num?` +} + +Stream? f2() async* { + yield 1; + yield null; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +FutureOr?> f3() async* { + yield 1; + yield null; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + yield Future.value(null); +// ^^^^^^^^^^^^^^^^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + yield Future.value(1); +// ^^^^^^^^^^^^^^^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + f1(); + f2(); + f3(); +} diff --git a/Language/Functions/element_type_A02_t02.dart b/Language/Functions/element_type_A02_t02.dart new file mode 100644 index 0000000000..c1074ddc82 --- /dev/null +++ b/Language/Functions/element_type_A02_t02.dart @@ -0,0 +1,51 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. +/// ... +/// If `f` is an asynchronous generator and `S` implements `Stream` for some +/// `U` then the element type of `f` is `U`. +/// +/// @description Check that if the declared return type of an asynchronous +/// generator function `f` is `T`, and `S` is the union-free type derived from +/// `T`, and `S` is of the form `Stream`, it is a compile-time error to +/// yield an expression whose static type isn't assignable to `U`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; + +Stream? f1() async* { + yield 1; + yield 3.14; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + yield "2"; +// ^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +FutureOr?> f2() async* { + yield 1; + yield 3.14; +// ^^^^ +// [analyzer] unspecified +// [cfe] unspecified + yield "2"; +// ^^^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + f1(); + f2(); +} diff --git a/Language/Functions/element_type_A02_t03.dart b/Language/Functions/element_type_A02_t03.dart new file mode 100644 index 0000000000..4dbfe1aae3 --- /dev/null +++ b/Language/Functions/element_type_A02_t03.dart @@ -0,0 +1,45 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. +/// ... +/// If `f` is an asynchronous generator and `S` implements `Stream` for some +/// `U` then the element type of `f` is `U`. +/// +/// @description Check a run-time type of a returned value of an asynchronous +/// generator function +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../Utils/expect.dart"; + +void isRuntimeTypeImplementsStream(Object? o) async { + if (o is! Stream) { + throw ExpectException("Not a Stream<$T>: ${o.runtimeType}"); + } + List list = await o.toList(); + try { + list.addAll([]); + } on TypeError catch (_) { + throw ExpectException("Expected Stream<$T> but found $o"); + } +} + +FutureOr?> foo() async* { + yield 1; + yield 2; + yield 3; +} + +main() async { + dynamic d = await foo(); + FutureOr> o = d; + isRuntimeTypeImplementsStream(d); +} diff --git a/Language/Functions/element_type_A02_t04.dart b/Language/Functions/element_type_A02_t04.dart new file mode 100644 index 0000000000..d3c548588f --- /dev/null +++ b/Language/Functions/element_type_A02_t04.dart @@ -0,0 +1,47 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. +/// ... +/// If `f` is an asynchronous generator and `S` implements `Stream` for some +/// `U` then the element type of `f` is `U`. +/// +/// @description Let `f` be an asynchronous generator function whose declared +/// return type derives the union-free type `S`, and assume that `S` implements +/// `Stream`. Then check that the element type of `f` is `U`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../Utils/expect.dart"; +import "../../Utils/static_type_helper.dart"; + +void isRuntimeTypeImplementsStream(Object? o) async { + if (o is! Stream) { + throw ExpectException("Not a Stream<$T>: ${o.runtimeType}"); + } + List list = await o.toList(); + try { + list.addAll([]); + } on TypeError catch (_) { + throw ExpectException("Expected Stream<$T> but found $o"); + } +} + +FutureOr?> foo() async* { + yield 1; + yield 2; + yield 3; +} + +main() async { + var o = await foo(); + o.expectStaticType?>>(); + isRuntimeTypeImplementsStream(o); +} diff --git a/Language/Functions/element_type_A02_t05.dart b/Language/Functions/element_type_A02_t05.dart new file mode 100644 index 0000000000..52aa383414 --- /dev/null +++ b/Language/Functions/element_type_A02_t05.dart @@ -0,0 +1,41 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. +/// ... +/// If `f` is an asynchronous generator and `S` implements `Stream` for some +/// `U` then the element type of `f` is `U`. +/// +/// @description Let `f` be an asynchronous generator function whose declared +/// return type derives the union-free type `S`, and assume that `S` implements +/// `Stream`. Then check that the element type of `f` is `U`. +/// @author sgrekhov22@gmail.com + +import "../../Utils/expect.dart"; + +Stream? f1() async* { + yield 1; + yield 2; + yield null; +} + +Stream? f2() async* { + yield 1; + yield 2; + yield 3; +} + +main() async { + var it1 = await f1()?.toList(); + Expect.isRuntimeTypeImplementsIterable(it1); + + var it2 = await f2()?.toList(); + Expect.isRuntimeTypeImplementsIterable(it2); +} diff --git a/Language/Functions/element_type_A02_t06.dart b/Language/Functions/element_type_A02_t06.dart new file mode 100644 index 0000000000..df4187ba65 --- /dev/null +++ b/Language/Functions/element_type_A02_t06.dart @@ -0,0 +1,44 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. +/// ... +/// If `f` is an asynchronous generator and `S` implements `Stream` for some +/// `U` then the element type of `f` is `U`. +/// +/// @description Let `f` be an asynchronous generator function whose declared +/// return type derives the union-free type `S`, and assume that `S` implements +/// `Stream`. Then check that the element type of `f` is `U`. +/// @author sgrekhov22@gmail.com +/// @issue 53051 + +import "dart:async"; +import "../../Utils/expect.dart"; + +FutureOr?> f1() async* { + yield 1; + yield 2; + yield null; +} + +FutureOr?>? f2() async* { + yield 1; + yield 2; + yield 3; +} + +main() async { + var res1 = await f1(); + var it1 = await res1?.toList(); + Expect.isRuntimeTypeImplementsIterable(it1); + + var it2 = (await f2())?.toList(); + Expect.isRuntimeTypeImplementsIterable(it2); +} diff --git a/Language/Functions/element_type_A03_t01.dart b/Language/Functions/element_type_A03_t01.dart new file mode 100644 index 0000000000..3af6390546 --- /dev/null +++ b/Language/Functions/element_type_A03_t01.dart @@ -0,0 +1,80 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. +/// ... +/// Otherwise, if `f` is a generator (synchronous or asynchronous) and `S` is a +/// supertype of `Object` then the element type of `f` is dynamic +/// +/// @description Let `f` be a synchronous generator function whose declared +/// return type derives a union-free type which is a supertype of `Object` +/// (including `Object` itself). Then check that its element type is `dynamic`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../Utils/expect.dart"; + +Object? f1() sync* { + yield 1; + yield 3.14; + yield null; + yield "42"; +} + +Object f2() sync* { + yield 1; + yield null; + yield "42"; +} + +FutureOr f3() sync* { + yield 1; + yield null; + yield "42"; + yield Future.value(null); + yield Future.value(1); +} + +FutureOr? f4() sync* { + yield 1; + yield null; + yield "42"; + yield Future.value(null); + yield Future.value(1); +} + +FutureOr f5() sync* { + yield 1; + yield null; + yield "42"; + yield Future.value(null); + yield Future.value(1); + yield Future.value(1); + yield Future.value(null); +} + +FutureOr? f6() sync* { + yield 1; + yield null; + yield "42"; + yield Future.value(null); + yield Future.value(1); + yield Future.value(1); + yield Future.value(null); +} + +main() { + Expect.isRuntimeTypeImplementsIterable(f1()); + Expect.isRuntimeTypeImplementsIterable(f2()); + Expect.isRuntimeTypeImplementsIterable(f3()); + Expect.isRuntimeTypeImplementsIterable(f4()); + Expect.isRuntimeTypeImplementsIterable(f5()); + Expect.isRuntimeTypeImplementsIterable(f6()); +} diff --git a/Language/Functions/element_type_A03_t02.dart b/Language/Functions/element_type_A03_t02.dart new file mode 100644 index 0000000000..d28b08f523 --- /dev/null +++ b/Language/Functions/element_type_A03_t02.dart @@ -0,0 +1,97 @@ +// 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 We define the union-free type derived from a type T as follows: +/// If T is of the form S? or the form FutureOr then the union-free type +/// derived from T is the union-free type derived from S. Otherwise, the +/// union-free type derived from T is T +/// +/// We define the element type of a generator function `f` as follows: +/// Let S be the union-free type derived from the declared return type of f. +/// ... +/// Otherwise, if `f` is a generator (synchronous or asynchronous) and `S` is a +/// supertype of `Object` then the element type of `f` is dynamic +/// +/// @description Let `f` be an asynchronous generator function whose declared +/// return type derives a union-free type which is a supertype of `Object` +/// (including `Object` itself). Then check that its element type is `dynamic`. +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../Utils/expect.dart"; + +Object? f1() async* { + yield 1; + yield 3.14; + yield null; + yield "42"; +} + +Object f2() async* { + yield 1; + yield null; + yield "42"; +} + +FutureOr f3() async* { + yield 1; + yield null; + yield "42"; + yield Future.value(null); + yield Future.value(1); +} + +FutureOr? f4() async* { + yield 1; + yield null; + yield "42"; + yield Future.value(null); + yield Future.value(1); +} + +FutureOr f5() async* { + yield 1; + yield null; + yield "42"; + yield Future.value(null); + yield Future.value(1); + yield Future.value(1); + yield Future.value(null); +} + +FutureOr? f6() async* { + yield 1; + yield null; + yield "42"; + yield Future.value(null); + yield Future.value(1); + yield Future.value(1); + yield Future.value(null); +} + +main() async { + dynamic r1 = f1(); + var v1 = await r1.toList(); + Expect.isRuntimeTypeImplementsIterable(v1); + + dynamic r2 = f2(); + var v2 = await r2.toList(); + Expect.isRuntimeTypeImplementsIterable(v2); + + dynamic r3 = f3(); + var v3 = await r3.toList(); + Expect.isRuntimeTypeImplementsIterable(v3); + + dynamic r4 = f4(); + var v4 = await r4.toList(); + Expect.isRuntimeTypeImplementsIterable(v4); + + dynamic r5 = f5(); + var v5 = await r5.toList(); + Expect.isRuntimeTypeImplementsIterable(v5); + + dynamic r6 = f6(); + var v6 = await r6.toList(); + Expect.isRuntimeTypeImplementsIterable(v6); +} diff --git a/Language/Functions/generator_return_type_t01.dart b/Language/Functions/generator_return_type_t01.dart index baf71407c3..908ec08d12 100644 --- a/Language/Functions/generator_return_type_t01.dart +++ b/Language/Functions/generator_return_type_t01.dart @@ -9,8 +9,8 @@ /// of synchronous generator function is not a supertype of `Iterable` /// @author a.semenov@unipro.ru -int f() sync* { } -//^ +/**/int f() sync* { } +// ^^^ // [analyzer] unspecified // [cfe] unspecified diff --git a/Language/Functions/generator_return_type_t02.dart b/Language/Functions/generator_return_type_t02.dart index 55c3457fa1..a01c5bbd2c 100644 --- a/Language/Functions/generator_return_type_t02.dart +++ b/Language/Functions/generator_return_type_t02.dart @@ -10,8 +10,8 @@ /// @issue 32192 /// @author a.semenov@unipro.ru -void h() sync* { } -//^ +/**/void h() sync* { } +// ^^^^ // [analyzer] unspecified // [cfe] unspecified diff --git a/Language/Functions/generator_return_type_t05.dart b/Language/Functions/generator_return_type_t05.dart index 79b6f623e1..7fcf6f59bf 100644 --- a/Language/Functions/generator_return_type_t05.dart +++ b/Language/Functions/generator_return_type_t05.dart @@ -9,8 +9,8 @@ /// of a function marked `async*` is not a supertype of Stream /// @author a.semenov@unipro.ru -int f() async* { } -//^ +/**/int f() async* { } +// ^^^ // [analyzer] unspecified // [cfe] unspecified diff --git a/Language/Functions/generator_return_type_t06.dart b/Language/Functions/generator_return_type_t06.dart index 2df4888430..04c893a148 100644 --- a/Language/Functions/generator_return_type_t06.dart +++ b/Language/Functions/generator_return_type_t06.dart @@ -10,8 +10,8 @@ /// @issue 32192 /// @author a.semenov@unipro.ru -void h() async* { } -//^ +/**/void h() async* { } +// ^^^^ // [analyzer] unspecified // [cfe] unspecified diff --git a/Utils/expect_common.dart b/Utils/expect_common.dart index 6d0a275490..c7ce53dfc1 100644 --- a/Utils/expect_common.dart +++ b/Utils/expect_common.dart @@ -355,6 +355,23 @@ class Expect { static void runtimeIsNotType(Object? o) { _checkType(_checkIs, false, o); } + + /// Checks that the run-time type of [o] implements `Iterable`, otherwise + /// throws. For example, + /// `isRuntimeTypeImplementsIterable([1, 2, 3])` will throw + /// `ExpectException`, but + /// `isRuntimeTypeImplementsIterable([1, 2, 3])` succeeds. + static void isRuntimeTypeImplementsIterable(Object? o) { + if (o is! Iterable) { + throw ExpectException("Not Iterable<$T>: ${o.runtimeType}"); + } + List list = o.toList(growable: true); + try { + list.addAll([]); + } on TypeError catch (_) { + throw ExpectException("Expected Iterable<$T> but found $o"); + } + } } bool _identical(a, b) => identical(a, b); diff --git a/Utils/tests/Expect/isRuntimeTypeIterable_A01_t01.dart b/Utils/tests/Expect/isRuntimeTypeIterable_A01_t01.dart new file mode 100644 index 0000000000..31409e2661 --- /dev/null +++ b/Utils/tests/Expect/isRuntimeTypeIterable_A01_t01.dart @@ -0,0 +1,53 @@ +// 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 static void isRuntimeTypeIterable(Object? it) +/// Failure if `it` is not instance of `Iterable` or has an element type of +/// which is not exactly the `T` +/// +/// @description Checks no exception is thrown when `it` is an `Iterable` and +/// all elements of it have a type `T` (not a subtype). Throws otherwise. +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../../Utils/expect.dart"; + +main() { + Expect.isRuntimeTypeImplementsIterable([1, 2, 3]); + Expect.isRuntimeTypeImplementsIterable([]); + Expect.isRuntimeTypeImplementsIterable([]); + FutureOr> o = [1, 2, 3]; + Expect.isRuntimeTypeImplementsIterable(o); + + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([1, 2, 3]); + }, (e) => e is ExpectException); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([]); + }, (e) => e is ExpectException); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([]); + }, (e) => e is ExpectException); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([1, 2, 3 as num]); + }, (e) => e is ExpectException); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([]); + }, (e) => e is ExpectException); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([1, 2, 3]); + }); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([1, 2, 3]); + }); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([1, 2, 3]); + }); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([1, 2, 3]); + }); + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable([1, 2, 3]); + }); +} diff --git a/Utils/tests/Expect/isRuntimeTypeIterable_A01_t02.dart b/Utils/tests/Expect/isRuntimeTypeIterable_A01_t02.dart new file mode 100644 index 0000000000..f99c78cb60 --- /dev/null +++ b/Utils/tests/Expect/isRuntimeTypeIterable_A01_t02.dart @@ -0,0 +1,30 @@ +// 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 static void iterableElementsRuntimeIs(dynamic it) +/// Failure if `it` is not instance of `Iterable` or has an element type of +/// which is not exactly the `T` +/// +/// @description Checks that an exception is thrown when `it` is not +/// `Iterable` +/// @author sgrekhov22@gmail.com + +import "dart:async"; +import "../../../Utils/expect.dart"; + +main() { + Expect.throws(() { + Expect.isRuntimeTypeImplementsIterable(Object()); + }, (e) => e is ExpectException); + + Expect.throws(() { + Future> o = Future.value([1, 2, 3]); + Expect.isRuntimeTypeImplementsIterable(o); + }, (e) => e is ExpectException); + + Expect.throws(() { + FutureOr> o = Future.value([1, 2, 3]); + Expect.isRuntimeTypeImplementsIterable(o); + }, (e) => e is ExpectException); +}