-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add cast-pattern tests for extension types.
- Loading branch information
Showing
9 changed files
with
1,053 additions
and
0 deletions.
There are no files selected for viewing
96 changes: 96 additions & 0 deletions
96
LanguageFeatures/Extension-types/exhaustiveness_cast_A01_t01.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// 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 The lifted space union for a pattern with matched value type M is | ||
/// ... | ||
/// Cast pattern: | ||
/// ... | ||
/// Let S be the lifted space union of the cast's subpattern in context C. | ||
/// i. If C is a subset (see below about type subsetting) of S then the result | ||
/// spaces is the lifted space union of M. | ||
/// ii. Otherwise, the result spaces is S plus the lifted space union of Null | ||
/// when C is a non-nullable type, and spaces is S when C is potentially | ||
/// nullable. | ||
/// | ||
/// @description Check a lifted space of a cast pattern in case of not a sealed | ||
/// type. Test switch statement which is not exhausted from a float analysis | ||
/// point of view | ||
/// @author sgrekhov22@gmail.com | ||
/// @issue 54460 | ||
// SharedOptions=--enable-experiment=inline-class | ||
|
||
extension type ObjectET1(Object _) {} | ||
extension type ObjectET2(Object _) implements Object {} | ||
|
||
extension type IntET1(int _) {} | ||
extension type IntET2(int _) implements int {} | ||
|
||
int test1_1(ObjectET1 obj) { | ||
// ^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
switch (obj) { | ||
case int(isEven: true) as int: | ||
return 1; | ||
case int _: | ||
return 2; | ||
} | ||
} | ||
|
||
int test1_2(ObjectET2 obj) { | ||
// ^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
switch (obj) { | ||
case int(isEven: true) as int: | ||
return 1; | ||
case int _: | ||
return 2; | ||
} | ||
} | ||
|
||
int test2(Object obj) { | ||
// ^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
switch (obj) { | ||
case int(isEven: true) as IntET1: | ||
return 1; | ||
case int _: | ||
return 2; | ||
} | ||
} | ||
|
||
int test3_1(ObjectET1 obj) { | ||
// ^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
switch (obj) { | ||
case IntET2(isEven: true) as IntET1: | ||
return 1; | ||
case int _: | ||
return 2; | ||
} | ||
} | ||
|
||
int test3_2(ObjectET2 obj) { | ||
// ^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
switch (obj) { | ||
case IntET2(isEven: true) as int: | ||
return 1; | ||
case IntET1 _: | ||
return 2; | ||
} | ||
} | ||
|
||
main() { | ||
print(test1_1); | ||
print(test1_2); | ||
print(test2); | ||
print(test3_1); | ||
print(test3_2); | ||
} |
89 changes: 89 additions & 0 deletions
89
LanguageFeatures/Extension-types/exhaustiveness_cast_A01_t02.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// 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 The lifted space union for a pattern with matched value type M is | ||
/// ... | ||
/// Cast pattern: | ||
/// ... | ||
/// Let S be the lifted space union of the cast's subpattern in context C. | ||
/// i. If C is a subset (see below about type subsetting) of S then the result | ||
/// spaces is the lifted space union of M. | ||
/// ii. Otherwise, the result spaces is S plus the lifted space union of Null | ||
/// when C is a non-nullable type, and spaces is S when C is potentially | ||
/// nullable. | ||
/// | ||
/// @description Check a lifted space of a cast pattern in case of not sealed | ||
/// type. Test switch expression | ||
/// @author sgrekhov22@gmail.com | ||
// SharedOptions=--enable-experiment=inline-class | ||
|
||
extension type ObjectET1(Object _) {} | ||
extension type ObjectET2(Object _) implements Object {} | ||
|
||
extension type IntET1(int _) {} | ||
extension type IntET2(int _) implements int {} | ||
|
||
// The corresponding switch statement (can be found in | ||
// `exhaustiveness_cast_A01_t01.dart`) will not complete normally in this case | ||
// (which means that there is no "returns null" error), but this switch | ||
// expression is an error because it can not be recognized as exhaustive. This | ||
// discrepancy is expected. For more details see | ||
// https://github.com/dart-lang/sdk/issues/51986#issuecomment-1864237801 | ||
int test1_1(ObjectET1 obj) => switch (obj) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
int(isEven: true) as int => 1, | ||
int _ => 2 | ||
}; | ||
|
||
int test1_2(ObjectET2 obj) => switch (obj) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
int(isEven: true) as int => 1, | ||
int _ => 2 | ||
}; | ||
|
||
int test2_1(Object obj) => switch (obj) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
int(isEven: true) as IntET1 => 1, | ||
int _ => 2 | ||
}; | ||
|
||
int test2_2(Object obj) => switch (obj) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
int(isEven: true) as IntET2 => 1, | ||
int _ => 2 | ||
}; | ||
|
||
int test3_1(ObjectET1 obj) => switch (obj) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
IntET2(isEven: true) as IntET1 => 1, | ||
int _ => 2 | ||
}; | ||
|
||
int test3_2(ObjectET2 obj) => switch (obj) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
IntET2(isEven: true) as int => 1, | ||
IntET1 _ => 2 | ||
}; | ||
|
||
main() { | ||
print(test1_1); | ||
print(test1_2); | ||
print(test2_1); | ||
print(test2_2); | ||
print(test3_1); | ||
print(test3_2); | ||
} |
51 changes: 51 additions & 0 deletions
51
LanguageFeatures/Extension-types/exhaustiveness_cast_A01_t03.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (c) 2024, 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 The lifted space union for a pattern with matched value type M is | ||
/// ... | ||
/// Cast pattern: | ||
/// ... | ||
/// Let S be the lifted space union of the cast's subpattern in context C. | ||
/// i. If C is a subset (see below about type subsetting) of S then the result | ||
/// spaces is the lifted space union of M. | ||
/// ii. Otherwise, the result spaces is S plus the lifted space union of Null | ||
/// when C is a non-nullable type, and spaces is S when C is potentially | ||
/// nullable. | ||
/// | ||
/// @description Check a lifted space of a cast pattern in case of not a sealed | ||
/// type. Test switch statement which is exhausted from a float analysis point | ||
/// of view | ||
/// @author sgrekhov22@gmail.com | ||
// SharedOptions=--enable-experiment=inline-class | ||
|
||
import "../../Utils/expect.dart"; | ||
|
||
extension type IntET1(int _) {} | ||
extension type IntET2(int _) implements int {} | ||
|
||
int test1(Object obj) { | ||
switch (obj) { | ||
case int(isEven: true) as IntET2: | ||
return 1; | ||
case int _: | ||
return 2; | ||
} | ||
} | ||
|
||
int test2(Object obj) { | ||
switch (obj) { | ||
case int(isEven: true) as int: | ||
return 1; | ||
case IntET2 _: | ||
return 2; | ||
} | ||
} | ||
|
||
main() { | ||
Expect.equals(2 ,test1(1)); | ||
Expect.equals(1 ,test1(2)); | ||
Expect.equals(2 ,test2(1)); | ||
Expect.equals(1 ,test2(2)); | ||
} |
129 changes: 129 additions & 0 deletions
129
LanguageFeatures/Extension-types/exhaustiveness_cast_A02_t01.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// 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 The lifted space union for a pattern with matched value type M is | ||
/// ... | ||
/// Cast pattern: | ||
/// ... | ||
/// Let S be the lifted space union of the cast's subpattern in context C. | ||
/// i. If C is a subset (see below about type subsetting) of S then the result | ||
/// spaces is the lifted space union of M. | ||
/// ii. Otherwise, the result spaces is S plus the lifted space union of Null | ||
/// when C is a non-nullable type, and spaces is S when C is potentially | ||
/// nullable. | ||
/// | ||
/// @description Check a lifted space of a cast pattern in case of a sealed type | ||
/// @author sgrekhov22@gmail.com | ||
sealed class A { | ||
final int field; | ||
A(this.field); | ||
} | ||
|
||
class B extends A { | ||
B(int field) : super(field); | ||
} | ||
|
||
class C extends A { | ||
C(int field) : super(field); | ||
} | ||
|
||
extension type AET1(A _) {} | ||
extension type AET2(A _) implements A {} | ||
extension type BET1(B _) {} | ||
extension type BET2(B _) implements B {} | ||
extension type CET1(C _) {} | ||
extension type CET2(C _) implements C {} | ||
|
||
int test1_1(AET1 a) { | ||
switch (a) { | ||
//^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
case C(field: 0) as C: | ||
return 0; | ||
case C _: | ||
return 1; | ||
} | ||
} | ||
|
||
int test1_2(AET2 a) { | ||
switch (a) { | ||
//^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
case C(field: 0) as C: | ||
return 0; | ||
case C _: | ||
return 1; | ||
} | ||
} | ||
|
||
int test1_3(AET1 a) => switch (a) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
C(field: 0) as C => 0, | ||
C _ => 1 | ||
}; | ||
|
||
int test1_4(AET2 a) => switch (a) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
C(field: 0) as C => 0, | ||
C _ => 1 | ||
}; | ||
|
||
int test2_1(A a) { | ||
switch (a) { | ||
//^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
case C(field: 0) as CET1: | ||
return 0; | ||
case CET1 _: | ||
return 1; | ||
} | ||
} | ||
|
||
int test2_2(A a) { | ||
switch (a) { | ||
//^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
case CET2(field: 0) as CET2: | ||
return 0; | ||
case C _: | ||
return 1; | ||
} | ||
} | ||
|
||
int test2_3(A a) => switch (a) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
C(field: 0) as CET1 => 0, | ||
C _ => 1 | ||
}; | ||
|
||
int test2_4(A a) => switch (a) { | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
CET2(field: 0) as CET2 => 0, | ||
CET2 _ => 1 | ||
}; | ||
|
||
main() { | ||
test1_1(AET1(C(0))); | ||
test1_2(AET2(C(0))); | ||
test1_3(AET1(C(0))); | ||
test1_4(AET2(C(0))); | ||
|
||
test2_1(C(0)); | ||
test2_2(C(0)); | ||
test2_3(C(0)); | ||
test2_4(C(0)); | ||
} |
Oops, something went wrong.