-
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 `is! T` constant evaluation tests
- Loading branch information
Showing
6 changed files
with
428 additions
and
0 deletions.
There are no files selected for viewing
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,75 @@ | ||
// 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 A constant expression is an expression whose value can never | ||
/// change, and that can be evaluated entirely at compile time. | ||
/// A constant expression is one of the following: | ||
/// ... | ||
/// • An expression of the form e is! T is equivalent to !(e is T) in every | ||
/// way, including whether it’s potentially constant or constant. | ||
/// | ||
/// @description Checks that an expression of the form `e is! T` is a constant | ||
/// expression if `e` is a constant expression and `T` is a constant type | ||
/// expression | ||
/// @author sgrekhov22@gmail.com | ||
/// @issue 54620 | ||
// SharedOptions=--enable-experiment=inline-class | ||
|
||
import "../../../Utils/expect.dart"; | ||
|
||
class C { | ||
const C(); | ||
} | ||
|
||
extension type const IntET1(int _) {} | ||
extension type const IntET2(int _) implements int {} | ||
|
||
main() { | ||
const c1 = 1 is! num; | ||
const c2 = (3.14 as num) is! double; | ||
const c3 = IntET1(1) is! int; | ||
const c4 = IntET2(1) is! int; | ||
const c5 = (IntET1(1),) is! (int,); | ||
const c6 = (IntET2(1),) is! (int,); | ||
const c7 = [IntET1(1)] is! List<int>; | ||
const c8 = [IntET2(1)] is! List<num>; | ||
const c9 = {IntET1(1)} is! Set<num>; | ||
const c10 = {IntET2(1)} is! Set<num>; | ||
const c11 = {IntET1(1): IntET1(2)} is! Map<num, int>; | ||
const c12 = {IntET1(1): IntET2(2)} is! Map<num, int>; | ||
const c13 = {IntET2(1): IntET1(2)} is! Map<num, int>; | ||
const c14 = {IntET2(1): IntET2(2)} is! Map<num, int>; | ||
const c15 = 1 is! IntET1; | ||
const c16 = 1 is! IntET2; | ||
const c17 = IntET1(1) is! IntET2; | ||
const c18 = IntET2(1) is! IntET1; | ||
const c19 = C() is! Object; | ||
const c20 = const C() is! Object; | ||
const c21 = () is! (); | ||
const c22 = (i: 1) is! ({num i}); | ||
|
||
Expect.isFalse(c1); | ||
Expect.isFalse(c2); | ||
Expect.isFalse(c3); | ||
Expect.isFalse(c4); | ||
Expect.isFalse(c5); | ||
Expect.isFalse(c6); | ||
Expect.isFalse(c7); | ||
Expect.isFalse(c8); | ||
Expect.isFalse(c9); | ||
Expect.isFalse(c10); | ||
Expect.isFalse(c11); | ||
Expect.isFalse(c12); | ||
Expect.isFalse(c13); | ||
Expect.isFalse(c14); | ||
Expect.isFalse(c15); | ||
Expect.isFalse(c16); | ||
Expect.isFalse(c17); | ||
Expect.isFalse(c18); | ||
Expect.isFalse(c19); | ||
Expect.isFalse(c20); | ||
Expect.isFalse(c21); | ||
Expect.isFalse(c22); | ||
} |
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) 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 A constant expression is an expression whose value can never | ||
/// change, and that can be evaluated entirely at compile time. | ||
/// A constant expression is one of the following: | ||
/// ... | ||
/// • An expression of the form e is! T is equivalent to !(e is T) in every | ||
/// way, including whether it’s potentially constant or constant. | ||
/// ... | ||
/// A constant type expression is one of: | ||
/// • An simple or qualified identifier denoting a type declaration (a type | ||
/// alias, class or mixin declaration) that is not qualified by a deferred | ||
/// prefix, optionally followed by type arguments of the form <T1, ..., Tn> | ||
/// where T1, ..., Tn are constant type expressions. | ||
/// • A type of the form FutureOr<T> where T is a constant type expression. | ||
/// • A function type R Function<typeParameters>(argumentTypes) (where | ||
/// R and <typeParameters> may be omitted) and where R, typeParameters | ||
/// and argumentTypes (if present) contain only constant type expressions. | ||
/// • The type void. | ||
/// • The type dynamic | ||
/// | ||
/// @description Checks that an expression of the form `e is! T` is a constant | ||
/// expression if `e` is a constant expression and `T` is a constant type | ||
/// expression. Test different constant type expressions | ||
/// @author sgrekhov22@gmail.com | ||
/// @issue 54636 | ||
// SharedOptions=--enable-experiment=inline-class | ||
|
||
import "dart:async"; | ||
import "../../../Utils/expect.dart"; | ||
|
||
mixin M {} | ||
|
||
class C<T> with M { | ||
const C(); | ||
} | ||
|
||
typedef CNumAlias = C<num>; | ||
|
||
enum E { | ||
e1, e2; | ||
} | ||
|
||
extension type const IntET1(int _) {} | ||
extension type const IntET2(int _) implements int {} | ||
|
||
typedef IntET1Alias = IntET1; | ||
typedef IntET2Alias = IntET2; | ||
|
||
void foo() {} | ||
void as() {} | ||
int bar<T>(T t) => 42; | ||
|
||
main() { | ||
const c1 = C() is! C; | ||
const c2 = C() is! M; | ||
const c3 = E.e1 is! E; | ||
const c4 = C<int>() is! C<num>; | ||
const c5 = C<int>() is! CNumAlias; | ||
const c6 = IntET1(1) is! IntET2Alias; | ||
const c7 = IntET2(1) is! IntET1Alias; | ||
|
||
const fo1 = C() is! FutureOr<C>; | ||
const fo2 = C() is! FutureOr<M>; | ||
const fo3 = E.e1 is! FutureOr<E>; | ||
const fo4 = C<int>() is! FutureOr<C<num>>; | ||
const fo5 = C<int>() is! FutureOr<CNumAlias>; | ||
const fo6 = IntET1(1) is! FutureOr<IntET2Alias>; | ||
const fo7 = IntET2(1) is! FutureOr<IntET1Alias>; | ||
|
||
const f1 = foo is! void Function(); | ||
const f2 = bar<int> is! int Function(int); | ||
|
||
const d = 2 is! dynamic; | ||
|
||
Expect.isFalse(c1); | ||
Expect.isFalse(c2); | ||
Expect.isFalse(c3); | ||
Expect.isFalse(c4); | ||
Expect.isFalse(c5); | ||
Expect.isFalse(c6); | ||
Expect.isFalse(c7); | ||
Expect.isFalse(fo1); | ||
Expect.isFalse(fo2); | ||
Expect.isFalse(fo3); | ||
Expect.isFalse(fo4); | ||
Expect.isFalse(fo5); | ||
Expect.isFalse(fo6); | ||
Expect.isFalse(fo7); | ||
Expect.isFalse(f1); | ||
Expect.isFalse(f2); | ||
Expect.isFalse(d); | ||
} |
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 A constant expression is an expression whose value can never | ||
/// change, and that can be evaluated entirely at compile time. | ||
/// A constant expression is one of the following: | ||
/// ... | ||
/// • An expression of the form e is! T is equivalent to !(e is T) in every | ||
/// way, including whether it’s potentially constant or constant. | ||
/// ... | ||
/// A constant type expression is one of: | ||
/// • An simple or qualified identifier denoting a type declaration (a type | ||
/// alias, class or mixin declaration) that is not qualified by a deferred | ||
/// prefix, optionally followed by type arguments of the form <T1, ..., Tn> | ||
/// where T1, ..., Tn are constant type expressions. | ||
/// • A type of the form FutureOr<T> where T is a constant type expression. | ||
/// • A function type R Function<typeParameters>(argumentTypes) (where | ||
/// R and <typeParameters> may be omitted) and where R, typeParameters | ||
/// and argumentTypes (if present) contain only constant type expressions. | ||
/// • The type void. | ||
/// • The type dynamic | ||
/// | ||
/// @description Checks that an expression of the form `e is! T` is a constant | ||
/// expression if `T` is a constant type expression of type `FutureOr<void>` or | ||
/// an extension type with a representation type `void` | ||
/// @author sgrekhov22@gmail.com | ||
/// @issue 54620 | ||
// SharedOptions=--enable-experiment=inline-class | ||
|
||
import "dart:async"; | ||
import "../../../Utils/expect.dart"; | ||
|
||
extension type const VoidET(void _) {} | ||
|
||
main() { | ||
const c1 = 1 is! VoidET; | ||
const c2 = 2 is! FutureOr<void>; | ||
const c3 = (3,) is! (VoidET,); | ||
const c4 = (4,) is! (FutureOr<void>,); | ||
const c5 = (i: 5) is! ({VoidET i}); | ||
const c6 = (i: 6) is! ({FutureOr<void> i}); | ||
|
||
Expect.isFalse(c1); | ||
Expect.isFalse(c2); | ||
Expect.isFalse(c3); | ||
Expect.isFalse(c4); | ||
Expect.isFalse(c5); | ||
Expect.isFalse(c6); | ||
} |
113 changes: 113 additions & 0 deletions
113
Language/Expressions/Constants/is_not_type_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,113 @@ | ||
// 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 A constant expression is an expression whose value can never | ||
/// change, and that can be evaluated entirely at compile time. | ||
/// A constant expression is one of the following: | ||
/// ... | ||
/// • An expression of the form e is! T is equivalent to !(e is T) in every | ||
/// way, including whether it’s potentially constant or constant. | ||
/// | ||
/// @description Checks that an expression of the form `e is! T` is not a | ||
/// constant expression if `e` is not a constant expression | ||
/// @author sgrekhov22@gmail.com | ||
// SharedOptions=--enable-experiment=inline-class | ||
|
||
class C { | ||
C(); | ||
} | ||
|
||
extension type IntET1(int _) {} | ||
extension type IntET2(int _) implements int {} | ||
|
||
test<T>() { | ||
const c = T is! Type; | ||
// ^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
} | ||
|
||
main() { | ||
int i = 1; | ||
var d = 3.14; | ||
var c = C(); | ||
|
||
const c1 = i is! num; | ||
// ^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c2 = (d as num) is! double; | ||
// ^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c3 = IntET1(1) is! int; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c4 = IntET2(1) is! int; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c5 = (i,) is! (int,); | ||
// ^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c6 = (IntET1(1),) is! (int,); | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c7 = (IntET2(1),) is! (int,); | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c8 = [i] is! List<int>; | ||
// ^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c9 = [IntET1(1)] is! List<int>; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c10 = [IntET2(1)] is! List<num>; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c11 = {d} is! Set<num>; | ||
// ^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c12 = {IntET1(1)} is! Set<num>; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c13 = {IntET2(1)} is! Set<num>; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c14 = {IntET1(1): IntET1(2)} is! Map<num, int>; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c15 = {IntET2(1): IntET2(2)} is! Map<num, int>; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c16 = IntET1(1) is! IntET2; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c17 = IntET2(1) is! IntET1; | ||
// ^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c19 = c is! Object; | ||
// ^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const c20 = () {} is! Function; | ||
// ^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
} |
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,39 @@ | ||
// 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 A constant expression is an expression whose value can never | ||
/// change, and that can be evaluated entirely at compile time. | ||
/// A constant expression is one of the following: | ||
/// ... | ||
/// • An expression of the form e is! T is equivalent to !(e is T) in every | ||
/// way, including whether it’s potentially constant or constant. | ||
/// | ||
/// @description Checks that an expression of the form `e is! T` is not a | ||
/// constant expression if `e` is not an expression | ||
/// @author sgrekhov22@gmail.com | ||
extension IntExtension on int {} | ||
|
||
main() { | ||
const Foo = int Function() is! Function; | ||
// ^^^^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const Void = void is! Type; | ||
// ^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const cIntExtension = IntExtension is! Type; | ||
// ^^^^^^^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const R1 = (void,) is! Type; | ||
// ^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
const R2 = ({int i}) is! Record; | ||
// ^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
} |
Oops, something went wrong.