Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions LibTest/js_interop/anonymous_A01_t01.dart
Original file line number Diff line number Diff line change
@@ -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);
}
41 changes: 41 additions & 0 deletions LibTest/js_interop/anonymous_A01_t02.dart
Original file line number Diff line number Diff line change
@@ -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);
}
39 changes: 39 additions & 0 deletions LibTest/js_interop/anonymous_A02_t01.dart
Original file line number Diff line number Diff line change
@@ -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);
}
69 changes: 69 additions & 0 deletions LibTest/js_interop/anonymous_A03_t01.dart
Original file line number Diff line number Diff line change
@@ -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);
}
51 changes: 51 additions & 0 deletions LibTest/js_interop/anonymous_A03_t02.dart
Original file line number Diff line number Diff line change
@@ -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);
}
48 changes: 48 additions & 0 deletions LibTest/js_interop/anonymous_A03_t03.dart
Original file line number Diff line number Diff line change
@@ -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);
}
49 changes: 49 additions & 0 deletions LibTest/js_interop/anonymous_A03_t04.dart
Original file line number Diff line number Diff line change
@@ -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);
}
50 changes: 50 additions & 0 deletions LibTest/js_interop/anonymous_A03_t05.dart
Original file line number Diff line number Diff line change
@@ -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);
}