Skip to content

Commit 265e8fe

Browse files
BridgeJS: Fix Array<@jsclass struct> support on imported interfaces
1 parent 9bf1c59 commit 265e8fe

File tree

7 files changed

+167
-8
lines changed

7 files changed

+167
-8
lines changed

Sources/JavaScriptKit/BridgeJSIntrinsics.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -510,12 +510,13 @@ extension _JSBridgedClass {
510510
@_spi(BridgeJS) public static func bridgeJSLiftParameter(_ id: Int32) -> Self {
511511
Self(unsafelyWrapping: JSObject.bridgeJSLiftParameter(id))
512512
}
513-
@_spi(BridgeJS) public static func bridgeJSStackPop() -> Self {
514-
bridgeJSLiftParameter(_swift_js_pop_i32())
515-
}
516513
@_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Int32 { jsObject.bridgeJSLowerReturn() }
517-
@_spi(BridgeJS) public consuming func bridgeJSStackPush() {
518-
_swift_js_push_i32(bridgeJSLowerReturn())
514+
515+
public static func bridgeJSStackPop() -> Self {
516+
Self(unsafelyWrapping: JSObject.bridgeJSStackPop())
517+
}
518+
public consuming func bridgeJSStackPush() {
519+
jsObject.bridgeJSStackPush()
519520
}
520521
}
521522

Sources/JavaScriptKit/JSBridgedType.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extension JSBridgedType {
1616
/// A protocol that Swift classes that are exposed to JavaScript via `@JS class` conform to.
1717
///
1818
/// The conformance is automatically synthesized by `@JSClass` for BridgeJS-generated declarations.
19-
public protocol _JSBridgedClass {
19+
public protocol _JSBridgedClass: Equatable, _BridgedSwiftStackType {
2020
/// The JavaScript object wrapped by this instance.
2121
/// You may assume that `jsObject instanceof Self.constructor == true`
2222
var jsObject: JSObject { get }
@@ -26,6 +26,12 @@ public protocol _JSBridgedClass {
2626
init(unsafelyWrapping jsObject: JSObject)
2727
}
2828

29+
extension _JSBridgedClass {
30+
public static func == (lhs: Self, rhs: Self) -> Bool {
31+
lhs.jsObject == rhs.jsObject
32+
}
33+
}
34+
2935
/// Conform to this protocol when your Swift class wraps a JavaScript class.
3036
public protocol JSBridgedClass: JSBridgedType, _JSBridgedClass {
3137
/// The constructor function for the JavaScript class

Tests/BridgeJSRuntimeTests/ArraySupportTests.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import XCTest
22
import JavaScriptKit
33

4+
@JSClass struct ArrayElementObject {
5+
@JSGetter var id: String
6+
7+
@JSFunction init(id: String) throws(JSException)
8+
}
9+
410
@JSClass struct ArraySupportImports {
511
@JSFunction static func jsIntArrayLength(_ items: [Int]) throws(JSException) -> Int
612

@@ -12,6 +18,8 @@ import JavaScriptKit
1218
@JSFunction static func jsRoundTripJSValueArray(_ v: [JSValue]) throws(JSException) -> [JSValue]
1319
@JSFunction static func jsRoundTripOptionalJSValueArray(_ v: Optional<[JSValue]>) throws(JSException) -> Optional<[JSValue]>
1420

21+
@JSFunction static func jsRoundTripJSClassArray(_ values: [ArrayElementObject]) throws(JSException) -> [ArrayElementObject]
22+
1523
@JSFunction static func jsSumNumberArray(_ values: [Double]) throws(JSException) -> Double
1624
@JSFunction static func jsCreateNumberArray() throws(JSException) -> [Double]
1725
}
@@ -85,4 +93,15 @@ final class ArraySupportTests: XCTestCase {
8593
let result = try ArraySupportImports.jsRoundTripOptionalJSValueArray(values)
8694
XCTAssertEqual(result, values)
8795
}
96+
97+
func testRoundTripJSClassArray() throws {
98+
let values = try [ArrayElementObject(id: "1"), ArrayElementObject(id: "2"), ArrayElementObject(id: "3")]
99+
let result = try ArraySupportImports.jsRoundTripJSClassArray(values)
100+
XCTAssertEqual(result, values)
101+
XCTAssertEqual(try result[0].id, "1")
102+
XCTAssertEqual(try result[1].id, "2")
103+
XCTAssertEqual(try result[2].id, "3")
104+
105+
XCTAssertEqual(try ArraySupportImports.jsRoundTripJSClassArray([]), [])
106+
}
88107
}

Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9229,6 +9229,48 @@ fileprivate func _bjs_LeakCheck_wrap_extern(_ pointer: UnsafeMutableRawPointer)
92299229
return _bjs_LeakCheck_wrap_extern(pointer)
92309230
}
92319231

9232+
#if arch(wasm32)
9233+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ArrayElementObject_init")
9234+
fileprivate func bjs_ArrayElementObject_init_extern(_ id: Int32) -> Int32
9235+
#else
9236+
fileprivate func bjs_ArrayElementObject_init_extern(_ id: Int32) -> Int32 {
9237+
fatalError("Only available on WebAssembly")
9238+
}
9239+
#endif
9240+
@inline(never) fileprivate func bjs_ArrayElementObject_init(_ id: Int32) -> Int32 {
9241+
return bjs_ArrayElementObject_init_extern(id)
9242+
}
9243+
9244+
#if arch(wasm32)
9245+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ArrayElementObject_id_get")
9246+
fileprivate func bjs_ArrayElementObject_id_get_extern(_ self: Int32) -> Int32
9247+
#else
9248+
fileprivate func bjs_ArrayElementObject_id_get_extern(_ self: Int32) -> Int32 {
9249+
fatalError("Only available on WebAssembly")
9250+
}
9251+
#endif
9252+
@inline(never) fileprivate func bjs_ArrayElementObject_id_get(_ self: Int32) -> Int32 {
9253+
return bjs_ArrayElementObject_id_get_extern(self)
9254+
}
9255+
9256+
func _$ArrayElementObject_init(_ id: String) throws(JSException) -> JSObject {
9257+
let idValue = id.bridgeJSLowerParameter()
9258+
let ret = bjs_ArrayElementObject_init(idValue)
9259+
if let error = _swift_js_take_exception() {
9260+
throw error
9261+
}
9262+
return JSObject.bridgeJSLiftReturn(ret)
9263+
}
9264+
9265+
func _$ArrayElementObject_id_get(_ self: JSObject) throws(JSException) -> String {
9266+
let selfValue = self.bridgeJSLowerParameter()
9267+
let ret = bjs_ArrayElementObject_id_get(selfValue)
9268+
if let error = _swift_js_take_exception() {
9269+
throw error
9270+
}
9271+
return String.bridgeJSLiftReturn(ret)
9272+
}
9273+
92329274
#if arch(wasm32)
92339275
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ArraySupportImports_jsIntArrayLength_static")
92349276
fileprivate func bjs_ArraySupportImports_jsIntArrayLength_static_extern() -> Int32
@@ -9313,6 +9355,18 @@ fileprivate func bjs_ArraySupportImports_jsRoundTripOptionalJSValueArray_static_
93139355
return bjs_ArraySupportImports_jsRoundTripOptionalJSValueArray_static_extern(v)
93149356
}
93159357

9358+
#if arch(wasm32)
9359+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ArraySupportImports_jsRoundTripJSClassArray_static")
9360+
fileprivate func bjs_ArraySupportImports_jsRoundTripJSClassArray_static_extern() -> Void
9361+
#else
9362+
fileprivate func bjs_ArraySupportImports_jsRoundTripJSClassArray_static_extern() -> Void {
9363+
fatalError("Only available on WebAssembly")
9364+
}
9365+
#endif
9366+
@inline(never) fileprivate func bjs_ArraySupportImports_jsRoundTripJSClassArray_static() -> Void {
9367+
return bjs_ArraySupportImports_jsRoundTripJSClassArray_static_extern()
9368+
}
9369+
93169370
#if arch(wasm32)
93179371
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ArraySupportImports_jsSumNumberArray_static")
93189372
fileprivate func bjs_ArraySupportImports_jsSumNumberArray_static_extern() -> Float64
@@ -9400,6 +9454,15 @@ func _$ArraySupportImports_jsRoundTripOptionalJSValueArray(_ v: Optional<[JSValu
94009454
return Optional<[JSValue]>.bridgeJSLiftReturn()
94019455
}
94029456

9457+
func _$ArraySupportImports_jsRoundTripJSClassArray(_ values: [ArrayElementObject]) throws(JSException) -> [ArrayElementObject] {
9458+
let _ = values.bridgeJSLowerParameter()
9459+
bjs_ArraySupportImports_jsRoundTripJSClassArray_static()
9460+
if let error = _swift_js_take_exception() {
9461+
throw error
9462+
}
9463+
return [ArrayElementObject].bridgeJSLiftReturn()
9464+
}
9465+
94039466
func _$ArraySupportImports_jsSumNumberArray(_ values: [Double]) throws(JSException) -> Double {
94049467
let _ = values.bridgeJSLowerParameter()
94059468
let ret = bjs_ArraySupportImports_jsSumNumberArray_static()

Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13379,6 +13379,40 @@
1337913379

1338013380
],
1338113381
"types" : [
13382+
{
13383+
"constructor" : {
13384+
"parameters" : [
13385+
{
13386+
"name" : "id",
13387+
"type" : {
13388+
"string" : {
13389+
13390+
}
13391+
}
13392+
}
13393+
]
13394+
},
13395+
"getters" : [
13396+
{
13397+
"name" : "id",
13398+
"type" : {
13399+
"string" : {
13400+
13401+
}
13402+
}
13403+
}
13404+
],
13405+
"methods" : [
13406+
13407+
],
13408+
"name" : "ArrayElementObject",
13409+
"setters" : [
13410+
13411+
],
13412+
"staticMethods" : [
13413+
13414+
]
13415+
},
1338213416
{
1338313417
"getters" : [
1338413418

@@ -13579,6 +13613,32 @@
1357913613
}
1358013614
}
1358113615
},
13616+
{
13617+
"name" : "jsRoundTripJSClassArray",
13618+
"parameters" : [
13619+
{
13620+
"name" : "values",
13621+
"type" : {
13622+
"array" : {
13623+
"_0" : {
13624+
"jsObject" : {
13625+
"_0" : "ArrayElementObject"
13626+
}
13627+
}
13628+
}
13629+
}
13630+
}
13631+
],
13632+
"returnType" : {
13633+
"array" : {
13634+
"_0" : {
13635+
"jsObject" : {
13636+
"_0" : "ArrayElementObject"
13637+
}
13638+
}
13639+
}
13640+
}
13641+
},
1358213642
{
1358313643
"name" : "jsSumNumberArray",
1358413644
"parameters" : [

Tests/BridgeJSRuntimeTests/JavaScript/ArraySupportTests.mjs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
// @ts-check
22

3+
export class ArrayElementObject {
4+
constructor(id) {
5+
this.id = id;
6+
}
7+
}
8+
39
/**
410
* @returns {import('../../../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.d.ts').Imports["ArraySupportImports"]}
511
*/
@@ -31,6 +37,9 @@ export function getImports(importsContext) {
3137
},
3238
jsCreateNumberArray: function () {
3339
return [1, 2, 3, 4, 5];
34-
}
40+
},
41+
jsRoundTripJSClassArray: (values) => {
42+
return values;
43+
},
3544
};
3645
}

Tests/prelude.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { runJsOptionalSupportTests } from './BridgeJSRuntimeTests/JavaScript/Opt
88
import { getImports as getClosureSupportImports } from './BridgeJSRuntimeTests/JavaScript/ClosureSupportTests.mjs';
99
import { getImports as getSwiftClassSupportImports } from './BridgeJSRuntimeTests/JavaScript/SwiftClassSupportTests.mjs';
1010
import { getImports as getOptionalSupportImports } from './BridgeJSRuntimeTests/JavaScript/OptionalSupportTests.mjs';
11-
import { getImports as getArraySupportImports } from './BridgeJSRuntimeTests/JavaScript/ArraySupportTests.mjs';
11+
import { getImports as getArraySupportImports, ArrayElementObject } from './BridgeJSRuntimeTests/JavaScript/ArraySupportTests.mjs';
1212
import { getImports as getJSClassSupportImports, JSClassWithArrayMembers } from './BridgeJSRuntimeTests/JavaScript/JSClassSupportTests.mjs';
1313

1414
/** @type {import('../.build/plugins/PackageToJS/outputs/PackageTests/test.d.ts').SetupOptionsFn} */
@@ -112,6 +112,7 @@ export async function setupOptions(options, context) {
112112
"$jsWeirdFunction": () => {
113113
return 42;
114114
},
115+
ArrayElementObject,
115116
JSClassWithArrayMembers,
116117
JsGreeter: class {
117118
/**

0 commit comments

Comments
 (0)