Skip to content

Commit

Permalink
dart-lang#2420. Add extension types exhaustiveness tests. Maps (dart-…
Browse files Browse the repository at this point in the history
…lang#2426)

Add extension type exhaustiveness tests about map patterns.
  • Loading branch information
sgrekhov authored Dec 14, 2023
1 parent 3b2c399 commit 593a9f6
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 7 deletions.
79 changes: 79 additions & 0 deletions LanguageFeatures/Extension-types/exhaustiveness_map_A01_t01.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// 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 Exhaustiveness with map patterns can only be achieved when there
/// is an exhaustive pattern in addition to any map patterns
///
/// @description Check that a switch statement/expression with map patterns only
/// cannot be exhaustive. Test the case when a matched type is an extension type
/// with a `Map` as a representation type
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

extension type ET1<K, V>(Map<K, V> _) {}
extension type ET2<K, V>(Map<K, V> _) implements Map<K, V> {}

String test1_1(ET1<bool, bool> m) =>
switch (m) {
//^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
{true: true} => "case-1",
{true: false} => "case-2",
{false: true} => "case-3",
{false: false} => "case-4",
};

String test1_2(ET2<bool, bool> m) =>
switch (m) {
//^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
{true: true} => "case-1",
{true: false} => "case-2",
{false: true} => "case-3",
{false: false} => "case-4",
};

String test2_1(ET1<bool, bool> m) {
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
switch (m) {
case {true: true}:
return "case-1";
case {true: false}:
return "case-2";
case {false: true}:
return "case-3";
case {false: false}:
return "case-4";
}
// There is no return statement here, switch statement is not exhaustive, so an
// error above occurs because function return type cannot be null
}

String test2_2(ET2<bool, bool> m) {
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
switch (m) {
case {true: true}:
return "case-1";
case {true: false}:
return "case-2";
case {false: true}:
return "case-3";
case {false: false}:
return "case-4";
}
}

main() {
print(test1_1(ET1({true: false})));
print(test1_2(ET2({true: false})));
print(test2_1(ET1({true: false})));
print(test2_2(ET2({true: false})));
}
61 changes: 61 additions & 0 deletions LanguageFeatures/Extension-types/exhaustiveness_map_A01_t02.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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 Exhaustiveness with map patterns can only be achieved when there
/// is an exhaustive pattern in addition to any map patterns
///
/// @description Check that a switch statement/expression with map patterns only
/// cannot be exhaustive. Test the case when a matched type is an extension type
/// with a `Map` as a representation type
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

extension type ET1<K, V>(Map<K, V> _) {}
extension type ET2<K, V>(Map<K, V> _) implements Map<K, V> {}

String test1_1(ET1<bool, bool> m) =>
switch (m) {
//^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
Map(length: <= 0) => "match"
};

String test1_2(ET2<bool, bool> m) =>
switch (m) {
//^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
Map(length: <= 0) => "match"
};

String test2_1(ET1<bool, bool> m) {
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
switch (m) {
case Map(length: <= 0):
return "match";
}
// There is no return statement here, switch statement is not exhaustive, so an
// error above occurs because function return type cannot be null
}

String test2_2(ET2<bool, bool> m) {
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
switch (m) {
case Map(length: <= 0):
return "match";
}
}

main() {
print(test1_1(ET1({true: false})));
print(test1_2(ET2({true: false})));
print(test2_1(ET1({true: false})));
print(test2_2(ET2({true: false})));
}
81 changes: 81 additions & 0 deletions LanguageFeatures/Extension-types/exhaustiveness_map_A02_t01.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// 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 Exhaustiveness with map patterns can only be achieved when there
/// is an exhaustive pattern in addition to any map patterns
///
/// @description Check that a switch statement/expression with map patterns and
/// additional exhaustive pattern can be exhaustive. Test the case when a
/// matched type is an extension type with a `Map` as a representation type
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

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

extension type ET1<K, V>(Map<K, V> _) {}
extension type ET2<K, V>(Map<K, V> _) implements Map<K, V> {}

String test1_1(ET1<bool, bool> m) =>
switch (m) {
{true: true} => "case-1",
{true: false} => "case-2",
{false: true} => "case-3",
{false: false} => "case-4",
Map() => "other"
};

String test1_2(ET2<bool, bool> m) =>
switch (m) {
{true: true} => "case-1",
{true: false} => "case-2",
{false: true} => "case-3",
{false: false} => "case-4",
Map() => "other"
};

String test2_1(ET1<bool, bool> m) {
switch (m) {
case {true: true}:
return "case-1";
case {true: false}:
return "case-2";
case {false: true}:
return "case-3";
case {false: false}:
return "case-4";
case Map():
return "other";
}
}

String test2_2(ET2<bool, bool> m) {
switch (m) {
case {true: true}:
return "case-1";
case {true: false}:
return "case-2";
case {false: true}:
return "case-3";
case {false: false}:
return "case-4";
case Map():
return "other";
}
}

main() {
Expect.equals("case-1", test1_1(ET1({true: true})));
Expect.equals("case-2", test1_2(ET2({true: false})));
Expect.equals("case-3", test2_1(ET1({false: true})));
Expect.equals("case-4", test2_2(ET2({false: false})));
Expect.equals("other", test1_1(ET1<bool, bool>({})));
Expect.equals("other", test1_2(ET2<bool, bool>({})));
Expect.equals("other", test2_1(ET1<bool, bool>({})));
Expect.equals("other", test2_2(ET2<bool, bool>({})));
Expect.equals("other", test1_1(ET1({true: true, false: false})));
Expect.equals("other", test1_2(ET2({true: false, false: false})));
Expect.equals("other", test2_1(ET1({false: true, true: true})));
Expect.equals("other", test2_2(ET2({false: false, true: true})));
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
// 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 Switch statements and expressions with map as a matched type can
/// never be exhaustive
/// @assertion Exhaustiveness with map patterns can only be achieved when there
/// is an exhaustive pattern in addition to any map patterns
///
/// @description Check that map pattern cannot be exhaustive
/// @description Check that switch expression/statement with map patterns only
/// cannot be exhaustive
/// @author sgrekhov22@gmail.com
String test1(Map<bool, bool> m) =>
switch (m) { // Empty map is not matched
switch (m) {
//^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
// 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 Switch statements and expressions with map as a matched type can
/// never be exhaustive
/// @assertion Exhaustiveness with map patterns can only be achieved when there
/// is an exhaustive pattern in addition to any map patterns
///
/// @description Check that map pattern cannot be exhaustive
/// @description Check that switch expression/statement with a `Map` as a
/// matched type and without an additional exhaustive pattern is not exhaustive
/// @author sgrekhov22@gmail.com
String test1(Map<bool, bool> m) =>
Expand Down

0 comments on commit 593a9f6

Please sign in to comment.