#3180. Add `@staticInterop` tests. Part 2. (#3257)

* #3180. Add `@staticInterop` tests. Part 2.

* Make mixin class an error
diff --git a/LibTest/js_interop/anonymous_A03_t04.dart b/LibTest/js_interop/anonymous_A03_t04.dart
index 55ced9f..67bda35 100644
--- a/LibTest/js_interop/anonymous_A03_t04.dart
+++ b/LibTest/js_interop/anonymous_A03_t04.dart
@@ -13,6 +13,7 @@
 /// @description Checks that it is a compile-time error if an extension
 /// is annotated with `@anonymous`.
 /// @author sgrekhov22@gmail.com
+/// @issue 61082
 
 import 'dart:js_interop';
 
diff --git a/LibTest/js_interop/staticInterop_A03_t05.dart b/LibTest/js_interop/staticInterop_A03_t05.dart
new file mode 100644
index 0000000..26bf8b8
--- /dev/null
+++ b/LibTest/js_interop/staticInterop_A03_t05.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2025, 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.
+
+/// @assertion `staticInterop` enables the JS annotated class to be treated as
+/// a "static" interop class.
+///
+/// These classes implicitly all erase to the internal interceptor
+/// `JavaScriptObject`, so they can be freely casted to and from other
+/// [staticInterop] types, `dart:html` types, and `JSObject` from
+/// `dart:js_interop`. Non-[staticInterop] `package:js` types can be casted to
+/// [staticInterop] types, but the reverse can fail if the underlying value is a
+/// `@Native`-reserved type (like `dart:html` types).
+///
+/// [staticInterop] classes have the following restrictions:
+///  - They must contain a [JS] annotation, either from this library or from
+///    `dart:js_interop`.
+///  - They should not contain any instance members, inherited or otherwise, and
+///    should instead use static extension members, which can be external or
+///    non-external.
+///  - They can only contain factories and `static` members. They can be
+///    combined with [anonymous] to make external factories create new
+///    JavaScript object literals instead.
+///  - They should not implement, extend, or mixin non-[staticInterop] classes
+///    and vice-versa.
+///  - The annotation should only be applied to non-mixin classes and no other
+///    declarations.
+///
+/// @description Checks that a class annotated with `@staticInterop` can be
+/// `abstract`, `base`, `final`, `sealed` or `interface`.
+/// @author sgrekhov22@gmail.com
+
+import 'dart:js_interop';
+import 'dart:js_interop_unsafe';
+import '../../Utils/expect.dart';
+import 'js_utils.dart';
+
+@staticInterop
+@JS()
+abstract class C1 {
+}
+
+@staticInterop
+@JS()
+base class C2 {
+}
+
+@staticInterop
+@JS()
+final class C3 {
+}
+
+@staticInterop
+@JS()
+sealed class C4 {
+}
+
+@staticInterop
+@JS()
+interface class C5 {
+}
+
+extension Ext1 on C1 {
+  external String getString();
+  external int getNumber();
+  external bool getBool();
+}
+
+extension Ext2 on C2 {
+  external String getString();
+  external int getNumber();
+  external bool getBool();
+}
+
+extension Ext3 on C3 {
+  external String getString();
+  external int getNumber();
+  external bool getBool();
+}
+
+extension Ext4 on C4 {
+  external String getString();
+  external int getNumber();
+  external bool getBool();
+}
+
+extension Ext5 on C5 {
+  external String getString();
+  external int getNumber();
+  external bool getBool();
+}
+
+main() {
+  eval(r'''
+    globalThis.obj = {
+      getString: function () {
+        return "I'm JS String";
+      },
+      getNumber: function () {
+        return 42;
+      },
+      getBool: function () {
+        return true;
+      }
+    };
+  ''');
+
+  C1 c1 = globalContext["obj"] as C1;
+  Expect.equals("I'm JS String", c1.getString());
+  Expect.equals(42, c1.getNumber());
+  Expect.equals(true, c1.getBool());
+
+  C2 c2 = globalContext["obj"] as C2;
+  Expect.equals("I'm JS String", c2.getString());
+  Expect.equals(42, c2.getNumber());
+  Expect.equals(true, c2.getBool());
+
+  C3 c3 = globalContext["obj"] as C3;
+  Expect.equals("I'm JS String", c3.getString());
+  Expect.equals(42, c3.getNumber());
+  Expect.equals(true, c3.getBool());
+
+  C4 c4 = globalContext["obj"] as C4;
+  Expect.equals("I'm JS String", c4.getString());
+  Expect.equals(42, c4.getNumber());
+  Expect.equals(true, c4.getBool());
+
+  C5 c5 = globalContext["obj"] as C5;
+  Expect.equals("I'm JS String", c5.getString());
+  Expect.equals(42, c5.getNumber());
+  Expect.equals(true, c5.getBool());
+}
diff --git a/LibTest/js_interop/staticInterop_A04_t01.dart b/LibTest/js_interop/staticInterop_A04_t01.dart
new file mode 100644
index 0000000..746bef4
--- /dev/null
+++ b/LibTest/js_interop/staticInterop_A04_t01.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2025, 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.
+
+/// @assertion `staticInterop` enables the JS annotated class to be treated as
+/// a "static" interop class.
+///
+/// These classes implicitly all erase to the internal interceptor
+/// `JavaScriptObject`, so they can be freely casted to and from other
+/// [staticInterop] types, `dart:html` types, and `JSObject` from
+/// `dart:js_interop`. Non-[staticInterop] `package:js` types can be casted to
+/// [staticInterop] types, but the reverse can fail if the underlying value is a
+/// `@Native`-reserved type (like `dart:html` types).
+///
+/// [staticInterop] classes have the following restrictions:
+///  - They must contain a [JS] annotation, either from this library or from
+///    `dart:js_interop`.
+///  - They should not contain any instance members, inherited or otherwise, and
+///    should instead use static extension members, which can be external or
+///    non-external.
+///  - They can only contain factories and `static` members. They can be
+///    combined with [anonymous] to make external factories create new
+///    JavaScript object literals instead.
+///  - They should not implement, extend, or mixin non-[staticInterop] classes
+///    and vice-versa.
+///  - The annotation should only be applied to non-mixin classes and no other
+///    declarations.
+///
+/// @description Checks that it is a compile-time error if a class without
+/// `@staticInterop` annotation extends or implements one with this annotation.
+/// @author sgrekhov22@gmail.com
+
+import 'dart:js_interop';
+
+@staticInterop
+@JS()
+class A {}
+
+@staticInterop
+@JS()
+abstract interface class I {}
+
+@JS()
+class C1 extends A {}
+//    ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+@JS()
+class C2 implements I {}
+//    ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+main() {
+  print(C1);
+  print(C2);
+}
diff --git a/LibTest/js_interop/staticInterop_A04_t02.dart b/LibTest/js_interop/staticInterop_A04_t02.dart
new file mode 100644
index 0000000..192a446
--- /dev/null
+++ b/LibTest/js_interop/staticInterop_A04_t02.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2025, 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.
+
+/// @assertion `staticInterop` enables the JS annotated class to be treated as
+/// a "static" interop class.
+///
+/// These classes implicitly all erase to the internal interceptor
+/// `JavaScriptObject`, so they can be freely casted to and from other
+/// [staticInterop] types, `dart:html` types, and `JSObject` from
+/// `dart:js_interop`. Non-[staticInterop] `package:js` types can be casted to
+/// [staticInterop] types, but the reverse can fail if the underlying value is a
+/// `@Native`-reserved type (like `dart:html` types).
+///
+/// [staticInterop] classes have the following restrictions:
+///  - They must contain a [JS] annotation, either from this library or from
+///    `dart:js_interop`.
+///  - They should not contain any instance members, inherited or otherwise, and
+///    should instead use static extension members, which can be external or
+///    non-external.
+///  - They can only contain factories and `static` members. They can be
+///    combined with [anonymous] to make external factories create new
+///    JavaScript object literals instead.
+///  - They should not implement, extend, or mixin non-[staticInterop] classes
+///    and vice-versa.
+///  - The annotation should only be applied to non-mixin classes and no other
+///    declarations.
+///
+/// @description Checks that it is a compile-time error if a class annotated
+/// with `@staticInterop` annotation extends, mixin or implements one without
+/// this annotation.
+/// @author sgrekhov22@gmail.com
+
+import 'dart:js_interop';
+
+class A {}
+
+mixin class M {}
+
+abstract interface class I {}
+
+@staticInterop
+@JS()
+class C1 extends A {}
+//    ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+@staticInterop
+@JS()
+class C2 with M {}
+//    ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+@staticInterop
+@JS()
+class C3 implements I {}
+//    ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+main() {
+  print(C1);
+  print(C2);
+  print(C3);
+}
diff --git a/LibTest/js_interop/staticInterop_A04_t03.dart b/LibTest/js_interop/staticInterop_A04_t03.dart
new file mode 100644
index 0000000..247edc3
--- /dev/null
+++ b/LibTest/js_interop/staticInterop_A04_t03.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2025, 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.
+
+/// @assertion `staticInterop` enables the JS annotated class to be treated as
+/// a "static" interop class.
+///
+/// These classes implicitly all erase to the internal interceptor
+/// `JavaScriptObject`, so they can be freely casted to and from other
+/// [staticInterop] types, `dart:html` types, and `JSObject` from
+/// `dart:js_interop`. Non-[staticInterop] `package:js` types can be casted to
+/// [staticInterop] types, but the reverse can fail if the underlying value is a
+/// `@Native`-reserved type (like `dart:html` types).
+///
+/// [staticInterop] classes have the following restrictions:
+///  - They must contain a [JS] annotation, either from this library or from
+///    `dart:js_interop`.
+///  - They should not contain any instance members, inherited or otherwise, and
+///    should instead use static extension members, which can be external or
+///    non-external.
+///  - They can only contain factories and `static` members. They can be
+///    combined with [anonymous] to make external factories create new
+///    JavaScript object literals instead.
+///  - They should not implement, extend, or mixin non-[staticInterop] classes
+///    and vice-versa.
+///  - The annotation should only be applied to non-mixin classes and no other
+///    declarations.
+///
+/// @description Checks that a class annotated with `@staticInterop` can extend,
+/// or implement another class/mixin annotated with `@staticInterop`.
+/// @author sgrekhov22@gmail.com
+
+import 'dart:js_interop';
+import 'dart:js_interop_unsafe';
+import '../../Utils/expect.dart';
+import 'js_utils.dart';
+
+@staticInterop
+@JS()
+abstract class A {}
+
+extension Ext on A {
+  external String getString();
+  external int getNumber();
+  external bool getBool();
+}
+
+@staticInterop
+@JS()
+class C1 extends A {
+}
+
+@staticInterop
+@JS()
+class C2 implements A {
+}
+
+main() {
+  eval(r'''
+    globalThis.obj = {
+      getString: function () {
+        return "I'm JS String";
+      },
+      getNumber: function () {
+        return 42;
+      },
+      getBool: function () {
+        return true;
+      }
+    };
+  ''');
+
+  C1 c1 = globalContext["obj"] as C1;
+  Expect.equals("I'm JS String", c1.getString());
+  Expect.equals(42, c1.getNumber());
+  Expect.equals(true, c1.getBool());
+
+  C2 c2 = globalContext["obj"] as C2;
+  Expect.equals("I'm JS String", c2.getString());
+  Expect.equals(42, c2.getNumber());
+  Expect.equals(true, c2.getBool());
+}
diff --git a/LibTest/js_interop/staticInterop_A05_t01.dart b/LibTest/js_interop/staticInterop_A05_t01.dart
new file mode 100644
index 0000000..7055934
--- /dev/null
+++ b/LibTest/js_interop/staticInterop_A05_t01.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2025, 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.
+
+/// @assertion `staticInterop` enables the JS annotated class to be treated as
+/// a "static" interop class.
+///
+/// These classes implicitly all erase to the internal interceptor
+/// `JavaScriptObject`, so they can be freely casted to and from other
+/// [staticInterop] types, `dart:html` types, and `JSObject` from
+/// `dart:js_interop`. Non-[staticInterop] `package:js` types can be casted to
+/// [staticInterop] types, but the reverse can fail if the underlying value is a
+/// `@Native`-reserved type (like `dart:html` types).
+///
+/// [staticInterop] classes have the following restrictions:
+///  - They must contain a [JS] annotation, either from this library or from
+///    `dart:js_interop`.
+///  - They should not contain any instance members, inherited or otherwise, and
+///    should instead use static extension members, which can be external or
+///    non-external.
+///  - They can only contain factories and `static` members. They can be
+///    combined with [anonymous] to make external factories create new
+///    JavaScript object literals instead.
+///  - They should not implement, extend, or mixin non-[staticInterop] classes
+///    and vice-versa.
+///  - The annotation should only be applied to non-mixin classes and no other
+///    declarations.
+///
+/// @description Checks that it is a compile-time error if a mixin or mixin
+/// class is annotated with `@staticInterop`.
+/// @author sgrekhov22@gmail.com
+/// @issue 61125
+
+import 'dart:js_interop';
+
+@staticInterop
+@JS()
+mixin M1 {}
+//    ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+@staticInterop
+@JS()
+base mixin M2 {}
+//         ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+@staticInterop
+@JS()
+mixin class M3 {}
+//          ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+@staticInterop
+@JS()
+abstract mixin class M4 {}
+//                   ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+@staticInterop
+@JS()
+base mixin class M5 {}
+//               ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+@staticInterop
+@JS()
+abstract base mixin class M6 {}
+//                        ^^
+// [analyzer] unspecified
+// [web] unspecified
+
+main() {
+  print(M1);
+  print(M2);
+  print(M3);
+  print(M4);
+  print(M5);
+  print(M6);
+}