Add spread collection token to scanner
Change-Id: I1932d7c7fa6daba244ad2d93ddc7e2de18100fee
Reviewed-on: https://dart-review.googlesource.com/c/89600
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
index 6ac7640..3377316 100644
--- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
@@ -736,8 +736,20 @@
if (($0 <= next && next <= $9)) {
return tokenizeFractionPart(next, start);
} else if (identical($PERIOD, next)) {
- return select(
- $PERIOD, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
+ next = advance();
+ if (identical(next, $PERIOD)) {
+ next = advance();
+ if (identical(next, $QUESTION)) {
+ appendPrecedenceToken(TokenType.PERIOD_PERIOD_PERIOD_QUESTION);
+ return advance();
+ } else {
+ appendPrecedenceToken(TokenType.PERIOD_PERIOD_PERIOD);
+ return next;
+ }
+ } else {
+ appendPrecedenceToken(TokenType.PERIOD_PERIOD);
+ return next;
+ }
} else {
appendPrecedenceToken(TokenType.PERIOD);
return next;
diff --git a/pkg/front_end/lib/src/fasta/scanner/token_constants.dart b/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
index 6ac1842..f29765c 100644
--- a/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
@@ -87,3 +87,4 @@
const int GENERIC_METHOD_TYPE_ASSIGN_TOKEN = QUESTION_QUESTION_EQ_TOKEN + 1;
const int GENERIC_METHOD_TYPE_LIST_TOKEN = GENERIC_METHOD_TYPE_ASSIGN_TOKEN + 1;
const int GT_GT_GT_TOKEN = GENERIC_METHOD_TYPE_LIST_TOKEN + 1;
+const int PERIOD_PERIOD_PERIOD_QUESTION_TOKEN = GT_GT_GT_TOKEN + 1;
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index 119006f..3b01015 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -1422,6 +1422,12 @@
static const TokenType PERIOD_PERIOD_PERIOD = const TokenType(
'...', 'PERIOD_PERIOD_PERIOD', NO_PRECEDENCE, PERIOD_PERIOD_PERIOD_TOKEN);
+ static const TokenType PERIOD_PERIOD_PERIOD_QUESTION = const TokenType(
+ '...?',
+ 'PERIOD_PERIOD_PERIOD_QUESTION',
+ NO_PRECEDENCE,
+ PERIOD_PERIOD_PERIOD_QUESTION_TOKEN);
+
static const TokenType AS = Keyword.AS;
static const TokenType IS = Keyword.IS;
@@ -1513,6 +1519,7 @@
TokenType.BACKPING,
TokenType.BACKSLASH,
TokenType.PERIOD_PERIOD_PERIOD,
+ TokenType.PERIOD_PERIOD_PERIOD_QUESTION,
// TODO(danrubel): Should these be added to the "all" list?
//TokenType.IS,
diff --git a/pkg/front_end/test/precedence_info_test.dart b/pkg/front_end/test/precedence_info_test.dart
index 3d6ee26..e8fc1eb 100644
--- a/pkg/front_end/test/precedence_info_test.dart
+++ b/pkg/front_end/test/precedence_info_test.dart
@@ -357,6 +357,7 @@
assertName('`', 'BACKPING');
assertName('\\', 'BACKSLASH');
assertName('...', 'PERIOD_PERIOD_PERIOD');
+ assertName('...?', 'PERIOD_PERIOD_PERIOD_QUESTION');
}
/// Assert precedence as per the Dart language spec
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index 4b68911..1305b34 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -324,6 +324,15 @@
}
}
+ void test_spread_operators() {
+ ErrorListener listener = new ErrorListener();
+ Token openBracket = scanWithListener('[ 1, ...[2], ...?[3], ]', listener);
+ Token spreadToken = openBracket.next.next.next;
+ expect(spreadToken.lexeme, '...');
+ Token spreadQToken = spreadToken.next.next.next.next.next;
+ expect(spreadQToken.lexeme, '...?');
+ }
+
@override
void test_unmatched_openers() {
ErrorListener listener = new ErrorListener();