Skip to content

Commit caf1be7

Browse files
committed
#3330. Add static extensions tests. Part 1.
1 parent dfea6e4 commit caf1be7

9 files changed

+760
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (c) 2025, 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 Consider an expression `e` which is a member invocation with
6+
/// syntactic receiver `C` and an associated member name `m`. Assume that `m` is
7+
/// a static member declared by `D`. The static analysis and dynamic semantics
8+
/// of this expression is the same as in Dart before the introduction of this
9+
/// feature.
10+
/// ...
11+
/// In the case where `D` does not declare any static members whose basename is
12+
/// the basename of `m`, and `D` does not declare any constructors named `C.m2`
13+
/// where `m2` is the basename of `m`, let `M` be the set containing each
14+
/// accessible extension whose on-declaration is `D`, and whose static members
15+
/// include one with the name `m`, or which declares a constructor named `C.m`.
16+
/// ...
17+
/// An error occurs if `M` is empty, or `M` contains more than one member.
18+
///
19+
/// @description Checks that that it is a compile-time error if `M` is empty.
20+
/// @author [email protected]
21+
22+
// SharedOptions=--enable-experiment=static-extensions
23+
24+
class A {
25+
static int foo = 42;
26+
}
27+
28+
class C extends A {}
29+
30+
mixin M {}
31+
32+
extension type ET(int _) {}
33+
34+
enum E {
35+
e0;
36+
}
37+
38+
extension ExtC on C {
39+
static int foo = 42;
40+
}
41+
42+
extension ExtM on M {
43+
static void bar() {}
44+
}
45+
46+
extension ExtET on ET {
47+
static int get baz => 42;
48+
}
49+
50+
extension ExtE on E {
51+
static void set qux(int v) {}
52+
}
53+
54+
main() {
55+
C.foo;
56+
// ^^^
57+
// [analyzer] unspecified
58+
// [cfe] unspecified
59+
60+
M.bar();
61+
// ^^^
62+
// [analyzer] unspecified
63+
// [cfe] unspecified
64+
65+
ET.baz;
66+
// ^^^
67+
// [analyzer] unspecified
68+
// [cfe] unspecified
69+
70+
E.qux = 42;
71+
// ^^^
72+
// [analyzer] unspecified
73+
// [cfe] unspecified
74+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) 2025, 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 Consider an expression `e` which is a member invocation with
6+
/// syntactic receiver `C` and an associated member name `m`. Assume that `m` is
7+
/// a static member declared by `D`. The static analysis and dynamic semantics
8+
/// of this expression is the same as in Dart before the introduction of this
9+
/// feature.
10+
/// ...
11+
/// In the case where `D` does not declare any static members whose basename is
12+
/// the basename of `m`, and `D` does not declare any constructors named `C.m2`
13+
/// where `m2` is the basename of `m`, let `M` be the set containing each
14+
/// accessible extension whose on-declaration is `D`, and whose static members
15+
/// include one with the name `m`, or which declares a constructor named `C.m`.
16+
/// ...
17+
/// An error occurs if `M` is empty, or `M` contains more than one member.
18+
///
19+
/// @description Checks that that it is a compile-time error to invoke `m` if
20+
/// `M` contains more than one member. Test a variable as `m`.
21+
/// @author [email protected]
22+
23+
// SharedOptions=--enable-experiment=static-extensions
24+
25+
class C {}
26+
27+
mixin M {}
28+
29+
extension type ET(int _) {}
30+
31+
enum E {
32+
e0;
33+
}
34+
35+
extension ExtC1 on C {
36+
static int v = 42;
37+
}
38+
39+
extension ExtC2 on C {
40+
static int v = 42;
41+
}
42+
43+
extension ExtM1 on M {
44+
static int v = 42;
45+
}
46+
47+
extension ExtM2 on M {
48+
static int v = 42;
49+
}
50+
51+
extension ExtET1 on ET {
52+
static int v = 42;
53+
}
54+
55+
extension ExtET2 on ET {
56+
static int v = 42;
57+
}
58+
59+
extension ExtE1 on E {
60+
static int v = 42;
61+
}
62+
63+
extension ExtE2 on E {
64+
static int v = 42;
65+
}
66+
67+
main() {
68+
C.v;
69+
// ^
70+
// [analyzer] unspecified
71+
// [cfe] unspecified
72+
73+
M.v;
74+
// ^
75+
// [analyzer] unspecified
76+
// [cfe] unspecified
77+
78+
ET.v;
79+
// ^
80+
// [analyzer] unspecified
81+
// [cfe] unspecified
82+
83+
E.v;
84+
// ^
85+
// [analyzer] unspecified
86+
// [cfe] unspecified
87+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) 2025, 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 Consider an expression `e` which is a member invocation with
6+
/// syntactic receiver `C` and an associated member name `m`. Assume that `m` is
7+
/// a static member declared by `D`. The static analysis and dynamic semantics
8+
/// of this expression is the same as in Dart before the introduction of this
9+
/// feature.
10+
/// ...
11+
/// In the case where `D` does not declare any static members whose basename is
12+
/// the basename of `m`, and `D` does not declare any constructors named `C.m2`
13+
/// where `m2` is the basename of `m`, let `M` be the set containing each
14+
/// accessible extension whose on-declaration is `D`, and whose static members
15+
/// include one with the name `m`, or which declares a constructor named `C.m`.
16+
/// ...
17+
/// An error occurs if `M` is empty, or `M` contains more than one member.
18+
///
19+
/// @description Checks that that it is a compile-time error to invoke `m` if
20+
/// `M` contains more than one member. Test a getter as `m`.
21+
/// @author [email protected]
22+
23+
// SharedOptions=--enable-experiment=static-extensions
24+
25+
class C {}
26+
27+
mixin M {}
28+
29+
extension type ET(int _) {}
30+
31+
enum E {
32+
e0;
33+
}
34+
35+
extension ExtC1 on C {
36+
static int get foo => 42;
37+
}
38+
39+
extension ExtC2 on C {
40+
static int get foo => 42;
41+
}
42+
43+
extension ExtM1 on M {
44+
static int get foo => 42;
45+
}
46+
47+
extension ExtM2 on M {
48+
static int get foo => 42;
49+
}
50+
51+
extension ExtET1 on ET {
52+
static int get foo => 42;
53+
}
54+
55+
extension ExtET2 on ET {
56+
static int get foo => 42;
57+
}
58+
59+
extension ExtE1 on E {
60+
static int get foo => 42;
61+
}
62+
63+
extension ExtE2 on E {
64+
static int get foo => 42;
65+
}
66+
67+
main() {
68+
C.foo;
69+
// ^^^
70+
// [analyzer] unspecified
71+
// [cfe] unspecified
72+
73+
M.foo;
74+
// ^^^
75+
// [analyzer] unspecified
76+
// [cfe] unspecified
77+
78+
ET.foo;
79+
// ^^^
80+
// [analyzer] unspecified
81+
// [cfe] unspecified
82+
83+
E.foo;
84+
// ^^^
85+
// [analyzer] unspecified
86+
// [cfe] unspecified
87+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) 2025, 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 Consider an expression `e` which is a member invocation with
6+
/// syntactic receiver `C` and an associated member name `m`. Assume that `m` is
7+
/// a static member declared by `D`. The static analysis and dynamic semantics
8+
/// of this expression is the same as in Dart before the introduction of this
9+
/// feature.
10+
/// ...
11+
/// In the case where `D` does not declare any static members whose basename is
12+
/// the basename of `m`, and `D` does not declare any constructors named `C.m2`
13+
/// where `m2` is the basename of `m`, let `M` be the set containing each
14+
/// accessible extension whose on-declaration is `D`, and whose static members
15+
/// include one with the name `m`, or which declares a constructor named `C.m`.
16+
/// ...
17+
/// An error occurs if `M` is empty, or `M` contains more than one member.
18+
///
19+
/// @description Checks that that it is a compile-time error to invoke `m` if
20+
/// `M` contains more than one member. Test a method as `m`.
21+
/// @author [email protected]
22+
23+
// SharedOptions=--enable-experiment=static-extensions
24+
25+
class C {}
26+
27+
mixin M {}
28+
29+
extension type ET(int _) {}
30+
31+
enum E {
32+
e0;
33+
}
34+
35+
extension ExtC1 on C {
36+
static int foo() => 42;
37+
}
38+
39+
extension ExtC2 on C {
40+
static int foo() => 42;
41+
}
42+
43+
extension ExtM1 on M {
44+
static int foo() => 42;
45+
}
46+
47+
extension ExtM2 on M {
48+
static int foo() => 42;
49+
}
50+
51+
extension ExtET1 on ET {
52+
static int foo() => 42;
53+
}
54+
55+
extension ExtET2 on ET {
56+
static int foo() => 42;
57+
}
58+
59+
extension ExtE1 on E {
60+
static int foo() => 42;
61+
}
62+
63+
extension ExtE2 on E {
64+
static int foo() => 42;
65+
}
66+
67+
main() {
68+
C.foo();
69+
// ^^^
70+
// [analyzer] unspecified
71+
// [cfe] unspecified
72+
73+
M.foo();
74+
// ^^^
75+
// [analyzer] unspecified
76+
// [cfe] unspecified
77+
78+
ET.foo();
79+
// ^^^
80+
// [analyzer] unspecified
81+
// [cfe] unspecified
82+
83+
E.foo();
84+
// ^^^
85+
// [analyzer] unspecified
86+
// [cfe] unspecified
87+
}

0 commit comments

Comments
 (0)