[tests] Language tests for 'final' class modifier.
Change-Id: Ia39b96db7470fd9d7bb5f6683262d78a1a08ada7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/276769
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
diff --git a/tests/language/class_modifiers/final/final_class_abstract_construct_error_test.dart b/tests/language/class_modifiers/final/final_class_abstract_construct_error_test.dart
new file mode 100644
index 0000000..6186183
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_abstract_construct_error_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2022, 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
+
+// Error when attempting to construct an abstract final class.
+
+abstract final class NotConstructable {}
+
+mixin M {}
+abstract final class AlsoNotConstructable = Object with M;
+
+main() {
+ var error = NotConstructable();
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+ var error2 = AlsoNotConstructable();
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/tests/language/class_modifiers/final/final_class_base_class_lib.dart b/tests/language/class_modifiers/final/final_class_base_class_lib.dart
new file mode 100644
index 0000000..bd2d270
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_base_class_lib.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, 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
+
+base class BaseClass {
+ int foo = 0;
+}
+
+base mixin BaseMixin {
+ int foo = 0;
+}
diff --git a/tests/language/class_modifiers/final/final_class_extend_lib.dart b/tests/language/class_modifiers/final/final_class_extend_lib.dart
new file mode 100644
index 0000000..9ed8dbc
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_extend_lib.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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
+
+// Allow final classes to be extended by multiple classes in the same
+// library.
+
+final class FinalClass {
+ int foo = 0;
+}
+
+abstract class A extends FinalClass {}
+
+class B extends FinalClass {}
diff --git a/tests/language/class_modifiers/final/final_class_extend_outside_error_test.dart b/tests/language/class_modifiers/final/final_class_extend_outside_error_test.dart
new file mode 100644
index 0000000..035e333
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_extend_outside_error_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, 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
+
+// Error when attempting to extend an final class outside of library.
+
+import 'final_class_extend_lib.dart';
+
+abstract class AOutside extends FinalClass {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class BOutside extends FinalClass {
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/tests/language/class_modifiers/final/final_class_extend_test.dart b/tests/language/class_modifiers/final/final_class_extend_test.dart
new file mode 100644
index 0000000..538b683
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_extend_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, 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
+
+// Allow final classes to be extended by multiple classes inside its
+// library.
+
+import 'package:expect/expect.dart';
+import 'final_class_extend_lib.dart';
+
+class AImpl extends A {}
+
+main() {
+ Expect.equals(0, AImpl().foo);
+ Expect.equals(0, B().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_class_extends_base_outside_test.dart b/tests/language/class_modifiers/final/final_class_extends_base_outside_test.dart
new file mode 100644
index 0000000..fadafc0
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_extends_base_outside_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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
+
+// Allow `final` on a `base` superclass outside its library.
+
+import 'package:expect/expect.dart';
+import 'final_class_base_class_lib.dart';
+
+final class A extends BaseClass {}
+
+main() {
+ Expect.equals(0, A().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_class_final_subtype_test.dart b/tests/language/class_modifiers/final/final_class_final_subtype_test.dart
new file mode 100644
index 0000000..a98c437
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_final_subtype_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2022, 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
+
+// Allow subtypes of a final class or mixin to be final as well.
+
+import 'package:expect/expect.dart';
+
+final class FinalClass {
+ int foo = 0;
+}
+final class A extends FinalClass {}
+final class B implements FinalClass {
+ @override
+ int foo = 1;
+}
+
+final mixin FinalMixin {
+ int foo = 0;
+}
+final class C implements FinalMixin {
+ @override
+ int foo = 1;
+}
+final class AMixin with FinalMixin {}
+final class BMixin = Object with FinalMixin;
+
+// Used for trivial runtime tests of the final subtypes.
+class AConcrete extends A {}
+class BConcrete extends B {}
+class CConcrete extends C {}
+class AMixinConcrete extends AMixin {}
+class BMixinConcrete extends BMixin {}
+
+main() {
+ Expect.equals(0, AConcrete().foo);
+ Expect.equals(1, BConcrete().foo);
+ Expect.equals(1, CConcrete().foo);
+ Expect.equals(0, AMixinConcrete().foo);
+ Expect.equals(0, BMixinConcrete().foo);
+}
\ No newline at end of file
diff --git a/tests/language/class_modifiers/final/final_class_implement_lib.dart b/tests/language/class_modifiers/final/final_class_implement_lib.dart
new file mode 100644
index 0000000..f503115
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_implement_lib.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, 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
+
+// Allow final classes to be implemented in the same library.
+
+final class FinalClass {
+ int foo = 0;
+}
+
+abstract class A implements FinalClass {}
+
+class B implements FinalClass {
+ @override
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_class_implement_outside_error_test.dart b/tests/language/class_modifiers/final/final_class_implement_outside_error_test.dart
new file mode 100644
index 0000000..a846b74
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_implement_outside_error_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2022, 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
+
+// Error when attempting to implement a final class outside of library.
+
+import 'final_class_implement_lib.dart';
+
+abstract class AOutside implements FinalClass {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class BOutside implements FinalClass {
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+ @override
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_class_implement_test.dart b/tests/language/class_modifiers/final/final_class_implement_test.dart
new file mode 100644
index 0000000..4e86469
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_implement_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2022, 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
+
+// Allow final classes to be implemented by multiple classes inside its
+// library.
+
+import 'package:expect/expect.dart';
+import 'final_class_implement_lib.dart';
+
+class AImpl implements A {
+ @override
+ int foo = 1;
+}
+
+main() {
+ Expect.equals(1, AImpl().foo);
+ Expect.equals(1, B().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_class_mixin_on_lib.dart b/tests/language/class_modifiers/final/final_class_mixin_on_lib.dart
new file mode 100644
index 0000000..1298b38
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_mixin_on_lib.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, 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
+
+final class FinalClass {}
+
+abstract class A extends FinalClass {}
+
+class B extends FinalClass {}
+
+final mixin FinalMixin {}
+
+class C extends FinalClass with FinalMixin {}
+
+class D with FinalMixin {}
diff --git a/tests/language/class_modifiers/final/final_class_mixin_on_test.dart b/tests/language/class_modifiers/final/final_class_mixin_on_test.dart
new file mode 100644
index 0000000..88d41fa
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_mixin_on_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2022, 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
+
+// Allow a final type to appear in the "on" clause of a mixin declaration in
+// another library.
+
+import 'package:expect/expect.dart';
+import 'final_class_mixin_on_lib.dart';
+
+mixin MA on FinalClass {}
+mixin MB on FinalClass {}
+
+class ConcreteA extends A with MA, MB {
+ int foo = 0;
+}
+
+mixin MC on FinalClass, FinalMixin {}
+
+class ConcreteC extends C with MC {
+ int foo = 0;
+}
+
+mixin MCSingular on FinalMixin {}
+
+class ConcreteD extends D with MCSingular {
+ int foo = 0;
+}
+
+main() {
+ Expect.equals(0, ConcreteA().foo);
+ Expect.equals(0, ConcreteC().foo);
+ Expect.equals(0, ConcreteD().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_class_part_lib.dart b/tests/language/class_modifiers/final/final_class_part_lib.dart
new file mode 100644
index 0000000..0be3feb
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_part_lib.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2022, 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
+
+part of 'final_class_part_test.dart';
+
+class A extends FinalClass {}
+
+class B implements FinalClass {
+ @override
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_class_part_test.dart b/tests/language/class_modifiers/final/final_class_part_test.dart
new file mode 100644
index 0000000..01c3e55
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_part_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, 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
+
+// Allow extending and implementing final classes in a part file of
+// the same library
+
+import 'package:expect/expect.dart';
+part 'final_class_part_lib.dart';
+
+final class FinalClass {
+ int foo = 0;
+}
+
+main() {
+ Expect.equals(0, A().foo);
+ Expect.equals(1, B().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_class_syntax_disabled_error_test.dart b/tests/language/class_modifiers/final/final_class_syntax_disabled_error_test.dart
new file mode 100644
index 0000000..4d1ce4d
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_syntax_disabled_error_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2022, 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.
+
+// Make sure errors are emitted when trying to use final classes without
+// the `class-modifiers` experiment enabled.
+
+final class FinalClass {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+mixin M {}
+final class FinalClassTypeAlias = Object with M;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+final mixin FinalMixin {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
diff --git a/tests/language/class_modifiers/final/final_class_typedef_lib.dart b/tests/language/class_modifiers/final/final_class_typedef_lib.dart
new file mode 100644
index 0000000..4b0cd70
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_typedef_lib.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, 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
+
+final class FinalClass {
+ int foo = 0;
+}
+
+typedef FinalClassTypeDef = FinalClass;
+
+class A extends FinalClassTypeDef {}
+
+class B implements FinalClassTypeDef {
+ @override
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_lib.dart b/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_lib.dart
new file mode 100644
index 0000000..c8e7b6f
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_lib.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, 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
+
+import 'final_class_typedef_outside_of_library_lib2.dart';
+
+final class FinalClass {
+ int foo = 0;
+}
+
+class A extends ATypeDef {}
+
+class B implements ATypeDef {
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_lib2.dart b/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_lib2.dart
new file mode 100644
index 0000000..cbedc82
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_lib2.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, 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
+
+import 'final_class_typedef_outside_of_library_lib.dart';
+
+typedef ATypeDef = FinalClass;
diff --git a/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_test.dart b/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_test.dart
new file mode 100644
index 0000000..e04ea84
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_typedef_outside_of_library_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, 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
+
+// Allow typedef in different library, used by class in library.
+
+import 'package:expect/expect.dart';
+import 'final_class_typedef_outside_of_library_lib.dart';
+
+main() {
+ Expect.equals(0, A().foo);
+ Expect.equals(1, B().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_class_typedef_subtype_error_test.dart b/tests/language/class_modifiers/final/final_class_typedef_subtype_error_test.dart
new file mode 100644
index 0000000..6865fdb
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_typedef_subtype_error_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2022, 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
+
+// Error when attempting to implement or extend a typedef final class outside of
+// its library.
+
+import 'final_class_typedef_lib.dart';
+
+class ATypeDef extends FinalClassTypeDef {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class BTypeDef implements FinalClassTypeDef {
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+ @override
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_class_typedef_test.dart b/tests/language/class_modifiers/final/final_class_typedef_test.dart
new file mode 100644
index 0000000..3ef1dcf
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_typedef_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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
+
+// Allow typedef final classes to be extended and implemented by
+// multiple classes in the same library.
+
+import 'package:expect/expect.dart';
+import 'final_class_typedef_lib.dart';
+
+main() {
+ Expect.equals(0, A().foo);
+ Expect.equals(1, B().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_class_typedef_used_outside_error_test.dart b/tests/language/class_modifiers/final/final_class_typedef_used_outside_error_test.dart
new file mode 100644
index 0000000..bc74010
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_typedef_used_outside_error_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2022, 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
+
+// Error when trying to implement or extend a typedef final class outside of
+// the final class' library when the typedef is also outside the final class
+// library.
+
+import 'final_class_typedef_used_outside_lib.dart';
+
+typedef ATypeDef = FinalClass;
+
+class A extends ATypeDef {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class B implements ATypeDef {
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_class_typedef_used_outside_lib.dart b/tests/language/class_modifiers/final/final_class_typedef_used_outside_lib.dart
new file mode 100644
index 0000000..39bdaba
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_typedef_used_outside_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, 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
+
+final class FinalClass {
+ int foo = 0;
+}
diff --git a/tests/language/class_modifiers/final/final_class_with_base_outside_test.dart b/tests/language/class_modifiers/final/final_class_with_base_outside_test.dart
new file mode 100644
index 0000000..b9f1ec0
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_class_with_base_outside_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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
+
+// Allow `final` class with a `base` mixin outside its library.
+
+import 'package:expect/expect.dart';
+import 'final_class_base_class_lib.dart';
+
+final class A with BaseMixin {}
+
+main() {
+ Expect.equals(0, A().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_mixin_implement_lib.dart b/tests/language/class_modifiers/final/final_mixin_implement_lib.dart
new file mode 100644
index 0000000..92fde6c
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_implement_lib.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, 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
+
+// Allow final mixins to be implemented by multiple classes in the same library.
+
+final mixin FinalMixin {
+ int foo = 0;
+}
+
+abstract class A implements FinalMixin {}
+
+class B implements FinalMixin {
+ @override
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_mixin_implement_outside_error_test.dart b/tests/language/class_modifiers/final/final_mixin_implement_outside_error_test.dart
new file mode 100644
index 0000000..b75e021
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_implement_outside_error_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2022, 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
+
+// Error when attempting to implement final mixin outside of library.
+
+import 'final_mixin_implement_lib.dart';
+
+abstract class AOutside implements FinalMixin {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class BOutside implements FinalMixin {
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+ @override
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_mixin_implement_test.dart b/tests/language/class_modifiers/final/final_mixin_implement_test.dart
new file mode 100644
index 0000000..2a38c9a
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_implement_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, 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
+
+// Allow final mixins to be implemented by multiple classes in the same library.
+
+import 'package:expect/expect.dart';
+import 'final_mixin_implement_lib.dart';
+
+class AImpl implements A {
+ @override
+ int foo = 1;
+}
+
+main() {
+ Expect.equals(1, AImpl().foo);
+ Expect.equals(1, B().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_mixin_typedef_with_lib.dart b/tests/language/class_modifiers/final/final_mixin_typedef_with_lib.dart
new file mode 100644
index 0000000..710a002
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_typedef_with_lib.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, 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
+
+final mixin FinalMixin {
+ int foo = 0;
+}
+
+typedef FinalMixinTypeDef = FinalMixin;
+
+class A with FinalMixinTypeDef {
+ @override
+ int foo = 1;
+}
diff --git a/tests/language/class_modifiers/final/final_mixin_typedef_with_outside_error_test.dart b/tests/language/class_modifiers/final/final_mixin_typedef_with_outside_error_test.dart
new file mode 100644
index 0000000..92276ad
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_typedef_with_outside_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2022, 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
+
+// Error when attempting to mix in a typedef final mixin outside of library.
+
+import 'final_mixin_typedef_with_lib.dart';
+
+abstract class AOutside with FinalMixinTypeDef {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class BOutside with FinalMixinTypeDef {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
diff --git a/tests/language/class_modifiers/final/final_mixin_typedef_with_test.dart b/tests/language/class_modifiers/final/final_mixin_typedef_with_test.dart
new file mode 100644
index 0000000..7d138dc
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_typedef_with_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, 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
+
+// Allow typedef final mixins to be mixed in by multiple classes in the same
+// library.
+
+import 'package:expect/expect.dart';
+import 'final_mixin_typedef_with_lib.dart';
+
+main() {
+ Expect.equals(1, A().foo);
+}
diff --git a/tests/language/class_modifiers/final/final_mixin_with_lib.dart b/tests/language/class_modifiers/final/final_mixin_with_lib.dart
new file mode 100644
index 0000000..5076357
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_with_lib.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, 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
+
+// Allow final mixins to be mixed by multiple classes in the same library.
+
+final mixin FinalMixin {
+ int foo = 0;
+}
+
+abstract class A with FinalMixin {}
+
+class B with FinalMixin {}
diff --git a/tests/language/class_modifiers/final/final_mixin_with_outside_error_test.dart b/tests/language/class_modifiers/final/final_mixin_with_outside_error_test.dart
new file mode 100644
index 0000000..c526040
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_with_outside_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2022, 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
+
+// Error when attempting to mix in final mixin outside of library.
+
+import 'final_mixin_with_lib.dart';
+
+abstract class AOutside with FinalMixin {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class BOutside with FinalMixin {}
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
diff --git a/tests/language/class_modifiers/final/final_mixin_with_test.dart b/tests/language/class_modifiers/final/final_mixin_with_test.dart
new file mode 100644
index 0000000..f2849aa
--- /dev/null
+++ b/tests/language/class_modifiers/final/final_mixin_with_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, 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
+
+// Allow final mixins to be mixed by multiple classes in the same library.
+
+import 'package:expect/expect.dart';
+import 'final_mixin_with_lib.dart';
+
+class AImpl extends A {}
+
+main() {
+ Expect.equals(0, AImpl().foo);
+ Expect.equals(0, B().foo);
+}