Skip to content

Commit 59bc36e

Browse files
authored
#3315. Add grammar tests for factory() (#3390)
1 parent 1fc5e80 commit 59bc36e

File tree

8 files changed

+519
-0
lines changed

8 files changed

+519
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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 The grammar is ambiguous with regard to the keyword `factory`.
6+
/// For example, `factory() => C();` could be a method named `factory` with an
7+
/// implicitly inferred return type, or it could be a factory constructor whose
8+
/// name is the name of the enclosing class.
9+
///
10+
/// This ambiguity is resolved as follows: When a Dart parser expects to parse a
11+
/// `<memberDeclaration>`, and the beginning of the declaration is `factory` or
12+
/// one or more of the modifiers `const`, `augment`, or `external` followed by
13+
/// `factory`, it proceeds to parse the following input as a factory constructor.
14+
///
15+
/// @description Check that if the first token of a `<memberDeclaration>` is
16+
/// `factory` then parser expects a factory constructor and it is a compile-time
17+
/// error to call it as a function named `factory` with an implicitly inferred
18+
/// return type.
19+
/// @author [email protected]
20+
21+
// SharedOptions=--enable-experiment=declaring-constructors
22+
23+
class C {
24+
C.create();
25+
26+
factory() => C.create();
27+
}
28+
29+
extension type ET.create(int _) {
30+
factory() => ET.create(0);
31+
}
32+
33+
main() {
34+
C(); // Ok
35+
C.create().factory();
36+
// ^^^^^^^
37+
// [analyzer] unspecified
38+
// [cfe] unspecified
39+
40+
ET(0); //Ok
41+
ET.create(0).factory();
42+
// ^^^^^^^
43+
// [analyzer] unspecified
44+
// [cfe] unspecified
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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 The grammar is ambiguous with regard to the keyword `factory`.
6+
/// For example, `factory() => C();` could be a method named `factory` with an
7+
/// implicitly inferred return type, or it could be a factory constructor whose
8+
/// name is the name of the enclosing class.
9+
///
10+
/// This ambiguity is resolved as follows: When a Dart parser expects to parse a
11+
/// `<memberDeclaration>`, and the beginning of the declaration is `factory` or
12+
/// one or more of the modifiers `const`, `augment`, or `external` followed by
13+
/// `factory`, it proceeds to parse the following input as a factory constructor.
14+
///
15+
/// @description Check that if the first token of a `<memberDeclaration>` is
16+
/// `const` followed by `factory` then parser expects a factory constructor and
17+
/// it is a compile-time error to call it as a function named `factory` with an
18+
/// implicitly inferred return type.
19+
/// @author [email protected]
20+
21+
// SharedOptions=--enable-experiment=declaring-constructors
22+
23+
class C {
24+
const C.create();
25+
26+
const factory() => C.create();
27+
}
28+
29+
extension type const ET.create(int _) {
30+
const factory() => ET.create(0);
31+
}
32+
33+
main() {
34+
C(); // Ok
35+
C.create().factory();
36+
// ^^^^^^^
37+
// [analyzer] unspecified
38+
// [cfe] unspecified
39+
40+
ET(0); // Ok
41+
ET.create(0).factory();
42+
// ^^^^^^^
43+
// [analyzer] unspecified
44+
// [cfe] unspecified
45+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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 The grammar is ambiguous with regard to the keyword `factory`.
6+
/// For example, `factory() => C();` could be a method named `factory` with an
7+
/// implicitly inferred return type, or it could be a factory constructor whose
8+
/// name is the name of the enclosing class.
9+
///
10+
/// This ambiguity is resolved as follows: When a Dart parser expects to parse a
11+
/// `<memberDeclaration>`, and the beginning of the declaration is `factory` or
12+
/// one or more of the modifiers `const`, `augment`, or `external` followed by
13+
/// `factory`, it proceeds to parse the following input as a factory constructor.
14+
///
15+
/// @description Check that if the first token of a `<memberDeclaration>` is
16+
/// `augment` followed by `factory` then parser expects a factory constructor
17+
/// and it is a compile-time error to call it as a function named `factory` with
18+
/// an implicitly inferred return type.
19+
/// @author [email protected]
20+
21+
// SharedOptions=--enable-experiment=augmentations,declaring-constructors
22+
23+
class C1 {
24+
C1.create();
25+
factory();
26+
}
27+
28+
augment class C1 {
29+
augment factory() => C1.create();
30+
}
31+
32+
class C2 {
33+
const C2.create();
34+
const factory();
35+
}
36+
37+
augment class C2 {
38+
augment const factory() => C2.create();
39+
}
40+
41+
class C3 {
42+
C3.create();
43+
factory();
44+
}
45+
46+
augment class C3 {
47+
augment external factory();
48+
}
49+
50+
class C4 {
51+
C4.create();
52+
const factory();
53+
}
54+
55+
augment class C4 {
56+
augment external const factory();
57+
}
58+
59+
extension type ET1.create(int _) {
60+
factory();
61+
62+
augment factory() => ET1.create(0);
63+
}
64+
65+
extension type const ET2.create(int _) {
66+
factory();
67+
68+
augment const factory() => ET2.create(0);
69+
}
70+
71+
extension type const ET3.create(int _) {
72+
factory();
73+
74+
augment external factory();
75+
}
76+
77+
extension type ET4.create(int _) {
78+
const factory();
79+
80+
augment external const factory();
81+
}
82+
83+
main() {
84+
C1(); // Ok
85+
C1.create().factory();
86+
// ^^^^^^^
87+
// [analyzer] unspecified
88+
// [cfe] unspecified
89+
90+
C2(); // Ok
91+
C2.create().factory();
92+
// ^^^^^^^
93+
// [analyzer] unspecified
94+
// [cfe] unspecified
95+
96+
C3(); // Ok
97+
C3.create().factory();
98+
// ^^^^^^^
99+
// [analyzer] unspecified
100+
// [cfe] unspecified
101+
102+
C4(); // Ok
103+
C4.create().factory();
104+
// ^^^^^^^
105+
// [analyzer] unspecified
106+
// [cfe] unspecified
107+
108+
ET1(0); // Ok
109+
ET1.create(0).factory();
110+
// ^^^^^^^
111+
// [analyzer] unspecified
112+
// [cfe] unspecified
113+
114+
ET2(0); // Ok
115+
ET2.create(0).factory();
116+
// ^^^^^^^
117+
// [analyzer] unspecified
118+
// [cfe] unspecified
119+
120+
ET3(0); // Ok
121+
ET3.create(0).factory();
122+
// ^^^^^^^
123+
// [analyzer] unspecified
124+
// [cfe] unspecified
125+
126+
ET4(0); // Ok
127+
ET4.create(0).factory();
128+
// ^^^^^^^
129+
// [analyzer] unspecified
130+
// [cfe] unspecified
131+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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 The grammar is ambiguous with regard to the keyword `factory`.
6+
/// For example, `factory() => C();` could be a method named `factory` with an
7+
/// implicitly inferred return type, or it could be a factory constructor whose
8+
/// name is the name of the enclosing class.
9+
///
10+
/// This ambiguity is resolved as follows: When a Dart parser expects to parse a
11+
/// `<memberDeclaration>`, and the beginning of the declaration is `factory` or
12+
/// one or more of the modifiers `const`, `augment`, or `external` followed by
13+
/// `factory`, it proceeds to parse the following input as a factory constructor.
14+
///
15+
/// @description Check that if the first token of a `<memberDeclaration>` is
16+
/// `external` followed by `factory` or `const factory` then parser expects a
17+
/// factory constructor and it is a compile-time error to call it as a function
18+
/// named `factory` with an implicitly inferred return type.
19+
/// @author [email protected]
20+
21+
// SharedOptions=--enable-experiment=declaring-constructors
22+
23+
class C1 {
24+
C1.create();
25+
26+
external factory();
27+
}
28+
29+
class C2 {
30+
C2.create();
31+
32+
external const factory();
33+
}
34+
35+
extension type ET1.create(int _) {
36+
external factory();
37+
}
38+
39+
extension type const ET2.create(int _) {
40+
external const factory();
41+
}
42+
43+
main() {
44+
C1(); // Ok
45+
C1.create().factory();
46+
// ^^^^^^^
47+
// [analyzer] unspecified
48+
// [cfe] unspecified
49+
50+
C2(); // Ok
51+
C2.create().factory();
52+
// ^^^^^^^
53+
// [analyzer] unspecified
54+
// [cfe] unspecified
55+
56+
ET1(0); // Ok
57+
ET1.create(0).factory();
58+
// ^^^^^^^
59+
// [analyzer] unspecified
60+
// [cfe] unspecified
61+
62+
ET2(0); // Ok
63+
ET2.create(0).factory();
64+
// ^^^^^^^
65+
// [analyzer] unspecified
66+
// [cfe] unspecified
67+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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 The grammar is ambiguous with regard to the keyword `factory`.
6+
/// For example, `factory() => C();` could be a method named `factory` with an
7+
/// implicitly inferred return type, or it could be a factory constructor whose
8+
/// name is the name of the enclosing class.
9+
///
10+
/// This ambiguity is resolved as follows: When a Dart parser expects to parse a
11+
/// `<memberDeclaration>`, and the beginning of the declaration is `factory` or
12+
/// one or more of the modifiers `const`, `augment`, or `external` followed by
13+
/// `factory`, it proceeds to parse the following input as a factory constructor.
14+
///
15+
/// @description Check that it is a compile-time error if the first tokens of a
16+
/// `<memberDeclaration>` are `const external`, `const augment` or
17+
/// `external augment` followed by `factory`.
18+
/// @author [email protected]
19+
20+
// SharedOptions=--enable-experiment=augmentations,declaring-constructors
21+
22+
class C1 {
23+
C1.create();
24+
25+
const external factory();
26+
// ^^^^^^^^
27+
// [analyzer] unspecified
28+
// [cfe] unspecified
29+
}
30+
31+
class C2 {
32+
C2.create();
33+
34+
const factory();
35+
36+
const augment factory();
37+
// ^^^^^^^
38+
// [analyzer] unspecified
39+
// [cfe] unspecified
40+
}
41+
42+
class C3 {
43+
C3.create();
44+
45+
factory();
46+
47+
external augment factory();
48+
// ^^^^^^^
49+
// [analyzer] unspecified
50+
// [cfe] unspecified
51+
}
52+
53+
extension type ET1.create(int _) {
54+
const external factory();
55+
// ^^^^^^^^
56+
// [analyzer] unspecified
57+
// [cfe] unspecified
58+
}
59+
60+
extension type const ET2.create(int _) {
61+
const factory();
62+
63+
const augment factory();
64+
// ^^^^^^^
65+
// [analyzer] unspecified
66+
// [cfe] unspecified
67+
}
68+
69+
extension type const ET3.create(int _) {
70+
factory();
71+
72+
external augment factory();
73+
// ^^^^^^^
74+
// [analyzer] unspecified
75+
// [cfe] unspecified
76+
}
77+
78+
main() {
79+
print(C1);
80+
print(C2);
81+
print(C3);
82+
print(E1);
83+
print(E2);
84+
print(E3);
85+
}

0 commit comments

Comments
 (0)