Add tests for the transitivity of the base modifier when applied to

base mixins and base mixin classes.

Change-Id: Idfe7576f38382c5e9a0ff968aae00f48990e1d38
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290351
Commit-Queue: Leaf Petersen <leafp@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
This commit is contained in:
Leaf Petersen 2023-03-24 21:59:23 +00:00 committed by Commit Queue
parent 84c0f2c880
commit 386825ee8c
15 changed files with 1841 additions and 7 deletions

View file

@ -41,11 +41,19 @@ sealed class SealedExtendWith extends BaseClass with _MixinOnObject {}
// Extending via an anonymous mixin application class. // Extending via an anonymous mixin application class.
final class FinalExtendApplication = BaseClass with _MixinOnObject; final class FinalExtendApplication = BaseClass with _MixinOnObject;
base class BaseExtendApplication = BaseClass with _MixinOnObject; base class BaseExtendApplication = BaseClass with _MixinOnObject;
sealed class SealedExtendApplication = BaseClass with _MixinOnObject; sealed class SealedExtendApplication = BaseClass with _MixinOnObject;
/// BaseClass can be an `on` type, so long as the subtype is base. /// BaseClass can be an `on` type, so long as the subtype is base.
base mixin BaseMixinOn on BaseClass {} base mixin BaseMixinOn on BaseClass {}
main() {} // This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -119,4 +119,10 @@ sealed class SealedMixinImplementApplied extends Object
base mixin BaseMixinOn on BaseClass {} base mixin BaseMixinOn on BaseClass {}
main() {} // This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -0,0 +1,426 @@
// 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.
// SharedOptions=--enable-experiment=class-modifiers
/// Test the invalid uses of a base mixin class defined in a different library.
import "shared_library_definitions.dart" show SimpleClass, BaseMixinClass;
mixin _MixinOnObject {}
/// It is an error if BaseMixinClass is extended by something which is not base,
/// final or sealed.
// Simple extension.
class SimpleExtend extends BaseMixinClass {}
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceExtend extends BaseMixinClass {}
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Extending with a sealed class (valid, used to check the errors below).
sealed class SealedExtend extends BaseMixinClass {}
// Extending through a sealed class.
class SimpleSealedExtendExtend extends SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleSealedExtendExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceSealedExtendExtend extends SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceSealedExtendExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Implementing through a sealed class.
class SimpleSealedExtendImplement implements SealedExtend {}
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' 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] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
interface class InterfaceSealedExtendImplement implements SealedExtend {}
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' 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] The class 'BaseMixinClass' 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] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
mixin class MixinClassSealedExtendImplement implements SealedExtend {}
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' 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] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
mixin MixinSealedExtendImplement implements SealedExtend {}
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' 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] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
// Using a sealed class as an `on` type
mixin MixinSealedExtendOn on SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'MixinSealedExtendOn' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Extending via an anonymous mixin class.
class SimpleExtendWith extends BaseMixinClass with _MixinOnObject {}
// ^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleExtendWith' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceExtendWith extends BaseMixinClass
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceExtendWith' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject {}
// Extending via an anonymous mixin application class.
class SimpleExtendApplication = BaseMixinClass with _MixinOnObject;
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleExtendApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceExtendApplication = BaseMixinClass with _MixinOnObject;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceExtendApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
/// It is an error if BaseMixinClass is implemented by something which is not base,
/// final or sealed.
// Simple implementation.
class SimpleImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base class BaseImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
interface class InterfaceImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
final class FinalImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
sealed class SealedImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
// Implementing with a mixin class.
mixin class SimpleMixinClassImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base mixin class BaseMixinClassImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
// Implementing with a mixin application class.
class SimpleImplementApplication = Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleImplementApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject
implements
BaseMixinClass;
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base class BaseImplementApplication = Object
with _MixinOnObject
implements BaseMixinClass;
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
interface class InterfaceImplementApplication = Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceImplementApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject
implements
BaseMixinClass;
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
final class FinalImplementApplication = Object
with _MixinOnObject
implements BaseMixinClass;
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
sealed class SealedImplementApplication = Object
with _MixinOnObject
implements BaseMixinClass;
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
// Implementing with a mixin.
mixin SimpleMixinImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base mixin BaseMixinImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
/// It is an error if BaseMixinClass is the `on` type of something which is not base.
mixin SimpleMixinOn on BaseMixinClass {}
// ^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOn' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
mixin SimpleMixinOnSimpleBase on SimpleClass, BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOnSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
mixin SimpleMixinOnBaseSimple on BaseMixinClass, SimpleClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOnBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
/// It is an error to use BaseMixinClass as a mixin, if the result is not base,
/// final or sealed.
class SimpleMixinClassApply extends Object with BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApply' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
class SimpleMixinClassApplySimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplySimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject,
BaseMixinClass {}
class SimpleMixinClassApplyBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplyBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass,
_MixinOnObject {}
interface class InterfaceMixinClassApply extends Object with BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApply' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceMixinClassApplySimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplySimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject,
BaseMixinClass {}
interface class InterfaceMixinClassApplyBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplyBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass,
_MixinOnObject {}
// Sealed class from mixing in a base mixin class. (valid, used for tests
// below)
sealed class SealedMixinClassApply extends Object with BaseMixinClass {}
// Implementing through a sealed class.
class SimpleSealedMixinClassApplyImplement implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base class BaseSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
interface class InterfaceSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
final class FinalSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
sealed class SealedSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base mixin class BaseMixinClassSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base mixin BaseMixinSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
/// It is an error to use BaseMixinClass as a mixin application, if the result
/// is not base, final or sealed.
class SimpleMixinClassApplication extends Object with BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
class SimpleMixinClassApplicationSimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplicationSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject,
BaseMixinClass {}
class SimpleMixinClassApplicationBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplicationBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass,
_MixinOnObject {}
interface class InterfaceMixinClassApplication extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass {}
interface class InterfaceMixinClassApplicationSimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplicationSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject,
BaseMixinClass {}
interface class InterfaceMixinClassApplicationBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplicationBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass,
_MixinOnObject {}
// Sealed class from mixing in a base mixin class. (valid, used for tests
// below)
sealed class SealedMixinApplication = Object with BaseMixinClass;
// Implementing through a sealed class.
class SimpleSealedMixinApplicationImplement implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base class BaseSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
interface class InterfaceSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
final class FinalSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
sealed class SealedSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base mixin class BaseMixinClassSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.
base mixin BaseMixinSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixinClass' can't be implemented outside of its library because it's a base class.

View file

@ -0,0 +1,97 @@
// 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.
// SharedOptions=--enable-experiment=class-modifiers
/// Test the valid uses of a base mixin class defined in a different library
import "shared_library_definitions.dart" show BaseMixinClass;
mixin _MixinOnObject {}
/// BaseMixinClass can be extended, so long as the subtype is base, final
/// or sealed.
// Simple extension.
base class BaseExtend extends BaseMixinClass {}
final class FinalExtend extends BaseMixinClass {}
// Extending with a sealed class.
sealed class SealedExtend extends BaseMixinClass {}
// Extending through a sealed class.
base class BaseSealedExtendExtend extends SealedExtend {}
final class FinalSealedExtendExtend extends SealedExtend {}
sealed class SealedSealedExtendExtend extends SealedExtend {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedExtendOn on SealedExtend {}
// Extending via an anonymous mixin class.
base class BaseExtendWith extends BaseMixinClass with _MixinOnObject {}
final class FinalExtendWith extends BaseMixinClass with _MixinOnObject {}
sealed class SealedExtendWith extends BaseMixinClass with _MixinOnObject {}
// Extending via an anonymous mixin application class.
final class FinalExtendApplication = BaseMixinClass with _MixinOnObject;
base class BaseExtendApplication = BaseMixinClass with _MixinOnObject;
sealed class SealedExtendApplication = BaseMixinClass with _MixinOnObject;
/// BaseMixinClass can be an `on` type, so long as the subtype is base.
base mixin BaseMixinOn on BaseMixinClass {}
/// BaseMixinClass can be used as a mixin, so long as the result is base, final,
/// or sealed.
base class BaseMixinClassApply extends Object with BaseMixinClass {}
final class FinalMixinClassApply extends Object with BaseMixinClass {}
sealed class SealedMixinClassApply extends Object with BaseMixinClass {}
// Extending through a sealed class.
base class BaseSealedMixinClassApplyExtend extends SealedMixinClassApply {}
final class FinalSealedMixinClassApplyExtend extends SealedMixinClassApply {}
sealed class SealedSealedMixinClassApplyExtend extends SealedMixinClassApply {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedMixinApplyOn on SealedMixinClassApply {}
/// BaseMixinClass can be used as a mixin application, so long as the result is
/// base, final, or sealed.
base class BaseMixinApplication = Object with BaseMixinClass;
final class FinalMixinApplication = Object with BaseMixinClass;
sealed class SealedMixinApplication = Object with BaseMixinClass;
// Extending through a sealed class.
base class BaseSealedMixinApplicationExtend extends SealedMixinApplication {}
final class FinalSealedMixinApplicationExtend extends SealedMixinApplication {}
sealed class SealedSealedMixinApplicationExtend
extends SealedMixinApplication {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedMixinApplicationOn on SealedMixinApplication {}
// This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -0,0 +1,304 @@
// 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.
// SharedOptions=--enable-experiment=class-modifiers
/// Test the invalid uses of a base mixin class within the same library
class SimpleClass {}
base mixin class BaseMixinClass {}
mixin _MixinOnObject {}
/// It is an error if BaseMixinClass is extended by something which is not base,
/// final or sealed.
// Simple extension.
class SimpleExtend extends BaseMixinClass {}
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceExtend extends BaseMixinClass {}
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Extending with a sealed class (valid, used to check the errors below).
sealed class SealedExtend extends BaseMixinClass {}
// Extending through a sealed class.
class SimpleSealedExtendExtend extends SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleSealedExtendExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceSealedExtendExtend extends SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceSealedExtendExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Implementing through a sealed class.
class SimpleSealedExtendImplement implements SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleSealedExtendImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceSealedExtendImplement implements SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceSealedExtendImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
mixin class MixinClassSealedExtendImplement implements SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'MixinClassSealedExtendImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
mixin MixinSealedExtendImplement implements SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'MixinSealedExtendImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Using a sealed class as an `on` type
mixin MixinSealedExtendOn on SealedExtend {}
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'MixinSealedExtendOn' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Extending via an anonymous mixin class.
class SimpleExtendWith extends BaseMixinClass with _MixinOnObject {}
// ^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleExtendWith' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceExtendWith extends BaseMixinClass
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceExtendWith' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject {}
// Extending via an anonymous mixin application class.
class SimpleExtendApplication = BaseMixinClass with _MixinOnObject;
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleExtendApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceExtendApplication = BaseMixinClass with _MixinOnObject;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceExtendApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
/// It is an error if BaseMixinClass is implemented by something which is not base,
/// final or sealed.
// Simple implementation.
class SimpleImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Implementing with a sealed class (valid, used for tests below).
sealed class SealedImplement implements BaseMixinClass {}
// Extending through a sealed class.
class SimpleSealedImplementExtend extends SealedImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleSealedImplementExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceSealedImplementExtend extends SealedImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceSealedImplementExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Implementing through a sealed class.
class SimpleSealedImplementImplement implements SealedImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleSealedImplementImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceSealedImplementImplement implements SealedImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceSealedImplementImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Implementing with a mixin class.
mixin class SimpleMixinClassImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Implementing with a base mixin class (valid, used for tests below)
base mixin class BaseMixinClassImplement implements BaseMixinClass {}
// Implementing by applying a mixin class.
class SimpleMixinClassImplementApplied extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassImplementApplied' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClassImplement' is 'base'.
with
BaseMixinClassImplement {}
interface class InterfaceMixinClassImplementApplied extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassImplementApplied' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClassImplement' is 'base'.
with
BaseMixinClassImplement {}
// Implementing with a mixin application class.
interface class InterfaceImplementApplication = Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceImplementApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject
implements
BaseMixinClass;
class SimpleImplementApplication = Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleImplementApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject
implements
BaseMixinClass;
// Implementing with a mixin.
mixin SimpleMixinImplement implements BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
// Implementing with a base mixin (valid, used for tests below)
base mixin BaseMixinImplement implements BaseMixinClass {}
// Implementing by applying a mixin.
class SimpleMixinImplementApplied extends Object with BaseMixinImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinImplementApplied' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinImplement' is 'base'.
interface class InterfaceMixinImplementApplied extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinImplementApplied' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinImplement' is 'base'.
with
BaseMixinImplement {}
/// It is an error if BaseMixinClass is the `on` type of something which is not base.
mixin SimpleMixinOn on BaseMixinClass {}
// ^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOn' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
mixin SimpleMixinOnBaseSimple on BaseMixinClass, SimpleClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOnBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
mixin SimpleMixinOnSimpleBase on SimpleClass, BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOnSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
/// It is an error to use BaseMixinClass as a mixin, if the result is not base,
/// final or sealed.
class SimpleMixinClassApply extends Object with BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApply' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
class SimpleMixinClassApplySimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplySimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject,
BaseMixinClass {}
class SimpleMixinClassApplyBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplyBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass,
_MixinOnObject {}
interface class InterfaceMixinClassApply extends Object with BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApply' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
interface class InterfaceMixinClassApplySimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplySimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject,
BaseMixinClass {}
interface class InterfaceMixinClassApplyBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplyBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass,
_MixinOnObject {}
/// It is an error to use BaseMixinClass as a mixin application, if the result
/// is not base, final or sealed.
class SimpleMixinClassApplication extends Object with BaseMixinClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
class SimpleMixinClassApplicationSimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplicationSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject,
BaseMixinClass {}
class SimpleMixinClassApplicationBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplicationBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass,
_MixinOnObject {}
interface class InterfaceMixinClassApplication extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass {}
interface class InterfaceMixinClassApplicationSimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplicationSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
_MixinOnObject,
BaseMixinClass {}
interface class InterfaceMixinClassApplicationBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplicationBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClass' is 'base'.
with
BaseMixinClass,
_MixinOnObject {}

View file

@ -0,0 +1,201 @@
// 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.
// SharedOptions=--enable-experiment=class-modifiers
/// Test the valid uses of a base mixin class within the same library
base mixin class BaseMixinClass {}
mixin _MixinOnObject {}
/// BaseMixinClass can be extended, so long as the subtype is base, final
/// or sealed.
// Simple extension.
base class BaseExtend extends BaseMixinClass {}
final class FinalExtend extends BaseMixinClass {}
// Extending with a sealed class.
sealed class SealedExtend extends BaseMixinClass {}
// Extending through a sealed class.
base class BaseSealedExtendExtend extends SealedExtend {}
final class FinalSealedExtendExtend extends SealedExtend {}
sealed class SealedSealedExtendExtend extends SealedExtend {}
// Implementing through a sealed class.
base class BaseSealedExtendImplement implements SealedExtend {}
final class FinalSealedExtendImplement implements SealedExtend {}
sealed class SealedSealedExtendImplement implements SealedExtend {}
base mixin class BaseMixinClassSealedExtendImplement implements SealedExtend {}
base mixin BaseMixinSealedExtendImplement implements SealedExtend {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedExtendOn on SealedExtend {}
// Extending via an anonymous mixin class.
base class BaseExtendWith extends BaseMixinClass with _MixinOnObject {}
final class FinalExtendWith extends BaseMixinClass with _MixinOnObject {}
sealed class SealedExtendWith extends BaseMixinClass with _MixinOnObject {}
// Extending via an anonymous mixin application class.
final class FinalExtendApplication = BaseMixinClass with _MixinOnObject;
base class BaseExtendApplication = BaseMixinClass with _MixinOnObject;
sealed class SealedExtendApplication = BaseMixinClass with _MixinOnObject;
/// BaseMixinClass can be implemented, so long as the subtype is base, final, or
/// sealed
// Simple implementation.
base class BaseImplement implements BaseMixinClass {}
final class FinalImplement implements BaseMixinClass {}
// Implementing with a sealed class.
sealed class SealedImplement implements BaseMixinClass {}
// Extending through a sealed class.
base class BaseSealedImplementExtend extends SealedImplement {}
final class FinalSealedImplementExtend extends SealedImplement {}
sealed class SealedSealedImplementExtend extends SealedImplement {}
// Implementing through a sealed class.
base class BaseSealedImplementImplement implements SealedImplement {}
final class FinalSealedImplementImplement implements SealedImplement {}
sealed class SealedSealedImplementImplement implements SealedImplement {}
// Implementing with a mixin class.
base mixin class BaseMixinClassImplement implements BaseMixinClass {}
// Implementing by applying a mixin class.
base class BaseMixinClassImplementApplied extends Object
with BaseMixinClassImplement {}
final class FinalMixinClassImplementApplied extends Object
with BaseMixinClassImplement {}
sealed class SealedMixinClassImplementApplied extends Object
with BaseMixinClassImplement {}
// Implementing with a mixin application class.
base class BaseImplementApplication = Object
with _MixinOnObject
implements BaseMixinClass;
final class FinalImplementApplication = Object
with _MixinOnObject
implements BaseMixinClass;
sealed class SealedImplementApplication = Object
with _MixinOnObject
implements BaseMixinClass;
// Implementing with a mixin.
base mixin BaseMixinImplement implements BaseMixinClass {}
// Implementing by applying a mixin.
base class BaseMixinImplementApplied extends Object with BaseMixinImplement {}
final class FinalMixinImplementApplied extends Object with BaseMixinImplement {}
sealed class SealedMixinImplementApplied extends Object
with BaseMixinImplement {}
/// BaseMixinClass can be an `on` type, so long as the subtype is base.
base mixin BaseMixinOn on BaseMixinClass {}
/// BaseMixinClass can be used as a mixin, so long as the result is base, final,
/// or sealed.
base class BaseMixinClassApply extends Object with BaseMixinClass {}
final class FinalMixinClassApply extends Object with BaseMixinClass {}
sealed class SealedMixinClassApply extends Object with BaseMixinClass {}
// Extending through a sealed class.
base class BaseSealedMixinClassApplyExtend extends SealedMixinClassApply {}
final class FinalSealedMixinClassApplyExtend extends SealedMixinClassApply {}
sealed class SealedSealedMixinClassApplyExtend extends SealedMixinClassApply {}
// Implementing through a sealed class.
base class BaseSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
final class FinalSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
sealed class SealedSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
base mixin class BaseMixinClassSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
base mixin BaseMixinSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedMixinApplyOn on SealedMixinClassApply {}
/// BaseMixinClass can be used as a mixin application, so long as the result is
/// base, final, or sealed.
base class BaseMixinApplication = Object with BaseMixinClass;
final class FinalMixinApplication = Object with BaseMixinClass;
sealed class SealedMixinApplication = Object with BaseMixinClass;
// Extending through a sealed class.
base class BaseSealedMixinApplicationExtend extends SealedMixinApplication {}
final class FinalSealedMixinApplicationExtend extends SealedMixinApplication {}
sealed class SealedSealedMixinApplicationExtend
extends SealedMixinApplication {}
// Implementing through a sealed class.
base class BaseSealedMixinApplicationImplement
implements SealedMixinApplication {}
final class FinalSealedMixinApplicationImplement
implements SealedMixinApplication {}
sealed class SealedSealedMixinApplicationImplement
implements SealedMixinApplication {}
base mixin class BaseMixinClassSealedMixinApplicationImplement
implements SealedMixinApplication {}
base mixin BaseMixinSealedMixinApplicationImplement
implements SealedMixinApplication {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedMixinApplicationOn on SealedMixinApplication {}
// This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -0,0 +1,317 @@
// 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.
// SharedOptions=--enable-experiment=class-modifiers
/// Test the invalid uses of a base mixin defined in a different library.
import "shared_library_definitions.dart" show SimpleClass, BaseMixin;
mixin _MixinOnObject {}
/// It is an error if BaseMixin is implemented by something which is not base,
/// final or sealed.
// Simple implementation.
class SimpleImplement implements BaseMixin {}
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
base class BaseImplement implements BaseMixin {}
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
interface class InterfaceImplement implements BaseMixin {}
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
final class FinalImplement implements BaseMixin {}
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
sealed class SealedImplement implements BaseMixin {}
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
// Implementing with a mixin class.
mixin class SimpleMixinClassImplement implements BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
base mixin class BaseMixinClassImplement implements BaseMixin {}
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
// Implementing with a mixin application class.
class SimpleImplementApplication = Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleImplementApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject
implements
BaseMixin;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
base class BaseImplementApplication = Object
with _MixinOnObject
implements BaseMixin;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
interface class InterfaceImplementApplication = Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceImplementApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject
implements
BaseMixin;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
final class FinalImplementApplication = Object
with _MixinOnObject
implements BaseMixin;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
sealed class SealedImplementApplication = Object
with _MixinOnObject
implements BaseMixin;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
// Implementing with a mixin.
mixin SimpleMixinImplement implements BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
base mixin BaseMixinImplement implements BaseMixin {}
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The mixin 'BaseMixin' can't be implemented outside of its library because it's a base mixin.
/// It is an error if BaseMixin is the `on` type of something which is not base.
mixin SimpleMixinOn on BaseMixin {}
// ^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOn' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
mixin SimpleMixinOnSimpleBase on SimpleClass, BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOnSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
mixin SimpleMixinOnBaseSimple on BaseMixin, SimpleClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOnBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
/// It is an error to use BaseMixin as a mixin, if the result is not base,
/// final or sealed.
class SimpleMixinClassApply extends Object with BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApply' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
class SimpleMixinClassApplySimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplySimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject,
BaseMixin {}
class SimpleMixinClassApplyBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplyBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
BaseMixin,
_MixinOnObject {}
interface class InterfaceMixinClassApply extends Object with BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApply' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
interface class InterfaceMixinClassApplySimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplySimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject,
BaseMixin {}
interface class InterfaceMixinClassApplyBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplyBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
BaseMixin,
_MixinOnObject {}
// Sealed class produced from a base mixin (valid, used for tests below)
sealed class SealedMixinClassApply extends Object with BaseMixin {}
// Implementing through a sealed class.
class SimpleSealedMixinClassApplyImplement implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
base class BaseSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
interface class InterfaceSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
final class FinalSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
sealed class SealedSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
base mixin class BaseMixinClassSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
base mixin BaseMixinSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
/// It is an error to use BaseMixin as a mixin application, if the result
/// is not base, final or sealed.
class SimpleMixinClassApplication extends Object with BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
class SimpleMixinClassApplicationSimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplicationSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject,
BaseMixin {}
class SimpleMixinClassApplicationBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplicationBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
BaseMixin,
_MixinOnObject {}
interface class InterfaceMixinClassApplication extends Object with BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
interface class InterfaceMixinClassApplicationSimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplicationSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject,
BaseMixin {}
interface class InterfaceMixinClassApplicationBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplicationBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
BaseMixin,
_MixinOnObject {}
// Sealed class produced from a base mixin (valid, used for tests below).
sealed class SealedMixinApplication = Object with BaseMixin;
// Implementing through a sealed class.
class SimpleSealedMixinApplicationImplement implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
base class BaseSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
interface class InterfaceSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
final class FinalSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
sealed class SealedSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
base mixin class BaseMixinClassSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.
base mixin BaseMixinSealedMixinApplicationImplement
implements SealedMixinApplication {}
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'BaseMixin' can't be implemented outside of its library because it's a base class.

View file

@ -0,0 +1,62 @@
// 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.
// SharedOptions=--enable-experiment=class-modifiers
/// Test the valid uses of a base mixin defined in a different library
import "shared_library_definitions.dart" show BaseMixin;
/// BaseMixin can be an `on` type, so long as the subtype is base.
base mixin BaseMixinOn on BaseMixin {}
/// BaseMixin can be used as a mixin, so long as the result is base, final,
/// or sealed.
base class BaseMixinApply extends Object with BaseMixin {}
final class FinalMixinClassApply extends Object with BaseMixin {}
sealed class SealedMixinClassApply extends Object with BaseMixin {}
// Extending through a sealed class.
base class BaseSealedMixinClassApplyExtend extends SealedMixinClassApply {}
final class FinalSealedMixinClassApplyExtend extends SealedMixinClassApply {}
sealed class SealedSealedMixinClassApplyExtend extends SealedMixinClassApply {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedMixinApplyOn on SealedMixinClassApply {}
/// BaseMixin can be used as a mixin application, so long as the result is
/// base, final, or sealed.
base class BaseMixinApplication = Object with BaseMixin;
final class FinalMixinApplication = Object with BaseMixin;
sealed class SealedMixinApplication = Object with BaseMixin;
// Extending through a sealed class.
base class BaseSealedMixinApplicationExtend extends SealedMixinApplication {}
final class FinalSealedMixinApplicationExtend extends SealedMixinApplication {}
sealed class SealedSealedMixinApplicationExtend
extends SealedMixinApplication {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedMixinApplicationOn on SealedMixinApplication {}
// This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -0,0 +1,223 @@
// 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.
// SharedOptions=--enable-experiment=class-modifiers
/// Test the invalid uses of a base mixin class within the same library
class SimpleClass {}
base mixin BaseMixin {}
mixin _MixinOnObject {}
/// It is an error if BaseMixin is implemented by something which is not
/// base, final or sealed.
// Simple implementation.
class SimpleImplement implements BaseMixin {}
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
interface class InterfaceImplement implements BaseMixin {}
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// Implementing with a sealed class (valid, used for tests below).
sealed class SealedImplement implements BaseMixin {}
// Extending through a sealed class.
class SimpleSealedImplementExtend extends SealedImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleSealedImplementExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
interface class InterfaceSealedImplementExtend extends SealedImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceSealedImplementExtend' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// Implementing through a sealed class.
class SimpleSealedImplementImplement implements SealedImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleSealedImplementImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
interface class InterfaceSealedImplementImplement implements SealedImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceSealedImplementImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// Implementing with a mixin class.
mixin class SimpleMixinClassImplement implements BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// Implementing with a base mixin class (valid, used for tests below)
base mixin class BaseMixinClassImplement implements BaseMixin {}
// Implementing by applying a mixin class.
class SimpleMixinClassImplementApplied extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassImplementApplied' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClassImplement' is 'base'.
with
BaseMixinClassImplement {}
interface class InterfaceMixinClassImplementApplied extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassImplementApplied' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinClassImplement' is 'base'.
with
BaseMixinClassImplement {}
// Implementing with a mixin application class.
interface class InterfaceImplementApplication = Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceImplementApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject
implements
BaseMixin;
class SimpleImplementApplication = Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleImplementApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject
implements
BaseMixin;
// Implementing with a mixin.
mixin SimpleMixinImplement implements BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinImplement' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
// Implementing with a base mixin (valid, used for tests below)
base mixin BaseMixinImplement implements BaseMixin {}
// Implementing by applying a mixin.
class SimpleMixinImplementApplied extends Object with BaseMixinImplement {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinImplementApplied' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinImplement' is 'base'.
interface class InterfaceMixinImplementApplied extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinImplementApplied' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixinImplement' is 'base'.
with
BaseMixinImplement {}
/// It is an error if BaseMixin is the `on` type of something which is not base.
mixin SimpleMixinOn on BaseMixin {}
// ^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOn' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
mixin SimpleMixinOnBaseSimple on BaseMixin, SimpleClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOnBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
mixin SimpleMixinOnSimpleBase on SimpleClass, BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinOnSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
/// It is an error to use BaseMixin as a mixin, if the result is not base,
/// final or sealed.
class SimpleMixinClassApply extends Object with BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApply' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
class SimpleMixinClassApplySimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplySimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject,
BaseMixin {}
class SimpleMixinClassApplyBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplyBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
BaseMixin,
_MixinOnObject {}
interface class InterfaceMixinClassApply extends Object with BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApply' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
interface class InterfaceMixinClassApplySimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplySimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject,
BaseMixin {}
interface class InterfaceMixinClassApplyBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplyBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
BaseMixin,
_MixinOnObject {}
/// It is an error to use BaseMixin as a mixin application, if the result
/// is not base, final or sealed.
class SimpleMixinClassApplication extends Object with BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
class SimpleMixinClassApplicationSimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplicationSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject,
BaseMixin {}
class SimpleMixinClassApplicationBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'SimpleMixinClassApplicationBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
BaseMixin,
_MixinOnObject {}
interface class InterfaceMixinClassApplication extends Object with BaseMixin {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplication' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
interface class InterfaceMixinClassApplicationSimpleBase extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplicationSimpleBase' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
_MixinOnObject,
BaseMixin {}
interface class InterfaceMixinClassApplicationBaseSimple extends Object
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// [cfe] The type 'InterfaceMixinClassApplicationBaseSimple' must be 'base', 'final' or 'sealed' because the supertype 'BaseMixin' is 'base'.
with
BaseMixin,
_MixinOnObject {}

View file

@ -0,0 +1,156 @@
// 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.
// SharedOptions=--enable-experiment=class-modifiers
/// Test the valid uses of a base mixin within the same library
base mixin BaseMixin {}
mixin _MixinOnObject {}
/// BaseMixin can be implemented, so long as the subtype is base, final, or
/// sealed
// Simple implementation.
base class BaseImplement implements BaseMixin {}
final class FinalImplement implements BaseMixin {}
// Implementing with a sealed class.
sealed class SealedImplement implements BaseMixin {}
// Extending through a sealed class.
base class BaseSealedImplementExtend extends SealedImplement {}
final class FinalSealedImplementExtend extends SealedImplement {}
sealed class SealedSealedImplementExtend extends SealedImplement {}
// Implementing through a sealed class.
base class BaseSealedImplementImplement implements SealedImplement {}
final class FinalSealedImplementImplement implements SealedImplement {}
sealed class SealedSealedImplementImplement implements SealedImplement {}
// Implementing with a mixin class.
base mixin class BaseMixinClassImplement implements BaseMixin {}
// Implementing by applying a mixin class.
base class BaseMixinClassImplementApplied extends Object
with BaseMixinClassImplement {}
final class FinalMixinClassImplementApplied extends Object
with BaseMixinClassImplement {}
sealed class SealedMixinClassImplementApplied extends Object
with BaseMixinClassImplement {}
// Implementing with a mixin application class.
base class BaseImplementApplication = Object
with _MixinOnObject
implements BaseMixin;
final class FinalImplementApplication = Object
with _MixinOnObject
implements BaseMixin;
sealed class SealedImplementApplication = Object
with _MixinOnObject
implements BaseMixin;
// Implementing with a mixin.
base mixin BaseMixinImplement implements BaseMixin {}
// Implementing by applying a mixin.
base class BaseMixinImplementApplied extends Object with BaseMixinImplement {}
final class FinalMixinImplementApplied extends Object with BaseMixinImplement {}
sealed class SealedMixinImplementApplied extends Object
with BaseMixinImplement {}
/// BaseMixin can be an `on` type, so long as the subtype is base.
base mixin BaseMixinOn on BaseMixin {}
/// BaseMixin can be used as a mixin, so long as the result is base, final,
/// or sealed.
base class BaseMixinApply extends Object with BaseMixin {}
final class FinalMixinClassApply extends Object with BaseMixin {}
sealed class SealedMixinClassApply extends Object with BaseMixin {}
// Extending through a sealed class.
base class BaseSealedMixinClassApplyExtend extends SealedMixinClassApply {}
final class FinalSealedMixinClassApplyExtend extends SealedMixinClassApply {}
sealed class SealedSealedMixinClassApplyExtend extends SealedMixinClassApply {}
// Implementing through a sealed class.
base class BaseSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
final class FinalSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
sealed class SealedSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
base mixin class BaseMixinSealedMixinClassApplyImplement
implements SealedMixinClassApply {}
base mixin BaseMixinSealedMixinApplyImplement
implements SealedMixinClassApply {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedMixinApplyOn on SealedMixinClassApply {}
/// BaseMixin can be used as a mixin application, so long as the result is
/// base, final, or sealed.
base class BaseMixinApplication = Object with BaseMixin;
final class FinalMixinApplication = Object with BaseMixin;
sealed class SealedMixinApplication = Object with BaseMixin;
// Extending through a sealed class.
base class BaseSealedMixinApplicationExtend extends SealedMixinApplication {}
final class FinalSealedMixinApplicationExtend extends SealedMixinApplication {}
sealed class SealedSealedMixinApplicationExtend
extends SealedMixinApplication {}
// Implementing through a sealed class.
base class BaseSealedMixinApplicationImplement
implements SealedMixinApplication {}
final class FinalSealedMixinApplicationImplement
implements SealedMixinApplication {}
sealed class SealedSealedMixinApplicationImplement
implements SealedMixinApplication {}
base mixin class BaseMixinClassSealedMixinApplicationImplement
implements SealedMixinApplication {}
base mixin BaseMixinSealedMixinApplicationImplement
implements SealedMixinApplication {}
// Using a sealed class as an `on` type
base mixin BaseMixinSealedMixinApplicationOn on SealedMixinApplication {}
// This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -197,7 +197,17 @@ mixin SimpleMixinOnSimpleFinal on SimpleClass, FinalClass {}
base mixin BaseMixinOn on FinalClass {} base mixin BaseMixinOn on FinalClass {}
// ^ // ^
// [analyzer] unspecified
// [cfe] unspecified // [cfe] unspecified
// [analyzer] unspecified
base mixin BaseMixinOnFinalSimple on SimpleClass, FinalClass {}
// ^
// [cfe] unspecified
// [analyzer] unspecified
base mixin BaseMixinOnSimpleFinal on FinalClass, SimpleClass {}
// ^
// [cfe] unspecified
// [analyzer] unspecified
main() {} main() {}

View file

@ -119,4 +119,10 @@ sealed class SealedMixinImplementApplied extends Object
base mixin BaseMixinOn on FinalClass {} base mixin BaseMixinOn on FinalClass {}
main() {} // This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -113,4 +113,10 @@ mixin SimpleMixinOn on InterfaceClass {}
base mixin BaseMixinOn on InterfaceClass {} base mixin BaseMixinOn on InterfaceClass {}
main() {} // This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -185,4 +185,10 @@ mixin SimpleMixinOn on InterfaceClass {}
base mixin BaseMixinOn on InterfaceClass {} base mixin BaseMixinOn on InterfaceClass {}
main() {} // This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.

View file

@ -184,4 +184,10 @@ mixin SimpleMixinOn on SealedClass {}
base mixin BaseMixinOn on SealedClass {} base mixin BaseMixinOn on SealedClass {}
main() {} // This test is intended just to check that certain combinations of modifiers
// are statically allowed. Make this a static error test so that backends don't
// try to run it.
int x = "This is a static error test";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.