Skip to content

Commit

Permalink
Extension type. Report EXTENSION_TYPE_WITH_ABSTRACT_MEMBER.
Browse files Browse the repository at this point in the history
dart-lang/language@913b81e

Change-Id: Ic3303744ea4c1f2cc90df63a3ae52b51861757ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/322983
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
  • Loading branch information
scheglov authored and Commit Queue committed Aug 28, 2023
1 parent 52143ec commit 83fc715
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,10 @@ CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT:
status: noFix
CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF:
status: noFix
CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER:
status: needsFix
notes: |-
Convert to block body.
CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER:
status: needsFix
notes: |-
Expand Down
10 changes: 10 additions & 0 deletions pkg/analyzer/lib/src/error/codes.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,16 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
correctionMessage: "Try specifying a different type.",
);

/// Parameters:
/// 0: the name of the abstract method
/// 1: the name of the enclosing extension type
static const CompileTimeErrorCode EXTENSION_TYPE_WITH_ABSTRACT_MEMBER =
CompileTimeErrorCode(
'EXTENSION_TYPE_WITH_ABSTRACT_MEMBER',
"'{0}' must have a method body because '{1}' is an extension type.",
correctionMessage: "Try adding a body to '{0}'.",
);

static const CompileTimeErrorCode EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER =
CompileTimeErrorCode(
'EXTERNAL_WITH_INITIALIZER',
Expand Down
1 change: 1 addition & 0 deletions pkg/analyzer/lib/src/error/error_code_values.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ const List<ErrorCode> errorCodeValues = [
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE,
CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT,
CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF,
CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER,
CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER,
CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER,
CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER,
Expand Down
17 changes: 17 additions & 0 deletions pkg/analyzer/lib/src/generated/error_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
node: node,
element: element,
);
_checkForExtensionTypeWithAbstractMember(node);

super.visitExtensionTypeDeclaration(node);
} finally {
Expand Down Expand Up @@ -2961,6 +2962,22 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
}
}

void _checkForExtensionTypeWithAbstractMember(
ExtensionTypeDeclarationImpl node,
) {
for (final member in node.members) {
if (member is MethodDeclarationImpl && !member.isStatic) {
if (member.isAbstract) {
errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER,
member,
[member.name.lexeme, node.name.lexeme],
);
}
}
}
}

/// Verify that the given field formal [parameter] is in a constructor
/// declaration.
///
Expand Down
7 changes: 7 additions & 0 deletions pkg/analyzer/messages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5154,6 +5154,13 @@ CompileTimeErrorCode:
problemMessage: "The extension type representation can't depend on itself."
correctionMessage: Try specifying a different type.
comment: No parameters.
EXTENSION_TYPE_WITH_ABSTRACT_MEMBER:
problemMessage: "'{0}' must have a method body because '{1}' is an extension type."
correctionMessage: "Try adding a body to '{0}'."
comment: |-
Parameters:
0: the name of the abstract method
1: the name of the enclosing extension type
EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER:
sharedName: EXTERNAL_WITH_INITIALIZER
problemMessage: External fields can't have initializers.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) 2023, 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/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../dart/resolution/context_collection_resolution.dart';

main() {
defineReflectiveSuite(() {
defineReflectiveTests(ExtensionTypeWithAbstractMemberTest);
});
}

@reflectiveTest
class ExtensionTypeWithAbstractMemberTest extends PubPackageResolutionTest {
test_getter() async {
await assertErrorsInCode('''
extension type A(int it) {
int get foo;
}
''', [
error(CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER, 29, 12),
]);
}

test_getter_external() async {
await assertNoErrorsInCode('''
extension type A(int it) {
external int get foo;
}
''');
}

test_getter_static() async {
await assertErrorsInCode('''
extension type A(int it) {
static int get foo;
}
''', [
error(ParserErrorCode.MISSING_FUNCTION_BODY, 47, 1),
]);
}

test_method() async {
await assertErrorsInCode('''
extension type A(int it) {
void foo();
}
''', [
error(CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER, 29, 11),
]);
}

test_method_external() async {
await assertNoErrorsInCode('''
extension type A(int it) {
external void foo();
}
''');
}

test_method_static() async {
await assertErrorsInCode('''
extension type A(int it) {
static void foo();
}
''', [
error(ParserErrorCode.MISSING_FUNCTION_BODY, 46, 1),
]);
}

test_setter() async {
await assertErrorsInCode('''
extension type A(int it) {
set foo(int _);
}
''', [
error(CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER, 29, 15),
]);
}

test_setter_external() async {
await assertNoErrorsInCode('''
extension type A(int it) {
external set foo(int _);
}
''');
}

test_setter_static() async {
await assertErrorsInCode('''
extension type A(int it) {
static set foo(int _);
}
''', [
error(ParserErrorCode.MISSING_FUNCTION_BODY, 50, 1),
]);
}
}
3 changes: 3 additions & 0 deletions pkg/analyzer/test/src/diagnostics/test_all.dart
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ import 'extension_type_inherited_member_conflict_test.dart'
as extension_type_inherited_member_conflict;
import 'extension_type_representation_depends_on_itself_test.dart'
as extension_type_representation_depends_on_itself;
import 'extension_type_with_abstract_member_test.dart'
as extension_type_with_abstract_member;
import 'external_field_constructor_initializer_test.dart'
as external_field_constructor_initializer;
import 'external_field_initializer_test.dart' as external_field_initializer;
Expand Down Expand Up @@ -1067,6 +1069,7 @@ main() {
extension_type_implements_representation_not_supertype.main();
extension_type_inherited_member_conflict.main();
extension_type_representation_depends_on_itself.main();
extension_type_with_abstract_member.main();
external_field_constructor_initializer.main();
external_field_initializer.main();
external_variable_initializer.main();
Expand Down

0 comments on commit 83fc715

Please sign in to comment.