blob: 9024b8b0971312244ed39e9c03a1f44aade7b96a [file] [edit]
// 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 omitted then the
/// variable's type is inferred and the pattern matches all values. Test `var`
/// and `final`
/// @author sgrekhov22@gmail.com
import "../../Utils/static_type_helper.dart";
import "../../Utils/expect.dart";
import "patterns_lib.dart";
String testRecord1(Record r, [bool doTypeTest = false]) {
switch (r) {
case (var a, final b):
if (doTypeTest) {
a.expectStaticType<Exactly<Object?>>();
b.expectStaticType<Exactly<Object?>>();
}
return "($a, $b)";
default:
return "default";
}
}
String testRecord2(Record r) {
return switch (r) {
(var a, final b) => "($a, $b)",
_ => "default"
};
}
String testRecord3(Record r, [bool doTypeTest = false]) {
if (r case (var a, final b)) {
if (doTypeTest) {
a.expectStaticType<Exactly<Object?>>();
b.expectStaticType<Exactly<Object?>>();
}
return "($a, $b)";
} else {
return "default";
}
}
String testList1(List l, [bool doTypeTest = false]) {
switch (l) {
case [var a, final b]:
if (doTypeTest) {
// Expect here static type dynamic
a.isOdd;
b.substring(0);
Expect.throws(() {a.whatever;});
Expect.throws(() {b.whatever;});
}
return "[$a, $b]";
default:
return "default";
}
}
String testList2(List l) {
return switch (l) {
[var a, final b] => "[$a, $b]",
_ => "default"
};
}
String testList3(List l, [bool doTypeTest = false]) {
if (l case [var a, final b]) {
if (doTypeTest) {
a.isOdd;
b.substring(0);
Expect.throws(() {a.whatever;});
Expect.throws(() {b.whatever;});
}
return "[$a, $b]";
} else {
return "default";
}
}
String testMap1(Map m) {
switch (m) {
case {1: var a}:
a.isOdd;
Expect.throws(() {a.whatever;});
return "{1: $a}";
case {2: final b}:
b.substring(0);
Expect.throws(() {b.whatever;});
return "{2: $b}";
default:
return "default";
}
}
String testMap2(Map m) {
return switch (m) {
{1: var a} => "{1: $a}",
{2: final b} => "{2: $b}",
_ => "default"
};
}
String testMap3(Map m) {
if (m case {1: var a}) {
a.isOdd;
Expect.throws(() {a.whatever;});
return "{1: $a}";
}
if (m case {2: final b}) {
b.substring(0);
Expect.throws(() {b.whatever;});
return "{2: $b}";
} else {
return "default";
}
}
String testObject1(Shape shape) {
switch (shape) {
case Square(area: var a):
return "a=$a";
case Rectangle(area: final b):
return "b=$b";
default:
return "default";
}
}
String testObject2(Shape shape) {
return switch (shape) {
Square(area: var a) => "a=$a",
Rectangle(area: final b) => "b=$b",
_ => "default"
};
}
String testObject3(Shape shape) {
if (shape case Square(area: var a)) {
return "a=$a";
}
if (shape case Rectangle(area: final b)) {
return "b=$b";
} else {
return "default";
}
}
main() {
Expect.equals("(1, x)", testRecord1((1, "x"), true));
Expect.equals("(1, 2)", testRecord1((1, 2)));
Expect.equals("(true, false)", testRecord1((true, false)));
Expect.equals("default", testRecord1((1, 2, 3)));
Expect.equals("default", testRecord1(("x",)));
Expect.equals("(1, x)", testRecord2((1, "x")));
Expect.equals("(1, 2)", testRecord2((1, 2)));
Expect.equals("(true, false)", testRecord2((true, false)));
Expect.equals("default", testRecord2((1, 2, 3)));
Expect.equals("default", testRecord2(("x",)));
Expect.equals("(1, x)", testRecord3((1, "x"), true));
Expect.equals("(1, 2)", testRecord3((1, 2)));
Expect.equals("(true, false)", testRecord3((true, false)));
Expect.equals("default", testRecord3((1, 2, 3)));
Expect.equals("default", testRecord3(("x",)));
Expect.equals("[1, x]", testList1([1, "x"], true));
Expect.equals("[1, 2]", testList1([1, 2]));
Expect.equals("[true, false]", testList1([true, false]));
Expect.equals("default", testList1([1, 2, 3]));
Expect.equals("default", testList1(["x"]));
Expect.equals("[1, x]", testList2([1, "x"]));
Expect.equals("[1, 2]", testList2([1, 2]));
Expect.equals("[true, false]", testList2([true, false]));
Expect.equals("default", testList2([1, 2, 3]));
Expect.equals("default", testList2(["x"]));
Expect.equals("[1, x]", testList3([1, "x"]));
Expect.equals("[1, 2]", testList3([1, 2]));
Expect.equals("[true, false]", testList3([true, false]));
Expect.equals("default", testList3([1, 2, 3]));
Expect.equals("default", testList3(["x"]));
Expect.equals("{1: 2}", testMap1({1: 2}));
Expect.equals("{1: 3}", testMap1({1: 3, 3: 4}));
Expect.equals("{2: x}", testMap1({2: "x"}));
Expect.equals("default", testMap1({3: 3}));
Expect.equals("default", testMap1({}));
Expect.equals("{1: 2}", testMap2({1: 2}));
Expect.equals("{1: 3}", testMap2({1: 3, 3: 4}));
Expect.equals("{2: x}", testMap2({2: "x"}));
Expect.equals("{2: true}", testMap2({2: true}));
Expect.equals("default", testMap2({3: 3}));
Expect.equals("default", testMap2({}));
Expect.equals("{1: 2}", testMap3({1: 2}));
Expect.equals("{1: 3}", testMap3({1: 3, 3: 4}));
Expect.equals("{2: x}", testMap3({2: "x"}));
Expect.equals("default", testMap3({3: 3}));
Expect.equals("default", testMap3({}));
Expect.equals("a=1", testObject1(Square(1)));
Expect.equals("a=4", testObject1(Square(2)));
Expect.equals("b=2", testObject1(Rectangle(1, 2)));
Expect.equals("b=4", testObject1(Rectangle(2, 2)));
Expect.equals("default", testObject1(Circle(1)));
Expect.equals("default", testObject1(Shape()));
Expect.equals("a=1", testObject2(Square(1)));
Expect.equals("a=4", testObject2(Square(2)));
Expect.equals("b=2", testObject2(Rectangle(1, 2)));
Expect.equals("b=4", testObject2(Rectangle(2, 2)));
Expect.equals("default", testObject2(Circle(1)));
Expect.equals("default", testObject2(Shape()));
Expect.equals("a=1", testObject3(Square(1)));
Expect.equals("a=4", testObject3(Square(2)));
Expect.equals("b=2", testObject3(Rectangle(1, 2)));
Expect.equals("b=4", testObject3(Rectangle(2, 2)));
Expect.equals("default", testObject3(Circle(1)));
Expect.equals("default", testObject3(Shape()));
}