// Copyright (c) 2020, 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. import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/src/dart/scanner/scanner.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../util/ast_type_matchers.dart'; import 'parser_test_base.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(ClassMemberParserTest); }); } /// Tests which exercise the parser using a class member. @reflectiveTest class ClassMemberParserTest extends FastaParserTestCase implements AbstractParserViaProxyTestCase { final tripleShift = FeatureSet.forTesting( sdkVersion: '2.0.0', additionalFeatures: [Feature.triple_shift]); void test_parse_member_called_late() { var unit = parseCompilationUnit( 'class C { void late() { new C().late(); } }', featureSet: nonNullable); var declaration = unit.declarations[0] as ClassDeclaration; var method = declaration.members[0] as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNull); expect(method.propertyKeyword, isNull); expect(method.returnType, isNotNull); expect(method.name.name, 'late'); expect(method.operatorKeyword, isNull); expect(method.typeParameters, isNull); expect(method.parameters, isNotNull); expect(method.body, isNotNull); var body = method.body as BlockFunctionBody; var statement = body.block.statements[0] as ExpressionStatement; var invocation = statement.expression as MethodInvocation; expect(invocation.operator!.lexeme, '.'); expect(invocation.toSource(), 'new C().late()'); } void test_parseAwaitExpression_asStatement_inAsync() { createParser('m() async { await x; }'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; FunctionBody body = method.body; expect(body, isBlockFunctionBody); Statement statement = (body as BlockFunctionBody).block.statements[0]; expect(statement, isExpressionStatement); Expression expression = (statement as ExpressionStatement).expression; expect(expression, isAwaitExpression); expect((expression as AwaitExpression).awaitKeyword, isNotNull); expect(expression.expression, isNotNull); } void test_parseAwaitExpression_asStatement_inSync() { createParser('m() { await x; }'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; FunctionBody body = method.body; expect(body, isBlockFunctionBody); Statement statement = (body as BlockFunctionBody).block.statements[0]; expect(statement, isVariableDeclarationStatement); } void test_parseAwaitExpression_inSync() { createParser('m() { return await x + await y; }'); var method = parser.parseClassMember('C') as MethodDeclaration; expect(method, isNotNull); listener.assertErrors([ expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 13, 5), expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 23, 5) ]); FunctionBody body = method.body; expect(body, isBlockFunctionBody); Statement statement = (body as BlockFunctionBody).block.statements[0]; expect(statement, isReturnStatement); Expression expression = (statement as ReturnStatement).expression!; expect(expression, isBinaryExpression); } 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, isConstructorDeclaration); var constructor = member as ConstructorDeclaration; 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, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNotNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list.keyword, isNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isFalse); expect(list.lateKeyword, isNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseClassMember_field_generic() { createParser('List> _allComponents = new List>();'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list, isNotNull); expect(list.keyword, isNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isFalse); expect(list.lateKeyword, isNull); var type = list.type as TypeName; expect(type.name.name, 'List'); List typeArguments = type.typeArguments!.arguments; expect(typeArguments, hasLength(1)); var type2 = typeArguments[0] as TypeName; expect(type2.name.name, 'List'); NodeList typeArguments2 = type2.typeArguments!.arguments; expect(typeArguments2, hasLength(1)); var type3 = typeArguments2[0] as TypeName; expect(type3.name.name, 'N'); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseClassMember_field_gftType_gftReturnType() { createParser(''' Function(int) Function(String) v; '''); ClassMember member = parser.parseClassMember('C'); assertNoErrors(); expect(member, isFieldDeclaration); VariableDeclarationList fields = (member as FieldDeclaration).fields; expect(fields.type, isGenericFunctionType); } void test_parseClassMember_field_gftType_noReturnType() { createParser(''' Function(int, String) v; '''); ClassMember member = parser.parseClassMember('C'); assertNoErrors(); expect(member, isFieldDeclaration); VariableDeclarationList fields = (member as FieldDeclaration).fields; expect(fields.type, isGenericFunctionType); } void test_parseClassMember_field_instance_prefixedType() { createParser('p.A f;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list, isNotNull); expect(list.keyword, isNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isFalse); expect(list.lateKeyword, isNull); NodeList 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, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isFalse); expect(list.lateKeyword, isNull); NodeList 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, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isFalse); expect(list.lateKeyword, isNull); NodeList 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, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isFalse); expect(list.lateKeyword, isNull); NodeList 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, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isFalse); expect(list.lateKeyword, isNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseClassMember_field_nameKeyword() { createParser('var for;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); listener.assertErrors([ expectedError(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 4, 3) ]); } void test_parseClassMember_field_nameMissing() { createParser('var ;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); listener.assertErrors( [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 1)]); } void test_parseClassMember_field_nameMissing2() { createParser('var "";'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); listener.assertErrors( [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 2)]); } void test_parseClassMember_field_static() { createParser('static A f;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNotNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list, isNotNull); expect(list.keyword, isNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isFalse); expect(list.lateKeyword, isNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseClassMember_finalAndCovariantLateWithInitializer() { createParser( 'covariant late final int f = 0;', featureSet: nonNullable, ); parser.parseClassMember('C'); assertErrors(errors: [ expectedError( ParserErrorCode.FINAL_AND_COVARIANT_LATE_WITH_INITIALIZER, 0, 9) ]); } void test_parseClassMember_getter_functionType() { createParser('int Function(int) get g {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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_noReturnType() { createParser('m() {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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_parameterType() { createParser('m(T p) => null;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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); FormalParameterList parameters = method.parameters!; expect(parameters, isNotNull); expect(parameters.parameters, hasLength(1)); var parameter = parameters.parameters[0] as SimpleFormalParameter; var parameterType = parameter.type as TypeName; expect(parameterType.name.name, 'T'); expect(method.body, isNotNull); } void test_parseClassMember_method_generic_returnType() { createParser('T m() {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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_returnType_bound() { createParser('T m() {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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_returnType_complex() { createParser('Map m() => null;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNull); expect(method.propertyKeyword, isNull); { var returnType = method.returnType as TypeName; expect(returnType, isNotNull); expect(returnType.name.name, 'Map'); List typeArguments = returnType.typeArguments!.arguments; expect(typeArguments, hasLength(2)); expect((typeArguments[0] as TypeName).name.name, 'int'); expect((typeArguments[1] 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_returnType_static() { createParser('static T m() {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNotNull); expect(method.propertyKeyword, isNull); expect(method.returnType, isNotNull); 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_void() { createParser('void m() {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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_static_namedAsClass() { createParser('static int get C => 0;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); listener.assertErrors([ expectedError(ParserErrorCode.MEMBER_WITH_CLASS_NAME, 15, 1), ]); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNotNull); expect(method.propertyKeyword, isNotNull); expect(method.returnType, isNotNull); expect(method.name, isNotNull); expect(method.operatorKeyword, isNull); expect(method.typeParameters, isNull); expect(method.parameters, isNull); expect(method.body, isNotNull); } void test_parseClassMember_method_get_type() { createParser('int get() {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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_gftReturnType_noReturnType() { createParser(''' Function(core.List x) m() => null; '''); ClassMember member = parser.parseClassMember('C'); assertNoErrors(); expect(member, isMethodDeclaration); expect((member as MethodDeclaration).body, isExpressionFunctionBody); } void test_parseClassMember_method_gftReturnType_voidReturnType() { createParser(''' void Function(core.List x) m() => null; '''); ClassMember member = parser.parseClassMember('C'); assertNoErrors(); expect(member, isMethodDeclaration); expect((member as MethodDeclaration).body, isExpressionFunctionBody); } void test_parseClassMember_method_native_allowed() { allowNativeClause = true; _parseClassMember_method_native(); assertNoErrors(); } void test_parseClassMember_method_native_missing_literal_allowed() { allowNativeClause = true; _parseClassMember_method_native_missing_literal(); assertNoErrors(); } void test_parseClassMember_method_native_missing_literal_not_allowed() { allowNativeClause = false; _parseClassMember_method_native_missing_literal(); listener.assertErrors([ expectedError(ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION, 4, 6), ]); } void test_parseClassMember_method_native_not_allowed() { allowNativeClause = false; _parseClassMember_method_native(); listener.assertErrors([ expectedError(ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION, 4, 6), ]); } void test_parseClassMember_method_native_with_body_allowed() { allowNativeClause = true; _parseClassMember_method_native_with_body(); // TODO(brianwilkerson) Convert codes to errors when highlighting is fixed. assertErrorsWithCodes([ ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, ]); // listener.assertErrors([ // expectedError(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, 17, 2), // ]); } void test_parseClassMember_method_native_with_body_not_allowed() { allowNativeClause = false; _parseClassMember_method_native_with_body(); // TODO(brianwilkerson) Convert codes to errors when highlighting is fixed. assertErrorsWithCodes([ ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION, ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, ]); // listener.assertErrors([ // expectedError(ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION, 4, 6), // expectedError(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, 17, 2), // ]); } void test_parseClassMember_method_operator_noType() { createParser('operator() {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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_static_namedAsClass() { createParser('static void set C(_) {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); listener.assertErrors([ expectedError(ParserErrorCode.MEMBER_WITH_CLASS_NAME, 16, 1), ]); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNotNull); expect(method.propertyKeyword, isNotNull); 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_type() { createParser('int set() {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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_static_class() { var unit = parseCompilationUnit('class C { static void m() {} }'); var c = unit.declarations[0] as ClassDeclaration; var method = c.members[0] as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNotNull); 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_static_mixin() { var unit = parseCompilationUnit('mixin C { static void m() {} }'); var c = unit.declarations[0] as MixinDeclaration; var method = c.members[0] as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNotNull); 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, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNull); expect(method.propertyKeyword, isNull); expect(method.returnType, isGenericFunctionType); expect(method.name, isNotNull); expect(method.operatorKeyword, isNotNull); expect(method.typeParameters, isNull); expect(method.parameters, isNotNull); NodeList parameters = method.parameters!.parameters; expect(parameters, hasLength(1)); expect( (parameters[0] as SimpleFormalParameter).type, isGenericFunctionType); expect(method.body, isNotNull); } void test_parseClassMember_operator_gtgtgt() { var unit = parseCompilationUnit( 'class C { bool operator >>>(other) => false; }', featureSet: tripleShift); var declaration = unit.declarations[0] as ClassDeclaration; var method = declaration.members[0] as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNull); expect(method.propertyKeyword, isNull); expect(method.returnType, isNotNull); expect(method.name.name, '>>>'); expect(method.operatorKeyword, isNotNull); expect(method.typeParameters, isNull); expect(method.parameters, isNotNull); expect(method.body, isNotNull); } void test_parseClassMember_operator_gtgtgteq() { var unit = parseCompilationUnit( 'class C { foo(int value) { x >>>= value; } }', featureSet: tripleShift); var declaration = unit.declarations[0] as ClassDeclaration; var method = declaration.members[0] as MethodDeclaration; var blockFunctionBody = method.body as BlockFunctionBody; NodeList statements = blockFunctionBody.block.statements; expect(statements, hasLength(1)); var statement = statements[0] as ExpressionStatement; var assignment = statement.expression as AssignmentExpression; var leftHandSide = assignment.leftHandSide as SimpleIdentifier; expect(leftHandSide.name, 'x'); expect(assignment.operator.lexeme, '>>>='); var rightHandSide = assignment.rightHandSide as SimpleIdentifier; expect(rightHandSide.name, 'value'); } void test_parseClassMember_operator_index() { createParser('int operator [](int i) {}'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; 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, isMethodDeclaration); var method = member as MethodDeclaration; 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_lessThan() { createParser('bool operator <(other) => false;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isMethodDeclaration); var method = member as MethodDeclaration; expect(method.documentationComment, isNull); expect(method.externalKeyword, isNull); expect(method.modifierKeyword, isNull); expect(method.propertyKeyword, isNull); expect(method.returnType, isNotNull); expect(method.name.name, '<'); 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 as SimpleIdentifier, 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, isEmptyFunctionBody); } void test_parseClassMember_redirectingFactory_expressionBody() { createParser('factory C() => throw 0;'); 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, isConstructorDeclaration); var constructor = member as ConstructorDeclaration; expect(constructor.externalKeyword, isNull); expect(constructor.constKeyword, isNull); expect(constructor.factoryKeyword!.keyword, Keyword.FACTORY); expect(constructor.returnType.name, 'C'); _assertIsDeclarationName(constructor.returnType as SimpleIdentifier, 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, isEmptyFunctionBody); } void test_parseConstructor_assert() { createParser('C(x, y) : _x = x, assert (x < y), _y = y;'); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isConstructorDeclaration); ConstructorDeclaration constructor = member as ConstructorDeclaration; NodeList initializers = constructor.initializers; expect(initializers, hasLength(3)); ConstructorInitializer initializer = initializers[1]; expect(initializer, isAssertInitializer); var assertInitializer = initializer as AssertInitializer; expect(assertInitializer.condition, isNotNull); expect(assertInitializer.message, isNull); } void test_parseConstructor_factory_const_external() { // Although the spec does not allow external const factory, // there are several instances of this in the Dart SDK. // For example `external const factory bool.fromEnvironment(...)`. createParser('external const factory C();'); ClassMember member = parser.parseClassMember('C'); expectNotNullIfNoErrors(member); assertNoErrors(); } void test_parseConstructor_factory_named() { createParser('factory C.foo() => throw 0;'); var constructor = parser.parseClassMember('C') as ConstructorDeclaration; assertNoErrors(); expect(constructor, isNotNull); expect(constructor.externalKeyword, isNull); expect(constructor.constKeyword, isNull); expect(constructor.factoryKeyword, isNotNull); expect(constructor.returnType.name, 'C'); _assertIsDeclarationName(constructor.returnType as SimpleIdentifier, 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, isExpressionFunctionBody); } 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, isConstructorDeclaration); ConstructorDeclaration constructor = member as ConstructorDeclaration; NodeList 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_invalidInitializer() { // https://github.com/dart-lang/sdk/issues/37693 parseCompilationUnit('class C{ C() : super() * (); }', errors: [ expectedError(ParserErrorCode.INVALID_INITIALIZER, 15, 12), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 26, 1), ]); } 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 as SimpleIdentifier, 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, isEmptyFunctionBody); } void test_parseConstructor_nullSuperArgList_openBrace_37735() { // https://github.com/dart-lang/sdk/issues/37735 var unit = parseCompilationUnit('class{const():super.{n', errors: [ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 5, 1), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1), expectedError(ParserErrorCode.INVALID_CONSTRUCTOR_NAME, 11, 1), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 20, 1), expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 1), expectedError(ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, 20, 1), expectedError(ParserErrorCode.EXPECTED_TOKEN, 21, 1), expectedError(ScannerErrorCode.EXPECTED_TOKEN, 22, 1), expectedError(ScannerErrorCode.EXPECTED_TOKEN, 22, 1), ]); var classDeclaration = unit.declarations[0] as ClassDeclaration; var constructor = classDeclaration.members[0] as ConstructorDeclaration; var invocation = constructor.initializers[0] as SuperConstructorInvocation; expect(invocation.argumentList.arguments, hasLength(0)); } void test_parseConstructor_operator_name() { var unit = parseCompilationUnit('class A { operator/() : super(); }', errors: [ expectedError(ParserErrorCode.INVALID_CONSTRUCTOR_NAME, 10, 8) ]); var classDeclaration = unit.declarations[0] as ClassDeclaration; var constructor = classDeclaration.members[0] as ConstructorDeclaration; var invocation = constructor.initializers[0] as SuperConstructorInvocation; expect(invocation.argumentList.arguments, hasLength(0)); } void test_parseConstructor_superIndexed() { createParser('C() : super()[];'); var constructor = parser.parseClassMember('C') as ConstructorDeclaration; listener.assertErrors([ expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 6, 5), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 14, 1), ]); expect(constructor, isNotNull); expect(constructor.externalKeyword, isNull); expect(constructor.constKeyword, isNull); expect(constructor.factoryKeyword, isNull); expect(constructor.returnType.name, 'C'); _assertIsDeclarationName(constructor.returnType as SimpleIdentifier, false); expect(constructor.name, isNull); expect(constructor.parameters, isNotNull); expect(constructor.parameters.parameters, isEmpty); expect(constructor.separator!.lexeme, ':'); expect(constructor.initializers, hasLength(1)); var initializer = constructor.initializers[0] as SuperConstructorInvocation; expect(initializer.argumentList.arguments, isEmpty); expect(constructor.redirectedConstructor, isNull); expect(constructor.body, isEmptyFunctionBody); } void test_parseConstructor_thisIndexed() { createParser('C() : this()[];'); var constructor = parser.parseClassMember('C') as ConstructorDeclaration; listener.assertErrors([ expectedError(ParserErrorCode.INVALID_THIS_IN_INITIALIZER, 6, 4), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 13, 1), ]); expect(constructor, isNotNull); expect(constructor.externalKeyword, isNull); expect(constructor.constKeyword, isNull); expect(constructor.factoryKeyword, isNull); expect(constructor.returnType.name, 'C'); _assertIsDeclarationName(constructor.returnType as SimpleIdentifier, false); expect(constructor.name, isNull); expect(constructor.parameters, isNotNull); expect(constructor.parameters.parameters, isEmpty); expect(constructor.separator!.lexeme, ':'); expect(constructor.initializers, hasLength(1)); var initializer = constructor.initializers[0] as RedirectingConstructorInvocation; expect(initializer.argumentList.arguments, isEmpty); expect(constructor.redirectedConstructor, isNull); expect(constructor.body, isEmptyFunctionBody); } 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 as SimpleIdentifier, 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, isEmptyFunctionBody); } 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, isConstructorDeclaration); ConstructorDeclaration constructor = member as ConstructorDeclaration; NodeList initializers = constructor.initializers; expect(initializers, hasLength(1)); ConstructorInitializer initializer = initializers[0]; expect(initializer, isConstructorFieldInitializer); expect((initializer as ConstructorFieldInitializer).expression, isParenthesizedExpression); expect(constructor.body, isBlockFunctionBody); } void test_parseConstructorFieldInitializer_qualified() { var initializer = parseConstructorInitializer('this.a = b') as ConstructorFieldInitializer; 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() { var initializer = parseConstructorInitializer('a = b') as ConstructorFieldInitializer; 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_parseField_abstract() { createParser('abstract int i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.abstractKeyword, isNotNull); } void test_parseField_abstract_external() { createParser('abstract external int i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.ABSTRACT_EXTERNAL_FIELD, 0, 8), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.abstractKeyword, isNotNull); expect(field.externalKeyword, isNotNull); } void test_parseField_abstract_late() { createParser('abstract late int? i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.ABSTRACT_LATE_FIELD, 0, 8), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.abstractKeyword, isNotNull); } void test_parseField_abstract_late_final() { createParser('abstract late final int? i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.ABSTRACT_LATE_FIELD, 0, 8), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.abstractKeyword, isNotNull); } void test_parseField_abstract_static() { createParser('abstract static int? i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.ABSTRACT_STATIC_FIELD, 0, 8), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.abstractKeyword, isNotNull); } void test_parseField_const_late() { createParser('const late T f = 0;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.CONFLICTING_MODIFIERS, 6, 4), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isTrue); expect(list.isFinal, isFalse); expect(list.isLate, isTrue); expect(list.lateKeyword, isNotNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseField_external() { createParser('external int i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.externalKeyword, isNotNull); } void test_parseField_external_abstract() { createParser('external abstract int i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.ABSTRACT_EXTERNAL_FIELD, 9, 8), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.abstractKeyword, isNotNull); expect(field.externalKeyword, isNotNull); } void test_parseField_external_late() { createParser('external late int? i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.externalKeyword, isNotNull); } void test_parseField_external_late_final() { createParser('external late final int? i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.externalKeyword, isNotNull); } void test_parseField_external_static() { createParser('external static int? i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.externalKeyword, isNotNull); } void test_parseField_final_late() { createParser('final late T f;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); assertErrors(errors: [ expectedError(ParserErrorCode.MODIFIER_OUT_OF_ORDER, 6, 4), ]); expect(member, isNotNull); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isFalse); expect(list.isFinal, isTrue); expect(list.isLate, isTrue); expect(list.lateKeyword, isNotNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseField_late() { createParser('late T f;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list.keyword, isNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isTrue); expect(list.lateKeyword, isNotNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseField_late_const() { createParser('late const T f = 0;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.CONFLICTING_MODIFIERS, 5, 5), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isTrue); expect(list.isFinal, isFalse); expect(list.isLate, isTrue); expect(list.lateKeyword, isNotNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseField_late_final() { createParser('late final T f;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isFalse); expect(list.isFinal, isTrue); expect(list.isLate, isTrue); expect(list.lateKeyword, isNotNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseField_late_var() { createParser('late var f;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isTrue); expect(list.lateKeyword, isNotNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseField_non_abstract() { createParser('int i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.abstractKeyword, isNull); } void test_parseField_non_external() { createParser('int i;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertNoErrors(); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.externalKeyword, isNull); } void test_parseField_var_late() { createParser('var late f;', featureSet: nonNullable); ClassMember member = parser.parseClassMember('C'); expect(member, isNotNull); assertErrors(errors: [ expectedError(ParserErrorCode.MODIFIER_OUT_OF_ORDER, 4, 4), ]); expect(member, isFieldDeclaration); var field = member as FieldDeclaration; expect(field.covariantKeyword, isNull); expect(field.documentationComment, isNull); expect(field.metadata, hasLength(0)); expect(field.staticKeyword, isNull); VariableDeclarationList list = field.fields; expect(list, isNotNull); expect(list.keyword, isNotNull); expect(list.isConst, isFalse); expect(list.isFinal, isFalse); expect(list.isLate, isTrue); expect(list.lateKeyword, isNotNull); NodeList variables = list.variables; expect(variables, hasLength(1)); VariableDeclaration variable = variables[0]; expect(variable.name, isNotNull); } void test_parseGetter_identifier_colon_issue_36961() { createParser('get a:'); var constructor = parser.parseClassMember('C') as ConstructorDeclaration; expect(constructor, isNotNull); listener.assertErrors([ expectedError(ParserErrorCode.GETTER_CONSTRUCTOR, 0, 3), expectedError(ParserErrorCode.MISSING_METHOD_PARAMETERS, 4, 1), expectedError(ParserErrorCode.INVALID_CONSTRUCTOR_NAME, 4, 1), expectedError(ParserErrorCode.MISSING_INITIALIZER, 5, 1), expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 6, 0), ]); expect(constructor.body, isNotNull); expect(constructor.documentationComment, isNull); expect(constructor.externalKeyword, isNull); expect(constructor.name, isNull); expect(constructor.parameters, isNotNull); expect(constructor.returnType, isNotNull); } void test_parseGetter_nonStatic() { createParser('/// Doc\nT get a;'); var method = parser.parseClassMember('C') as MethodDeclaration; 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;'); var method = parser.parseClassMember('C') as MethodDeclaration; 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;"); var declaration = parser.parseClassMember('C') as FieldDeclaration; 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;'); var declaration = parser.parseClassMember('C') as FieldDeclaration; 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);'); var method = parser.parseClassMember('C') as MethodDeclaration; 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);'); var method = parser.parseClassMember('C') as MethodDeclaration; 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) {}'); var method = parser.parseClassMember('C') as MethodDeclaration; 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); } void _parseClassMember_method_native() { createParser('m() native "str";'); var method = parser.parseClassMember('C') as MethodDeclaration; var body = method.body as NativeFunctionBody; expect(body.nativeKeyword, isNotNull); expect(body.stringLiteral, isNotNull); expect(body.stringLiteral?.stringValue, "str"); expect(body.semicolon, isNotNull); } void _parseClassMember_method_native_missing_literal() { createParser('m() native;'); var method = parser.parseClassMember('C') as MethodDeclaration; var body = method.body as NativeFunctionBody; expect(body.nativeKeyword, isNotNull); expect(body.stringLiteral, isNull); expect(body.semicolon, isNotNull); } void _parseClassMember_method_native_with_body() { createParser('m() native "str" {}'); parser.parseClassMember('C') as MethodDeclaration; } }