Add set literal spread collection parsing support
Change-Id: I12f4675a3a034a82acc16c4d189b001d52c23039
Reviewed-on: https://dart-review.googlesource.com/c/89681
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 44249b8..b4e158e 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -328,6 +328,58 @@
expect(value2.value, 6);
}
+ void test_setLiteral_spread_typed() {
+ // TODO(danrubel): Revise this once AST supports new syntax
+ SetLiteral set = parseExpression('<int>{...[3]}',
+ parseSetLiterals: true,
+ errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 6, 3)]);
+ expect(set.constKeyword, isNull);
+ expect(set.typeArguments, isNotNull);
+ expect(set.elements, hasLength(1));
+ ListLiteral list = set.elements[0];
+ expect(list.elements, hasLength(1));
+ }
+
+ void test_setLiteral_spreadQ_typed() {
+ // TODO(danrubel): Revise this once AST supports new syntax
+ SetLiteral set = parseExpression('<int>{...?[3]}',
+ parseSetLiterals: true,
+ errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 6, 4)]);
+ expect(set.constKeyword, isNull);
+ expect(set.typeArguments, isNotNull);
+ expect(set.elements, hasLength(1));
+ ListLiteral list = set.elements[0];
+ expect(list.elements, hasLength(1));
+ }
+
+ void test_setLiteral_spread2() {
+ // TODO(danrubel): Revise this once AST supports new syntax
+ SetLiteral set = parseExpression('{3, ...[4]}',
+ parseSetLiterals: true,
+ errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 3)]);
+ expect(set.constKeyword, isNull);
+ expect(set.typeArguments, isNull);
+ expect(set.elements, hasLength(2));
+ IntegerLiteral value = set.elements[0];
+ expect(value.value, 3);
+ ListLiteral list = set.elements[1];
+ expect(list.elements, hasLength(1));
+ }
+
+ void test_setLiteral_spread2Q() {
+ // TODO(danrubel): Revise this once AST supports new syntax
+ SetLiteral set = parseExpression('{3, ...?[4]}',
+ parseSetLiterals: true,
+ errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 4)]);
+ expect(set.constKeyword, isNull);
+ expect(set.typeArguments, isNull);
+ expect(set.elements, hasLength(2));
+ IntegerLiteral value = set.elements[0];
+ expect(value.value, 3);
+ ListLiteral list = set.elements[1];
+ expect(list.elements, hasLength(1));
+ }
+
void test_setLiteral_const_typeArgument() {
SetLiteral set = parseExpression('const <int>{3}', parseSetLiterals: true);
expect(set.constKeyword, isNotNull);
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 6ab177a..48e16d1 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -4186,12 +4186,7 @@
token = next;
break;
}
- if (optional('...', next) || optional('...?', next)) {
- token = parseExpression(token.next);
- listener.handleSpreadExpression(next);
- } else {
- token = parseExpression(token);
- }
+ token = parseSpreadExpressionOrExpression(token);
next = token.next;
++count;
if (!optional(',', next)) {
@@ -4228,6 +4223,17 @@
return token;
}
+ Token parseSpreadExpressionOrExpression(Token token) {
+ Token next = token.next;
+ if (optional('...', next) || optional('...?', next)) {
+ token = parseExpression(token.next);
+ listener.handleSpreadExpression(next);
+ } else {
+ token = parseExpression(token);
+ }
+ return token;
+ }
+
/// This method parses the portion of a set or map literal that starts with
/// the left curly brace when there are no leading type arguments.
Token parseLiteralSetOrMapSuffix(final Token start, Token constKeyword) {
@@ -4369,7 +4375,7 @@
bool old = mayParseFunctionExpressions;
mayParseFunctionExpressions = true;
- token = parseExpression(token);
+ token = parseSpreadExpressionOrExpression(token);
mayParseFunctionExpressions = old;
return parseLiteralSetRest(token, constKeyword, beginToken);
@@ -4408,7 +4414,7 @@
break;
}
}
- token = parseExpression(token);
+ token = parseSpreadExpressionOrExpression(token);
++count;
}
assert(optional('}', token));