diff --git a/LibTest/js_interop/anonymous_A01_t01.dart b/LibTest/js_interop/anonymous_A01_t01.dart new file mode 100644 index 0000000000..556619c82d --- /dev/null +++ b/LibTest/js_interop/anonymous_A01_t01.dart @@ -0,0 +1,41 @@ +// 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 An annotation that indicates a JS annotated class is structural +/// and does not have a known JavaScript prototype. +/// +/// A class marked with [anonymous] must have an unnamed factory constructor +/// with no positional arguments, only named arguments. Invoking the constructor +/// desugars to creating a JavaScript object literal with name-value pairs +/// corresponding to the parameter names and values. +/// +/// @description Checks that invoking the constructor desugars to creating a +/// JavaScript object literal with name-value pairs corresponding to the +/// parameter names and values. +/// @author sgrekhov22@gmail.com + +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; +import '../../Utils/expect.dart'; +import 'js_utils.dart'; + +@anonymous +@staticInterop +@JS() +class C { + external factory C({String s, int n, bool b}); +} + +main() { + var c = C(s: "s value", n: 42, b: true); + globalContext["c"] = c as JSObject; + eval(r''' + globalThis.resS = globalThis.c.s; + globalThis.resN = globalThis.c.n; + globalThis.resB = globalThis.c.b; + '''); + Expect.equals("s value", (globalContext["resS"] as JSString).toDart); + Expect.equals(42, (globalContext["resN"] as JSNumber).toDartInt); + Expect.equals(true, (globalContext["resB"] as JSBoolean).toDart); +} diff --git a/LibTest/js_interop/anonymous_A01_t02.dart b/LibTest/js_interop/anonymous_A01_t02.dart new file mode 100644 index 0000000000..bbdcdd40ff --- /dev/null +++ b/LibTest/js_interop/anonymous_A01_t02.dart @@ -0,0 +1,41 @@ +// 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 An annotation that indicates a JS annotated class is structural +/// and does not have a known JavaScript prototype. +/// +/// A class marked with [anonymous] must have an unnamed factory constructor +/// with no positional arguments, only named arguments. Invoking the constructor +/// desugars to creating a JavaScript object literal with name-value pairs +/// corresponding to the parameter names and values. +/// +/// @description Checks that invoking the constructor desugars to creating a +/// JavaScript object literal with name-value pairs corresponding to the +/// parameter names and values. Test a named factory constructor. +/// @author sgrekhov22@gmail.com + +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; +import '../../Utils/expect.dart'; +import 'js_utils.dart'; + +@anonymous +@staticInterop +@JS() +class C { + external factory C.f({String s, int n, bool b}); +} + +main() { + var c = C.f(s: "s value", n: 42, b: true); + globalContext["c"] = c as JSObject; + eval(r''' + globalThis.resS = globalThis.c.s; + globalThis.resN = globalThis.c.n; + globalThis.resB = globalThis.c.b; + '''); + Expect.equals("s value", (globalContext["resS"] as JSString).toDart); + Expect.equals(42, (globalContext["resN"] as JSNumber).toDartInt); + Expect.equals(true, (globalContext["resB"] as JSBoolean).toDart); +} diff --git a/LibTest/js_interop/anonymous_A02_t01.dart b/LibTest/js_interop/anonymous_A02_t01.dart new file mode 100644 index 0000000000..8da886e7f2 --- /dev/null +++ b/LibTest/js_interop/anonymous_A02_t01.dart @@ -0,0 +1,39 @@ +// 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 An annotation that indicates a JS annotated class is structural +/// and does not have a known JavaScript prototype. +/// +/// A class marked with [anonymous] must have an unnamed factory constructor +/// with no positional arguments, only named arguments. Invoking the constructor +/// desugars to creating a JavaScript object literal with name-value pairs +/// corresponding to the parameter names and values. +/// +/// @description Checks that it is not an error if a class annotated with +/// [anonymous] has no unnamed factory constructor. Creating an instance creates +/// an empty JS object. +/// @author sgrekhov22@gmail.com + +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; +import 'js_utils.dart'; + +@anonymous +class C1 { +} + +@anonymous +@staticInterop +@JS() +abstract class C2 { +} + +main() { + globalContext["o"] = C1().jsify(); + eval(r''' + globalThis.keys = Object.keys(globalThis.o); + '''); + jsExpectArrayEquals(JSArray(), globalContext["keys"]); + print(C2); +} diff --git a/LibTest/js_interop/anonymous_A03_t01.dart b/LibTest/js_interop/anonymous_A03_t01.dart new file mode 100644 index 0000000000..761e83fde1 --- /dev/null +++ b/LibTest/js_interop/anonymous_A03_t01.dart @@ -0,0 +1,69 @@ +// 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 An annotation that indicates a JS annotated class is structural +/// and does not have a known JavaScript prototype. +/// +/// A class marked with [anonymous] must have an unnamed factory constructor +/// with no positional arguments, only named arguments. Invoking the constructor +/// desugars to creating a JavaScript object literal with name-value pairs +/// corresponding to the parameter names and values. +/// +/// @description Checks that it is a warning if an extension type is annotated +/// with [anonymous]. +/// @author sgrekhov22@gmail.com +/// @issue 61018 + +import 'dart:js_interop'; + +@anonymous +@JS() +extension type Ext1(JSObject _) { +// ^^^^ +// [analyzer] unspecified +// [web] unspecified +} + +@anonymous +@JS() +extension type Ext2.x(JSObject _) { +// ^^^^ +// [analyzer] unspecified +// [web] unspecified + + external factory Ext2({String id}); +} + +@anonymous +@staticInterop +@JS() +extension type Ext3._(JSObject _) { +// ^^^^ +// [analyzer] unspecified +// [web] unspecified + external factory Ext3({String id}); +} + +@anonymous +extension type Ext4(JSObject id) { +// ^^^^ +// [analyzer] unspecified +// [web] unspecified +} + +@anonymous +extension type Ext5.x(JSObject id) { +// ^^^^ +// [analyzer] unspecified +// [web] unspecified + factory Ext5(JSObject id) = Ext5.x; +} + +main() { + print(Ext1); + print(Ext2); + print(Ext3); + print(Ext4); + print(Ext5); +} diff --git a/LibTest/js_interop/anonymous_A03_t02.dart b/LibTest/js_interop/anonymous_A03_t02.dart new file mode 100644 index 0000000000..9f9a94bd21 --- /dev/null +++ b/LibTest/js_interop/anonymous_A03_t02.dart @@ -0,0 +1,51 @@ +// 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 An annotation that indicates a JS annotated class is structural +/// and does not have a known JavaScript prototype. +/// +/// A class marked with [anonymous] must have an unnamed factory constructor +/// with no positional arguments, only named arguments. Invoking the constructor +/// desugars to creating a JavaScript object literal with name-value pairs +/// corresponding to the parameter names and values. +/// +/// @description Checks that it is a compile-time error if an enum is annotated +/// with [anonymous]. +/// @author sgrekhov22@gmail.com +/// @issue 61115 + +import 'dart:js_interop'; + +@anonymous +@staticInterop +@JS() +enum E1 { +// ^^ +// [analyzer] unspecified +// [web] unspecified + e0; +} + +@anonymous +@JS() +enum E2 { +// ^^ +// [analyzer] unspecified +// [web] unspecified + e0; +} + +@anonymous +enum E3 { +// ^^ +// [analyzer] unspecified +// [web] unspecified + e0; +} + +main() { + print(E1); + print(E2); + print(E3); +} diff --git a/LibTest/js_interop/anonymous_A03_t03.dart b/LibTest/js_interop/anonymous_A03_t03.dart new file mode 100644 index 0000000000..decf4cfd4c --- /dev/null +++ b/LibTest/js_interop/anonymous_A03_t03.dart @@ -0,0 +1,48 @@ +// 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 An annotation that indicates a JS annotated class is structural +/// and does not have a known JavaScript prototype. +/// +/// A class marked with [anonymous] must have an unnamed factory constructor +/// with no positional arguments, only named arguments. Invoking the constructor +/// desugars to creating a JavaScript object literal with name-value pairs +/// corresponding to the parameter names and values. +/// +/// @description Checks that it is a compile-time error if a mixin is annotated +/// with [anonymous]. +/// @author sgrekhov22@gmail.com +/// @issue 61018 + +import 'dart:js_interop'; + +@anonymous +@JS() +mixin M1 { +// ^^ +// [analyzer] unspecified +// [web] unspecified +} + +@anonymous +@staticInterop +@JS() +mixin M2 { +// ^^ +// [analyzer] unspecified +// [web] unspecified +} + +@anonymous +mixin M3 { +// ^^ +// [analyzer] unspecified +// [web] unspecified +} + +main() { + print(M1); + print(M2); + print(M3); +} diff --git a/LibTest/js_interop/anonymous_A03_t04.dart b/LibTest/js_interop/anonymous_A03_t04.dart new file mode 100644 index 0000000000..55ced9f92f --- /dev/null +++ b/LibTest/js_interop/anonymous_A03_t04.dart @@ -0,0 +1,49 @@ +// 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 An annotation that indicates a JS annotated class is structural +/// and does not have a known JavaScript prototype. +/// +/// A class marked with [anonymous] must have an unnamed factory constructor +/// with no positional arguments, only named arguments. Invoking the constructor +/// desugars to creating a JavaScript object literal with name-value pairs +/// corresponding to the parameter names and values. +/// +/// @description Checks that it is a compile-time error if an extension +/// is annotated with `@anonymous`. +/// @author sgrekhov22@gmail.com + +import 'dart:js_interop'; + +class C1 { + C1.n({String id = ""}); + factory C1({String id}) = C1.n; +} + +@anonymous +@JS() +extension Ext1 on C1 { +// ^^^^ +// [analyzer] unspecified +// [web] unspecified +} + +@anonymous +@staticInterop +@JS() +class C2 { + external factory C2({String id}); +} + +@anonymous +extension Ext2 on C2 { +// ^^^^ +// [analyzer] unspecified +// [web] unspecified +} + +main() { + print(C1); + print(C2); +} diff --git a/LibTest/js_interop/anonymous_A03_t05.dart b/LibTest/js_interop/anonymous_A03_t05.dart new file mode 100644 index 0000000000..9d54ecb27e --- /dev/null +++ b/LibTest/js_interop/anonymous_A03_t05.dart @@ -0,0 +1,50 @@ +// 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 An annotation that indicates a JS annotated class is structural +/// and does not have a known JavaScript prototype. +/// +/// A class marked with [anonymous] must have an unnamed factory constructor +/// with no positional arguments, only named arguments. Invoking the constructor +/// desugars to creating a JavaScript object literal with name-value pairs +/// corresponding to the parameter names and values. +/// +/// @description Checks that it is a compile-time error if a non-type is marked +/// with [anonymous]. +/// @author sgrekhov22@gmail.com +/// @issue 61109 + +import 'dart:js_interop'; + +@anonymous +void foo() {} +// ^^^ +// [analyzer] unspecified +// [web] unspecified + +@anonymous +@JS() +int get bar => 42; +// ^^^ +// [analyzer] unspecified +// [web] unspecified + +@anonymous +@JS() +String baz = "baz"; +// ^^^ +// [analyzer] unspecified +// [web] unspecified + +@anonymous +void set qux(int _) {} +// ^^^ +// [analyzer] unspecified +// [web] unspecified + +main() { + print(foo); + print(bar); + print(baz); +}