|  | // 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/ast/ast.dart'; | 
|  | import 'package:analyzer/src/dart/scanner/scanner.dart'; | 
|  | import 'package:test/test.dart'; | 
|  | import 'package:test_reflective_loader/test_reflective_loader.dart'; | 
|  |  | 
|  | import 'parser_test_base.dart'; | 
|  |  | 
|  | main() { | 
|  | defineReflectiveSuite(() { | 
|  | defineReflectiveTests(ExtensionMethodsParserTest); | 
|  | }); | 
|  | } | 
|  |  | 
|  | @reflectiveTest | 
|  | class ExtensionMethodsParserTest extends FastaParserTestCase { | 
|  | void test_complex_extends() { | 
|  | var unit = parseCompilationUnit( | 
|  | 'extension E extends A with B, C implements D { }', | 
|  | errors: [ | 
|  | expectedError(ParserErrorCode.EXPECTED_INSTEAD, 12, 7), | 
|  | expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 22, 4), | 
|  | expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 28, 1), | 
|  | expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 32, 10), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'extends'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, 'A'); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_complex_implements() { | 
|  | var unit = parseCompilationUnit('extension E implements C, D { }', errors: [ | 
|  | expectedError(ParserErrorCode.EXPECTED_INSTEAD, 12, 10), | 
|  | expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 24, 1), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'implements'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, 'C'); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_complex_type() { | 
|  | var unit = parseCompilationUnit('extension E on C<T> { }'); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | var namedType = extension.onClause!.extendedType as NamedType; | 
|  | expect(namedType.name2.lexeme, 'C'); | 
|  | expect(namedType.typeArguments!.arguments, hasLength(1)); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_complex_type2() { | 
|  | var unit = parseCompilationUnit('extension E<T> on C<T> { }'); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | var namedType = extension.onClause!.extendedType as NamedType; | 
|  | expect(namedType.name2.lexeme, 'C'); | 
|  | expect(namedType.typeArguments!.arguments, hasLength(1)); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_complex_type2_no_name() { | 
|  | var unit = parseCompilationUnit('extension<T> on C<T> { }'); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name, isNull); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | var namedType = extension.onClause!.extendedType as NamedType; | 
|  | expect(namedType.name2.lexeme, 'C'); | 
|  | expect(namedType.typeArguments!.arguments, hasLength(1)); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_constructor_named() { | 
|  | var unit = parseCompilationUnit(''' | 
|  | extension E on C { | 
|  | E.named(); | 
|  | } | 
|  | class C {} | 
|  | ''', errors: [ | 
|  | expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(2)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_constructor_unnamed() { | 
|  | var unit = parseCompilationUnit(''' | 
|  | extension E on C { | 
|  | E(); | 
|  | } | 
|  | class C {} | 
|  | ''', errors: [ | 
|  | expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(2)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_missing_on() { | 
|  | var unit = parseCompilationUnit('extension E', errors: [ | 
|  | expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1), | 
|  | expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 11, 0), | 
|  | expectedError(ParserErrorCode.EXPECTED_EXTENSION_BODY, 11, 0), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, ''); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_missing_on_withBlock() { | 
|  | var unit = parseCompilationUnit('extension E {}', errors: [ | 
|  | expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1), | 
|  | expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 1), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, ''); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_missing_on_withClassAndBlock() { | 
|  | var unit = parseCompilationUnit('extension E C {}', errors: [ | 
|  | expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, 'C'); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_parse_toplevel_member_called_late_calling_self() { | 
|  | var unit = parseCompilationUnit('void late() { late(); }'); | 
|  | var method = unit.declarations[0] as FunctionDeclaration; | 
|  |  | 
|  | expect(method.documentationComment, isNull); | 
|  | expect(method.externalKeyword, isNull); | 
|  | expect(method.propertyKeyword, isNull); | 
|  | expect(method.returnType, isNotNull); | 
|  | expect(method.name.lexeme, 'late'); | 
|  | expect(method.functionExpression, isNotNull); | 
|  |  | 
|  | var body = method.functionExpression.body as BlockFunctionBody; | 
|  | var statement = body.block.statements[0] as ExpressionStatement; | 
|  | var invocation = statement.expression as MethodInvocation; | 
|  | expect(invocation.operator, isNull); | 
|  | expect(invocation.toSource(), 'late()'); | 
|  | } | 
|  |  | 
|  | void test_simple() { | 
|  | var unit = parseCompilationUnit('extension E on C { }'); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, 'C'); | 
|  | var namedType = extension.onClause!.extendedType as NamedType; | 
|  | expect(namedType.name2.lexeme, 'C'); | 
|  | expect(namedType.typeArguments, isNull); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_simple_extends() { | 
|  | var unit = parseCompilationUnit('extension E extends C { }', errors: [ | 
|  | expectedError(ParserErrorCode.EXPECTED_INSTEAD, 12, 7), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'extends'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, 'C'); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_simple_implements() { | 
|  | var unit = parseCompilationUnit('extension E implements C { }', errors: [ | 
|  | expectedError(ParserErrorCode.EXPECTED_INSTEAD, 12, 10), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'implements'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, 'C'); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_simple_no_name() { | 
|  | var unit = parseCompilationUnit('extension on C { }'); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name, isNull); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, 'C'); | 
|  | var namedType = extension.onClause!.extendedType as NamedType; | 
|  | expect(namedType.name2.lexeme, 'C'); | 
|  | expect(namedType.typeArguments, isNull); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_simple_with() { | 
|  | var unit = parseCompilationUnit('extension E with C { }', errors: [ | 
|  | expectedError(ParserErrorCode.EXPECTED_INSTEAD, 12, 4), | 
|  | ]); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'with'); | 
|  | expect((extension.onClause!.extendedType as NamedType).name2.lexeme, 'C'); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  |  | 
|  | void test_void_type() { | 
|  | var unit = parseCompilationUnit('extension E on void { }'); | 
|  | expect(unit.declarations, hasLength(1)); | 
|  | var extension = unit.declarations[0] as ExtensionDeclaration; | 
|  | expect(extension.name!.lexeme, 'E'); | 
|  | expect(extension.onClause!.onKeyword.lexeme, 'on'); | 
|  | expect( | 
|  | (extension.onClause!.extendedType as NamedType).name2.lexeme, 'void'); | 
|  | expect(extension.members, hasLength(0)); | 
|  | } | 
|  | } |