Skip to content

Commit 83fc715

Browse files
scheglovCommit Queue
authored andcommitted
Extension type. Report EXTENSION_TYPE_WITH_ABSTRACT_MEMBER.
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>
1 parent 52143ec commit 83fc715

File tree

7 files changed

+144
-0
lines changed

7 files changed

+144
-0
lines changed

pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,10 @@ CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT:
673673
status: noFix
674674
CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF:
675675
status: noFix
676+
CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER:
677+
status: needsFix
678+
notes: |-
679+
Convert to block body.
676680
CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER:
677681
status: needsFix
678682
notes: |-

pkg/analyzer/lib/src/error/codes.g.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,16 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
17051705
correctionMessage: "Try specifying a different type.",
17061706
);
17071707

1708+
/// Parameters:
1709+
/// 0: the name of the abstract method
1710+
/// 1: the name of the enclosing extension type
1711+
static const CompileTimeErrorCode EXTENSION_TYPE_WITH_ABSTRACT_MEMBER =
1712+
CompileTimeErrorCode(
1713+
'EXTENSION_TYPE_WITH_ABSTRACT_MEMBER',
1714+
"'{0}' must have a method body because '{1}' is an extension type.",
1715+
correctionMessage: "Try adding a body to '{0}'.",
1716+
);
1717+
17081718
static const CompileTimeErrorCode EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER =
17091719
CompileTimeErrorCode(
17101720
'EXTERNAL_WITH_INITIALIZER',

pkg/analyzer/lib/src/error/error_code_values.g.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ const List<ErrorCode> errorCodeValues = [
205205
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE,
206206
CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT,
207207
CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF,
208+
CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER,
208209
CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER,
209210
CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER,
210211
CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER,

pkg/analyzer/lib/src/generated/error_verifier.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
718718
node: node,
719719
element: element,
720720
);
721+
_checkForExtensionTypeWithAbstractMember(node);
721722

722723
super.visitExtensionTypeDeclaration(node);
723724
} finally {
@@ -2961,6 +2962,22 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
29612962
}
29622963
}
29632964

2965+
void _checkForExtensionTypeWithAbstractMember(
2966+
ExtensionTypeDeclarationImpl node,
2967+
) {
2968+
for (final member in node.members) {
2969+
if (member is MethodDeclarationImpl && !member.isStatic) {
2970+
if (member.isAbstract) {
2971+
errorReporter.reportErrorForNode(
2972+
CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER,
2973+
member,
2974+
[member.name.lexeme, node.name.lexeme],
2975+
);
2976+
}
2977+
}
2978+
}
2979+
}
2980+
29642981
/// Verify that the given field formal [parameter] is in a constructor
29652982
/// declaration.
29662983
///

pkg/analyzer/messages.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5154,6 +5154,13 @@ CompileTimeErrorCode:
51545154
problemMessage: "The extension type representation can't depend on itself."
51555155
correctionMessage: Try specifying a different type.
51565156
comment: No parameters.
5157+
EXTENSION_TYPE_WITH_ABSTRACT_MEMBER:
5158+
problemMessage: "'{0}' must have a method body because '{1}' is an extension type."
5159+
correctionMessage: "Try adding a body to '{0}'."
5160+
comment: |-
5161+
Parameters:
5162+
0: the name of the abstract method
5163+
1: the name of the enclosing extension type
51575164
EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER:
51585165
sharedName: EXTERNAL_WITH_INITIALIZER
51595166
problemMessage: External fields can't have initializers.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
6+
import 'package:analyzer/src/error/codes.dart';
7+
import 'package:test_reflective_loader/test_reflective_loader.dart';
8+
9+
import '../dart/resolution/context_collection_resolution.dart';
10+
11+
main() {
12+
defineReflectiveSuite(() {
13+
defineReflectiveTests(ExtensionTypeWithAbstractMemberTest);
14+
});
15+
}
16+
17+
@reflectiveTest
18+
class ExtensionTypeWithAbstractMemberTest extends PubPackageResolutionTest {
19+
test_getter() async {
20+
await assertErrorsInCode('''
21+
extension type A(int it) {
22+
int get foo;
23+
}
24+
''', [
25+
error(CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER, 29, 12),
26+
]);
27+
}
28+
29+
test_getter_external() async {
30+
await assertNoErrorsInCode('''
31+
extension type A(int it) {
32+
external int get foo;
33+
}
34+
''');
35+
}
36+
37+
test_getter_static() async {
38+
await assertErrorsInCode('''
39+
extension type A(int it) {
40+
static int get foo;
41+
}
42+
''', [
43+
error(ParserErrorCode.MISSING_FUNCTION_BODY, 47, 1),
44+
]);
45+
}
46+
47+
test_method() async {
48+
await assertErrorsInCode('''
49+
extension type A(int it) {
50+
void foo();
51+
}
52+
''', [
53+
error(CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER, 29, 11),
54+
]);
55+
}
56+
57+
test_method_external() async {
58+
await assertNoErrorsInCode('''
59+
extension type A(int it) {
60+
external void foo();
61+
}
62+
''');
63+
}
64+
65+
test_method_static() async {
66+
await assertErrorsInCode('''
67+
extension type A(int it) {
68+
static void foo();
69+
}
70+
''', [
71+
error(ParserErrorCode.MISSING_FUNCTION_BODY, 46, 1),
72+
]);
73+
}
74+
75+
test_setter() async {
76+
await assertErrorsInCode('''
77+
extension type A(int it) {
78+
set foo(int _);
79+
}
80+
''', [
81+
error(CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER, 29, 15),
82+
]);
83+
}
84+
85+
test_setter_external() async {
86+
await assertNoErrorsInCode('''
87+
extension type A(int it) {
88+
external set foo(int _);
89+
}
90+
''');
91+
}
92+
93+
test_setter_static() async {
94+
await assertErrorsInCode('''
95+
extension type A(int it) {
96+
static set foo(int _);
97+
}
98+
''', [
99+
error(ParserErrorCode.MISSING_FUNCTION_BODY, 50, 1),
100+
]);
101+
}
102+
}

pkg/analyzer/test/src/diagnostics/test_all.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ import 'extension_type_inherited_member_conflict_test.dart'
260260
as extension_type_inherited_member_conflict;
261261
import 'extension_type_representation_depends_on_itself_test.dart'
262262
as extension_type_representation_depends_on_itself;
263+
import 'extension_type_with_abstract_member_test.dart'
264+
as extension_type_with_abstract_member;
263265
import 'external_field_constructor_initializer_test.dart'
264266
as external_field_constructor_initializer;
265267
import 'external_field_initializer_test.dart' as external_field_initializer;
@@ -1067,6 +1069,7 @@ main() {
10671069
extension_type_implements_representation_not_supertype.main();
10681070
extension_type_inherited_member_conflict.main();
10691071
extension_type_representation_depends_on_itself.main();
1072+
extension_type_with_abstract_member.main();
10701073
external_field_constructor_initializer.main();
10711074
external_field_initializer.main();
10721075
external_variable_initializer.main();

0 commit comments

Comments
 (0)