Skip to content

Commit e43ef65

Browse files
authored
#1400. More static analysis of the inline class tests (#2068)
More static analysis of the inline class tests
1 parent 736b818 commit e43ef65

17 files changed

+781
-3
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
inline class V1<T extends num> {
28+
final int id;
29+
V1(this.id);
30+
}
31+
32+
inline class V2<T extends Object> {
33+
final int id;
34+
V2(this.id);
35+
}
36+
37+
inline class V3<T extends Object?> {
38+
final int id;
39+
V3(this.id);
40+
}
41+
42+
main() {
43+
var v1 = V1(42);
44+
v1.expectStaticType<Exactly<V1<num>>>();
45+
46+
var v2 = V2(42);
47+
v2.expectStaticType<Exactly<V2<Object>>>();
48+
49+
var v3 = V3(42);
50+
v3.expectStaticType<Exactly<V3<Object?>>>();
51+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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. Test default bound
21+
/// @author [email protected]
22+
23+
// SharedOptions=--enable-experiment=inline-class
24+
25+
import "../../Utils/expect.dart";
26+
27+
inline class V1<T> {
28+
final int id;
29+
V1(this.id);
30+
31+
Type get type => T;
32+
}
33+
34+
main() {
35+
var v1 = V1(42);
36+
Expect.equals(dynamic, v1.type);
37+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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. Test a super-bounded type
21+
/// @author [email protected]
22+
23+
// SharedOptions=--enable-experiment=inline-class
24+
25+
import "../../Utils/expect.dart";
26+
27+
class A<T extends A<T>> {}
28+
class B extends A<B> {}
29+
30+
inline class V<T extends A<T>> {
31+
final int id;
32+
V(this.id);
33+
34+
Type get type => T;
35+
}
36+
37+
main() {
38+
var v1 = V<Never>(42);
39+
Expect.equals(Never, v1.type);
40+
41+
var v2 = V<B>(42);
42+
Expect.equals(B, v2.type);
43+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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 it is a compile-time error to use super-bounded
20+
/// inline type with wrong type arguments
21+
/// @author [email protected]
22+
23+
// SharedOptions=--enable-experiment=inline-class
24+
25+
class A<T extends A<T>> {}
26+
27+
inline class V<T extends A<T>> {
28+
final int id;
29+
V(this.id);
30+
31+
Type get type => T;
32+
}
33+
34+
main() {
35+
var v1 = V<void>(42);
36+
// ^^^^
37+
// [analyzer] unspecified
38+
// [cfe] unspecified
39+
40+
var v2 = V<Object?>(42);
41+
// ^^^^^^^
42+
// [analyzer] unspecified
43+
// [cfe] unspecified
44+
45+
var v3 = V<dynamic>(42);
46+
// ^^^^^^^
47+
// [analyzer] unspecified
48+
// [cfe] unspecified
49+
50+
var v4 = V<Null>(42);
51+
// ^^^^
52+
// [analyzer] unspecified
53+
// [cfe] unspecified
54+
55+
var v5 = V<A>(42);
56+
// ^
57+
// [analyzer] unspecified
58+
// [cfe] unspecified
59+
60+
var v6 = V<A<Object?>>(42);
61+
// ^^^^^^^^^^
62+
// [analyzer] unspecified
63+
// [cfe] unspecified
64+
65+
var v7 = V<A<void>>(42);
66+
// ^^^^^^^
67+
// [analyzer] unspecified
68+
// [cfe] unspecified
69+
70+
var v8 = V<A<Null>>(42);
71+
// ^^^^^^
72+
// [analyzer] unspecified
73+
// [cfe] unspecified
74+
75+
var v9 = V<A<dynamic>>(42);
76+
// ^^^^^^^^^
77+
// [analyzer] unspecified
78+
// [cfe] unspecified
79+
}

LanguageFeatures/Inline-classes/static_analysis_inline_class_A06_t01.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313

1414
inline class V1 {
1515
final int id;
16-
V(this.id);
16+
V1(this.id);
1717
}
1818

1919
inline class V2<T> {
2020
final T id;
21-
V(this.id);
21+
V2(this.id);
2222
}
2323

2424
inline class V3<T extends num> {
2525
final T id;
26-
V(this.id);
26+
V3(this.id);
2727
}
2828

2929
main() async {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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 If e is an expression whose static type V is the inline type
6+
/// Inline<T1, .. Ts> and m is the name of a member that V has, a member access
7+
/// like e.m(args) is treated as an invocation of the inline member m on the
8+
/// receiver e according to the inline type Inline and with the actual type
9+
/// arguments T1, ..., Ts, with the actual argument part args.
10+
///
11+
/// @description Checks that a member access `e.m(args)` is treated as an
12+
/// invocation of the inline member m on the receiver `e` according to the
13+
/// inline type `Inline` and with the actual type arguments `T1, ..., Ts`, with
14+
/// the actual argument part `args`.
15+
/// @author [email protected]
16+
17+
// SharedOptions=--enable-experiment=inline-class
18+
19+
import "../../Utils/static_type_helper.dart";
20+
21+
inline class V1<T> {
22+
final T id;
23+
V1(this.id);
24+
25+
(Map<K, V>, T) asMap<K, V>() => (<K, V>{}, id);
26+
}
27+
28+
main() {
29+
V1<num> v1 = V1(42);
30+
v1.asMap<String, bool>()
31+
.expectStaticType<Exactly<(Map<String, bool>, num)>>();
32+
33+
V1<String> v2 = V1("42");
34+
v2.asMap<String, String>()
35+
.expectStaticType<Exactly<(Map<String, String>, String)>>();
36+
}
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 Similarly, e.m is treated an invocation of the inline member m on
6+
/// the receiver e according to the inline type Inline and with the actual type
7+
/// arguments T1, ..., Ts and no actual argument part.
8+
///
9+
/// @description Checks that a member access `e.m` is treated as an invocation
10+
/// of the inline member `m` on the receiver `e` according to the inline type
11+
/// `Inline` and with the actual type arguments `T1, ..., Ts` and no actual
12+
/// argument part
13+
/// @author [email protected]
14+
15+
// SharedOptions=--enable-experiment=inline-class
16+
17+
import "../../Utils/static_type_helper.dart";
18+
19+
inline class V1<T, K, V> {
20+
final T id;
21+
V1(this.id);
22+
23+
(Map<K, V>, T) get asMap => (<K, V>{}, id);
24+
}
25+
26+
main() {
27+
V1<num, String, bool> v1 = V1(42);
28+
v1.asMap.expectStaticType<Exactly<(Map<String, bool>, num)>>();
29+
30+
V1<String, String, Null> v2 = V1("42");
31+
v2.asMap.expectStaticType<Exactly<(Map<String, Null>, String)>>();
32+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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 If e is an expression whose static type V is the inline type
6+
/// Inline<T1, .. Ts> and V has no member whose basename is the basename of m,
7+
/// a member access like e.m(args) may be an extension member access, following
8+
/// the normal rules about applicability and accessibility of extensions, in
9+
/// particular that V must match the on-type of the extension.
10+
///
11+
/// @description Checks that if `V` has no member with the name `m`, but there
12+
/// is an extension member `m` then it is invoked
13+
/// @author [email protected]
14+
15+
// SharedOptions=--enable-experiment=inline-class
16+
17+
import "../../Utils/expect.dart";
18+
19+
extension Ex1 on V {
20+
String foo() => "Ex1.foo()";
21+
}
22+
23+
extension Ex2 on int {
24+
String bar() => "Ex2.bar()";
25+
}
26+
27+
inline class V {
28+
final int id;
29+
V(this.id);
30+
}
31+
32+
main() {
33+
V v = V(42);
34+
Expect.equals("Ex1.foo()", v.foo());
35+
Expect.equals("Ex2.bar()", v.id.bar());
36+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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 If e is an expression whose static type V is the inline type
6+
/// Inline<T1, .. Ts> and V has no member whose basename is the basename of m,
7+
/// a member access like e.m(args) may be an extension member access, following
8+
/// the normal rules about applicability and accessibility of extensions, in
9+
/// particular that V must match the on-type of the extension.
10+
///
11+
/// @description Checks that it is a compile-time error if `V` has no member
12+
/// with name `m` and there is no extension member with the name `m`
13+
/// @author [email protected]
14+
15+
// SharedOptions=--enable-experiment=inline-class
16+
17+
extension Ex1 on V {
18+
String foo() => "Ex1.foo()";
19+
}
20+
21+
extension Ex2 on int {
22+
String bar() => "Ex2.bar()";
23+
}
24+
25+
inline class V {
26+
final int id;
27+
V(this.id);
28+
}
29+
30+
main() {
31+
V v = V(42);
32+
v.bar();
33+
// ^^^
34+
// [analyzer] unspecified
35+
// [cfe] unspecified
36+
37+
v.id.foo();
38+
// ^^^
39+
// [analyzer] unspecified
40+
// [cfe] unspecified
41+
}

0 commit comments

Comments
 (0)