Skip to content

Commit da1fae6

Browse files
authored
#1400. Static analysis of inline class tests. Part 1 (#2058)
Add tests about the static analysis of inline classes. Part 1
1 parent c3b8fe1 commit da1fae6

12 files changed

+542
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion The unique instance variable declared by an inline class must
6+
/// have a type annotation.
7+
///
8+
/// @description Checks that it is a compile-time error if an instance variable
9+
/// of the inline class has no type annotation
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=inline-class
13+
14+
inline class IC1 {
15+
final id;
16+
// ^^
17+
// [analyzer] unspecified
18+
// [cfe] unspecified
19+
IC1(this.id);
20+
}
21+
22+
inline class IC2 {
23+
final id = 42;
24+
// ^^
25+
// [analyzer] unspecified
26+
// [cfe] unspecified
27+
}
28+
29+
main() {
30+
IC1 ic1 = IC1(42);
31+
IC2 ic2 = IC2();
32+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion Assume that T1, .. Ts are types, and V resolves to an inline
6+
/// class declaration of the following form:
7+
///
8+
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
9+
/// final T id;
10+
/// V(this.id);
11+
///
12+
/// ... // Other members.
13+
/// }
14+
/// It is then allowed to use V<T1, .. Ts> as a type.
15+
///
16+
/// @description Checks that `V<T1, .. Ts>` can be used as a type
17+
/// @author [email protected]
18+
19+
// SharedOptions=--enable-experiment=inline-class
20+
21+
import "../../Utils/expect.dart";
22+
23+
inline class V<X1 extends num, X2 extends Object> {
24+
final X1 id;
25+
V(this.id);
26+
}
27+
28+
V<int, int> foo(V<int, int> v) => v;
29+
30+
class C<T extends V<num, Object>> {
31+
V<int, int> bar<T extends V<num, num>>(T t) => t as V<int, int>;
32+
}
33+
34+
main() {
35+
V v1 = V(42);
36+
Expect.isTrue(v1 is V<num, Object>);
37+
Expect.isTrue(v1 is V<num, Never>);
38+
Expect.isTrue(v1 is V<int, String>);
39+
40+
V<int, int> v2 = V(42);
41+
Expect.isTrue(v2 is V<int, int>);
42+
43+
V<num, Object> v3 = V<int, Never>(42);
44+
Expect.isTrue(v3 is V<num, Object>);
45+
46+
List<V> l1 = List.empty();
47+
Expect.isTrue(l1 is List<V<num, Object>>);
48+
49+
List<V<num, double>> l2 = List.empty();
50+
Expect.isTrue(l2 is List<V<num, double>>);
51+
52+
foo(v2);
53+
C<V<int, int>>().bar<V<int, int>>(v2);
54+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion Assume that T1, .. Ts are types, and V resolves to an inline
6+
/// class declaration of the following form:
7+
///
8+
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
9+
/// final T id;
10+
/// V(this.id);
11+
///
12+
/// ... // Other members.
13+
/// }
14+
/// It is then allowed to use V<T1, .. Ts> as a type.
15+
///
16+
/// @description Checks that an inline type `V<T1, .. Ts>` can be used in a
17+
/// function types and type aliases
18+
/// @author [email protected]
19+
20+
// SharedOptions=--enable-experiment=inline-class
21+
22+
import "../../Utils/expect.dart";
23+
24+
inline class V<X1 extends num, X2 extends Object> {
25+
final X1 id;
26+
V(this.id);
27+
}
28+
29+
typedef V<int, int> Foo<T extends V<num, Object>>(V<int, int> v);
30+
typedef IntNumV = V<int, num>;
31+
32+
V<int, int> foo<T extends V<num, Object>>(T t) => t as V<int, int>;
33+
34+
class C<T extends V<num, Object>> {
35+
Foo<T> f = foo<V<int, int>>;
36+
}
37+
38+
main() {
39+
IntNumV v = IntNumV(42);
40+
Expect.equals(42, v.id);
41+
42+
Expect.equals(v, foo(v));
43+
Expect.equals(V<int, int>(0), C<V<int, int>>().f(V<int, int>(0)));
44+
Expect.equals(V(1), C<V<int, int>>().f(V<int, int>(1)));
45+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion Assume that T1, .. Ts are types, and V resolves to an inline
6+
/// class declaration of the following form:
7+
///
8+
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
9+
/// final T id;
10+
/// V(this.id);
11+
///
12+
/// ... // Other members.
13+
/// }
14+
/// ...
15+
/// A compile-time error occurs if the type V<T1, .. Ts> is not regular-bounded.
16+
///
17+
/// @description Checks that it is a compile-time error if the type
18+
/// `V<T1, .. Ts>` is not regular-bounded.
19+
/// @author [email protected]
20+
21+
// SharedOptions=--enable-experiment=inline-class
22+
23+
class A {}
24+
class B extends A {}
25+
class C extends B {}
26+
27+
inline class V<X1 extends num, X2 extends B> {
28+
final X1 id;
29+
V(this.id);
30+
31+
X2 foo() => id as X2;
32+
}
33+
34+
main() {
35+
V<int, Object?> v1 = V(42);
36+
// ^^^^^^^
37+
// [analyzer] unspecified
38+
// [cfe] unspecified
39+
40+
V<String, B> v2 = V("42");
41+
// ^^^^^^
42+
// [analyzer] unspecified
43+
// [cfe] unspecified
44+
45+
<V<num, A>>[];
46+
// ^
47+
// [analyzer] unspecified
48+
// [cfe] unspecified
49+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion Assume that T1, .. Ts are types, and V resolves to an inline
6+
/// class declaration of the following form:
7+
///
8+
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
9+
/// final T id;
10+
/// V(this.id);
11+
///
12+
/// ... // Other members.
13+
/// }
14+
/// ...
15+
/// A compile-time error occurs if the type V<T1, .. Ts> is not regular-bounded.
16+
///
17+
/// @description Checks that it is a compile-time error if the type
18+
/// `V<T1, .. Ts>` is not regular-bounded.
19+
/// @author [email protected]
20+
21+
// SharedOptions=--enable-experiment=inline-class
22+
23+
inline class V<T extends V<T>> {
24+
final T id;
25+
V(this.id);
26+
}
27+
28+
main() {
29+
List<V> l = [];
30+
// ^
31+
// [analyzer] unspecified
32+
// [cfe] unspecified
33+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion A compile-time error occurs if a type parameter of an inline
6+
/// class occurs in a non-covariant position in the representation type.
7+
///
8+
/// @description Checks that it is a compile-time error if a type parameter of
9+
/// an inline class occurs in a non-covariant position in the representation
10+
/// type
11+
/// @author [email protected]
12+
// SharedOptions=--enable-experiment=inline-class
13+
14+
inline class V<T extends num> {
15+
final void Function(T) f;
16+
// ^
17+
// [analyzer] unspecified
18+
// [cfe] unspecified
19+
V(this.f);
20+
}
21+
22+
main() {
23+
print(V);
24+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion Assume that T1, .. Ts are types, and V resolves to an inline
6+
/// class declaration of the following form:
7+
///
8+
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
9+
/// final T id;
10+
/// V(this.id);
11+
///
12+
/// ... // Other members.
13+
/// }
14+
/// ...
15+
/// When s is zero, V<T1, .. Ts> simply stands for V, a non-generic inline type.
16+
/// When s is greater than zero, a raw occurrence V is treated like a raw type:
17+
/// Instantiation to bound is used to obtain the omitted type arguments
18+
///
19+
/// @description Checks that instantiation to bound is used to obtain the
20+
/// omitted type arguments
21+
/// @author [email protected]
22+
23+
// SharedOptions=--enable-experiment=inline-class
24+
25+
import "../../Utils/static_type_helper.dart";
26+
27+
class A {}
28+
class B extends A {}
29+
class C extends B {}
30+
31+
inline class V<T1 extends num, T2 extends B> {
32+
final T1 id;
33+
V(this.id);
34+
}
35+
36+
main() {
37+
num n = 42;
38+
V(n).expectStaticType<Exactly<V<num, B>>>();
39+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion Assume that T1, .. Ts are types, and V resolves to an inline
6+
/// class declaration of the following form:
7+
///
8+
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
9+
/// final T id;
10+
/// V(this.id);
11+
///
12+
/// ... // Other members.
13+
/// }
14+
/// ...
15+
/// When s is zero, V<T1, .. Ts> simply stands for V, a non-generic inline type.
16+
/// When s is greater than zero, a raw occurrence V is treated like a raw type:
17+
/// Instantiation to bound is used to obtain the omitted type arguments
18+
///
19+
/// @description Checks that instantiation to bound is used to obtain the
20+
/// omitted type arguments
21+
/// @author [email protected]
22+
23+
// SharedOptions=--enable-experiment=inline-class
24+
25+
import "../../Utils/static_type_helper.dart";
26+
27+
class V<X extends List<Y>, Y extends num> {
28+
final Y id;
29+
V(this.id);
30+
}
31+
32+
main() {
33+
List<V> l = [];
34+
l.expectStaticType<Exactly<List<V<List<num>, num>>>>();
35+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion It is a compile-time error if await e occurs, and the static type
6+
/// of e is an inline type.
7+
///
8+
/// @description Checks that it is a compile-time error if `await e` occurs, and
9+
/// the static type of `e` is an inline type.
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=inline-class
13+
14+
inline class V1 {
15+
final int id;
16+
V(this.id);
17+
}
18+
19+
inline class V2<T> {
20+
final T id;
21+
V(this.id);
22+
}
23+
24+
inline class V3<T extends num> {
25+
final T id;
26+
V(this.id);
27+
}
28+
29+
main() async {
30+
V1 v1 = V1(42);
31+
await v1;
32+
// ^^
33+
// [analyzer] unspecified
34+
// [cfe] unspecified
35+
36+
V2<String> v2_1 = V2("42");
37+
await v2_1;
38+
// ^^^^
39+
// [analyzer] unspecified
40+
// [cfe] unspecified
41+
42+
V2 v2_2 = V2("42");
43+
await v2_2;
44+
// ^^^^
45+
// [analyzer] unspecified
46+
// [cfe] unspecified
47+
48+
V3<int> v3_1 = V3(42);
49+
await v3_1;
50+
// ^^^^
51+
// [analyzer] unspecified
52+
// [cfe] unspecified
53+
54+
V3 v3_2 = V3(42);
55+
await v3_2;
56+
// ^^^^
57+
// [analyzer] unspecified
58+
// [cfe] unspecified
59+
}

0 commit comments

Comments
 (0)