blob: e577850c8af88456957133d4f36dfe6f5e3a6ed7 [file] [log] [blame]
// Copyright (c) 2014, 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.
library analyzer.test.generated.parser_test;
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'test_support.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ClassMemberParserTest);
defineReflectiveTests(ComplexParserTest);
defineReflectiveTests(ErrorParserTest);
defineReflectiveTests(ExpressionParserTest);
defineReflectiveTests(FormalParameterParserTest);
defineReflectiveTests(NonErrorParserTest);
defineReflectiveTests(RecoveryParserTest);
defineReflectiveTests(SimpleParserTest);
defineReflectiveTests(StatementParserTest);
defineReflectiveTests(TopLevelParserTest);
});
}
/**
* Abstract base class for parser tests, which does not make assumptions about
* which parser is used.
*/
abstract class AbstractParserTestCase implements ParserTestHelpers {
void set enableAssertInitializer(bool value);
void set enableGenericMethodComments(bool value);
void set enableLazyAssignmentOperators(bool value);
void set enableNnbd(bool value);
/**
* Set a flag indicating whether the parser is to parse part-of directives
* that specify a URI rather than a library name.
*/
void set enableUriInPartOf(bool value);
/**
* Get the parser used by the test.
*
* Caller must first invoke [createParser].
*/
Parser get parser;
/**
* Assert that the number and codes of errors occurred during parsing is the
* same the the [expectedErrorCodes].
*/
void assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes);
/**
* Asserts that no errors occurred during parsing.
*/
void assertNoErrors();
/**
* Prepares to parse using tokens scanned from the given [content] string.
*/
void createParser(String content);
Expression parseAdditiveExpression(String code);
Expression parseAssignableExpression(String code, bool primaryAllowed);
Expression parseAssignableSelector(String code, bool optional,
{bool allowConditional: true});
AwaitExpression parseAwaitExpression(String code);
Expression parseBitwiseAndExpression(String code);
Expression parseBitwiseOrExpression(String code);
Expression parseBitwiseXorExpression(String code);
Expression parseCascadeSection(String code);
CompilationUnit parseCompilationUnit(String source,
[List<ErrorCode> errorCodes = const <ErrorCode>[]]);
/// TODO(paulberry): merge with [parseCompilationUnit]
CompilationUnit parseCompilationUnitWithOptions(String source,
[List<ErrorCode> errorCodes = const <ErrorCode>[]]);
ConditionalExpression parseConditionalExpression(String code);
Expression parseConstExpression(String code);
ConstructorInitializer parseConstructorInitializer(String code);
/**
* Parse the given source as a compilation unit.
*
* @param source the source to be parsed
* @param errorCodes the error codes of the errors that are expected to be found
* @return the compilation unit that was parsed
* @throws Exception if the source could not be parsed, if the compilation errors in the source do
* not match those that are expected, or if the result would have been `null`
*/
CompilationUnit parseDirectives(String source,
[List<ErrorCode> errorCodes = const <ErrorCode>[]]);
BinaryExpression parseEqualityExpression(String code);
Expression parseExpression(String source,
[List<ErrorCode> errorCodes = const <ErrorCode>[]]);
List<Expression> parseExpressionList(String code);
Expression parseExpressionWithoutCascade(String code);
FormalParameter parseFormalParameter(String code, ParameterKind kind,
{List<ErrorCode> errorCodes: const <ErrorCode>[]});
FormalParameterList parseFormalParameterList(String code,
{bool inFunctionType: false,
List<ErrorCode> errorCodes: const <ErrorCode>[]});
/**
* Parses a single top level member of a compilation unit (other than a
* directive), including any comment and/or metadata that precedes it.
*/
CompilationUnitMember parseFullCompilationUnitMember();
/**
* Parses a single top level directive, including any comment and/or metadata
* that precedes it.
*/
Directive parseFullDirective();
FunctionExpression parseFunctionExpression(String code);
InstanceCreationExpression parseInstanceCreationExpression(
String code, Token newToken);
ListLiteral parseListLiteral(
Token token, String typeArgumentsCode, String code);
TypedLiteral parseListOrMapLiteral(Token modifier, String code);
Expression parseLogicalAndExpression(String code);
Expression parseLogicalOrExpression(String code);
MapLiteral parseMapLiteral(
Token token, String typeArgumentsCode, String code);
MapLiteralEntry parseMapLiteralEntry(String code);
Expression parseMultiplicativeExpression(String code);
InstanceCreationExpression parseNewExpression(String code);
NormalFormalParameter parseNormalFormalParameter(String code,
{bool inFunctionType: false});
Expression parsePostfixExpression(String code);
Identifier parsePrefixedIdentifier(String code);
Expression parsePrimaryExpression(String code);
Expression parseRelationalExpression(String code);
RethrowExpression parseRethrowExpression(String code);
BinaryExpression parseShiftExpression(String code);
SimpleIdentifier parseSimpleIdentifier(String code);
Statement parseStatement(String source, [bool enableLazyAssignmentOperators]);
Expression parseStringLiteral(String code);
SymbolLiteral parseSymbolLiteral(String code);
Expression parseThrowExpression(String code);
Expression parseThrowExpressionWithoutCascade(String code);
PrefixExpression parseUnaryExpression(String code);
}
/**
* Instances of the class `AstValidator` are used to validate the correct construction of an
* AST structure.
*/
class AstValidator extends UnifyingAstVisitor<Object> {
/**
* A list containing the errors found while traversing the AST structure.
*/
List<String> _errors = new List<String>();
/**
* Assert that no errors were found while traversing any of the AST structures that have been
* visited.
*/
void assertValid() {
if (!_errors.isEmpty) {
StringBuffer buffer = new StringBuffer();
buffer.write("Invalid AST structure:");
for (String message in _errors) {
buffer.write("\r\n ");
buffer.write(message);
}
fail(buffer.toString());
}
}
@override
Object visitNode(AstNode node) {
_validate(node);
return super.visitNode(node);
}
/**
* Validate that the given AST node is correctly constructed.
*
* @param node the AST node being validated
*/
void _validate(AstNode node) {
AstNode parent = node.parent;
if (node is CompilationUnit) {
if (parent != null) {
_errors.add("Compilation units should not have a parent");
}
} else {
if (parent == null) {
_errors.add("No parent for ${node.runtimeType}");
}
}
if (node.beginToken == null) {
_errors.add("No begin token for ${node.runtimeType}");
}
if (node.endToken == null) {
_errors.add("No end token for ${node.runtimeType}");
}
int nodeStart = node.offset;
int nodeLength = node.length;
if (nodeStart < 0 || nodeLength < 0) {
_errors.add("No source info for ${node.runtimeType}");
}
if (parent != null) {
int nodeEnd = nodeStart + nodeLength;
int parentStart = parent.offset;
int parentEnd = parentStart + parent.length;
if (nodeStart < parentStart) {
_errors.add(
"Invalid source start ($nodeStart) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
}
if (nodeEnd > parentEnd) {
_errors.add(
"Invalid source end ($nodeEnd) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
}
}
}
}
@reflectiveTest
class ClassMemberParserTest extends ParserTestCase
with ClassMemberParserTestMixin {}
/**
* Tests which exercise the parser using a class member.
*/
abstract class ClassMemberParserTestMixin implements AbstractParserTestCase {
void test_parseAwaitExpression_asStatement_inAsync() {
createParser('m() async { await x; }');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
FunctionBody body = method.body;
EngineTestCase.assertInstanceOf(
(obj) => obj is BlockFunctionBody, BlockFunctionBody, body);
Statement statement = (body as BlockFunctionBody).block.statements[0];
EngineTestCase.assertInstanceOf(
(obj) => obj is ExpressionStatement, ExpressionStatement, statement);
Expression expression = (statement as ExpressionStatement).expression;
EngineTestCase.assertInstanceOf(
(obj) => obj is AwaitExpression, AwaitExpression, expression);
expect((expression as AwaitExpression).awaitKeyword, isNotNull);
expect((expression as AwaitExpression).expression, isNotNull);
}
void test_parseAwaitExpression_asStatement_inSync() {
createParser('m() { await x; }');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
FunctionBody body = method.body;
EngineTestCase.assertInstanceOf(
(obj) => obj is BlockFunctionBody, BlockFunctionBody, body);
Statement statement = (body as BlockFunctionBody).block.statements[0];
EngineTestCase.assertInstanceOf(
(obj) => obj is VariableDeclarationStatement,
VariableDeclarationStatement,
statement);
}
@failingTest
void test_parseAwaitExpression_inSync() {
// This test requires better error recovery than we currently have. In
// particular, we need to be able to distinguish between an await expression
// in the wrong context, and the use of 'await' as an identifier.
createParser('m() { return await x + await y; }');
MethodDeclaration method = parser.parseClassMember('C');
expect(method, isNotNull);
assertNoErrors();
FunctionBody body = method.body;
EngineTestCase.assertInstanceOf(
(obj) => obj is BlockFunctionBody, BlockFunctionBody, body);
Statement statement = (body as BlockFunctionBody).block.statements[0];
EngineTestCase.assertInstanceOf(
(obj) => obj is ReturnStatement, ReturnStatement, statement);
Expression expression = (statement as ReturnStatement).expression;
EngineTestCase.assertInstanceOf(
(obj) => obj is BinaryExpression, BinaryExpression, expression);
EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
AwaitExpression, (expression as BinaryExpression).leftOperand);
EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
AwaitExpression, (expression as BinaryExpression).rightOperand);
}
void test_parseClassMember_constructor_withDocComment() {
createParser('/// Doc\nC();');
var constructor = parser.parseClassMember('C') as ConstructorDeclaration;
expectCommentText(constructor.documentationComment, '/// Doc');
}
void test_parseClassMember_constructor_withInitializers() {
// TODO(brianwilkerson) Test other kinds of class members: fields, getters
// and setters.
createParser('C(_, _\$, this.__) : _a = _ + _\$ {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<ConstructorDeclaration>());
ConstructorDeclaration constructor = member;
expect(constructor.body, isNotNull);
expect(constructor.separator, isNotNull);
expect(constructor.externalKeyword, isNull);
expect(constructor.constKeyword, isNull);
expect(constructor.factoryKeyword, isNull);
expect(constructor.name, isNull);
expect(constructor.parameters, isNotNull);
expect(constructor.period, isNull);
expect(constructor.returnType, isNotNull);
expect(constructor.initializers, hasLength(1));
}
void test_parseClassMember_field_covariant() {
createParser('covariant T f;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<FieldDeclaration>());
FieldDeclaration field = member;
expect(field.covariantKeyword, isNotNull);
expect(field.documentationComment, isNull);
expect(field.metadata, hasLength(0));
expect(field.staticKeyword, isNull);
VariableDeclarationList list = field.fields;
expect(list, isNotNull);
NodeList<VariableDeclaration> variables = list.variables;
expect(variables, hasLength(1));
VariableDeclaration variable = variables[0];
expect(variable.name, isNotNull);
}
void test_parseClassMember_field_instance_prefixedType() {
createParser('p.A f;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<FieldDeclaration>());
FieldDeclaration field = member;
expect(field.covariantKeyword, isNull);
expect(field.documentationComment, isNull);
expect(field.metadata, hasLength(0));
expect(field.staticKeyword, isNull);
VariableDeclarationList list = field.fields;
expect(list, isNotNull);
NodeList<VariableDeclaration> variables = list.variables;
expect(variables, hasLength(1));
VariableDeclaration variable = variables[0];
expect(variable.name, isNotNull);
_assertIsDeclarationName(variable.name);
}
void test_parseClassMember_field_namedGet() {
createParser('var get;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<FieldDeclaration>());
FieldDeclaration field = member;
expect(field.covariantKeyword, isNull);
expect(field.documentationComment, isNull);
expect(field.metadata, hasLength(0));
expect(field.staticKeyword, isNull);
VariableDeclarationList list = field.fields;
expect(list, isNotNull);
NodeList<VariableDeclaration> variables = list.variables;
expect(variables, hasLength(1));
VariableDeclaration variable = variables[0];
expect(variable.name, isNotNull);
}
void test_parseClassMember_field_namedOperator() {
createParser('var operator;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<FieldDeclaration>());
FieldDeclaration field = member;
expect(field.covariantKeyword, isNull);
expect(field.documentationComment, isNull);
expect(field.metadata, hasLength(0));
expect(field.staticKeyword, isNull);
VariableDeclarationList list = field.fields;
expect(list, isNotNull);
NodeList<VariableDeclaration> variables = list.variables;
expect(variables, hasLength(1));
VariableDeclaration variable = variables[0];
expect(variable.name, isNotNull);
}
void test_parseClassMember_field_namedOperator_withAssignment() {
createParser('var operator = (5);');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<FieldDeclaration>());
FieldDeclaration field = member;
expect(field.covariantKeyword, isNull);
expect(field.documentationComment, isNull);
expect(field.metadata, hasLength(0));
expect(field.staticKeyword, isNull);
VariableDeclarationList list = field.fields;
expect(list, isNotNull);
NodeList<VariableDeclaration> variables = list.variables;
expect(variables, hasLength(1));
VariableDeclaration variable = variables[0];
expect(variable.name, isNotNull);
expect(variable.initializer, isNotNull);
}
void test_parseClassMember_field_namedSet() {
createParser('var set;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<FieldDeclaration>());
FieldDeclaration field = member;
expect(field.covariantKeyword, isNull);
expect(field.documentationComment, isNull);
expect(field.metadata, hasLength(0));
expect(field.staticKeyword, isNull);
VariableDeclarationList list = field.fields;
expect(list, isNotNull);
NodeList<VariableDeclaration> variables = list.variables;
expect(variables, hasLength(1));
VariableDeclaration variable = variables[0];
expect(variable.name, isNotNull);
}
void test_parseClassMember_field_static() {
createParser('static A f;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<FieldDeclaration>());
FieldDeclaration field = member;
expect(field.covariantKeyword, isNull);
expect(field.documentationComment, isNull);
expect(field.metadata, hasLength(0));
expect(field.staticKeyword, isNotNull);
VariableDeclarationList list = field.fields;
expect(list, isNotNull);
NodeList<VariableDeclaration> variables = list.variables;
expect(variables, hasLength(1));
VariableDeclaration variable = variables[0];
expect(variable.name, isNotNull);
}
void test_parseClassMember_getter_functionType() {
createParser('int Function(int) get g {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNotNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.body, isNotNull);
expect(method.parameters, isNull);
}
void test_parseClassMember_getter_void() {
createParser('void get g {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNotNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
_assertIsDeclarationName(method.name);
expect(method.operatorKeyword, isNull);
expect(method.body, isNotNull);
expect(method.parameters, isNull);
}
void test_parseClassMember_method_external() {
createParser('external m();');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNotNull);
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
_assertIsDeclarationName(method.name);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNull);
var body = method.body as EmptyFunctionBody;
expect(body.keyword, isNull);
expect(body.star, isNull);
expect(body.semicolon.type, TokenType.SEMICOLON);
}
void test_parseClassMember_method_external_withTypeAndArgs() {
createParser('external int m(int a);');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.body, isNotNull);
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNotNull);
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
}
void test_parseClassMember_method_generic_comment_noReturnType() {
enableGenericMethodComments = true;
createParser('m/*<T>*/() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNotNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_generic_comment_returnType() {
enableGenericMethodComments = true;
createParser('/*=T*/ m/*<T>*/() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect((method.returnType as TypeName).name.name, 'T');
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNotNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_generic_comment_returnType_bound() {
enableGenericMethodComments = true;
createParser('num/*=T*/ m/*<T extends num>*/() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect((method.returnType as TypeName).name.name, 'T');
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNotNull);
TypeParameter tp = method.typeParameters.typeParameters[0];
expect(tp.name.name, 'T');
expect(tp.extendsKeyword, isNotNull);
expect((tp.bound as TypeName).name.name, 'num');
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_generic_comment_void() {
enableGenericMethodComments = true;
createParser('void m/*<T>*/() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNotNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_generic_noReturnType() {
createParser('m<T>() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNotNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_generic_returnType() {
createParser('T m<T>() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNotNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_generic_void() {
createParser('void m<T>() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNotNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_get_noType() {
createParser('get() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_get_type() {
createParser('int get() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_get_void() {
createParser('void get() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_operator_noType() {
createParser('operator() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_operator_type() {
createParser('int operator() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_operator_void() {
createParser('void operator() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_returnType_functionType() {
createParser('int Function(String) m() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.name.name, 'm');
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_returnType_parameterized() {
createParser('p.A m() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_set_noType() {
createParser('set() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_set_type() {
createParser('int set() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_set_void() {
createParser('void set() {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_method_trailing_commas() {
createParser('void f(int x, int y,) {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_operator_functionType() {
createParser('int Function() operator +(int Function() f) {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, new isInstanceOf<GenericFunctionType>());
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNotNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
NodeList<FormalParameter> parameters = method.parameters.parameters;
expect(parameters, hasLength(1));
expect((parameters[0] as SimpleFormalParameter).type,
new isInstanceOf<GenericFunctionType>());
expect(method.body, isNotNull);
}
void test_parseClassMember_operator_index() {
createParser('int operator [](int i) {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNotNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_operator_indexAssign() {
createParser('int operator []=(int i) {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<MethodDeclaration>());
MethodDeclaration method = member;
expect(method.documentationComment, isNull);
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNotNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
void test_parseClassMember_redirectingFactory_const() {
createParser('const factory C() = prefix.B.foo;');
var constructor = parser.parseClassMember('C') as ConstructorDeclaration;
assertNoErrors();
expect(constructor, isNotNull);
expect(constructor.externalKeyword, isNull);
expect(constructor.constKeyword.keyword, Keyword.CONST);
expect(constructor.factoryKeyword.keyword, Keyword.FACTORY);
expect(constructor.returnType.name, 'C');
expect(constructor.period, isNull);
expect(constructor.name, isNull);
_assertIsDeclarationName(constructor.returnType, false);
expect(constructor.parameters, isNotNull);
expect(constructor.parameters.parameters, isEmpty);
expect(constructor.separator.type, TokenType.EQ);
expect(constructor.initializers, isEmpty);
expect(constructor.redirectedConstructor, isNotNull);
expect(constructor.redirectedConstructor.type.name.name, 'prefix.B');
expect(constructor.redirectedConstructor.period.type, TokenType.PERIOD);
expect(constructor.redirectedConstructor.name.name, 'foo');
expect(constructor.body, new isInstanceOf<EmptyFunctionBody>());
}
void test_parseClassMember_redirectingFactory_expressionBody() {
createParser('factory C() => null;');
var constructor = parser.parseClassMember('C') as ConstructorDeclaration;
assertNoErrors();
expect(constructor, isNotNull);
expect(constructor.externalKeyword, isNull);
expect(constructor.constKeyword, isNull);
expect(constructor.factoryKeyword.keyword, Keyword.FACTORY);
expect(constructor.returnType.name, 'C');
expect(constructor.period, isNull);
expect(constructor.name, isNull);
expect(constructor.parameters, isNotNull);
expect(constructor.parameters.parameters, isEmpty);
expect(constructor.separator, isNull);
expect(constructor.initializers, isEmpty);
expect(constructor.redirectedConstructor, isNull);
var body = constructor.body as ExpressionFunctionBody;
expect(body.keyword, isNull);
expect(body.star, isNull);
expect(body.functionDefinition.type, TokenType.FUNCTION);
expect(body.expression, isNotNull);
expect(body.semicolon, isNotNull);
}
void test_parseClassMember_redirectingFactory_nonConst() {
createParser('factory C() = B;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<ConstructorDeclaration>());
ConstructorDeclaration constructor = member;
expect(constructor.externalKeyword, isNull);
expect(constructor.constKeyword, isNull);
expect(constructor.factoryKeyword.keyword, Keyword.FACTORY);
expect(constructor.returnType.name, 'C');
_assertIsDeclarationName(constructor.returnType, false);
expect(constructor.period, isNull);
expect(constructor.name, isNull);
expect(constructor.parameters, isNotNull);
expect(constructor.parameters.parameters, isEmpty);
expect(constructor.separator.type, TokenType.EQ);
expect(constructor.initializers, isEmpty);
expect(constructor.redirectedConstructor, isNotNull);
expect(constructor.redirectedConstructor.type.name.name, 'B');
expect(constructor.redirectedConstructor.period, isNull);
expect(constructor.redirectedConstructor.name, isNull);
expect(constructor.body, new isInstanceOf<EmptyFunctionBody>());
}
void test_parseConstructor_assert() {
enableAssertInitializer = true;
createParser('C(x, y) : _x = x, assert (x < y), _y = y;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<ConstructorDeclaration>());
ConstructorDeclaration constructor = member as ConstructorDeclaration;
NodeList<ConstructorInitializer> initializers = constructor.initializers;
expect(initializers, hasLength(3));
ConstructorInitializer initializer = initializers[1];
expect(initializer, new isInstanceOf<AssertInitializer>());
AssertInitializer assertInitializer = initializer;
expect(assertInitializer.condition, isNotNull);
expect(assertInitializer.message, isNull);
}
void test_parseConstructor_initializers_field() {
createParser('C(x, y) : _x = x, this._y = y;');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<ConstructorDeclaration>());
ConstructorDeclaration constructor = member as ConstructorDeclaration;
NodeList<ConstructorInitializer> initializers = constructor.initializers;
expect(initializers, hasLength(2));
{
var initializer = initializers[0] as ConstructorFieldInitializer;
expect(initializer.thisKeyword, isNull);
expect(initializer.period, isNull);
expect(initializer.fieldName.name, '_x');
expect(initializer.expression, isNotNull);
}
{
var initializer = initializers[1] as ConstructorFieldInitializer;
expect(initializer.thisKeyword, isNotNull);
expect(initializer.period, isNotNull);
expect(initializer.fieldName.name, '_y');
expect(initializer.expression, isNotNull);
}
}
void test_parseConstructor_named() {
createParser('C.foo();');
var constructor = parser.parseClassMember('C') as ConstructorDeclaration;
assertNoErrors();
expect(constructor, isNotNull);
expect(constructor.externalKeyword, isNull);
expect(constructor.constKeyword, isNull);
expect(constructor.factoryKeyword, isNull);
expect(constructor.returnType.name, 'C');
_assertIsDeclarationName(constructor.returnType, false);
expect(constructor.period.type, TokenType.PERIOD);
expect(constructor.name.name, 'foo');
_assertIsDeclarationName(constructor.name);
expect(constructor.parameters, isNotNull);
expect(constructor.parameters.parameters, isEmpty);
expect(constructor.separator, isNull);
expect(constructor.initializers, isEmpty);
expect(constructor.redirectedConstructor, isNull);
expect(constructor.body, new isInstanceOf<EmptyFunctionBody>());
}
void test_parseConstructor_unnamed() {
createParser('C();');
var constructor = parser.parseClassMember('C') as ConstructorDeclaration;
assertNoErrors();
expect(constructor, isNotNull);
expect(constructor.externalKeyword, isNull);
expect(constructor.constKeyword, isNull);
expect(constructor.factoryKeyword, isNull);
expect(constructor.returnType.name, 'C');
_assertIsDeclarationName(constructor.returnType, false);
expect(constructor.period, isNull);
expect(constructor.name, isNull);
expect(constructor.parameters, isNotNull);
expect(constructor.parameters.parameters, isEmpty);
expect(constructor.separator, isNull);
expect(constructor.initializers, isEmpty);
expect(constructor.redirectedConstructor, isNull);
expect(constructor.body, new isInstanceOf<EmptyFunctionBody>());
}
void test_parseConstructor_with_pseudo_function_literal() {
// "(b) {}" should not be misinterpreted as a function literal even though
// it looks like one.
createParser('C() : a = (b) {}');
ClassMember member = parser.parseClassMember('C');
expect(member, isNotNull);
assertNoErrors();
expect(member, new isInstanceOf<ConstructorDeclaration>());
ConstructorDeclaration constructor = member as ConstructorDeclaration;
NodeList<ConstructorInitializer> initializers = constructor.initializers;
expect(initializers, hasLength(1));
ConstructorInitializer initializer = initializers[0];
EngineTestCase.assertInstanceOf((obj) => obj is ConstructorFieldInitializer,
ConstructorFieldInitializer, initializer);
EngineTestCase.assertInstanceOf(
(obj) => obj is ParenthesizedExpression,
ParenthesizedExpression,
(initializer as ConstructorFieldInitializer).expression);
EngineTestCase.assertInstanceOf(
(obj) => obj is BlockFunctionBody, BlockFunctionBody, constructor.body);
}
void test_parseConstructorFieldInitializer_qualified() {
createParser('this.a = b');
ConstructorFieldInitializer initializer =
parser.parseConstructorFieldInitializer(true);
expect(initializer, isNotNull);
assertNoErrors();
expect(initializer.equals, isNotNull);
expect(initializer.expression, isNotNull);
expect(initializer.fieldName, isNotNull);
expect(initializer.thisKeyword, isNotNull);
expect(initializer.period, isNotNull);
}
void test_parseConstructorFieldInitializer_unqualified() {
createParser('a = b');
ConstructorFieldInitializer initializer =
parser.parseConstructorFieldInitializer(false);
expect(initializer, isNotNull);
assertNoErrors();
expect(initializer.equals, isNotNull);
expect(initializer.expression, isNotNull);
expect(initializer.fieldName, isNotNull);
expect(initializer.thisKeyword, isNull);
expect(initializer.period, isNull);
}
void test_parseGetter_nonStatic() {
createParser('/// Doc\nT get a;');
MethodDeclaration method = parser.parseClassMember('C');
expect(method, isNotNull);
assertNoErrors();
expect(method.body, isNotNull);
expectCommentText(method.documentationComment, '/// Doc');
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.parameters, isNull);
expect(method.propertyKeyword, isNotNull);
expect((method.returnType as TypeName).name.name, 'T');
}
void test_parseGetter_static() {
createParser('/// Doc\nstatic T get a => 42;');
MethodDeclaration method = parser.parseClassMember('C');
expect(method, isNotNull);
assertNoErrors();
expect(method.body, isNotNull);
expectCommentText(method.documentationComment, '/// Doc');
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword.lexeme, 'static');
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNull);
expect(method.propertyKeyword, isNotNull);
expect((method.returnType as TypeName).name.name, 'T');
}
void test_parseInitializedIdentifierList_type() {
createParser("/// Doc\nstatic T a = 1, b, c = 3;");
FieldDeclaration declaration = parser.parseClassMember('C');
expect(declaration, isNotNull);
assertNoErrors();
expectCommentText(declaration.documentationComment, '/// Doc');
VariableDeclarationList fields = declaration.fields;
expect(fields, isNotNull);
expect(fields.keyword, isNull);
expect((fields.type as TypeName).name.name, 'T');
expect(fields.variables, hasLength(3));
expect(declaration.staticKeyword.lexeme, 'static');
expect(declaration.semicolon, isNotNull);
}
void test_parseInitializedIdentifierList_var() {
createParser('/// Doc\nstatic var a = 1, b, c = 3;');
FieldDeclaration declaration = parser.parseClassMember('C');
expect(declaration, isNotNull);
assertNoErrors();
expectCommentText(declaration.documentationComment, '/// Doc');
VariableDeclarationList fields = declaration.fields;
expect(fields, isNotNull);
expect(fields.keyword.lexeme, 'var');
expect(fields.type, isNull);
expect(fields.variables, hasLength(3));
expect(declaration.staticKeyword.lexeme, 'static');
expect(declaration.semicolon, isNotNull);
}
void test_parseOperator() {
createParser('/// Doc\nT operator +(A a);');
MethodDeclaration method = parser.parseClassMember('C');
expect(method, isNotNull);
assertNoErrors();
expect(method.body, isNotNull);
expectCommentText(method.documentationComment, '/// Doc');
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNotNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNull);
expect((method.returnType as TypeName).name.name, 'T');
}
void test_parseSetter_nonStatic() {
createParser('/// Doc\nT set a(var x);');
MethodDeclaration method = parser.parseClassMember('C');
expect(method, isNotNull);
assertNoErrors();
expect(method.body, isNotNull);
expectCommentText(method.documentationComment, '/// Doc');
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNotNull);
expect((method.returnType as TypeName).name.name, 'T');
}
void test_parseSetter_static() {
createParser('/// Doc\nstatic T set a(var x) {}');
MethodDeclaration method = parser.parseClassMember('C');
expect(method, isNotNull);
assertNoErrors();
expect(method.body, isNotNull);
expectCommentText(method.documentationComment, '/// Doc');
expect(method.externalKeyword, isNull);
expect(method.modifierKeyword.lexeme, 'static');
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNotNull);
expect((method.returnType as TypeName).name.name, 'T');
}
void test_simpleFormalParameter_withDocComment() {
createParser('''
int f(
/// Doc
int x) {}
''');
var function = parseFullCompilationUnitMember() as FunctionDeclaration;
var parameter = function.functionExpression.parameters.parameters[0]
as NormalFormalParameter;
expectCommentText(parameter.documentationComment, '/// Doc');
}
/**
* Assert that the given [name] is in declaration context.
*/
void _assertIsDeclarationName(SimpleIdentifier name, [bool expected = true]) {
expect(name.inDeclarationContext(), expected);
}
}
/**
* Tests of the analyzer parser based on [ComplexParserTestMixin].
*/
@reflectiveTest
class ComplexParserTest extends ParserTestCase with ComplexParserTestMixin {}
/**
* The class `ComplexParserTest` defines parser tests that test the parsing of more complex
* code fragments or the interactions between multiple parsing methods. For example, tests to ensure
* that the precedence of operations is being handled correctly should be defined in this class.
*
* Simpler tests should be defined in the class [SimpleParserTest].
*/
abstract class ComplexParserTestMixin implements AbstractParserTestCase {
void test_additiveExpression_normal() {
BinaryExpression expression = parseExpression("x + y - z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_additiveExpression_noSpaces() {
BinaryExpression expression = parseExpression("i+1");
EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
SimpleIdentifier, expression.leftOperand);
EngineTestCase.assertInstanceOf((obj) => obj is IntegerLiteral,
IntegerLiteral, expression.rightOperand);
}
void test_additiveExpression_precedence_multiplicative_left() {
BinaryExpression expression = parseExpression("x * y + z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_additiveExpression_precedence_multiplicative_left_withSuper() {
BinaryExpression expression = parseExpression("super * y - z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_additiveExpression_precedence_multiplicative_right() {
BinaryExpression expression = parseExpression("x + y * z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.rightOperand);
}
void test_additiveExpression_super() {
BinaryExpression expression = parseExpression("super + y - z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_assignableExpression_arguments_normal_chain() {
PropertyAccess propertyAccess1 = parseExpression("a(b)(c).d(e).f");
expect(propertyAccess1.propertyName.name, "f");
//
// a(b)(c).d(e)
//
MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(
(obj) => obj is MethodInvocation,
MethodInvocation,
propertyAccess1.target);
expect(invocation2.methodName.name, "d");
expect(invocation2.typeArguments, isNull);
ArgumentList argumentList2 = invocation2.argumentList;
expect(argumentList2, isNotNull);
expect(argumentList2.arguments, hasLength(1));
//
// a(b)(c)
//
FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
(obj) => obj is FunctionExpressionInvocation,
FunctionExpressionInvocation,
invocation2.target);
expect(invocation3.typeArguments, isNull);
ArgumentList argumentList3 = invocation3.argumentList;
expect(argumentList3, isNotNull);
expect(argumentList3.arguments, hasLength(1));
//
// a(b)
//
MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(
(obj) => obj is MethodInvocation,
MethodInvocation,
invocation3.function);
expect(invocation4.methodName.name, "a");
expect(invocation4.typeArguments, isNull);
ArgumentList argumentList4 = invocation4.argumentList;
expect(argumentList4, isNotNull);
expect(argumentList4.arguments, hasLength(1));
}
void test_assignableExpression_arguments_normal_chain_typeArgumentComments() {
enableGenericMethodComments = true;
_validate_assignableExpression_arguments_normal_chain_typeArguments(
"a/*<E>*/(b)/*<F>*/(c).d/*<G>*/(e).f");
}
void test_assignableExpression_arguments_normal_chain_typeArguments() {
_validate_assignableExpression_arguments_normal_chain_typeArguments(
"a<E>(b)<F>(c).d<G>(e).f");
}
void test_assignmentExpression_compound() {
AssignmentExpression expression = parseExpression("x = y = 0");
EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
SimpleIdentifier, expression.leftHandSide);
EngineTestCase.assertInstanceOf((obj) => obj is AssignmentExpression,
AssignmentExpression, expression.rightHandSide);
}
void test_assignmentExpression_indexExpression() {
AssignmentExpression expression = parseExpression("x[1] = 0");
EngineTestCase.assertInstanceOf((obj) => obj is IndexExpression,
IndexExpression, expression.leftHandSide);
EngineTestCase.assertInstanceOf((obj) => obj is IntegerLiteral,
IntegerLiteral, expression.rightHandSide);
}
void test_assignmentExpression_prefixedIdentifier() {
AssignmentExpression expression = parseExpression("x.y = 0");
EngineTestCase.assertInstanceOf((obj) => obj is PrefixedIdentifier,
PrefixedIdentifier, expression.leftHandSide);
EngineTestCase.assertInstanceOf((obj) => obj is IntegerLiteral,
IntegerLiteral, expression.rightHandSide);
}
void test_assignmentExpression_propertyAccess() {
AssignmentExpression expression = parseExpression("super.y = 0");
EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccess,
PropertyAccess, expression.leftHandSide);
EngineTestCase.assertInstanceOf((obj) => obj is IntegerLiteral,
IntegerLiteral, expression.rightHandSide);
}
void test_bitwiseAndExpression_normal() {
BinaryExpression expression = parseExpression("x & y & z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_bitwiseAndExpression_precedence_equality_left() {
BinaryExpression expression = parseExpression("x == y && z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_bitwiseAndExpression_precedence_equality_right() {
BinaryExpression expression = parseExpression("x && y == z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.rightOperand);
}
void test_bitwiseAndExpression_super() {
BinaryExpression expression = parseExpression("super & y & z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_bitwiseOrExpression_normal() {
BinaryExpression expression = parseExpression("x | y | z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_bitwiseOrExpression_precedence_xor_left() {
BinaryExpression expression = parseExpression("x ^ y | z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_bitwiseOrExpression_precedence_xor_right() {
BinaryExpression expression = parseExpression("x | y ^ z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.rightOperand);
}
void test_bitwiseOrExpression_super() {
BinaryExpression expression = parseExpression("super | y | z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_bitwiseXorExpression_normal() {
BinaryExpression expression = parseExpression("x ^ y ^ z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_bitwiseXorExpression_precedence_and_left() {
BinaryExpression expression = parseExpression("x & y ^ z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_bitwiseXorExpression_precedence_and_right() {
BinaryExpression expression = parseExpression("x ^ y & z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.rightOperand);
}
void test_bitwiseXorExpression_super() {
BinaryExpression expression = parseExpression("super ^ y ^ z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_cascade_withAssignment() {
CascadeExpression cascade =
parseExpression("new Map()..[3] = 4 ..[0] = 11");
Expression target = cascade.target;
for (Expression section in cascade.cascadeSections) {
EngineTestCase.assertInstanceOf(
(obj) => obj is AssignmentExpression, AssignmentExpression, section);
Expression lhs = (section as AssignmentExpression).leftHandSide;
EngineTestCase.assertInstanceOf(
(obj) => obj is IndexExpression, IndexExpression, lhs);
IndexExpression index = lhs as IndexExpression;
expect(index.isCascaded, isTrue);
expect(index.realTarget, same(target));
}
}
void test_conditionalExpression_precedence_ifNullExpression() {
ConditionalExpression expression = parseExpression('a ?? b ? y : z');
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.condition);
}
void test_conditionalExpression_precedence_logicalOrExpression() {
ConditionalExpression expression = parseExpression("a | b ? y : z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.condition);
}
void test_conditionalExpression_precedence_nullableType_as() {
enableNnbd = true;
Expression expression = parseExpression('x as String ? (x + y) : z');
expect(expression, isNotNull);
expect(expression, new isInstanceOf<ConditionalExpression>());
ConditionalExpression conditional = expression;
Expression condition = conditional.condition;
expect(condition, new isInstanceOf<AsExpression>());
Expression thenExpression = conditional.thenExpression;
expect(thenExpression, new isInstanceOf<ParenthesizedExpression>());
Expression elseExpression = conditional.elseExpression;
expect(elseExpression, new isInstanceOf<SimpleIdentifier>());
}
void test_conditionalExpression_precedence_nullableType_is() {
enableNnbd = true;
Expression expression = parseExpression('x is String ? (x + y) : z');
expect(expression, isNotNull);
expect(expression, new isInstanceOf<ConditionalExpression>());
ConditionalExpression conditional = expression;
Expression condition = conditional.condition;
expect(condition, new isInstanceOf<IsExpression>());
Expression thenExpression = conditional.thenExpression;
expect(thenExpression, new isInstanceOf<ParenthesizedExpression>());
Expression elseExpression = conditional.elseExpression;
expect(elseExpression, new isInstanceOf<SimpleIdentifier>());
}
void test_constructor_initializer_withParenthesizedExpression() {
CompilationUnit unit = parseCompilationUnit(r'''
class C {
C() :
this.a = (b == null ? c : d) {
}
}''');
NodeList<CompilationUnitMember> declarations = unit.declarations;
expect(declarations, hasLength(1));
}
void test_equalityExpression_normal() {
BinaryExpression expression = parseExpression(
"x == y != z", [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_equalityExpression_precedence_relational_left() {
BinaryExpression expression = parseExpression("x is y == z");
EngineTestCase.assertInstanceOf(
(obj) => obj is IsExpression, IsExpression, expression.leftOperand);
}
void test_equalityExpression_precedence_relational_right() {
BinaryExpression expression = parseExpression("x == y is z");
EngineTestCase.assertInstanceOf(
(obj) => obj is IsExpression, IsExpression, expression.rightOperand);
}
void test_equalityExpression_super() {
BinaryExpression expression = parseExpression("super == y != z",
[ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_ifNullExpression() {
BinaryExpression expression = parseExpression('x ?? y ?? z');
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_ifNullExpression_precedence_logicalOr_left() {
BinaryExpression expression = parseExpression('x || y ?? z');
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_ifNullExpression_precedence_logicalOr_right() {
BinaryExpression expression = parseExpression('x ?? y || z');
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.rightOperand);
}
void test_logicalAndExpression() {
BinaryExpression expression = parseExpression("x && y && z");
expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
}
void test_logicalAndExpression_precedence_bitwiseOr_left() {
BinaryExpression expression = parseExpression("x | y < z");
expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
}
void test_logicalAndExpression_precedence_bitwiseOr_right() {
BinaryExpression expression = parseExpression("x < y | z");
expect(expression.rightOperand, new isInstanceOf<BinaryExpression>());
}
void test_logicalAndExpression_precedence_nullableType() {
enableNnbd = true;
BinaryExpression expression = parseExpression("x is C? && y is D");
expect(expression.leftOperand, new isInstanceOf<IsExpression>());
expect(expression.rightOperand, new isInstanceOf<IsExpression>());
}
void test_logicalOrExpression() {
BinaryExpression expression = parseExpression("x || y || z");
expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
}
void test_logicalOrExpression_precedence_logicalAnd_left() {
BinaryExpression expression = parseExpression("x && y || z");
expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
}
void test_logicalOrExpression_precedence_logicalAnd_right() {
BinaryExpression expression = parseExpression("x || y && z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.rightOperand);
}
void test_logicalOrExpression_precedence_nullableType() {
enableNnbd = true;
BinaryExpression expression = parseExpression("a is X? || (b ? c : d)");
expect(expression.leftOperand, new isInstanceOf<IsExpression>());
expect(
expression.rightOperand, new isInstanceOf<ParenthesizedExpression>());
expect((expression.rightOperand as ParenthesizedExpression).expression,
new isInstanceOf<ConditionalExpression>());
}
void test_multipleLabels_statement() {
LabeledStatement statement = parseStatement("a: b: c: return x;");
expect(statement.labels, hasLength(3));
EngineTestCase.assertInstanceOf(
(obj) => obj is ReturnStatement, ReturnStatement, statement.statement);
}
void test_multiplicativeExpression_normal() {
BinaryExpression expression = parseExpression("x * y / z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_multiplicativeExpression_precedence_unary_left() {
BinaryExpression expression = parseExpression("-x * y");
EngineTestCase.assertInstanceOf((obj) => obj is PrefixExpression,
PrefixExpression, expression.leftOperand);
}
void test_multiplicativeExpression_precedence_unary_right() {
BinaryExpression expression = parseExpression("x * -y");
EngineTestCase.assertInstanceOf((obj) => obj is PrefixExpression,
PrefixExpression, expression.rightOperand);
}
void test_multiplicativeExpression_super() {
BinaryExpression expression = parseExpression("super * y / z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_relationalExpression_precedence_shift_right() {
IsExpression expression = parseExpression("x << y is z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.expression);
}
void test_shiftExpression_normal() {
BinaryExpression expression = parseExpression("x >> 4 << 3");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_shiftExpression_precedence_additive_left() {
BinaryExpression expression = parseExpression("x + y << z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_shiftExpression_precedence_additive_right() {
BinaryExpression expression = parseExpression("x << y + z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.rightOperand);
}
void test_shiftExpression_super() {
BinaryExpression expression = parseExpression("super >> 4 << 3");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
BinaryExpression, expression.leftOperand);
}
void test_topLevelFunction_nestedGenericFunction() {
parseCompilationUnitWithOptions('''
void f() {
void g<T>() {
}
}
''');
}
void _validate_assignableExpression_arguments_normal_chain_typeArguments(
String code) {
PropertyAccess propertyAccess1 = parseExpression(code);
expect(propertyAccess1.propertyName.name, "f");
//
// a<E>(b)<F>(c).d<G>(e)
//
MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(
(obj) => obj is MethodInvocation,
MethodInvocation,
propertyAccess1.target);
expect(invocation2.methodName.name, "d");
expect(invocation2.typeArguments, isNotNull);
ArgumentList argumentList2 = invocation2.argumentList;
expect(argumentList2, isNotNull);
expect(argumentList2.arguments, hasLength(1));
//
// a<E>(b)<F>(c)
//
FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
(obj) => obj is FunctionExpressionInvocation,
FunctionExpressionInvocation,
invocation2.target);
expect(invocation3.typeArguments, isNotNull);
ArgumentList argumentList3 = invocation3.argumentList;
expect(argumentList3, isNotNull);
expect(argumentList3.arguments, hasLength(1));
//
// a(b)
//
MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(
(obj) => obj is MethodInvocation,
MethodInvocation,
invocation3.function);
expect(invocation4.methodName.name, "a");
expect(invocation4.typeArguments, isNotNull);
ArgumentList argumentList4 = invocation4.argumentList;
expect(argumentList4, isNotNull);
expect(argumentList4.arguments, hasLength(1));
}
}
/**
* The class `ErrorParserTest` defines parser tests that test the parsing of code to ensure
* that errors are correctly reported, and in some cases, not reported.
*/
@reflectiveTest
class ErrorParserTest extends ParserTestCase {
void test_abstractClassMember_constructor() {
createParser('abstract C.c();');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
}
void test_abstractClassMember_field() {
createParser('abstract C f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
}
void test_abstractClassMember_getter() {
createParser('abstract get m;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
}
void test_abstractClassMember_method() {
createParser('abstract m();');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
}
void test_abstractClassMember_setter() {
createParser('abstract set m(v);');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
}
void test_abstractEnum() {
parseCompilationUnit(
"abstract enum E {ONE}", [ParserErrorCode.ABSTRACT_ENUM]);
}
void test_abstractTopLevelFunction_function() {
parseCompilationUnit(
"abstract f(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
}
void test_abstractTopLevelFunction_getter() {
parseCompilationUnit(
"abstract get m {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
}
void test_abstractTopLevelFunction_setter() {
parseCompilationUnit(
"abstract set m(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
}
void test_abstractTopLevelVariable() {
parseCompilationUnit(
"abstract C f;", [ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE]);
}
void test_abstractTypeDef() {
parseCompilationUnit(
"abstract typedef F();", [ParserErrorCode.ABSTRACT_TYPEDEF]);
}
void test_annotationOnEnumConstant_first() {
parseCompilationUnit("enum E { @override C }",
[ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT]);
}
void test_annotationOnEnumConstant_middle() {
parseCompilationUnit("enum E { C, @override D, E }",
[ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT]);
}
void test_breakOutsideOfLoop_breakInDoStatement() {
createParser('do {break;} while (x);');
DoStatement statement = parser.parseDoStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_breakOutsideOfLoop_breakInForStatement() {
createParser('for (; x;) {break;}');
Statement statement = parser.parseForStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_breakOutsideOfLoop_breakInIfStatement() {
createParser('if (x) {break;}');
IfStatement statement = parser.parseIfStatement();
expectNotNullIfNoErrors(statement);
listener.assertErrorsWithCodes([ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
}
void test_breakOutsideOfLoop_breakInSwitchStatement() {
createParser('switch (x) {case 1: break;}');
SwitchStatement statement = parser.parseSwitchStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_breakOutsideOfLoop_breakInWhileStatement() {
createParser('while (x) {break;}');
WhileStatement statement = parser.parseWhileStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_breakOutsideOfLoop_functionExpression_inALoop() {
parseStatement("for(; x;) {() {break;};}");
assertErrorsWithCodes([ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
}
void test_breakOutsideOfLoop_functionExpression_withALoop() {
parseStatement("() {for (; x;) {break;}};");
}
void test_classInClass_abstract() {
parseCompilationUnit(
"class C { abstract class B {} }", [ParserErrorCode.CLASS_IN_CLASS]);
}
void test_classInClass_nonAbstract() {
parseCompilationUnit(
"class C { class B {} }", [ParserErrorCode.CLASS_IN_CLASS]);
}
void test_classTypeAlias_abstractAfterEq() {
// This syntax has been removed from the language in favor of
// "abstract class A = B with C;" (issue 18098).
createParser('class A = abstract B with C;');
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes(
[ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN]);
}
void test_colonInPlaceOfIn() {
parseStatement("for (var x : list) {}");
assertErrorsWithCodes([ParserErrorCode.COLON_IN_PLACE_OF_IN]);
}
void test_constAndCovariant() {
createParser('covariant const C f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.CONST_AND_COVARIANT]);
}
void test_constAndFinal() {
createParser('const final int x;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.CONST_AND_FINAL]);
}
void test_constAndVar() {
createParser('const var x;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.CONST_AND_VAR]);
}
void test_constClass() {
parseCompilationUnit("const class C {}", [ParserErrorCode.CONST_CLASS]);
}
void test_constConstructorWithBody() {
createParser('const C() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener
.assertErrorsWithCodes([ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY]);
}
void test_constEnum() {
parseCompilationUnit("const enum E {ONE}", [ParserErrorCode.CONST_ENUM]);
}
void test_constFactory() {
createParser('const factory C() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.CONST_FACTORY]);
}
void test_constMethod() {
createParser('const int m() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.CONST_METHOD]);
}
void test_constructorWithReturnType() {
createParser('C C() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener
.assertErrorsWithCodes([ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
}
void test_constructorWithReturnType_var() {
createParser('var C() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener
.assertErrorsWithCodes([ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
}
void test_constTypedef() {
parseCompilationUnit("const typedef F();", [ParserErrorCode.CONST_TYPEDEF]);
}
void test_continueOutsideOfLoop_continueInDoStatement() {
createParser('do {continue;} while (x);');
DoStatement statement = parser.parseDoStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_continueOutsideOfLoop_continueInForStatement() {
createParser('for (; x;) {continue;}');
Statement statement = parser.parseForStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_continueOutsideOfLoop_continueInIfStatement() {
createParser('if (x) {continue;}');
IfStatement statement = parser.parseIfStatement();
expectNotNullIfNoErrors(statement);
listener.assertErrorsWithCodes([ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
}
void test_continueOutsideOfLoop_continueInSwitchStatement() {
createParser('switch (x) {case 1: continue a;}');
SwitchStatement statement = parser.parseSwitchStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_continueOutsideOfLoop_continueInWhileStatement() {
createParser('while (x) {continue;}');
WhileStatement statement = parser.parseWhileStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_continueOutsideOfLoop_functionExpression_inALoop() {
parseStatement("for(; x;) {() {continue;};}");
assertErrorsWithCodes([ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
}
void test_continueOutsideOfLoop_functionExpression_withALoop() {
parseStatement("() {for (; x;) {continue;}};");
}
void test_continueWithoutLabelInCase_error() {
createParser('switch (x) {case 1: continue;}');
SwitchStatement statement = parser.parseSwitchStatement();
expectNotNullIfNoErrors(statement);
listener.assertErrorsWithCodes(
[ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE]);
}
void test_continueWithoutLabelInCase_noError() {
createParser('switch (x) {case 1: continue a;}');
SwitchStatement statement = parser.parseSwitchStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_continueWithoutLabelInCase_noError_switchInLoop() {
createParser('while (a) { switch (b) {default: continue;}}');
WhileStatement statement = parser.parseWhileStatement();
expectNotNullIfNoErrors(statement);
listener.assertNoErrors();
}
void test_covariantAfterVar() {
createParser('var covariant f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.COVARIANT_AFTER_VAR]);
}
void test_covariantAndStatic() {
createParser('covariant static A f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.COVARIANT_AND_STATIC]);
}
void test_covariantConstructor() {
createParser('class C { covariant C(); }');
ClassDeclaration member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.COVARIANT_CONSTRUCTOR]);
}
void test_covariantMember_getter_noReturnType() {
createParser('static covariant get x => 0;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.COVARIANT_MEMBER]);
}
void test_covariantMember_getter_returnType() {
createParser('static covariant int get x => 0;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.COVARIANT_MEMBER]);
}
void test_covariantMember_method() {
createParser('covariant int m() => 0;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.COVARIANT_MEMBER]);
}
void test_covariantTopLevelDeclaration_class() {
createParser('covariant class C {}');
ClassDeclaration member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes(
[ParserErrorCode.COVARIANT_TOP_LEVEL_DECLARATION]);
}
void test_covariantTopLevelDeclaration_enum() {
createParser('covariant enum E { v }');
EnumDeclaration member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes(
[ParserErrorCode.COVARIANT_TOP_LEVEL_DECLARATION]);
}
void test_covariantTopLevelDeclaration_typedef() {
parseCompilationUnit("covariant typedef F();",
[ParserErrorCode.COVARIANT_TOP_LEVEL_DECLARATION]);
}
void test_defaultValueInFunctionType_named_colon() {
createParser('int x : 0');
FormalParameter parameter =
parser.parseFormalParameter(ParameterKind.NAMED, inFunctionType: true);
expectNotNullIfNoErrors(parameter);
listener.assertErrorsWithCodes(
[ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE]);
}
void test_defaultValueInFunctionType_named_equal() {
createParser('int x = 0');
FormalParameter parameter =
parser.parseFormalParameter(ParameterKind.NAMED, inFunctionType: true);
expectNotNullIfNoErrors(parameter);
listener.assertErrorsWithCodes(
[ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE]);
}
void test_defaultValueInFunctionType_positional() {
createParser('int x = 0');
FormalParameter parameter = parser
.parseFormalParameter(ParameterKind.POSITIONAL, inFunctionType: true);
expectNotNullIfNoErrors(parameter);
listener.assertErrorsWithCodes(
[ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE]);
}
void test_directiveAfterDeclaration_classBeforeDirective() {
CompilationUnit unit = parseCompilationUnit("class Foo{} library l;",
[ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
expect(unit, isNotNull);
}
void test_directiveAfterDeclaration_classBetweenDirectives() {
CompilationUnit unit = parseCompilationUnit(
"library l;\nclass Foo{}\npart 'a.dart';",
[ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
expect(unit, isNotNull);
}
void test_duplicatedModifier_const() {
createParser('const const m;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.DUPLICATED_MODIFIER]);
}
void test_duplicatedModifier_external() {
createParser('external external f();');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.DUPLICATED_MODIFIER]);
}
void test_duplicatedModifier_factory() {
createParser('factory factory C() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.DUPLICATED_MODIFIER]);
}
void test_duplicatedModifier_final() {
createParser('final final m;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.DUPLICATED_MODIFIER]);
}
void test_duplicatedModifier_static() {
createParser('static static var m;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.DUPLICATED_MODIFIER]);
}
void test_duplicatedModifier_var() {
createParser('var var m;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.DUPLICATED_MODIFIER]);
}
void test_duplicateLabelInSwitchStatement() {
createParser('switch (e) {l1: case 0: break; l1: case 1: break;}');
SwitchStatement statement = parser.parseSwitchStatement();
expectNotNullIfNoErrors(statement);
listener.assertErrorsWithCodes(
[ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
}
void test_emptyEnumBody() {
createParser('enum E {}');
EnumDeclaration declaration = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(declaration);
listener.assertErrorsWithCodes([ParserErrorCode.EMPTY_ENUM_BODY]);
}
void test_enumInClass() {
parseCompilationUnit(
r'''
class Foo {
enum Bar {
Bar1, Bar2, Bar3
}
}
''',
[ParserErrorCode.ENUM_IN_CLASS]);
}
void test_equalityCannotBeEqualityOperand_eq_eq() {
parseExpression(
"1 == 2 == 3", [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
}
void test_equalityCannotBeEqualityOperand_eq_neq() {
parseExpression(
"1 == 2 != 3", [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
}
void test_equalityCannotBeEqualityOperand_neq_eq() {
parseExpression(
"1 != 2 == 3", [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
}
void test_expectedCaseOrDefault() {
createParser('switch (e) {break;}');
SwitchStatement statement = parser.parseSwitchStatement();
expectNotNullIfNoErrors(statement);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]);
}
void test_expectedClassMember_inClass_afterType() {
createParser('heart 2 heart');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_CLASS_MEMBER]);
}
void test_expectedClassMember_inClass_beforeType() {
createParser('4 score');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_CLASS_MEMBER]);
}
void test_expectedExecutable_inClass_afterVoid() {
createParser('void 2 void');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_EXECUTABLE]);
}
void test_expectedExecutable_topLevel_afterType() {
createParser('heart 2 heart');
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_EXECUTABLE]);
}
void test_expectedExecutable_topLevel_afterVoid() {
createParser('void 2 void');
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_EXECUTABLE]);
}
void test_expectedExecutable_topLevel_beforeType() {
createParser('4 score');
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_EXECUTABLE]);
}
void test_expectedExecutable_topLevel_eof() {
createParser('x');
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrors(
[new AnalysisError(null, 0, 1, ParserErrorCode.EXPECTED_EXECUTABLE)]);
}
void test_expectedInterpolationIdentifier() {
createParser("'\$x\$'");
StringLiteral literal = parser.parseStringLiteral();
expectNotNullIfNoErrors(literal);
listener.assertErrorsWithCodes([ParserErrorCode.MISSING_IDENTIFIER]);
}
void test_expectedInterpolationIdentifier_emptyString() {
// The scanner inserts an empty string token between the two $'s; we need to
// make sure that the MISSING_IDENTIFIER error that is generated has a
// nonzero width so that it will show up in the editor UI.
createParser("'\$\$foo'");
StringLiteral literal = parser.parseStringLiteral();
expectNotNullIfNoErrors(literal);
listener.assertErrors(
[new AnalysisError(null, 2, 1, ParserErrorCode.MISSING_IDENTIFIER)]);
}
@failingTest
void test_expectedListOrMapLiteral() {
// It isn't clear that this test can ever pass. The parser is currently
// create a synthetic list literal in this case, but isSynthetic() isn't
// overridden for ListLiteral. The problem is that the synthetic list
// literals that are being created are not always zero length (because they
// could have type parameters), which violates the contract of
// isSynthetic().
TypedLiteral literal = parseListOrMapLiteral(null, '1');
expectNotNullIfNoErrors(literal);
listener
.assertErrorsWithCodes([ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
expect(literal.isSynthetic, isTrue);
}
void test_expectedStringLiteral() {
createParser('1');
StringLiteral literal = parser.parseStringLiteral();
expectNotNullIfNoErrors(literal);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_STRING_LITERAL]);
expect(literal.isSynthetic, isTrue);
}
void test_expectedToken_commaMissingInArgumentList() {
createParser('(x, y z)');
ArgumentList list = parser.parseArgumentList();
expectNotNullIfNoErrors(list);
listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_TOKEN]);
}
void test_expectedToken_parseStatement_afterVoid() {
parseStatement("void}");
assertErrorsWithCodes(
[ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.MISSING_IDENTIFIER]);
}
void test_expectedToken_semicolonMissingAfterExport() {
CompilationUnit unit = parseCompilationUnit(
"export '' class A {}", [ParserErrorCode.EXPECTED_TOKEN]);
ExportDirective directive = unit.directives[0] as ExportDirective;
Token semicolon = directive.semicolon;
expect(semicolon, isNotNull);
expect(semicolon.isSynthetic, isTrue);
}
void test_expectedToken_semicolonMissingAfterExpression() {
parseStatement("x");
assertErrorsWithCodes([ParserErrorCode.EXPECTED_TOKEN]);
}
void test_expectedToken_semicolonMissingAfterImport() {
CompilationUnit unit = parseCompilationUnit(
"import '' class A {}", [ParserErrorCode.EXPECTED_TOKEN]);
ImportDirective directive = unit.directives[0] as ImportDirective;
Token semicolon = directive.semicolon;
expect(semicolon, isNotNull);
expect(semicolon.isSynthetic, isTrue);
}
void test_expectedToken_whileMissingInDoStatement() {
parseStatement("do {} (x);");
assertErrorsWithCodes([ParserErrorCode.EXPECTED_TOKEN]);
}
void test_expectedTypeName_as() {
parseExpression("x as", [ParserErrorCode.EXPECTED_TYPE_NAME]);
}
void test_expectedTypeName_as_void() {
parseExpression("x as void)", [ParserErrorCode.EXPECTED_TYPE_NAME]);
}
void test_expectedTypeName_is() {
parseExpression("x is", [ParserErrorCode.EXPECTED_TYPE_NAME]);
}
void test_expectedTypeName_is_void() {
parseExpression("x is void)", [ParserErrorCode.EXPECTED_TYPE_NAME]);
}
void test_exportDirectiveAfterPartDirective() {
parseCompilationUnit("part 'a.dart'; export 'b.dart';",
[ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
}
void test_externalAfterConst() {
createParser('const external C();');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_AFTER_CONST]);
}
void test_externalAfterFactory() {
createParser('factory external C();');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_AFTER_FACTORY]);
}
void test_externalAfterStatic() {
createParser('static external int m();');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_AFTER_STATIC]);
}
void test_externalClass() {
parseCompilationUnit(
"external class C {}", [ParserErrorCode.EXTERNAL_CLASS]);
}
void test_externalConstructorWithBody_factory() {
createParser('external factory C() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes(
[ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
}
void test_externalConstructorWithBody_named() {
createParser('external C.c() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes(
[ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
}
void test_externalEnum() {
parseCompilationUnit(
"external enum E {ONE}", [ParserErrorCode.EXTERNAL_ENUM]);
}
void test_externalField_const() {
createParser('external const A f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_FIELD]);
}
void test_externalField_final() {
createParser('external final A f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_FIELD]);
}
void test_externalField_static() {
createParser('external static A f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_FIELD]);
}
void test_externalField_typed() {
createParser('external A f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_FIELD]);
}
void test_externalField_untyped() {
createParser('external var f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_FIELD]);
}
void test_externalGetterWithBody() {
createParser('external int get x {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]);
}
void test_externalMethodWithBody() {
createParser('external m() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]);
}
void test_externalOperatorWithBody() {
createParser('external operator +(int value) {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener
.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY]);
}
void test_externalSetterWithBody() {
createParser('external set x(int value) {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_SETTER_WITH_BODY]);
}
void test_externalTypedef() {
parseCompilationUnit(
"external typedef F();", [ParserErrorCode.EXTERNAL_TYPEDEF]);
}
void test_extraCommaInParameterList() {
createParser('(int a, , int b)');
FormalParameterList list = parser.parseFormalParameterList();
expectNotNullIfNoErrors(list);
listener.assertErrorsWithCodes(
[ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]);
}
void test_extraCommaTrailingNamedParameterGroup() {
createParser('({int b},)');
FormalParameterList list = parser.parseFormalParameterList();
expectNotNullIfNoErrors(list);
listener.assertErrorsWithCodes([
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
]);
}
void test_extraCommaTrailingPositionalParameterGroup() {
createParser('([int b],)');
FormalParameterList list = parser.parseFormalParameterList();
expectNotNullIfNoErrors(list);
listener.assertErrorsWithCodes([
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
]);
}
void test_extraTrailingCommaInParameterList() {
createParser('(a,,)');
FormalParameterList list = parser.parseFormalParameterList();
expectNotNullIfNoErrors(list);
listener.assertErrorsWithCodes([ParserErrorCode.MISSING_IDENTIFIER]);
}
void test_factoryTopLevelDeclaration_class() {
parseCompilationUnit(
"factory class C {}", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
}
void test_factoryTopLevelDeclaration_enum() {
parseCompilationUnit("factory enum E { v }",
[ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
}
void test_factoryTopLevelDeclaration_typedef() {
parseCompilationUnit("factory typedef F();",
[ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
}
void test_factoryWithInitializers() {
createParser('factory C() : x = 3 {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.FACTORY_WITH_INITIALIZERS]);
}
void test_factoryWithoutBody() {
createParser('factory C();');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.FACTORY_WITHOUT_BODY]);
}
void test_fieldInitializerOutsideConstructor() {
createParser('void m(this.x);');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes(
[ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
}
void test_finalAndCovariant() {
createParser('covariant final f;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.FINAL_AND_COVARIANT]);
}
void test_finalAndVar() {
createParser('final var x;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.FINAL_AND_VAR]);
}
void test_finalClass() {
parseCompilationUnit("final class C {}", [ParserErrorCode.FINAL_CLASS]);
}
void test_finalConstructor() {
createParser('final C() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.FINAL_CONSTRUCTOR]);
}
void test_finalEnum() {
parseCompilationUnit("final enum E {ONE}", [ParserErrorCode.FINAL_ENUM]);
}
void test_finalMethod() {
createParser('final int m() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.FINAL_METHOD]);
}
void test_finalTypedef() {
parseCompilationUnit("final typedef F();", [ParserErrorCode.FINAL_TYPEDEF]);
}
void test_functionTypedParameter_const() {
parseCompilationUnit(
"void f(const x()) {}", [ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR]);
}
void test_functionTypedParameter_final() {
parseCompilationUnit(
"void f(final x()) {}", [ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR]);
}
void test_functionTypedParameter_var() {
parseCompilationUnit(
"void f(var x()) {}", [ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR]);
}
void test_getterInFunction_block_noReturnType() {
FunctionDeclarationStatement statement =
parseStatement("get x { return _x; }");
assertErrorsWithCodes([ParserErrorCode.GETTER_IN_FUNCTION]);
expect(statement.functionDeclaration.functionExpression.parameters, isNull);
}
void test_getterInFunction_block_returnType() {
parseStatement("int get x { return _x; }");
assertErrorsWithCodes([ParserErrorCode.GETTER_IN_FUNCTION]);
}
void test_getterInFunction_expression_noReturnType() {
parseStatement("get x => _x;");
assertErrorsWithCodes([ParserErrorCode.GETTER_IN_FUNCTION]);
}
void test_getterInFunction_expression_returnType() {
parseStatement("int get x => _x;");
assertErrorsWithCodes([ParserErrorCode.GETTER_IN_FUNCTION]);
}
void test_getterWithParameters() {
createParser('int get x() {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.GETTER_WITH_PARAMETERS]);
}
void test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal() {
parseExpression(
"0--", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
}
void test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal() {
parseExpression(
"0++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
}
void test_illegalAssignmentToNonAssignable_postfix_plusPlus_parenthesized() {
parseExpression(
"(x)++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
}
void test_illegalAssignmentToNonAssignable_primarySelectorPostfix() {
parseExpression(
"x(y)(z)++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
}
void test_illegalAssignmentToNonAssignable_superAssigned() {
// TODO(brianwilkerson) When the test
// test_illegalAssignmentToNonAssignable_superAssigned_failing starts to pass,
// remove this test (there should only be one error generated, but we're
// keeping this test until that time so that we can catch other forms of
// regressions).
parseExpression("super = x;", [
ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR,
ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE
]);
}
@failingTest
void test_illegalAssignmentToNonAssignable_superAssigned_failing() {
// TODO(brianwilkerson) When this test starts to pass, remove the test
// test_illegalAssignmentToNonAssignable_superAssigned.
parseExpression(
"super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
}
void test_implementsBeforeExtends() {
parseCompilationUnit("class A implements B extends C {}",
[ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS]);
}
void test_implementsBeforeWith() {
parseCompilationUnit("class A extends B implements C with D {}",
[ParserErrorCode.IMPLEMENTS_BEFORE_WITH]);
}
void test_importDirectiveAfterPartDirective() {
parseCompilationUnit("part 'a.dart'; import 'b.dart';",
[ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
}
void test_initializedVariableInForEach() {
createParser('for (int a = 0 in foo) {}');
Statement statement = parser.parseForStatement();
expectNotNullIfNoErrors(statement);
listener.assertErrorsWithCodes(
[ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH]);
}
void test_invalidAwaitInFor() {
createParser('await for (; ;) {}');
Statement statement = parser.parseForStatement();
expectNotNullIfNoErrors(statement);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_AWAIT_IN_FOR]);
}
void test_invalidCodePoint() {
createParser("'\\u{110000}'");
StringLiteral literal = parser.parseStringLiteral();
expectNotNullIfNoErrors(literal);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_CODE_POINT]);
}
@failingTest
void test_invalidCommentReference__new_nonIdentifier() {
// This test fails because the method parseCommentReference returns null.
createParser('');
CommentReference reference = parser.parseCommentReference('new 42', 0);
expectNotNullIfNoErrors(reference);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
}
@failingTest
void test_invalidCommentReference__new_tooMuch() {
createParser('');
CommentReference reference = parser.parseCommentReference('new a.b.c.d', 0);
expectNotNullIfNoErrors(reference);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
}
@failingTest
void test_invalidCommentReference__nonNew_nonIdentifier() {
// This test fails because the method parseCommentReference returns null.
createParser('');
CommentReference reference = parser.parseCommentReference('42', 0);
expectNotNullIfNoErrors(reference);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
}
@failingTest
void test_invalidCommentReference__nonNew_tooMuch() {
createParser('');
CommentReference reference = parser.parseCommentReference('a.b.c.d', 0);
expectNotNullIfNoErrors(reference);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
}
void test_invalidConstructorName_with() {
createParser("C.with();");
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_CONSTRUCTOR_NAME]);
}
void test_invalidHexEscape_invalidDigit() {
createParser("'\\x0 a'");
StringLiteral literal = parser.parseStringLiteral();
expectNotNullIfNoErrors(literal);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_HEX_ESCAPE]);
}
void test_invalidHexEscape_tooFewDigits() {
createParser("'\\x0'");
StringLiteral literal = parser.parseStringLiteral();
expectNotNullIfNoErrors(literal);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_HEX_ESCAPE]);
}
void test_invalidInterpolationIdentifier_startWithDigit() {
createParser("'\$1'");
StringLiteral literal = parser.parseStringLiteral();
expectNotNullIfNoErrors(literal);
listener.assertErrorsWithCodes([ParserErrorCode.MISSING_IDENTIFIER]);
}
void test_invalidLiteralInConfiguration() {
createParser("if (a == 'x \$y z') 'a.dart'");
Configuration configuration = parser.parseConfiguration();
expectNotNullIfNoErrors(configuration);
listener.assertErrorsWithCodes(
[ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION]);
}
void test_invalidOperator() {
createParser('void operator ===(x) {}');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_OPERATOR]);
}
void test_invalidOperatorAfterSuper_assignableExpression() {
Expression expression = parseAssignableExpression('super?.v', false);
expectNotNullIfNoErrors(expression);
listener
.assertErrorsWithCodes([ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
}
void test_invalidOperatorAfterSuper_primaryExpression() {
Expression expression = parsePrimaryExpression('super?.v');
expectNotNullIfNoErrors(expression);
listener
.assertErrorsWithCodes([ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
}
void test_invalidOperatorForSuper() {
createParser('++super');
Expression expression = parser.parseUnaryExpression();
expectNotNullIfNoErrors(expression);
listener
.assertErrorsWithCodes([ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
}
void test_invalidStarAfterAsync() {
createParser('async* => 0;');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_STAR_AFTER_ASYNC]);
}
void test_invalidSync() {
createParser('sync* => 0;');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_SYNC]);
}
void test_invalidUnicodeEscape_incomplete_noDigits() {
Expression expression = parseStringLiteral("'\\u{'");
expectNotNullIfNoErrors(expression);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_UNICODE_ESCAPE]);
}
void test_invalidUnicodeEscape_incomplete_someDigits() {
Expression expression = parseStringLiteral("'\\u{0A'");