From 2e19faaec98181930c2c5947123970f077012ca1 Mon Sep 17 00:00:00 2001 From: Kallen Tu Date: Fri, 24 Mar 2023 17:09:09 +0000 Subject: [PATCH] [cfe] Report an error when implementing a base class through a sealed class. Bug: https://github.com/dart-lang/sdk/issues/51811 Change-Id: Ifad0519332965d79719173702293b48e94231024 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291040 Reviewed-by: Johnni Winther Commit-Queue: Kallen Tu --- .../lib/src/messages/codes_generated.dart | 28 ++++++ .../lib/src/fasta/source/source_loader.dart | 28 +++++- pkg/front_end/messages.yaml | 4 + .../base/outside_library_implements/main.dart | 22 +++++ .../main.dart.strong.expect | 85 +++++++++++++++++++ .../main.dart.strong.transformed.expect | 85 +++++++++++++++++++ .../main.dart.textual_outline.expect | 16 ++++ .../main.dart.textual_outline_modelled.expect | 16 ++++ .../main.dart.weak.expect | 85 +++++++++++++++++++ .../main.dart.weak.modular.expect | 75 ++++++++++++++++ .../main.dart.weak.outline.expect | 78 +++++++++++++++++ .../main.dart.weak.transformed.expect | 85 +++++++++++++++++++ .../outside_library_implements/main_lib.dart | 5 ++ .../outside_library_implements/test.options | 1 + ...se_class_different_library_error_test.dart | 22 ++--- 15 files changed, 619 insertions(+), 16 deletions(-) create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.strong.expect create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.expect create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart create mode 100644 pkg/front_end/testcases/class_modifiers/base/outside_library_implements/test.options diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index 5b07024065e..c46dd6503f6 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -367,6 +367,34 @@ Message _withArgumentsBaseClassImplementedOutsideOfLibrary(String name) { arguments: {'name': name}); } +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template + templateBaseClassImplementedOutsideOfLibraryCause = + const Template( + problemMessageTemplate: + r"""The type '#name' is a subtype of '#name2', and '#name2' is defined here.""", + withArguments: _withArgumentsBaseClassImplementedOutsideOfLibraryCause); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code + codeBaseClassImplementedOutsideOfLibraryCause = + const Code( + "BaseClassImplementedOutsideOfLibraryCause", + severity: Severity.context); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsBaseClassImplementedOutsideOfLibraryCause( + String name, String name2) { + if (name.isEmpty) throw 'No name provided'; + name = demangleMixinApplicationName(name); + if (name2.isEmpty) throw 'No name provided'; + name2 = demangleMixinApplicationName(name2); + return new Message(codeBaseClassImplementedOutsideOfLibraryCause, + problemMessage: + """The type '${name}' is a subtype of '${name2}', and '${name2}' is defined here.""", + arguments: {'name': name, 'name2': name2}); +} + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template< Message Function( diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart index 98ae00b538f..c296c71a3d8 100644 --- a/pkg/front_end/lib/src/fasta/source/source_loader.dart +++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart @@ -2236,7 +2236,8 @@ severity: $severity // All subtypes of a base or final class or mixin must also be base, // final, or sealed. Report an error otherwise. - void checkForBaseFinalRestriction(ClassBuilder superclass) { + void checkForBaseFinalRestriction(ClassBuilder superclass, + {TypeBuilder? implementsBuilder}) { if (classToBaseOrFinalSuperClass.containsKey(cls)) { // We've already visited this class. Don't check it again. return; @@ -2265,7 +2266,27 @@ severity: $severity classToBaseOrFinalSuperClass[cls] = baseOrFinalSuperClass; - if (!cls.isBase && + if (implementsBuilder != null && + superclass.isSealed && + baseOrFinalSuperClass.libraryBuilder.origin != + cls.libraryBuilder.origin) { + // It's an error to implement a class if it has a supertype from a + // different library which is marked base. + if (baseOrFinalSuperClass.isBase) { + cls.addProblem( + templateBaseClassImplementedOutsideOfLibrary + .withArguments(baseOrFinalSuperClass.fullNameForErrors), + implementsBuilder.charOffset ?? TreeNode.noOffset, + noLength, + context: [ + templateBaseClassImplementedOutsideOfLibraryCause + .withArguments(superclass.fullNameForErrors, + baseOrFinalSuperClass.fullNameForErrors) + .withLocation(baseOrFinalSuperClass.fileUri, + baseOrFinalSuperClass.charOffset, noLength) + ]); + } + } else if (!cls.isBase && !cls.isFinal && !cls.isSealed && !cls.cls.isAnonymousMixin && @@ -2425,7 +2446,8 @@ severity: $severity // supertype is a final type used outside of its library. // However, we still check the base and final subtyping // restriction if we are evaluating a multiple type 'on' clause. - checkForBaseFinalRestriction(interfaceDeclaration); + checkForBaseFinalRestriction(interfaceDeclaration, + implementsBuilder: interfaceBuilder); } if (cls.libraryBuilder.origin != diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index da869f754c1..4f903013d67 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -6277,6 +6277,10 @@ BaseClassImplementedOutsideOfLibrary: lib.dart: base class A {} +BaseClassImplementedOutsideOfLibraryCause: + problemMessage: "The type '#name' is a subtype of '#name2', and '#name2' is defined here." + severity: CONTEXT + BaseMixinImplementedOutsideOfLibrary: problemMessage: "The mixin '#name' can't be implemented outside of its library because it's a base mixin." analyzerCode: BASE_MIXIN_IMPLEMENTED_OUTSIDE_OF_LIBRARY diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart new file mode 100644 index 00000000000..bba0330e5e2 --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart @@ -0,0 +1,22 @@ +// 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 'main_lib.dart'; + +sealed class SealedClassExtendsBase extends A {} /* Ok */ + +class ClassImplementsIndirectBase + implements SealedClassExtendsBase {} /* Error */ + +final class FinalClassImplementsIndirectBase + implements SealedClassExtendsBase {} /* Error */ + +interface class InterfaceClassImplementsIndirectBase + implements SealedClassExtendsBase {} /* Error */ + +sealed class SealedClassImplementsIndirectBase + implements SealedClassExtendsBase {} /* Error */ + +base class BaseClassImplementsIndirectBase + implements SealedClassExtendsBase {} /* Error */ diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.strong.expect b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.strong.expect new file mode 100644 index 00000000000..206199dd7ef --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.strong.expect @@ -0,0 +1,85 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:10:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:13:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:16:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:19:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:22:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +import self as self; +import "main_lib.dart" as mai; +import "dart:core" as core; + +import "org-dartlang-testcase:///main_lib.dart"; + +abstract sealed class SealedClassExtendsBase extends mai::A { + synthetic constructor •() → self::SealedClassExtendsBase + : super mai::A::•() + ; +} +class ClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::ClassImplementsIndirectBase + : super core::Object::•() + ; +} +final class FinalClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::FinalClassImplementsIndirectBase + : super core::Object::•() + ; +} +interface class InterfaceClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::InterfaceClassImplementsIndirectBase + : super core::Object::•() + ; +} +abstract sealed class SealedClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::SealedClassImplementsIndirectBase + : super core::Object::•() + ; +} +base class BaseClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::BaseClassImplementsIndirectBase + : super core::Object::•() + ; +} + +library /*isNonNullableByDefault*/; +import self as mai; +import "dart:core" as core; + +base class A extends core::Object { + synthetic constructor •() → mai::A + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.strong.transformed.expect b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.strong.transformed.expect new file mode 100644 index 00000000000..206199dd7ef --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.strong.transformed.expect @@ -0,0 +1,85 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:10:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:13:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:16:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:19:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:22:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +import self as self; +import "main_lib.dart" as mai; +import "dart:core" as core; + +import "org-dartlang-testcase:///main_lib.dart"; + +abstract sealed class SealedClassExtendsBase extends mai::A { + synthetic constructor •() → self::SealedClassExtendsBase + : super mai::A::•() + ; +} +class ClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::ClassImplementsIndirectBase + : super core::Object::•() + ; +} +final class FinalClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::FinalClassImplementsIndirectBase + : super core::Object::•() + ; +} +interface class InterfaceClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::InterfaceClassImplementsIndirectBase + : super core::Object::•() + ; +} +abstract sealed class SealedClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::SealedClassImplementsIndirectBase + : super core::Object::•() + ; +} +base class BaseClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::BaseClassImplementsIndirectBase + : super core::Object::•() + ; +} + +library /*isNonNullableByDefault*/; +import self as mai; +import "dart:core" as core; + +base class A extends core::Object { + synthetic constructor •() → mai::A + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.textual_outline.expect b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.textual_outline.expect new file mode 100644 index 00000000000..37450a19670 --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.textual_outline.expect @@ -0,0 +1,16 @@ +import 'main_lib.dart'; + +sealed class SealedClassExtendsBase extends A {} + +class ClassImplementsIndirectBase implements SealedClassExtendsBase {} + +final class FinalClassImplementsIndirectBase + implements SealedClassExtendsBase {} + +interface class InterfaceClassImplementsIndirectBase + implements SealedClassExtendsBase {} + +sealed class SealedClassImplementsIndirectBase + implements SealedClassExtendsBase {} + +base class BaseClassImplementsIndirectBase implements SealedClassExtendsBase {} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..6107ecfbf7a --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.textual_outline_modelled.expect @@ -0,0 +1,16 @@ +import 'main_lib.dart'; + +base class BaseClassImplementsIndirectBase implements SealedClassExtendsBase {} + +class ClassImplementsIndirectBase implements SealedClassExtendsBase {} + +final class FinalClassImplementsIndirectBase + implements SealedClassExtendsBase {} + +interface class InterfaceClassImplementsIndirectBase + implements SealedClassExtendsBase {} + +sealed class SealedClassExtendsBase extends A {} + +sealed class SealedClassImplementsIndirectBase + implements SealedClassExtendsBase {} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.expect b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.expect new file mode 100644 index 00000000000..206199dd7ef --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.expect @@ -0,0 +1,85 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:10:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:13:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:16:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:19:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:22:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +import self as self; +import "main_lib.dart" as mai; +import "dart:core" as core; + +import "org-dartlang-testcase:///main_lib.dart"; + +abstract sealed class SealedClassExtendsBase extends mai::A { + synthetic constructor •() → self::SealedClassExtendsBase + : super mai::A::•() + ; +} +class ClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::ClassImplementsIndirectBase + : super core::Object::•() + ; +} +final class FinalClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::FinalClassImplementsIndirectBase + : super core::Object::•() + ; +} +interface class InterfaceClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::InterfaceClassImplementsIndirectBase + : super core::Object::•() + ; +} +abstract sealed class SealedClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::SealedClassImplementsIndirectBase + : super core::Object::•() + ; +} +base class BaseClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::BaseClassImplementsIndirectBase + : super core::Object::•() + ; +} + +library /*isNonNullableByDefault*/; +import self as mai; +import "dart:core" as core; + +base class A extends core::Object { + synthetic constructor •() → mai::A + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.modular.expect b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.modular.expect new file mode 100644 index 00000000000..c30e75664c3 --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.modular.expect @@ -0,0 +1,75 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:10:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:13:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:16:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:19:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:22:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +import self as self; +import "main_lib.dart" as mai; +import "dart:core" as core; + +import "org-dartlang-testcase:///main_lib.dart"; + +abstract sealed class SealedClassExtendsBase extends mai::A { + synthetic constructor •() → self::SealedClassExtendsBase + : super mai::A::•() + ; +} +class ClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::ClassImplementsIndirectBase + : super core::Object::•() + ; +} +final class FinalClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::FinalClassImplementsIndirectBase + : super core::Object::•() + ; +} +interface class InterfaceClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::InterfaceClassImplementsIndirectBase + : super core::Object::•() + ; +} +abstract sealed class SealedClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::SealedClassImplementsIndirectBase + : super core::Object::•() + ; +} +base class BaseClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::BaseClassImplementsIndirectBase + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.outline.expect b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.outline.expect new file mode 100644 index 00000000000..4c4d9e8d481 --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.outline.expect @@ -0,0 +1,78 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:10:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:13:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:16:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:19:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:22:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +import self as self; +import "main_lib.dart" as mai; +import "dart:core" as core; + +import "org-dartlang-testcase:///main_lib.dart"; + +abstract sealed class SealedClassExtendsBase extends mai::A { + synthetic constructor •() → self::SealedClassExtendsBase + ; +} +class ClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::ClassImplementsIndirectBase + ; +} +final class FinalClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::FinalClassImplementsIndirectBase + ; +} +interface class InterfaceClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::InterfaceClassImplementsIndirectBase + ; +} +abstract sealed class SealedClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::SealedClassImplementsIndirectBase + ; +} +base class BaseClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::BaseClassImplementsIndirectBase + ; +} + +library /*isNonNullableByDefault*/; +import self as mai; +import "dart:core" as core; + +base class A extends core::Object { + synthetic constructor •() → mai::A + ; +} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.transformed.expect b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.transformed.expect new file mode 100644 index 00000000000..206199dd7ef --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart.weak.transformed.expect @@ -0,0 +1,85 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:10:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:13:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:16:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:19:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main.dart:22:16: Error: The class 'A' can't be implemented outside of its library because it's a base class. +// implements SealedClassExtendsBase {} /* Error */ +// ^ +// pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart:5:12: Context: The type 'SealedClassExtendsBase' is a subtype of 'A', and 'A' is defined here. +// base class A {} +// ^ +// +import self as self; +import "main_lib.dart" as mai; +import "dart:core" as core; + +import "org-dartlang-testcase:///main_lib.dart"; + +abstract sealed class SealedClassExtendsBase extends mai::A { + synthetic constructor •() → self::SealedClassExtendsBase + : super mai::A::•() + ; +} +class ClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::ClassImplementsIndirectBase + : super core::Object::•() + ; +} +final class FinalClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::FinalClassImplementsIndirectBase + : super core::Object::•() + ; +} +interface class InterfaceClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::InterfaceClassImplementsIndirectBase + : super core::Object::•() + ; +} +abstract sealed class SealedClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::SealedClassImplementsIndirectBase + : super core::Object::•() + ; +} +base class BaseClassImplementsIndirectBase extends core::Object implements self::SealedClassExtendsBase { + synthetic constructor •() → self::BaseClassImplementsIndirectBase + : super core::Object::•() + ; +} + +library /*isNonNullableByDefault*/; +import self as mai; +import "dart:core" as core; + +base class A extends core::Object { + synthetic constructor •() → mai::A + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart new file mode 100644 index 00000000000..1cadf90b464 --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/main_lib.dart @@ -0,0 +1,5 @@ +// 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. + +base class A {} diff --git a/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/test.options b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/test.options new file mode 100644 index 00000000000..bfe6dc8532c --- /dev/null +++ b/pkg/front_end/testcases/class_modifiers/base/outside_library_implements/test.options @@ -0,0 +1 @@ +main_lib.dart \ No newline at end of file diff --git a/tests/language/class_modifiers/base_transitivity/base_class_different_library_error_test.dart b/tests/language/class_modifiers/base_transitivity/base_class_different_library_error_test.dart index f3ef842bf11..7f199a21732 100644 --- a/tests/language/class_modifiers/base_transitivity/base_class_different_library_error_test.dart +++ b/tests/language/class_modifiers/base_transitivity/base_class_different_library_error_test.dart @@ -40,53 +40,49 @@ interface class InterfaceSealedExtendExtend extends SealedExtend {} // Implementing through a sealed class. class SimpleSealedExtendImplement implements SealedExtend {} -// ^ -// [cfe] The type 'SimpleSealedExtendImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseClass' is 'base'. // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. base class BaseSealedExtendImplement implements SealedExtend {} // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY -// [cfe] unspecified +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. interface class InterfaceSealedExtendImplement implements SealedExtend {} -// ^ -// [cfe] The type 'InterfaceSealedExtendImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseClass' is 'base'. // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. final class FinalSealedExtendImplement implements SealedExtend {} // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY -// [cfe] unspecified +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. sealed class SealedSealedExtendImplement implements SealedExtend {} // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY -// [cfe] unspecified +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. mixin class MixinClassSealedExtendImplement implements SealedExtend {} -// ^ -// [cfe] The type 'MixinClassSealedExtendImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseClass' is 'base'. // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. base mixin class BaseMixinClassSealedExtendImplement implements SealedExtend {} // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY -// [cfe] unspecified +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. mixin MixinSealedExtendImplement implements SealedExtend {} -// ^ -// [cfe] The type 'MixinSealedExtendImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseClass' is 'base'. // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. base mixin BaseMixinSealedExtendImplement implements SealedExtend {} // ^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY -// [cfe] unspecified +// [cfe] The class 'BaseClass' can't be implemented outside of its library because it's a base class. // Using a sealed class as an `on` type