blob: cceb4f9402fe8d349204afcd5adfd2fe5200af33 [file]
// 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 collection element of the form:
///
/// for (<keyword> <pattern> in <expression>) <element>
///
/// 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 and append() is
/// an operation to add an element to the surrounding collection being built:
/// ```dart
/// I id1 = <expression>;
/// Iterator<E> id2 = id1.iterator;
/// while (id2.moveNext()) {
/// <keyword> <pattern> = id2.current;
/// append(<element>);
/// }
/// ```
/// @description Checks that if `I` is `dynamic` and runtime type of `I` is
/// `Iterable<T>` where `T` is assignable to `<pattern>` required type then
/// for-in element works as expected
/// @author sgrekhov22@gmail.com
import "../../Utils/expect.dart";
import "../../Utils/static_type_helper.dart";
import "patterns_lib.dart";
main() {
var l1 = [
0,
for (var (num v1) in [1, 2, 3] as dynamic) v1,
4
];
Expect.listEquals([0, 1, 2, 3, 4], l1);
l1.expectStaticType<Exactly<List<num>>>();
var l2 = [
0,
for (final (v2) in <num>[1, 2, 3] as dynamic)
(1 > 2 ? v2.whatever : null, v2).$2,
4
];
Expect.listEquals([0, 1, 2, 3, 4], l2);
l2.expectStaticType<Exactly<List<dynamic>>>();
var l3 = [
0,
for (var <num>[v3] in [[1], [2], [3]] as dynamic) v3,
4
];
Expect.listEquals([0, 1, 2, 3, 4], l3);
l3.expectStaticType<Exactly<List<num>>>();
var l4 = [
0,
for (final [v4] in <List<num>>[[1], [2], [3]] as dynamic)
(1 > 2 ? v4.whatever : null, v4).$2,
4
];
Expect.listEquals([0, 1, 2, 3, 4], l4);
l4.expectStaticType<Exactly<List<dynamic>>>();
var l5 = [
0,
for (var <String, num>{"k1": v5} in [{"k1": 1}] as dynamic) v5,
2
];
Expect.listEquals([0, 1, 2], l5);
l5.expectStaticType<Exactly<List<num>>>();
var l6 = [
0,
for (final {"k1": v6} in <Map<String, num>>[{"k1": 1}] as dynamic)
(1 > 2 ? v6.whatever : null, v6).$2,
2
];
Expect.listEquals([0, 1, 2], l6);
l6.expectStaticType<Exactly<List<dynamic>>>();
var l7 = [
0,
for (var (num v7, n: num v8) in [(1, n: 2)] as dynamic) v7,
2
];
Expect.listEquals([0, 1, 2], l7);
l7.expectStaticType<Exactly<List<num>>>();
var l8 = [
1,
for (final (v9, n: v10) in <(num, {num n})>[(1, n: 2)] as dynamic)
(1 > 2 ? v10.whatever : null, v10).$2,
3
];
Expect.listEquals([1, 2, 3], l8);
l8.expectStaticType<Exactly<List<dynamic>>>();
var l9 = [
for (var Square<Centimeter>(area: v11) in
[Square<Centimeter>(1)] as dynamic) v11,
];
Expect.isTrue(l9[0] == 1);
l9.expectStaticType<Exactly<List<Unit<Centimeter>>>>();
var l10 = [
for (final Square(area: v12) in
<Square<Centimeter>>[Square<Centimeter>(1)] as dynamic) v12
];
Expect.isTrue(l10[0] == 1);
l10.expectStaticType<Exactly<List<Unit<MetricUnits>>>>();
}