Skip to content

Commit 9c5eea2

Browse files
johnniwintherCommit Queue
authored andcommitted
[parser] Push handleEndingBinaryExpression implementation into subclasses
This moves implementation handling calls to handleEndingBinaryExpression into its own method in the subclasses. This splits the `.`, `.?`, `..` and `?..` from the real binary expressions. This is a step towards handling `a.b` different from `a + b` in the parser such that listeners don't have to create a value for `b` the works in both use cases; in the first is just a named operation performed on the receiver, whereas in the second case it is a full expression in its own right. Change-Id: I5291439f333971b7ff482325a15502e4d8a66b71 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/442820 Reviewed-by: Jens Johansen <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 50ab35b commit 9c5eea2

File tree

6 files changed

+99
-53
lines changed

6 files changed

+99
-53
lines changed

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,24 @@ class AnnotationsListener extends StackListener {
375375

376376
@override
377377
void handleEndingBinaryExpression(Token token, Token endToken) {
378-
endBinaryExpression(token, endToken);
378+
assert(
379+
checkState(token, [
380+
/* right */ _ValueKinds._Proto,
381+
/* left */ _ValueKinds._Proto,
382+
]),
383+
);
384+
Proto right = pop() as Proto;
385+
Proto left = pop() as Proto;
386+
switch (token.lexeme) {
387+
case '.':
388+
IdentifierProto identifierProto = right as IdentifierProto;
389+
push(left.apply(identifierProto));
390+
case '?.':
391+
IdentifierProto identifierProto = right as IdentifierProto;
392+
push(left.apply(identifierProto, isNullAware: true));
393+
default:
394+
throw new UnimplementedError("Binary operator '${token.lexeme}'.");
395+
}
379396
}
380397

381398
@override
@@ -389,12 +406,6 @@ class AnnotationsListener extends StackListener {
389406
Proto right = pop() as Proto;
390407
Proto left = pop() as Proto;
391408
switch (token.lexeme) {
392-
case '.':
393-
IdentifierProto identifierProto = right as IdentifierProto;
394-
push(left.apply(identifierProto));
395-
case '?.':
396-
IdentifierProto identifierProto = right as IdentifierProto;
397-
push(left.apply(identifierProto, isNullAware: true));
398409
case '??':
399410
push(
400411
new ExpressionProto(

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,10 +2075,7 @@ class Listener implements UnescapeErrorListener {
20752075
}
20762076

20772077
/// Called for `.`, `?.` and `..`.
2078-
void handleEndingBinaryExpression(Token token, Token endToken) {
2079-
// TODO(jensj): push implementation into subclasses
2080-
endBinaryExpression(token, endToken);
2081-
}
2078+
void handleEndingBinaryExpression(Token token, Token endToken) {}
20822079

20832080
/// Called when the parser encounters a `?` operator and begins parsing a
20842081
/// conditional expression.

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

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,37 +1069,26 @@ class AstBuilder extends StackListener {
10691069
void endBinaryExpression(Token operatorToken, Token endToken) {
10701070
assert(
10711071
operatorToken.isOperator ||
1072-
optional('.', operatorToken) ||
1073-
optional('?.', operatorToken) ||
1074-
optional('..', operatorToken) ||
1075-
optional('?..', operatorToken) ||
10761072
optional('===', operatorToken) ||
10771073
optional('!==', operatorToken),
10781074
);
10791075
debugEvent("BinaryExpression");
10801076

1081-
if (identical(".", operatorToken.stringValue) ||
1082-
identical("?.", operatorToken.stringValue) ||
1083-
identical("..", operatorToken.stringValue) ||
1084-
identical("?..", operatorToken.stringValue)) {
1085-
doDotExpression(operatorToken);
1086-
} else {
1087-
var right = pop() as ExpressionImpl;
1088-
var left = pop() as ExpressionImpl;
1089-
reportErrorIfSuper(right);
1090-
push(
1091-
BinaryExpressionImpl(
1092-
leftOperand: left,
1093-
operator: operatorToken,
1094-
rightOperand: right,
1095-
),
1077+
var right = pop() as ExpressionImpl;
1078+
var left = pop() as ExpressionImpl;
1079+
reportErrorIfSuper(right);
1080+
push(
1081+
BinaryExpressionImpl(
1082+
leftOperand: left,
1083+
operator: operatorToken,
1084+
rightOperand: right,
1085+
),
1086+
);
1087+
if (!enableTripleShift && operatorToken.type == TokenType.GT_GT_GT) {
1088+
_reportFeatureNotEnabled(
1089+
feature: ExperimentalFeatures.triple_shift,
1090+
startToken: operatorToken,
10961091
);
1097-
if (!enableTripleShift && operatorToken.type == TokenType.GT_GT_GT) {
1098-
_reportFeatureNotEnabled(
1099-
feature: ExperimentalFeatures.triple_shift,
1100-
startToken: operatorToken,
1101-
);
1102-
}
11031092
}
11041093
}
11051094

@@ -4363,6 +4352,19 @@ class AstBuilder extends StackListener {
43634352
push(EmptyStatementImpl(semicolon: semicolon));
43644353
}
43654354

4355+
@override
4356+
void handleEndingBinaryExpression(Token operatorToken, Token endToken) {
4357+
assert(
4358+
optional('.', operatorToken) ||
4359+
optional('?.', operatorToken) ||
4360+
optional('..', operatorToken) ||
4361+
optional('?..', operatorToken),
4362+
);
4363+
debugEvent("EndingBinaryExpression");
4364+
4365+
doDotExpression(operatorToken);
4366+
}
4367+
43664368
@override
43674369
void handleEnumElement(Token beginToken, Token? augmentToken) {
43684370
debugEvent("EnumElement");

pkg/analyzer/tool/summary/mini_ast.dart

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -219,19 +219,9 @@ class MiniAstBuilder extends StackListener {
219219
void endBinaryExpression(Token token, Token endToken) {
220220
debugEvent("BinaryExpression");
221221

222-
if (identical('.', token.stringValue)) {
223-
var rightOperand = pop() as String;
224-
var leftOperand = pop();
225-
if (leftOperand is String && !leftOperand.contains('.')) {
226-
push(PrefixedIdentifier(leftOperand, token, rightOperand));
227-
} else {
228-
push(UnknownExpression());
229-
}
230-
} else {
231-
pop(); // RHS
232-
pop(); // LHS
233-
push(UnknownExpression());
234-
}
222+
pop(); // RHS
223+
pop(); // LHS
224+
push(UnknownExpression());
235225
}
236226

237227
@override
@@ -478,6 +468,25 @@ class MiniAstBuilder extends StackListener {
478468
debugEvent("ClassWithClause");
479469
}
480470

471+
@override
472+
void handleEndingBinaryExpression(Token token, Token endToken) {
473+
debugEvent("EndingBinaryExpression");
474+
475+
if (identical('.', token.stringValue)) {
476+
var rightOperand = pop() as String;
477+
var leftOperand = pop();
478+
if (leftOperand is String && !leftOperand.contains('.')) {
479+
push(PrefixedIdentifier(leftOperand, token, rightOperand));
480+
} else {
481+
push(UnknownExpression());
482+
}
483+
} else {
484+
pop(); // RHS
485+
pop(); // LHS
486+
push(UnknownExpression());
487+
}
488+
}
489+
481490
@override
482491
void handleEnumElement(Token beginToken, Token? augmentToken) {
483492
debugEvent("EnumElement");

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2553,7 +2553,7 @@ class BodyBuilder extends StackListenerImpl
25532553
}
25542554

25552555
@override
2556-
void endBinaryExpression(Token token, Token endToken) {
2556+
void handleEndingBinaryExpression(Token token, Token endToken) {
25572557
assert(checkState(token, [
25582558
unionOfKinds([
25592559
ValueKinds.Expression,
@@ -2566,13 +2566,35 @@ class BodyBuilder extends StackListenerImpl
25662566
token.isA(TokenType.PERIOD_PERIOD) ||
25672567
token.isA(TokenType.QUESTION_PERIOD_PERIOD)) {
25682568
doDotOrCascadeExpression(token);
2569-
} else if (token.isA(TokenType.AMPERSAND_AMPERSAND) ||
2569+
} else if (token.isA(TokenType.QUESTION_PERIOD)) {
2570+
doIfNotNull(token);
2571+
} else {
2572+
throw new UnsupportedError("Unexpected ending binary $token.");
2573+
}
2574+
assert(checkState(token, [
2575+
unionOfKinds([
2576+
ValueKinds.Expression,
2577+
ValueKinds.Generator,
2578+
ValueKinds.Initializer,
2579+
]),
2580+
]));
2581+
}
2582+
2583+
@override
2584+
void endBinaryExpression(Token token, Token endToken) {
2585+
assert(checkState(token, [
2586+
unionOfKinds([
2587+
ValueKinds.Expression,
2588+
ValueKinds.Generator,
2589+
ValueKinds.Selector,
2590+
]),
2591+
]));
2592+
debugEvent("BinaryExpression");
2593+
if (token.isA(TokenType.AMPERSAND_AMPERSAND) ||
25702594
token.isA(TokenType.BAR_BAR)) {
25712595
doLogicalExpression(token);
25722596
} else if (token.isA(TokenType.QUESTION_QUESTION)) {
25732597
doIfNull(token);
2574-
} else if (token.isA(TokenType.QUESTION_PERIOD)) {
2575-
doIfNotNull(token);
25762598
} else {
25772599
doBinaryExpression(token);
25782600
}

pkg/front_end/test/parser/literal_entry_info_test.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,11 @@ class TestInfoListener implements Listener {
915915
calls.add('beginVariableInitializer $token');
916916
}
917917

918+
@override
919+
void handleEndingBinaryExpression(Token token, Token endToken) {
920+
calls.add('handleEndingBinaryExpression $token');
921+
}
922+
918923
@override
919924
void endBinaryExpression(Token token, Token endToken) {
920925
calls.add('endBinaryExpression $token');

0 commit comments

Comments
 (0)