blob: 318f02e817e8223258faefc0ada35fdae3bec19f [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart = 2.9
import 'package:_fe_analyzer_shared/src/parser/parser.dart';
import 'package:_fe_analyzer_shared/src/parser/async_modifier.dart';
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart';
import 'package:front_end/src/fasta/messages.dart';
import 'package:front_end/src/fasta/source/diet_parser.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(CollectionElementTest);
defineReflectiveTests(MapElementTest);
});
}
@reflectiveTest
class CollectionElementTest {
test_closingBrace() {
parseEntry(
'[ }',
[
'handleIdentifier expression',
'handleNoTypeArguments }',
'handleNoArguments }',
'handleSend }',
'handleLiteralList 1, [, null, ]',
],
errors: [error(codeExpectedIdentifier, 2, 1)],
expectAfter: '}',
);
}
test_comma() {
parseEntry(
'[ ,',
[
'handleIdentifier expression',
'handleNoTypeArguments ,',
'handleNoArguments ,',
'handleSend ,',
'handleLiteralList 1, [, null, ]',
],
errors: [error(codeExpectedIdentifier, 2, 1)],
);
}
test_expression() {
parseEntry(
'[ x',
[
'handleIdentifier x expression',
'handleNoTypeArguments ]',
'handleNoArguments ]',
'handleSend x ]',
'handleLiteralList 1, [, null, ]',
],
);
}
test_for() {
parseEntry(
'[ for (var i = 0; i < 10; ++i) 2',
[
'beginForControlFlow null for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration i var',
'handleIdentifier i localVariableDeclaration',
'beginInitializedIdentifier i',
'beginVariableInitializer =',
'handleLiteralInt 0',
'endVariableInitializer =',
'endInitializedIdentifier i',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration 0',
'handleIdentifier i expression',
'handleNoTypeArguments <',
'handleNoArguments <',
'handleSend i <',
'beginBinaryExpression <',
'handleLiteralInt 10',
'endBinaryExpression <',
'handleExpressionStatement ;',
'handleIdentifier i expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend i )',
'handleUnaryPrefixAssignmentExpression ++',
'handleForInitializerExpressionStatement for ( ; 1',
'handleLiteralInt 2',
'endForControlFlow 2',
'handleLiteralList 1, [, null, ]',
],
);
}
test_forForFor() {
parseEntry(
'[ for (var i = 0; i < 10; ++i) for (x in y) for (var a in [6]) 2',
[
// for (var i = 0; i < 10; ++i)
'beginForControlFlow null for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration i var',
'handleIdentifier i localVariableDeclaration',
'beginInitializedIdentifier i',
'beginVariableInitializer =',
'handleLiteralInt 0',
'endVariableInitializer =',
'endInitializedIdentifier i',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration 0',
'handleIdentifier i expression',
'handleNoTypeArguments <',
'handleNoArguments <',
'handleSend i <',
'beginBinaryExpression <',
'handleLiteralInt 10',
'endBinaryExpression <',
'handleExpressionStatement ;',
'handleIdentifier i expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend i )',
'handleUnaryPrefixAssignmentExpression ++',
'handleForInitializerExpressionStatement for ( ; 1',
// nested for (x in y)
'beginForControlFlow null for',
'handleIdentifier x expression',
'handleNoTypeArguments in',
'handleNoArguments in',
'handleSend x in',
'handleForInitializerExpressionStatement x',
'beginForInExpression y',
'handleIdentifier y expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend y )',
'endForInExpression )',
'handleForInLoopParts null for ( in',
// nested for (var a in [6])
'beginForControlFlow null for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration a var',
'handleIdentifier a localVariableDeclaration',
'beginInitializedIdentifier a',
'handleNoVariableInitializer a',
'endInitializedIdentifier a',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration a',
'beginForInExpression [',
'handleNoTypeArguments [',
'handleLiteralInt 6',
'handleLiteralList 1, [, null, ]',
'endForInExpression )',
'handleForInLoopParts null for ( in',
// entry
'handleLiteralInt 2',
// end nested for
'endForInControlFlow 2',
// end nested for
'endForInControlFlow 2',
// end for
'endForControlFlow 2',
'handleLiteralList 1, [, null, ]',
],
);
}
test_forIfForElse() {
parseEntry(
'[ await for (var x in y) if (a) for (b in c) 2 else 7',
[
// await for (var x in y)
'beginForControlFlow await for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration x var',
'handleIdentifier x localVariableDeclaration',
'beginInitializedIdentifier x',
'handleNoVariableInitializer x',
'endInitializedIdentifier x',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration x',
'beginForInExpression y',
'handleIdentifier y expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend y )',
'endForInExpression )',
'handleForInLoopParts await for ( in',
// nested if (a)
'beginIfControlFlow if',
'handleIdentifier a expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend a )',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
// nested for (b in c)
'beginForControlFlow null for',
'handleIdentifier b expression',
'handleNoTypeArguments in',
'handleNoArguments in',
'handleSend b in',
'handleForInitializerExpressionStatement b',
'beginForInExpression c',
'handleIdentifier c expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend c )',
'endForInExpression )',
'handleForInLoopParts null for ( in',
// for-if-for-entry
'handleLiteralInt 2',
// end nested for
'endForInControlFlow 2',
// nested else
'handleElseControlFlow else',
// nested if-else-entry
'handleLiteralInt 7',
// end nested else
'endIfElseControlFlow 7',
// end for
'endForInControlFlow 7',
'handleLiteralList 1, [, null, ]',
],
inAsync: true,
);
}
test_forIn() {
parseEntry(
'[ await for (var x in y) 2',
[
'beginForControlFlow await for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration x var',
'handleIdentifier x localVariableDeclaration',
'beginInitializedIdentifier x',
'handleNoVariableInitializer x',
'endInitializedIdentifier x',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration x',
'beginForInExpression y',
'handleIdentifier y expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend y )',
'endForInExpression )',
'handleForInLoopParts await for ( in',
'handleLiteralInt 2',
'endForInControlFlow 2',
'handleLiteralList 1, [, null, ]',
],
inAsync: true,
);
}
test_forInSpread() {
parseEntry(
'[ for (var x in y) ...[2]',
[
'beginForControlFlow null for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration x var',
'handleIdentifier x localVariableDeclaration',
'beginInitializedIdentifier x',
'handleNoVariableInitializer x',
'endInitializedIdentifier x',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration x',
'beginForInExpression y',
'handleIdentifier y expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend y )',
'endForInExpression )',
'handleForInLoopParts null for ( in',
'handleNoTypeArguments [',
'handleLiteralInt 2',
'handleLiteralList 1, [, null, ]',
'handleSpreadExpression ...',
'endForInControlFlow ]',
'handleLiteralList 1, [, null, ]',
],
);
}
test_forSpreadQ() {
parseEntry(
'[ for (i = 0; i < 10; ++i) ...[2]',
[
'beginForControlFlow null for',
'handleIdentifier i expression',
'handleNoTypeArguments =',
'handleNoArguments =',
'handleSend i =',
'handleLiteralInt 0',
'handleAssignmentExpression =',
'handleForInitializerExpressionStatement 0',
'handleIdentifier i expression',
'handleNoTypeArguments <',
'handleNoArguments <',
'handleSend i <',
'beginBinaryExpression <',
'handleLiteralInt 10',
'endBinaryExpression <',
'handleExpressionStatement ;',
'handleIdentifier i expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend i )',
'handleUnaryPrefixAssignmentExpression ++',
'handleForInitializerExpressionStatement for ( ; 1',
'handleNoTypeArguments [',
'handleLiteralInt 2',
'handleLiteralList 1, [, null, ]',
'handleSpreadExpression ...',
'endForControlFlow ]',
'handleLiteralList 1, [, null, ]',
],
);
}
test_if() {
parseEntry(
'[ if (true) 2',
[
'beginIfControlFlow if',
'handleLiteralBool true',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
'handleLiteralInt 2',
'endIfControlFlow 2',
'handleLiteralList 1, [, null, ]',
],
);
}
test_ifElse() {
parseEntry(
'[ if (true) 2 else 5',
[
'beginIfControlFlow if',
'handleLiteralBool true',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
'handleLiteralInt 2',
'handleElseControlFlow else',
'handleLiteralInt 5',
'endIfElseControlFlow 5',
'handleLiteralList 1, [, null, ]',
],
);
}
test_ifFor() {
parseEntry(
'[ if (true) for (x in y) 2',
[
// if (true)
'beginIfControlFlow if',
'handleLiteralBool true',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
// nested for (x in y)
'beginForControlFlow null for',
'handleIdentifier x expression',
'handleNoTypeArguments in',
'handleNoArguments in',
'handleSend x in',
'handleForInitializerExpressionStatement x',
'beginForInExpression y',
'handleIdentifier y expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend y )',
'endForInExpression )',
'handleForInLoopParts null for ( in',
// if-for-entry
'handleLiteralInt 2',
// end nested for
'endForInControlFlow 2',
// end if
'endIfControlFlow 2',
'handleLiteralList 1, [, null, ]',
],
);
}
test_ifForElseIfFor() {
parseEntry(
'[ if (true) for (a in b) 2 else if (c) for (d in e) 5',
[
// if (true)
'beginIfControlFlow if',
'handleLiteralBool true',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
// nested for (a in b)
'beginForControlFlow null for',
'handleIdentifier a expression',
'handleNoTypeArguments in',
'handleNoArguments in',
'handleSend a in',
'handleForInitializerExpressionStatement a',
'beginForInExpression b',
'handleIdentifier b expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend b )',
'endForInExpression )',
'handleForInLoopParts null for ( in',
// if-for-entry
'handleLiteralInt 2',
// end nested for
'endForInControlFlow 2',
// else
'handleElseControlFlow else',
// nested if (c)
'beginIfControlFlow if',
'handleIdentifier c expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend c )',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
// nested for (d in e)
'beginForControlFlow null for',
'handleIdentifier d expression',
'handleNoTypeArguments in',
'handleNoArguments in',
'handleSend d in',
'handleForInitializerExpressionStatement d',
'beginForInExpression e',
'handleIdentifier e expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend e )',
'endForInExpression )',
'handleForInLoopParts null for ( in',
// else-if-for-entry
'handleLiteralInt 5',
// end nested for
'endForInControlFlow 5',
// end nested if
'endIfControlFlow 5',
// end else
'endIfElseControlFlow 5',
'handleLiteralList 1, [, null, ]',
],
);
}
test_ifSpreadQ() {
parseEntry(
'[ if (true) ...?[2]',
[
'beginIfControlFlow if',
'handleLiteralBool true',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
'handleNoTypeArguments [',
'handleLiteralInt 2',
'handleLiteralList 1, [, null, ]',
'handleSpreadExpression ...?',
'endIfControlFlow ]',
'handleLiteralList 1, [, null, ]',
],
);
}
test_ifElseSpreadQ() {
parseEntry(
'[ if (true) ...?[2] else ... const {5}',
[
'beginIfControlFlow if',
'handleLiteralBool true',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
'handleNoTypeArguments [',
'handleLiteralInt 2',
'handleLiteralList 1, [, null, ]',
'handleSpreadExpression ...?',
'handleElseControlFlow else',
'beginConstLiteral {',
'handleNoTypeArguments {',
'handleLiteralInt 5',
'handleLiteralSetOrMap 1, {, const, }',
'endConstLiteral ]',
'handleSpreadExpression ...',
'endIfElseControlFlow }',
'handleLiteralList 1, [, null, ]',
],
);
}
test_intLiteral() {
parseEntry('[ 1', [
'handleLiteralInt 1',
'handleLiteralList 1, [, null, ]',
]);
}
test_spread() {
parseEntry('[ ...[1]', [
'handleNoTypeArguments [',
'handleLiteralInt 1',
'handleLiteralList 1, [, null, ]',
'handleSpreadExpression ...',
'handleLiteralList 1, [, null, ]',
]);
}
test_spreadQ() {
parseEntry('[ ...?[1]', [
'handleNoTypeArguments [',
'handleLiteralInt 1',
'handleLiteralList 1, [, null, ]',
'handleSpreadExpression ...?',
'handleLiteralList 1, [, null, ]',
]);
}
void parseEntry(String source, List<String> expectedCalls,
{bool inAsync, List<ExpectedError> errors, String expectAfter}) {
final start = scanString(source).tokens;
final listener = new TestInfoListener();
final parser = new Parser(listener,
useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
if (inAsync != null) parser.asyncState = AsyncModifier.Async;
final lastConsumed = parser.parseLiteralListSuffix(start, null);
expect(listener.errors, errors);
try {
expect(listener.calls, expectedCalls, reason: source);
} catch (e) {
listener.calls.forEach((line) => print(" '$line',"));
throw e;
}
if (expectAfter != null) {
expect(lastConsumed.next.lexeme, expectAfter);
} else {
expect(lastConsumed.next.isEof, isTrue, reason: lastConsumed.lexeme);
}
}
}
@reflectiveTest
class MapElementTest {
test_closingBrace() {
parseEntry(
'before }',
[
'handleIdentifier expression',
'handleNoTypeArguments }',
'handleNoArguments }',
'handleSend }',
'handleIdentifier expression',
'handleNoTypeArguments }',
'handleNoArguments }',
'handleSend }',
'handleLiteralMapEntry :, }',
],
errors: [
error(codeExpectedIdentifier, 7, 1),
error(codeExpectedButGot, 7, 1),
error(codeExpectedIdentifier, 7, 1),
],
expectAfter: '}',
);
}
test_comma() {
parseEntry(
'before ,',
[
'handleIdentifier expression',
'handleNoTypeArguments ,',
'handleNoArguments ,',
'handleSend ,',
'handleIdentifier expression',
'handleNoTypeArguments ,',
'handleNoArguments ,',
'handleSend ,',
'handleLiteralMapEntry :, ,',
],
errors: [
error(codeExpectedIdentifier, 7, 1),
error(codeExpectedButGot, 7, 1),
error(codeExpectedIdentifier, 7, 1),
],
expectAfter: ',',
);
}
test_expression() {
parseEntry(
'before x:y',
[
'handleIdentifier x expression',
'handleNoTypeArguments :',
'handleNoArguments :',
'handleSend x :',
'handleIdentifier y expression',
'handleNoTypeArguments ',
'handleNoArguments ',
'handleSend y ',
'handleLiteralMapEntry :, ',
],
);
}
test_for() {
parseEntry(
'before for (var i = 0; i < 10; ++i) 2:3',
[
'beginForControlFlow null for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration i var',
'handleIdentifier i localVariableDeclaration',
'beginInitializedIdentifier i',
'beginVariableInitializer =',
'handleLiteralInt 0',
'endVariableInitializer =',
'endInitializedIdentifier i',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration 0',
'handleIdentifier i expression',
'handleNoTypeArguments <',
'handleNoArguments <',
'handleSend i <',
'beginBinaryExpression <',
'handleLiteralInt 10',
'endBinaryExpression <',
'handleExpressionStatement ;',
'handleIdentifier i expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend i )',
'handleUnaryPrefixAssignmentExpression ++',
'handleForInitializerExpressionStatement for ( ; 1',
'handleLiteralInt 2',
'handleLiteralInt 3',
'handleLiteralMapEntry :, ',
'endForControlFlow 3',
],
);
}
test_forIn() {
parseEntry(
'before await for (var x in y) 2:3',
[
'beginForControlFlow await for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration x var',
'handleIdentifier x localVariableDeclaration',
'beginInitializedIdentifier x',
'handleNoVariableInitializer x',
'endInitializedIdentifier x',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration x',
'beginForInExpression y',
'handleIdentifier y expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend y )',
'endForInExpression )',
'handleForInLoopParts await for ( in',
'handleLiteralInt 2',
'handleLiteralInt 3',
'handleLiteralMapEntry :, ',
'endForInControlFlow 3',
],
inAsync: true,
);
}
test_forInSpread() {
parseEntry(
'before for (var x in y) ...{2:3}',
[
'beginForControlFlow null for',
'beginMetadataStar var',
'endMetadataStar 0',
'handleNoTypeArguments var',
'beginVariablesDeclaration x var',
'handleIdentifier x localVariableDeclaration',
'beginInitializedIdentifier x',
'handleNoVariableInitializer x',
'endInitializedIdentifier x',
'endVariablesDeclaration 1 null',
'handleForInitializerLocalVariableDeclaration x',
'beginForInExpression y',
'handleIdentifier y expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend y )',
'endForInExpression )',
'handleForInLoopParts null for ( in',
'handleNoTypeArguments {',
'handleLiteralInt 2',
'handleLiteralInt 3',
'handleLiteralMapEntry :, }',
'handleLiteralSetOrMap 1, {, null, }',
'handleSpreadExpression ...',
'endForInControlFlow }',
],
);
}
test_forSpreadQ() {
parseEntry(
'before for (i = 0; i < 10; ++i) ...?{2:7}',
[
'beginForControlFlow null for',
'handleIdentifier i expression',
'handleNoTypeArguments =',
'handleNoArguments =',
'handleSend i =',
'handleLiteralInt 0',
'handleAssignmentExpression =',
'handleForInitializerExpressionStatement 0',
'handleIdentifier i expression',
'handleNoTypeArguments <',
'handleNoArguments <',
'handleSend i <',
'beginBinaryExpression <',
'handleLiteralInt 10',
'endBinaryExpression <',
'handleExpressionStatement ;',
'handleIdentifier i expression',
'handleNoTypeArguments )',
'handleNoArguments )',
'handleSend i )',
'handleUnaryPrefixAssignmentExpression ++',
'handleForInitializerExpressionStatement for ( ; 1',
'handleNoTypeArguments {',
'handleLiteralInt 2',
'handleLiteralInt 7',
'handleLiteralMapEntry :, }',
'handleLiteralSetOrMap 1, {, null, }',
'handleSpreadExpression ...?',
'endForControlFlow }',
],
);
}
test_if() {
parseEntry(
'before if (true) 2:3',
[
'beginIfControlFlow if',
'handleLiteralBool true',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
'handleLiteralInt 2',
'handleLiteralInt 3',
'handleLiteralMapEntry :, ',
'endIfControlFlow 3',
],
);
}
test_ifSpread() {
parseEntry(
'before if (true) ...{2:3}',
[
'beginIfControlFlow if',
'handleLiteralBool true',
'handleParenthesizedCondition (',
'handleThenControlFlow )',
'handleNoTypeArguments {',
'handleLiteralInt 2',
'handleLiteralInt 3',
'handleLiteralMapEntry :, }',
'handleLiteralSetOrMap 1, {, null, }',
'handleSpreadExpression ...',
'endIfControlFlow }',
],
);
}
test_intLiteral() {
parseEntry('before 1:2', [
'handleLiteralInt 1',
'handleLiteralInt 2',
'handleLiteralMapEntry :, ',
]);
}
test_spread() {
parseEntry('before ...const {1:2}', [
'beginConstLiteral {',
'handleNoTypeArguments {',
'handleLiteralInt 1',
'handleLiteralInt 2',
'handleLiteralMapEntry :, }',
'handleLiteralSetOrMap 1, {, const, }',
'endConstLiteral ',
'handleSpreadExpression ...',
]);
}
test_spreadQ() {
parseEntry('before ...?const {1:3}', [
'beginConstLiteral {',
'handleNoTypeArguments {',
'handleLiteralInt 1',
'handleLiteralInt 3',
'handleLiteralMapEntry :, }',
'handleLiteralSetOrMap 1, {, const, }',
'endConstLiteral ',
'handleSpreadExpression ...?',
]);
}
void parseEntry(String source, List<String> expectedCalls,
{bool inAsync, List<ExpectedError> errors, String expectAfter}) {
final start = scanString(source).tokens;
final listener = new TestInfoListener();
final parser = new Parser(listener,
useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
if (inAsync != null) parser.asyncState = AsyncModifier.Async;
final lastConsumed = parser.parseMapLiteralEntry(start);
expect(listener.errors, errors);
try {
expect(listener.calls, expectedCalls, reason: source);
} catch (e) {
listener.calls.forEach((line) => print(" '$line',"));
throw e;
}
if (expectAfter != null) {
expect(lastConsumed.next.lexeme, expectAfter);
} else {
expect(lastConsumed.next.isEof, isTrue, reason: lastConsumed.lexeme);
}
}
}
class TestInfoListener implements Listener {
List<String> calls = <String>[];
List<ExpectedError> errors;
@override
void beginBinaryExpression(Token token) {
calls.add('beginBinaryExpression $token');
}
@override
void beginConstLiteral(Token token) {
calls.add('beginConstLiteral $token');
}
@override
void beginForControlFlow(Token awaitToken, Token forToken) {
calls.add('beginForControlFlow $awaitToken $forToken');
}
@override
void beginForInExpression(Token token) {
calls.add('beginForInExpression $token');
}
@override
void beginIfControlFlow(Token ifToken) {
calls.add('beginIfControlFlow $ifToken');
}
@override
void handleThenControlFlow(Token token) {
calls.add('handleThenControlFlow $token');
}
@override
void beginInitializedIdentifier(Token token) {
calls.add('beginInitializedIdentifier $token');
}
@override
void beginMetadataStar(Token token) {
calls.add('beginMetadataStar $token');
}
@override
void beginVariablesDeclaration(
Token token, Token lateToken, Token varFinalOrConst) {
// TODO(danrubel): update to include lateToken
calls.add('beginVariablesDeclaration $token $varFinalOrConst');
}
@override
void beginVariableInitializer(Token token) {
calls.add('beginVariableInitializer $token');
}
@override
void endBinaryExpression(Token token) {
calls.add('endBinaryExpression $token');
}
@override
void endConstLiteral(Token token) {
calls.add('endConstLiteral $token');
}
@override
void endForControlFlow(Token token) {
calls.add('endForControlFlow $token');
}
@override
void endForInControlFlow(Token token) {
calls.add('endForInControlFlow $token');
}
@override
void endForInExpression(Token token) {
calls.add('endForInExpression $token');
}
@override
void endIfControlFlow(Token token) {
calls.add('endIfControlFlow $token');
}
@override
void endIfElseControlFlow(Token token) {
calls.add('endIfElseControlFlow $token');
}
@override
void endInitializedIdentifier(Token nameToken) {
calls.add('endInitializedIdentifier $nameToken');
}
@override
void endMetadataStar(int count) {
calls.add('endMetadataStar $count');
}
@override
void endVariablesDeclaration(int count, Token endToken) {
calls.add('endVariablesDeclaration $count $endToken');
}
@override
void endVariableInitializer(Token assignmentOperator) {
calls.add('endVariableInitializer $assignmentOperator');
}
@override
void handleAssignmentExpression(Token token) {
calls.add('handleAssignmentExpression $token');
}
@override
void handleElseControlFlow(Token elseToken) {
calls.add('handleElseControlFlow $elseToken');
}
@override
void handleExpressionStatement(Token token) {
calls.add('handleExpressionStatement $token');
}
@override
void handleForInitializerExpressionStatement(Token token, bool forIn) {
calls.add('handleForInitializerExpressionStatement $token');
}
@override
void handleForInitializerLocalVariableDeclaration(Token token, bool forIn) {
calls.add('handleForInitializerLocalVariableDeclaration $token');
}
@override
void handleForInLoopParts(Token awaitToken, Token forToken,
Token leftParenthesis, Token inKeyword) {
calls.add('handleForInLoopParts '
'$awaitToken $forToken $leftParenthesis $inKeyword');
}
@override
void handleForLoopParts(Token forKeyword, Token leftParen,
Token leftSeparator, int updateExpressionCount) {
calls.add('handleForInitializerExpressionStatement '
'$forKeyword $leftParen $leftSeparator $updateExpressionCount');
}
@override
void handleIdentifier(Token token, IdentifierContext context) {
calls.add('handleIdentifier $token $context');
}
@override
void handleLiteralBool(Token token) {
calls.add('handleLiteralBool $token');
}
@override
void handleLiteralInt(Token token) {
calls.add('handleLiteralInt $token');
}
@override
void handleLiteralList(
int count, Token leftBracket, Token constKeyword, Token rightBracket) {
calls.add(
'handleLiteralList $count, $leftBracket, $constKeyword, $rightBracket');
}
@override
void handleLiteralSetOrMap(
int count,
Token leftBrace,
Token constKeyword,
Token rightBrace,
// TODO(danrubel): hasSetEntry parameter exists for replicating existing
// behavior and will be removed once unified collection has been enabled
bool hasSetEntry,
) {
calls.add(
'handleLiteralSetOrMap $count, $leftBrace, $constKeyword, $rightBrace');
}
@override
void handleLiteralMapEntry(Token colon, Token endToken) {
calls.add('handleLiteralMapEntry $colon, $endToken');
}
@override
void handleNoArguments(Token token) {
calls.add('handleNoArguments $token');
}
@override
void handleParenthesizedCondition(Token token) {
calls.add('handleParenthesizedCondition $token');
}
@override
void handleNoType(Token lastConsumed) {
calls.add('handleNoTypeArguments $lastConsumed');
}
@override
void handleNoTypeArguments(Token token) {
calls.add('handleNoTypeArguments $token');
}
@override
void handleNoVariableInitializer(Token token) {
calls.add('handleNoVariableInitializer $token');
}
@override
void handleRecoverableError(
Message message, Token startToken, Token endToken) {
errors ??= <ExpectedError>[];
int offset = startToken.charOffset;
errors.add(error(message.code, offset, endToken.charEnd - offset));
}
@override
void handleSend(Token beginToken, Token endToken) {
calls.add('handleSend $beginToken $endToken');
}
@override
void handleSpreadExpression(Token spreadToken) {
calls.add('handleSpreadExpression $spreadToken');
}
@override
void handleUnaryPrefixAssignmentExpression(Token token) {
calls.add('handleUnaryPrefixAssignmentExpression $token');
}
noSuchMethod(Invocation invocation) {
throw '${invocation.memberName} should not be called.';
}
}
ExpectedError error(Code code, int start, int length) =>
new ExpectedError(code, start, length);
class ExpectedError {
final Code code;
final int start;
final int length;
ExpectedError(this.code, this.start, this.length);
@override
bool operator ==(other) =>
other is ExpectedError &&
code == other.code &&
start == other.start &&
length == other.length;
@override
String toString() => 'error(code${code.name}, $start, $length)';
}