| // 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'"); |
|