Skip to content

Commit c9aa87b

Browse files
kallentuCommit Queue
authored and
Commit Queue
committed
[parser] Avoid an extra error in CFE for dot shorthands.
The parser was still WIP and was emitting an extra error, so this CL removes that error so tests can start passing and so I can properly test the new implementation e2e. It still needs some fixes after the analyzer implementation is complete. The current extra synthetic tokens added in the parser are temporary to prevent crashes on the analyzer side when the experiment flag is turned off. But it works fine for now, and I'll clean it up in a CL when the feature is complete. Bug: #59758 Change-Id: I83d8c840f66bedff4aa27a737a3f57e77d3973b8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/412344 Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
1 parent 04e06aa commit c9aa87b

18 files changed

+36
-116
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5833,9 +5833,17 @@ class Parser {
58335833

58345834
bool isDotShorthand = token.next!.isA(TokenType.PERIOD) &&
58355835
(token.next!.next!.isIdentifier || token.next!.next!.isA(Keyword.NEW));
5836-
// TODO(kallentu): Once the parser handles dot shorthands by default,
5837-
// we don't need to parse for an error here.
5838-
token = parseUnaryExpression(token, allowCascades, constantPatternContext);
5836+
if (isDotShorthand) {
5837+
// TODO(kallentu): Once the analyzer implementation is done, we can avoid
5838+
// adding a synthetic identifier completely, but currently, the parser
5839+
// will crash without one.
5840+
//
5841+
// Insert a synthetic identifier to satisfy listeners.
5842+
token = rewriter.insertSyntheticIdentifier(token);
5843+
} else {
5844+
token =
5845+
parseUnaryExpression(token, allowCascades, constantPatternContext);
5846+
}
58395847

58405848
Token bangToken = token;
58415849
if (token.next!.isA(TokenType.BANG)) {

pkg/analyzer/lib/src/fasta/ast_builder.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4063,9 +4063,6 @@ class AstBuilder extends StackListener {
40634063
feature: ExperimentalFeatures.dot_shorthands,
40644064
startToken: token,
40654065
);
4066-
4067-
// Recovery.
4068-
pop();
40694066
}
40704067

40714068
// TODO(kallentu): Handle dot shorthands.

pkg/analyzer/test/src/diagnostics/experiment_not_enabled_test.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ main() {
3232
]);
3333
}
3434

35+
test_dotShorthands_disabled() async {
36+
await assertErrorsInCode(r'''
37+
void main() {
38+
Object c = .hash;
39+
print(c);
40+
}
41+
''', [
42+
error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 27, 1),
43+
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 28, 4),
44+
]);
45+
}
46+
3547
test_nonFunctionTypeAliases_disabled() async {
3648
await assertErrorsInCode(r'''
3749
// @dart = 2.12

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10007,15 +10007,13 @@ class BodyBuilder extends StackListenerImpl
1000710007

1000810008
// Recovery, avoid crashing with an extra selector.
1000910009
pop();
10010+
push(new ParserErrorGenerator(this, token, cfe.messageSyntheticToken));
1001010011
return;
1001110012
}
1001210013

10013-
Object? selector = pop();
10014-
if (libraryFeatures.dotShorthands.isEnabled && selector is Selector) {
10015-
// TODO(kallentu): Remove this once we have more of the dot shorthands
10016-
// implementation complete.
10017-
pop(); // ParserGeneratorError
10018-
10014+
assert(checkState(token, [ValueKinds.Selector]));
10015+
Selector selector = pop() as Selector;
10016+
if (libraryFeatures.dotShorthands.isEnabled) {
1001910017
// TODO(kallentu): Handle invocations.
1002010018

1002110019
push(forest.createDotShorthandPropertyGet(

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

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
Problems reported:
2-
3-
parser/dot_shorthands/syntax:4:13: Expected an identifier, but got '.'.
4-
Color c = .red;
5-
^
6-
71
beginCompilationUnit(enum)
82
beginMetadataStar(enum)
93
endMetadataStar(0)
@@ -67,11 +61,6 @@ beginCompilationUnit(enum)
6761
handleIdentifier(c, localVariableDeclaration)
6862
beginInitializedIdentifier(c)
6963
beginVariableInitializer(=)
70-
handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '.'., Try inserting an identifier before '.'., {lexeme: .}], ., .)
71-
handleIdentifier(, expression)
72-
handleNoTypeArguments(.)
73-
handleNoArguments(.)
74-
handleSend(, )
7564
handleIdentifier(red, expressionContinuation)
7665
handleNoTypeArguments(;)
7766
handleNoArguments(;)

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

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,7 @@ parseUnit(enum)
104104
listener: beginVariableInitializer(=)
105105
parseExpression(=)
106106
parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none)
107-
parseUnaryExpression(=, true, ConstantPatternContext.none)
108-
parsePrimary(=, expression, ConstantPatternContext.none)
109-
parseSend(=, expression, ConstantPatternContext.none)
110-
isNextIdentifier(=)
111-
ensureIdentifier(=, expression)
112-
reportRecoverableErrorWithToken(., Template(ExpectedIdentifier))
113-
listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '.'., Try inserting an identifier before '.'., {lexeme: .}], ., .)
114-
rewriter()
115-
listener: handleIdentifier(, expression)
116-
listener: handleNoTypeArguments(.)
117-
parseArgumentsOpt()
118-
listener: handleNoArguments(.)
119-
listener: handleSend(, )
107+
rewriter()
120108
parsePrimary(., expressionContinuation, ConstantPatternContext.none)
121109
parseSendOrFunctionLiteral(., expressionContinuation, ConstantPatternContext.none)
122110
parseSend(., expressionContinuation, ConstantPatternContext.none)

pkg/front_end/testcases/dot_shorthands/simple_class.dart.strong.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/simple_class.dart:12:13: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Color c = .red;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

pkg/front_end/testcases/dot_shorthands/simple_class.dart.strong.modular.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/simple_class.dart:12:13: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Color c = .red;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

pkg/front_end/testcases/dot_shorthands/simple_class.dart.strong.transformed.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/simple_class.dart:12:13: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Color c = .red;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

pkg/front_end/testcases/dot_shorthands/simple_enum.dart.strong.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/simple_enum.dart:8:13: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Color c = .red;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

pkg/front_end/testcases/dot_shorthands/simple_enum.dart.strong.modular.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/simple_enum.dart:8:13: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Color c = .red;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

pkg/front_end/testcases/dot_shorthands/simple_enum.dart.strong.transformed.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/simple_enum.dart:8:13: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Color c = .red;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

pkg/front_end/testcases/dot_shorthands/tearoff.dart.strong.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/tearoff.dart:6:14: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Object o = .hash;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

pkg/front_end/testcases/dot_shorthands/tearoff.dart.strong.modular.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/tearoff.dart:6:14: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Object o = .hash;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

pkg/front_end/testcases/dot_shorthands/tearoff.dart.strong.transformed.expect

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
library;
2-
//
3-
// Problems in library:
4-
//
5-
// pkg/front_end/testcases/dot_shorthands/tearoff.dart:6:14: Error: Expected an identifier, but got '.'.
6-
// Try inserting an identifier before '.'.
7-
// Object o = .hash;
8-
// ^
9-
//
102
import self as self;
113
import "dart:core" as core;
124

tests/language/dot_shorthands/feature_disabled_error_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void main() {
1212
Color color = .blue;
1313
// ^
1414
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
15-
// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
16-
// [cfe] Expected an identifier, but got '.'.
1715
// [cfe] This requires the experimental 'dot-shorthands' language feature to be enabled.
16+
// ^^^^
17+
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
1818
}

tests/language/dot_shorthands/feature_enabled_error_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ void main() {
1111
Color color = .blue;
1212
// ^
1313
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
14-
// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
15-
// [cfe] Expected an identifier, but got '.'.
1614
// [cfe] This requires the experimental 'dot-shorthands' language feature to be enabled.
15+
// ^^^^
16+
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
1717
}

tests/language/explicit_type_instantiation_parsing_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,19 +249,19 @@ void main() {
249249
// [cfe] A comparison expression can't be an operand of another comparison expression.
250250
// ^
251251
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
252-
// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
253-
// [cfe] Expected an identifier, but got '.'.
254252
// [cfe] This requires the experimental 'dot-shorthands' language feature to be enabled.
253+
// ^^^^^^^^
254+
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
255255

256256
X<2>.any;
257257
// ^
258258
// [analyzer] SYNTACTIC_ERROR.EQUALITY_CANNOT_BE_EQUALITY_OPERAND
259259
// [cfe] A comparison expression can't be an operand of another comparison expression.
260260
// ^
261261
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
262-
// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
263-
// [cfe] Expected an identifier, but got '.'.
264262
// [cfe] This requires the experimental 'dot-shorthands' language feature to be enabled.
263+
// ^^^
264+
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
265265

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

0 commit comments

Comments
 (0)