5dfce919cd
Extension methods can no longer be disabled. This CL removes the option from the scanner config and the parser related specific recovery. It also removes any specific (triggered) test of the functionality. A follow-up CL will do the same for NNBD. Change-Id: Ia385008e5ed1333fb37697b8fe424b8759bce198 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403581 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
244 lines
9.7 KiB
Dart
244 lines
9.7 KiB
Dart
// 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));
|
|
}
|
|
}
|