Skip to content

Commit a58eb47

Browse files
johnniwintherCommit Queue
authored andcommitted
[parser] Support new factory constructor syntax
Part of #61699 Change-Id: I6afa9f4991d4b965a60d39e14618731a10a04a1f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/459820 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent 1029fc9 commit a58eb47

File tree

43 files changed

+3954
-120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3954
-120
lines changed

pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,6 +2193,11 @@ class ForwardingListener implements Listener {
21932193
listener?.handleWildcardPattern(keyword, wildcard);
21942194
}
21952195

2196+
@override
2197+
void handleNoIdentifier(Token token) {
2198+
listener?.handleNoIdentifier(token);
2199+
}
2200+
21962201
@override
21972202
void handleNoType(Token lastConsumed) {
21982203
listener?.handleNoType(lastConsumed);

pkg/_fe_analyzer_shared/lib/src/parser/listener.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,6 +2389,10 @@ abstract class Listener implements UnescapeErrorListener {
23892389
logEvent("NoConstructorReferenceContinuationAfterTypeArguments");
23902390
}
23912391

2392+
void handleNoIdentifier(Token token) {
2393+
logEvent("NoIdentifier");
2394+
}
2395+
23922396
void handleNoTypeNameInConstructorReference(Token token) {
23932397
logEvent("NoTypeNameInConstructorReference");
23942398
}

pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4015,7 +4015,7 @@ class Parser {
40154015
}
40164016

40174017
Token beforeType = token;
4018-
if (varFinalOrConst != null) {
4018+
if (varFinalOrConst != null && !varFinalOrConst.isA(Keyword.CONST)) {
40194019
Token? afterOuterPattern = skipOuterPattern(beforeType);
40204020
if (afterOuterPattern != null &&
40214021
(afterOuterPattern.next!.isA(TokenType.EQ))) {
@@ -5192,7 +5192,7 @@ class Parser {
51925192
listener.beginMember();
51935193

51945194
Token beforeType = token;
5195-
if (varFinalOrConst != null) {
5195+
if (varFinalOrConst != null && !varFinalOrConst.isA(Keyword.CONST)) {
51965196
Token? afterOuterPattern = skipOuterPattern(beforeType);
51975197
if (afterOuterPattern != null &&
51985198
(afterOuterPattern.next!.isA(TokenType.EQ))) {
@@ -5267,9 +5267,31 @@ class Parser {
52675267
externalToken,
52685268
staticToken ?? covariantToken,
52695269
varFinalOrConst,
5270+
/* hasName = */ true,
52705271
);
52715272
listener.endMember();
52725273
return token;
5274+
} else if (_isDeclaringConstructorsFeatureEnabled &&
5275+
next2.isA(TokenType.OPEN_PAREN)) {
5276+
if (typeInfo == noType &&
5277+
covariantToken == null &&
5278+
//externalToken = null &&
5279+
lateToken == null &&
5280+
staticToken == null &&
5281+
(varFinalOrConst == null || varFinalOrConst.isA(Keyword.CONST)) &&
5282+
abstractToken == null) {
5283+
token = parseFactoryMethod(
5284+
token,
5285+
kind,
5286+
beforeStart,
5287+
externalToken,
5288+
staticToken ?? covariantToken,
5289+
varFinalOrConst,
5290+
/* hasName = */ false,
5291+
);
5292+
listener.endMember();
5293+
return token;
5294+
}
52735295
}
52745296
// Fall through to continue parsing `factory` as an identifier.
52755297
} else if (identical(value, 'operator')) {
@@ -5832,6 +5854,7 @@ class Parser {
58325854
Token? externalToken,
58335855
Token? staticOrCovariant,
58345856
Token? varFinalOrConst,
5857+
bool hasName,
58355858
) {
58365859
Token factoryKeyword = token = token.next!;
58375860
assert(factoryKeyword.isA(Keyword.FACTORY));
@@ -5870,11 +5893,15 @@ class Parser {
58705893
externalToken,
58715894
varFinalOrConst,
58725895
);
5873-
token = ensureIdentifier(token, IdentifierContext.methodDeclaration);
5874-
token = parseQualifiedRestOpt(
5875-
token,
5876-
IdentifierContext.methodDeclarationContinuation,
5877-
);
5896+
if (!hasName) {
5897+
listener.handleNoIdentifier(token);
5898+
} else {
5899+
token = ensureIdentifier(token, IdentifierContext.methodDeclaration);
5900+
token = parseQualifiedRestOpt(
5901+
token,
5902+
IdentifierContext.methodDeclarationContinuation,
5903+
);
5904+
}
58785905
token = parseMethodTypeVar(token);
58795906
token = parseFormalParametersRequiredOpt(token, MemberKind.Factory);
58805907
Token asyncToken = token.next!;

pkg/front_end/lib/src/util/parser_ast_helper.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3651,6 +3651,15 @@ abstract class AbstractParserAstListener implements Listener {
36513651
seen(data);
36523652
}
36533653

3654+
@override
3655+
void handleNoIdentifier(Token token) {
3656+
NoIdentifierHandle data = new NoIdentifierHandle(
3657+
ParserAstType.HANDLE,
3658+
token: token,
3659+
);
3660+
seen(data);
3661+
}
3662+
36543663
@override
36553664
void handleNoTypeNameInConstructorReference(Token token) {
36563665
NoTypeNameInConstructorReferenceHandle data =
@@ -10286,6 +10295,19 @@ class NoConstructorReferenceContinuationAfterTypeArgumentsHandle
1028610295
v.visitNoConstructorReferenceContinuationAfterTypeArgumentsHandle(this);
1028710296
}
1028810297

10298+
class NoIdentifierHandle extends ParserAstNode {
10299+
final Token token;
10300+
10301+
NoIdentifierHandle(ParserAstType type, {required this.token})
10302+
: super("NoIdentifier", type);
10303+
10304+
@override
10305+
Map<String, Object?> get deprecatedArguments => {"token": token};
10306+
10307+
@override
10308+
R accept<R>(ParserAstVisitor<R> v) => v.visitNoIdentifierHandle(this);
10309+
}
10310+
1028910311
class NoTypeNameInConstructorReferenceHandle extends ParserAstNode {
1029010312
final Token token;
1029110313

@@ -11657,6 +11679,7 @@ abstract class ParserAstVisitor<R> {
1165711679
R visitNoConstructorReferenceContinuationAfterTypeArgumentsHandle(
1165811680
NoConstructorReferenceContinuationAfterTypeArgumentsHandle node,
1165911681
);
11682+
R visitNoIdentifierHandle(NoIdentifierHandle node);
1166011683
R visitNoTypeNameInConstructorReferenceHandle(
1166111684
NoTypeNameInConstructorReferenceHandle node,
1166211685
);
@@ -12950,6 +12973,10 @@ class RecursiveParserAstVisitor implements ParserAstVisitor<void> {
1295012973
NoConstructorReferenceContinuationAfterTypeArgumentsHandle node,
1295112974
) => node.visitChildren(this);
1295212975

12976+
@override
12977+
void visitNoIdentifierHandle(NoIdentifierHandle node) =>
12978+
node.visitChildren(this);
12979+
1295312980
@override
1295412981
void visitNoTypeNameInConstructorReferenceHandle(
1295512982
NoTypeNameInConstructorReferenceHandle node,
@@ -14464,6 +14491,10 @@ class RecursiveParserAstVisitorWithDefaultNodeAsync
1446414491
NoConstructorReferenceContinuationAfterTypeArgumentsHandle node,
1446514492
) => defaultNode(node);
1446614493

14494+
@override
14495+
Future<void> visitNoIdentifierHandle(NoIdentifierHandle node) =>
14496+
defaultNode(node);
14497+
1446714498
@override
1446814499
Future<void> visitNoTypeNameInConstructorReferenceHandle(
1446914500
NoTypeNameInConstructorReferenceHandle node,

pkg/front_end/parser_testcases/augmentation/member_declarations.dart.intertwined.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,6 @@ parseUnit(class)
297297
listener: beginMetadataStar(augment)
298298
listener: endMetadataStar(0)
299299
listener: beginMember()
300-
skipOuterPattern(const)
301-
skipObjectPatternRest(field)
302300
parseFields(;, null, augment, null, null, null, null, const, const, NoType(), field, DeclarationKind.Class, Class, false)
303301
listener: beginFields(DeclarationKind.Class, null, augment, null, null, null, null, const, ;)
304302
listener: handleNoType(const)
@@ -649,8 +647,6 @@ parseUnit(class)
649647
listener: beginMetadataStar(augment)
650648
listener: endMetadataStar(0)
651649
listener: beginMember()
652-
skipOuterPattern(const)
653-
skipObjectPatternRest(field)
654650
parseFields(;, null, augment, null, static, null, null, const, const, NoType(), field, DeclarationKind.Class, Class, false)
655651
listener: beginFields(DeclarationKind.Class, null, augment, null, static, null, null, const, ;)
656652
listener: handleNoType(const)
@@ -1030,8 +1026,6 @@ parseUnit(class)
10301026
listener: beginMetadataStar(augment)
10311027
listener: endMetadataStar(0)
10321028
listener: beginMember()
1033-
skipOuterPattern(const)
1034-
skipObjectPatternRest(field)
10351029
parseFields(;, null, augment, null, null, null, null, const, const, NoType(), field, DeclarationKind.Mixin, Mixin, false)
10361030
listener: beginFields(DeclarationKind.Mixin, null, augment, null, null, null, null, const, ;)
10371031
listener: handleNoType(const)
@@ -1382,8 +1376,6 @@ parseUnit(class)
13821376
listener: beginMetadataStar(augment)
13831377
listener: endMetadataStar(0)
13841378
listener: beginMember()
1385-
skipOuterPattern(const)
1386-
skipObjectPatternRest(field)
13871379
parseFields(;, null, augment, null, static, null, null, const, const, NoType(), field, DeclarationKind.Mixin, Mixin, false)
13881380
listener: beginFields(DeclarationKind.Mixin, null, augment, null, static, null, null, const, ;)
13891381
listener: handleNoType(const)

pkg/front_end/parser_testcases/augmentation/member_errors.dart.intertwined.expect

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,6 @@ parseUnit(class)
797797
reportRecoverableErrorWithToken(augment, Template(DuplicatedModifier))
798798
listener: handleRecoverableError(Message[Template(DuplicatedModifier), The modifier 'augment' was already specified., Try removing all but one occurrence of the modifier., {lexeme: augment}], augment, augment)
799799
listener: beginMember()
800-
skipOuterPattern(const)
801-
skipObjectPatternRest(field)
802800
parseFields(;, null, augment, null, null, null, null, const, const, NoType(), field, DeclarationKind.Class, Class, false)
803801
listener: beginFields(DeclarationKind.Class, null, augment, null, null, null, null, const, ;)
804802
listener: handleNoType(const)
@@ -825,8 +823,6 @@ parseUnit(class)
825823
reportRecoverableError(external, Message[Template(ConflictingModifiers), Members can't be declared to be both 'external' and 'augment'., Try removing one of the keywords., {string: external, string2: augment}])
826824
listener: handleRecoverableError(Message[Template(ConflictingModifiers), Members can't be declared to be both 'external' and 'augment'., Try removing one of the keywords., {string: external, string2: augment}], external, external)
827825
listener: beginMember()
828-
skipOuterPattern(const)
829-
skipObjectPatternRest(field)
830826
parseFields(;, null, augment, external, null, null, null, const, const, NoType(), field, DeclarationKind.Class, Class, false)
831827
listener: beginFields(DeclarationKind.Class, null, augment, external, null, null, null, const, ;)
832828
listener: handleNoType(const)
@@ -846,8 +842,6 @@ parseUnit(class)
846842
reportRecoverableError(augment, Message[Template(ConflictingModifiers), Members can't be declared to be both 'augment' and 'external'., Try removing one of the keywords., {string: augment, string2: external}])
847843
listener: handleRecoverableError(Message[Template(ConflictingModifiers), Members can't be declared to be both 'augment' and 'external'., Try removing one of the keywords., {string: augment, string2: external}], augment, augment)
848844
listener: beginMember()
849-
skipOuterPattern(const)
850-
skipObjectPatternRest(field)
851845
parseFields(;, null, null, external, null, null, null, const, const, NoType(), field, DeclarationKind.Class, Class, false)
852846
listener: beginFields(DeclarationKind.Class, null, null, external, null, null, null, const, ;)
853847
listener: handleNoType(const)
@@ -1631,8 +1625,6 @@ parseUnit(class)
16311625
reportRecoverableErrorWithToken(augment, Template(DuplicatedModifier))
16321626
listener: handleRecoverableError(Message[Template(DuplicatedModifier), The modifier 'augment' was already specified., Try removing all but one occurrence of the modifier., {lexeme: augment}], augment, augment)
16331627
listener: beginMember()
1634-
skipOuterPattern(const)
1635-
skipObjectPatternRest(field)
16361628
parseFields(;, null, augment, null, static, null, null, const, const, NoType(), field, DeclarationKind.Class, Class, false)
16371629
listener: beginFields(DeclarationKind.Class, null, augment, null, static, null, null, const, ;)
16381630
listener: handleNoType(const)
@@ -1659,8 +1651,6 @@ parseUnit(class)
16591651
reportRecoverableError(augment, Message[Template(ModifierOutOfOrder), The modifier 'augment' should be before the modifier 'static'., Try re-ordering the modifiers., {string: augment, string2: static}])
16601652
listener: handleRecoverableError(Message[Template(ModifierOutOfOrder), The modifier 'augment' should be before the modifier 'static'., Try re-ordering the modifiers., {string: augment, string2: static}], augment, augment)
16611653
listener: beginMember()
1662-
skipOuterPattern(const)
1663-
skipObjectPatternRest(field)
16641654
parseFields(;, null, null, null, static, null, null, const, const, NoType(), field, DeclarationKind.Class, Class, false)
16651655
listener: beginFields(DeclarationKind.Class, null, null, null, static, null, null, const, ;)
16661656
listener: handleNoType(const)

pkg/front_end/parser_testcases/augmentation/top_level_declarations.dart.intertwined.expect

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,6 @@ parseUnit(augment)
250250
listener: endMetadataStar(0)
251251
parseTopLevelMemberImpl(;)
252252
listener: beginTopLevelMember(augment)
253-
skipOuterPattern(const)
254-
skipObjectPatternRest(field)
255253
parseFields(;, null, augment, null, null, null, null, const, const, NoType(), field, DeclarationKind.TopLevel, null, false)
256254
listener: beginFields(DeclarationKind.TopLevel, null, augment, null, null, null, null, const, ;)
257255
listener: handleNoType(const)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class C {
2+
external factory ();
3+
external factory C();
4+
external factory name();
5+
external factory C.name();
6+
factory () => C();
7+
factory C() => C();
8+
factory name() => C();
9+
factory C.name() => C();
10+
factory () {}
11+
factory C() {}
12+
factory name() {}
13+
factory C.name() {}
14+
factory () = C;
15+
factory C() = C;
16+
factory name() = C;
17+
factory C.name() = C;
18+
external const factory ();
19+
external const factory C();
20+
external const factory name();
21+
external const factory C.name();
22+
const factory () => C();
23+
const factory C() => C();
24+
const factory name() => C();
25+
const factory C.name() => C();
26+
const factory () {}
27+
const factory C() {}
28+
const factory name() {}
29+
const factory C.name() {}
30+
const factory () = C;
31+
const factory C() = C;
32+
const factory name() = C;
33+
const factory C.name() = C;
34+
35+
void factory() => C(); // Not a factory constructor.
36+
}

0 commit comments

Comments
 (0)