blob: 90221b80404780ad33df3a0346c0a709926246c8 [file]
// 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
/// variablePattern ::= ( 'var' | 'final' | 'final'? type )? identifier
///
/// A variable pattern binds the matched value to a new variable. These usually
/// occur as subpatterns of a destructuring pattern in order to capture a
/// destructured value.
/// ```dart
/// var (a, b) = (1, 2);
/// ```
/// Here, a and b are variable patterns and end up bound to 1 and 2,
/// respectively.
///
/// The pattern may have a type annotation in order to only match values of the
/// specified type. If the type annotation is omitted, the variable's type is
/// inferred and the pattern matches all values.
/// ```dart
/// switch (record) {
/// case (int x, String s):
/// print('First field is int $x and second is String $s.');
/// }
/// ```
/// @description Check that if the type annotation is specified then the
/// pattern matches values of the appropriate type only. Test records
/// @author sgrekhov22@gmail.com
import "../../Utils/static_type_helper.dart";
import "../../Utils/expect.dart";
class C {
@override
String toString() => "C";
}
String test1(Record r) {
switch (r) {
case (int a, String b):
a.expectStaticType<Exactly<int>>();
b.expectStaticType<Exactly<String>>();
return "(<int>$a, <String>$b)";
case (int c, final int d):
c.expectStaticType<Exactly<int>>();
d.expectStaticType<Exactly<int>>();
return "(<int>$c, <int>$d)";
case (String e, bool f):
e.expectStaticType<Exactly<String>>();
f.expectStaticType<Exactly<bool>>();
return "(<String>$e, <bool>$f)";
case (int g, final h):
g.expectStaticType<Exactly<int>>();
return "(<int>$g, final $h)";
default:
return "default";
}
}
String test2(Record r) {
return switch (r) {
(int a, String b) => "(<int>$a, <String>$b)",
(int c, final int d) => "(<int>$c, <int>$d)",
(String e, bool f) => "(<String>$e, <bool>$f)",
(int g, final h) => "(<int>$g, final $h)",
_ => "default"
};
}
String test3(Record r) {
if (r case (int a, String b)) {
a.expectStaticType<Exactly<int>>();
b.expectStaticType<Exactly<String>>();
return "(<int>$a, <String>$b)";
}
if (r case (int c, final int d)) {
c.expectStaticType<Exactly<int>>();
d.expectStaticType<Exactly<int>>();
return "(<int>$c, <int>$d)";
}
if (r case (String e, bool f)) {
e.expectStaticType<Exactly<String>>();
f.expectStaticType<Exactly<bool>>();
return "(<String>$e, <bool>$f)";
}
if (r case (int g, final h)) {
g.expectStaticType<Exactly<int>>();
return "(<int>$g, final $h)";
} else {
return "default";
}
}
main() {
Expect.equals("(<int>1, <String>x)", test1((1, "x")));
Expect.equals("(<int>42, <String>answer)", test1((42, "answer")));
Expect.equals("(<int>1, <int>2)", test1((1, 2)));
Expect.equals("(<int>3, <int>4)", test1((3, 4)));
Expect.equals("(<String>x, <bool>true)", test1(("x", true)));
Expect.equals("(<String>y, <bool>false)", test1(("y", false)));
Expect.equals("(<int>0, final false)", test1((0, false)));
Expect.equals("(<int>1, final C)", test1((1, C())));
Expect.equals("default", test1((true, false)));
Expect.equals("default", test1((C(), C())));
Expect.equals("default", test1((1, 2, 3)));
Expect.equals("default", test1((1,)));
Expect.equals("default", test1((1, "2", 3)));
Expect.equals("default", test1(("x",)));
Expect.equals("(<int>1, <String>x)", test2((1, "x")));
Expect.equals("(<int>42, <String>answer)", test2((42, "answer")));
Expect.equals("(<int>1, <int>2)", test2((1, 2)));
Expect.equals("(<int>3, <int>4)", test2((3, 4)));
Expect.equals("(<String>x, <bool>true)", test2(("x", true)));
Expect.equals("(<String>y, <bool>false)", test2(("y", false)));
Expect.equals("(<int>0, final false)", test2((0, false)));
Expect.equals("(<int>1, final C)", test2((1, C())));
Expect.equals("default", test2((true, false)));
Expect.equals("default", test2((C(), C())));
Expect.equals("default", test2((1, 2, 3)));
Expect.equals("default", test2((1,)));
Expect.equals("default", test2((1, "2", 3)));
Expect.equals("default", test2(("x",)));
Expect.equals("(<int>1, <String>x)", test3((1, "x")));
Expect.equals("(<int>42, <String>answer)", test3((42, "answer")));
Expect.equals("(<int>1, <int>2)", test3((1, 2)));
Expect.equals("(<int>3, <int>4)", test3((3, 4)));
Expect.equals("(<String>x, <bool>true)", test3(("x", true)));
Expect.equals("(<String>y, <bool>false)", test3(("y", false)));
Expect.equals("(<int>0, final false)", test3((0, false)));
Expect.equals("(<int>1, final C)", test3((1, C())));
Expect.equals("default", test3((true, false)));
Expect.equals("default", test3((C(), C())));
Expect.equals("default", test3((1, 2, 3)));
Expect.equals("default", test3((1,)));
Expect.equals("default", test3((1, "2", 3)));
Expect.equals("default", test3(("x",)));
}