Skip to content

Commit 79ea6a4

Browse files
scheglovCommit Queue
authored and
Commit Queue
committed
[beta] Issue 52160. Report BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY for implementing 'base' via 'extends'.
Bug: #52160 Change-Id: I47a72021a002663d04fd8ea14c11a012917e8a8c Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/298320 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/298201 Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent d2b8bf9 commit 79ea6a4

5 files changed

+75
-24
lines changed

pkg/analyzer/lib/src/error/base_or_final_type_verifier.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,15 @@ class BaseOrFinalTypeVerifier {
198198
superElement.isSealed &&
199199
baseOrFinalSuperElement.library != element.library) {
200200
if (baseOrFinalSuperElement.isBase) {
201+
var errorCode = baseOrFinalSuperElement is MixinElement
202+
? CompileTimeErrorCode.BASE_MIXIN_IMPLEMENTED_OUTSIDE_OF_LIBRARY
203+
: CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY;
201204
_errorReporter.reportErrorForNode(
202-
CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY,
203-
implementsNamedType,
204-
[baseOrFinalSuperElement.displayName],
205-
contextMessage);
205+
errorCode,
206+
implementsNamedType,
207+
[baseOrFinalSuperElement.displayName],
208+
contextMessage,
209+
);
206210
return true;
207211
}
208212
}

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

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,24 +1748,32 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
17481748
for (NamedType interface in implementsClause.interfaces) {
17491749
final interfaceType = interface.type;
17501750
if (interfaceType is InterfaceType) {
1751-
final interfaceElement = interfaceType.element;
1752-
if (interfaceElement is ClassOrMixinElementImpl &&
1753-
interfaceElement.isBase &&
1754-
interfaceElement.library != _currentLibrary &&
1755-
!_mayIgnoreClassModifiers(interfaceElement.library)) {
1756-
// Should this be combined with _checkForImplementsClauseErrorCodes
1757-
// to avoid double errors if implementing `int`.
1758-
if (interfaceElement is ClassElementImpl &&
1759-
!interfaceElement.isSealed) {
1760-
errorReporter.reportErrorForNode(
1761-
CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY,
1762-
interface,
1763-
[interfaceElement.name]);
1764-
} else if (interfaceElement is MixinElement) {
1765-
errorReporter.reportErrorForNode(
1766-
CompileTimeErrorCode.BASE_MIXIN_IMPLEMENTED_OUTSIDE_OF_LIBRARY,
1767-
interface,
1768-
[interfaceElement.name]);
1751+
final implementedInterfaces = [
1752+
interfaceType,
1753+
...interfaceType.element.allSupertypes,
1754+
].map((e) => e.element).toList();
1755+
for (final interfaceElement in implementedInterfaces) {
1756+
if (interfaceElement is ClassOrMixinElementImpl &&
1757+
interfaceElement.isBase &&
1758+
interfaceElement.library != _currentLibrary &&
1759+
!_mayIgnoreClassModifiers(interfaceElement.library)) {
1760+
// Should this be combined with _checkForImplementsClauseErrorCodes
1761+
// to avoid double errors if implementing `int`.
1762+
if (interfaceElement is ClassElementImpl &&
1763+
!interfaceElement.isSealed) {
1764+
errorReporter.reportErrorForNode(
1765+
CompileTimeErrorCode
1766+
.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY,
1767+
interface,
1768+
[interfaceElement.name]);
1769+
} else if (interfaceElement is MixinElement) {
1770+
errorReporter.reportErrorForNode(
1771+
CompileTimeErrorCode
1772+
.BASE_MIXIN_IMPLEMENTED_OUTSIDE_OF_LIBRARY,
1773+
interface,
1774+
[interfaceElement.name]);
1775+
}
1776+
break;
17691777
}
17701778
}
17711779
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,21 @@ class C implements B {}
9090
]);
9191
}
9292

93+
test_class_outside_viaExtends() async {
94+
newFile('$testPackageLibPath/a.dart', r'''
95+
base class A {}
96+
''');
97+
98+
await assertErrorsInCode(r'''
99+
import 'a.dart';
100+
base class B extends A {}
101+
base class C implements B {}
102+
''', [
103+
error(CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY, 67,
104+
1),
105+
]);
106+
}
107+
93108
test_class_outside_viaTypedef_inside() async {
94109
newFile('$testPackageLibPath/foo.dart', r'''
95110
base class Foo {}

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ base class Bar implements Foo {}
3737
]);
3838
}
3939

40+
test_class_outside_viaExtends() async {
41+
newFile('$testPackageLibPath/a.dart', r'''
42+
base mixin A {}
43+
''');
44+
45+
await assertErrorsInCode(r'''
46+
import 'a.dart';
47+
48+
sealed class B extends Object with A {}
49+
class C implements B {}
50+
''', [
51+
error(
52+
CompileTimeErrorCode.BASE_MIXIN_IMPLEMENTED_OUTSIDE_OF_LIBRARY, 77, 1,
53+
contextMessages: [message('/home/test/lib/a.dart', 11, 1)]),
54+
]);
55+
}
56+
4057
test_class_outside_viaTypedef_inside() async {
4158
newFile('$testPackageLibPath/foo.dart', r'''
4259
base mixin Foo {}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ final class AbiSpecificInteger4 implements AbiSpecificInteger1 {
5858
const AbiSpecificInteger4();
5959
}
6060
''', [
61+
error(CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY, 216,
62+
19),
6163
error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 216, 19),
6264
]);
6365
}
@@ -69,8 +71,9 @@ final class S extends Struct {}
6971
final class C implements S {}
7072
''', [
7173
error(FfiCode.EMPTY_STRUCT, 31, 1),
72-
error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 76, 1,
73-
messageContains: ["class 'C'", "implement 'S'"]),
74+
error(CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY, 76,
75+
1),
76+
error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 76, 1),
7477
]);
7578
}
7679

@@ -83,6 +86,8 @@ final class S extends Struct {}
8386
import 'lib1.dart' as lib1;
8487
class C implements lib1.S {}
8588
''', [
89+
error(CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY, 47,
90+
6),
8691
error(CompileTimeErrorCode.FINAL_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY, 47,
8792
6),
8893
error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 47, 6),
@@ -96,6 +101,8 @@ final class S extends Union {}
96101
final class C implements S {}
97102
''', [
98103
error(FfiCode.EMPTY_STRUCT, 31, 1),
104+
error(CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY, 75,
105+
1),
99106
error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 75, 1),
100107
]);
101108
}

0 commit comments

Comments
 (0)