Skip to content

Commit 4ddb83e

Browse files
kallentuCommit Queue
authored andcommitted
[parser] Dot shorthands: Remove synthetic token in parser.
Context: A while back, I inserted a synthetic token in the parser to allow us to parse without crashing the analyzer while I worked on the CFE. Now that both implementations are up and working, we can remove this synthetic token and allow the parser to parse as if we had enabled dot shorthands by default, and produce an error if the experiment isn't enabled. This change allows a bunch of different language tests to start passing since they were blocked on the weird synthetic token messing up the parsing stream. Bug: #59758 Change-Id: I792e3b917a76241b04ee708de06f670bbde64036 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423563 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
1 parent 16d6594 commit 4ddb83e

File tree

6 files changed

+25
-39
lines changed

6 files changed

+25
-39
lines changed

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5844,14 +5844,7 @@ class Parser {
58445844
assert(precedence <= SELECTOR_PRECEDENCE);
58455845

58465846
bool isDotShorthand = _isDotShorthand(token.next!);
5847-
if (isDotShorthand) {
5848-
// TODO(kallentu): Once the analyzer implementation is done, we can avoid
5849-
// adding a synthetic identifier completely, but currently, the parser
5850-
// will crash without one.
5851-
//
5852-
// Insert a synthetic identifier to satisfy listeners.
5853-
token = rewriter.insertSyntheticIdentifier(token);
5854-
} else {
5847+
if (!isDotShorthand) {
58555848
token =
58565849
parseUnaryExpression(token, allowCascades, constantPatternContext);
58575850
}

pkg/front_end/lib/src/kernel/body_builder.dart

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10033,7 +10033,6 @@ class BodyBuilder extends StackListenerImpl
1003310033
.withArguments(ExperimentalFlag.dotShorthands.name),
1003410034
token.offset,
1003510035
token.length);
10036-
return;
1003710036
}
1003810037

1003910038
assert(checkState(token, [
@@ -10055,30 +10054,23 @@ class BodyBuilder extends StackListenerImpl
1005510054
.withArguments(ExperimentalFlag.dotShorthands.name),
1005610055
token.offset,
1005710056
token.length);
10058-
10059-
// Recovery, avoid crashing with an extra selector.
10060-
pop();
10061-
push(new ParserErrorGenerator(this, token, cfe.messageSyntheticToken));
10062-
return;
1006310057
}
1006410058

1006510059
assert(checkState(token, [ValueKinds.Selector]));
1006610060
Selector selector = pop() as Selector;
10067-
if (libraryFeatures.dotShorthands.isEnabled) {
10068-
if (selector is InvocationSelector) {
10069-
// e.g. `.parse(2)`
10070-
push(forest.createDotShorthandInvocation(
10071-
offsetForToken(token), selector.name, selector.arguments,
10072-
nameOffset: offsetForToken(token.next),
10073-
isConst: constantContext == ConstantContext.inferred));
10074-
} else if (selector is PropertySelector) {
10075-
// e.g. `.zero`
10076-
push(forest.createDotShorthandPropertyGet(
10077-
offsetForToken(token),
10078-
selector.name,
10061+
if (selector is InvocationSelector) {
10062+
// e.g. `.parse(2)`
10063+
push(forest.createDotShorthandInvocation(
10064+
offsetForToken(token), selector.name, selector.arguments,
1007910065
nameOffset: offsetForToken(token.next),
10080-
));
10081-
}
10066+
isConst: constantContext == ConstantContext.inferred));
10067+
} else if (selector is PropertySelector) {
10068+
// e.g. `.zero`
10069+
push(forest.createDotShorthandPropertyGet(
10070+
offsetForToken(token),
10071+
selector.name,
10072+
nameOffset: offsetForToken(token.next),
10073+
));
1008210074
}
1008310075
}
1008410076

pkg/front_end/parser_testcases/dot_shorthands/syntax.dart.intertwined.expect

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ parseUnit(enum)
104104
listener: beginVariableInitializer(=)
105105
parseExpression(=)
106106
parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none)
107-
rewriter()
108107
parsePrimary(., expressionContinuation, ConstantPatternContext.none)
109108
parseSendOrFunctionLiteral(., expressionContinuation, ConstantPatternContext.none)
110109
parseSend(., expressionContinuation, ConstantPatternContext.none)
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
NOTICE: Stream was rewritten by parser!
2-
31
enum Color { red, blue, green }
42

53
void main() {
6-
Color c = *synthetic*.red;
4+
Color c = .red;
75
}
86

97

108
enum[KeywordToken] Color[StringToken] {[BeginToken] red[StringToken],[SimpleToken] blue[StringToken],[SimpleToken] green[StringToken] }[SimpleToken]
119

1210
void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
13-
Color[StringToken] c[StringToken] =[SimpleToken] [SyntheticStringToken].[SimpleToken]red[StringToken];[SimpleToken]
11+
Color[StringToken] c[StringToken] =[SimpleToken] .[SimpleToken]red[StringToken];[SimpleToken]
1412
}[SimpleToken]
1513
[SimpleToken]

tests/language/dot_shorthands/simple/simple_identifier_if_null_test.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,17 @@ void main() {
4343
noContextLHSContextColor(Color.red);
4444

4545
// Class
46-
Expect.equals(integerTest(null), Integer.one);
47-
Expect.equals(integerTest(Integer.two), Integer.two);
46+
Expect.equals(integerTest(null).integer, 1);
47+
Expect.equals(integerTest(Integer.two).integer, 2);
4848

4949
noContextLHSContextInteger(null);
5050
noContextLHSContextInteger(Integer.one);
5151

5252
Integer possiblyNullableInteger = .nullable ?? Integer.one;
5353

5454
// Extension type
55-
Expect.equals(integerExtTest(null), IntegerExt.one);
56-
Expect.equals(integerExtTest(IntegerExt.two), IntegerExt.two);
55+
Expect.equals(integerExtTest(null).integer, 1);
56+
Expect.equals(integerExtTest(IntegerExt.two).integer, 2);
5757

5858
noContextLHSContextIntegerExt(null);
5959
noContextLHSContextIntegerExt(IntegerExt.one);
@@ -62,8 +62,8 @@ void main() {
6262
IntegerExt possiblyNullableIntegerExt2 = .one ?? IntegerExt.one;
6363

6464
// Mixin
65-
Expect.equals(integerMixinTest(null), IntegerMixin.mixinOne);
66-
Expect.equals(integerMixinTest(IntegerMixin.mixinTwo), IntegerMixin.mixinTwo);
65+
Expect.equals(integerMixinTest(null).integer, 1);
66+
Expect.equals(integerMixinTest(IntegerMixin.mixinTwo).integer, 2);
6767

6868
noContextLHSContextIntegerMixin(null);
6969
noContextLHSContextIntegerMixin(IntegerMixin.mixinOne);

tests/language/explicit_type_instantiation_parsing_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ void main() {
250250
// ^
251251
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
252252
// [cfe] This requires the experimental 'dot-shorthands' language feature to be enabled.
253+
// ^
254+
// [cfe] The static getter or field 'instance' isn't defined for the type 'dynamic'.
253255

254256
X<2>.any;
255257
// ^
@@ -258,6 +260,8 @@ void main() {
258260
// ^
259261
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
260262
// [cfe] This requires the experimental 'dot-shorthands' language feature to be enabled.
263+
// ^
264+
// [cfe] The static getter or field 'any' isn't defined for the type 'dynamic'.
261265

262266
// This would be invalid even if `X` had an `any` member. See next.
263267
X<X>.any; // Invalid, Class does not have any static `any` member.

0 commit comments

Comments
 (0)