Skip to content

Commit eb818b6

Browse files
Expanded runtime coverage for optionals/undefined:
- Added JS null vs undefined round-trips for numbers plus optional Greeter callbacks/holders; extended prelude to verify new exported optional pathways. - Introduced stricter TS config so union types (null/undefined) are preserved in generation. - Regenerated BridgeJS runtime bindings and updated tests to exercise optional callbacks and holders. Tests run: - `swift test --package-path ./Plugins/BridgeJS` - `SWIFT_SDK_ID=DEVELOPMENT-SNAPSHOT-2025-11-03-a-wasm32-unknown-wasip1 make unittest`
1 parent 7aae4b8 commit eb818b6

File tree

4 files changed

+422
-5
lines changed

4 files changed

+422
-5
lines changed

Tests/BridgeJSRuntimeTests/ExportAPITests.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,29 @@ typealias OptionalAge = Int?
611611
@JS func roundTripOptionalClass(value: Greeter?) -> Greeter? {
612612
return value
613613
}
614+
615+
@JS func roundTripOptionalGreeter(_ value: Greeter?) -> Greeter? {
616+
value
617+
}
618+
619+
@JS func applyOptionalGreeter(_ value: Greeter?, _ transform: (Greeter?) -> Greeter?) -> Greeter? {
620+
transform(value)
621+
}
622+
623+
@JS class OptionalHolder {
624+
@JS var nullableGreeter: Greeter?
625+
@JS var undefinedNumber: JSUndefinedOr<Double>
626+
627+
@JS init(nullableGreeter: Greeter?, undefinedNumber: JSUndefinedOr<Double>) {
628+
self.nullableGreeter = nullableGreeter
629+
self.undefinedNumber = undefinedNumber
630+
}
631+
}
632+
633+
@JS func makeOptionalHolder(nullableGreeter: Greeter?, undefinedNumber: JSUndefinedOr<Double>) -> OptionalHolder {
634+
OptionalHolder(nullableGreeter: nullableGreeter, undefinedNumber: undefinedNumber)
635+
}
636+
614637
@JS class OptionalPropertyHolder {
615638
@JS var optionalName: String?
616639
@JS var optionalAge: Int? = nil

Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,54 @@ public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq7
679679
#endif
680680
}
681681

682+
#if arch(wasm32)
683+
@_extern(wasm, module: "bjs", name: "invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC")
684+
fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC(_ callback: Int32, _ param0IsSome: Int32, _ param0Pointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer
685+
#else
686+
fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC(_ callback: Int32, _ param0IsSome: Int32, _ param0Pointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer {
687+
fatalError("Only available on WebAssembly")
688+
}
689+
#endif
690+
691+
private final class _BJS_ClosureBox_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC: _BridgedSwiftClosureBox {
692+
let closure: (Optional<Greeter>) -> Optional<Greeter>
693+
init(_ closure: @escaping (Optional<Greeter>) -> Optional<Greeter>) {
694+
self.closure = closure
695+
}
696+
}
697+
698+
private enum _BJS_Closure_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC {
699+
static func bridgeJSLower(_ closure: @escaping (Optional<Greeter>) -> Optional<Greeter>) -> UnsafeMutableRawPointer {
700+
let box = _BJS_ClosureBox_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC(closure)
701+
return Unmanaged.passRetained(box).toOpaque()
702+
}
703+
static func bridgeJSLift(_ callbackId: Int32) -> (Optional<Greeter>) -> Optional<Greeter> {
704+
let callback = JSObject.bridgeJSLiftParameter(callbackId)
705+
return { [callback] param0 in
706+
#if arch(wasm32)
707+
let callbackValue = callback.bridgeJSLowerParameter()
708+
let (param0IsSome, param0Pointer) = param0.bridgeJSLowerParameter()
709+
let ret = invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC(callbackValue, param0IsSome, param0Pointer)
710+
return Optional<Greeter>.bridgeJSLiftReturn(ret)
711+
#else
712+
fatalError("Only available on WebAssembly")
713+
#endif
714+
}
715+
}
716+
}
717+
718+
@_expose(wasm, "invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC")
719+
@_cdecl("invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC")
720+
public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC(_ boxPtr: UnsafeMutableRawPointer, _ param0IsSome: Int32, _ param0Value: UnsafeMutableRawPointer) -> Void {
721+
#if arch(wasm32)
722+
let box = Unmanaged<_BJS_ClosureBox_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC>.fromOpaque(boxPtr).takeUnretainedValue()
723+
let result = box.closure(Optional<Greeter>.bridgeJSLiftParameter(param0IsSome, param0Value))
724+
return result.bridgeJSLowerReturn()
725+
#else
726+
fatalError("Only available on WebAssembly")
727+
#endif
728+
}
729+
682730
#if arch(wasm32)
683731
@_extern(wasm, module: "bjs", name: "invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq9APIResultO_SS")
684732
fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSq9APIResultO_SS(_ callback: Int32, _ param0IsSome: Int32, _ param0CaseId: Int32) -> Int32
@@ -4316,6 +4364,39 @@ public func _bjs_roundTripOptionalClass(_ valueIsSome: Int32, _ valueValue: Unsa
43164364
#endif
43174365
}
43184366

4367+
@_expose(wasm, "bjs_roundTripOptionalGreeter")
4368+
@_cdecl("bjs_roundTripOptionalGreeter")
4369+
public func _bjs_roundTripOptionalGreeter(_ valueIsSome: Int32, _ valueValue: UnsafeMutableRawPointer) -> Void {
4370+
#if arch(wasm32)
4371+
let ret = roundTripOptionalGreeter(_: Optional<Greeter>.bridgeJSLiftParameter(valueIsSome, valueValue))
4372+
return ret.bridgeJSLowerReturn()
4373+
#else
4374+
fatalError("Only available on WebAssembly")
4375+
#endif
4376+
}
4377+
4378+
@_expose(wasm, "bjs_applyOptionalGreeter")
4379+
@_cdecl("bjs_applyOptionalGreeter")
4380+
public func _bjs_applyOptionalGreeter(_ valueIsSome: Int32, _ valueValue: UnsafeMutableRawPointer, _ transform: Int32) -> Void {
4381+
#if arch(wasm32)
4382+
let ret = applyOptionalGreeter(_: Optional<Greeter>.bridgeJSLiftParameter(valueIsSome, valueValue), _: _BJS_Closure_20BridgeJSRuntimeTestsSq7GreeterC_Sq7GreeterC.bridgeJSLift(transform))
4383+
return ret.bridgeJSLowerReturn()
4384+
#else
4385+
fatalError("Only available on WebAssembly")
4386+
#endif
4387+
}
4388+
4389+
@_expose(wasm, "bjs_makeOptionalHolder")
4390+
@_cdecl("bjs_makeOptionalHolder")
4391+
public func _bjs_makeOptionalHolder(_ nullableGreeterIsSome: Int32, _ nullableGreeterValue: UnsafeMutableRawPointer, _ undefinedNumberIsDefined: Int32, _ undefinedNumberValue: Float64) -> UnsafeMutableRawPointer {
4392+
#if arch(wasm32)
4393+
let ret = makeOptionalHolder(nullableGreeter: Optional<Greeter>.bridgeJSLiftParameter(nullableGreeterIsSome, nullableGreeterValue), undefinedNumber: JSUndefinedOr<Double>.bridgeJSLiftParameter(undefinedNumberIsDefined, undefinedNumberValue))
4394+
return ret.bridgeJSLowerReturn()
4395+
#else
4396+
fatalError("Only available on WebAssembly")
4397+
#endif
4398+
}
4399+
43194400
@_expose(wasm, "bjs_roundTripOptionalAPIOptionalResult")
43204401
@_cdecl("bjs_roundTripOptionalAPIOptionalResult")
43214402
public func _bjs_roundTripOptionalAPIOptionalResult(_ resultIsSome: Int32, _ resultCaseId: Int32) -> Void {
@@ -5619,6 +5700,84 @@ fileprivate func _bjs_TestServer_wrap(_ pointer: UnsafeMutableRawPointer) -> Int
56195700
}
56205701
#endif
56215702

5703+
@_expose(wasm, "bjs_OptionalHolder_init")
5704+
@_cdecl("bjs_OptionalHolder_init")
5705+
public func _bjs_OptionalHolder_init(_ nullableGreeterIsSome: Int32, _ nullableGreeterValue: UnsafeMutableRawPointer, _ undefinedNumberIsDefined: Int32, _ undefinedNumberValue: Float64) -> UnsafeMutableRawPointer {
5706+
#if arch(wasm32)
5707+
let ret = OptionalHolder(nullableGreeter: Optional<Greeter>.bridgeJSLiftParameter(nullableGreeterIsSome, nullableGreeterValue), undefinedNumber: JSUndefinedOr<Double>.bridgeJSLiftParameter(undefinedNumberIsDefined, undefinedNumberValue))
5708+
return ret.bridgeJSLowerReturn()
5709+
#else
5710+
fatalError("Only available on WebAssembly")
5711+
#endif
5712+
}
5713+
5714+
@_expose(wasm, "bjs_OptionalHolder_nullableGreeter_get")
5715+
@_cdecl("bjs_OptionalHolder_nullableGreeter_get")
5716+
public func _bjs_OptionalHolder_nullableGreeter_get(_ _self: UnsafeMutableRawPointer) -> Void {
5717+
#if arch(wasm32)
5718+
let ret = OptionalHolder.bridgeJSLiftParameter(_self).nullableGreeter
5719+
return ret.bridgeJSLowerReturn()
5720+
#else
5721+
fatalError("Only available on WebAssembly")
5722+
#endif
5723+
}
5724+
5725+
@_expose(wasm, "bjs_OptionalHolder_nullableGreeter_set")
5726+
@_cdecl("bjs_OptionalHolder_nullableGreeter_set")
5727+
public func _bjs_OptionalHolder_nullableGreeter_set(_ _self: UnsafeMutableRawPointer, _ valueIsSome: Int32, _ valueValue: UnsafeMutableRawPointer) -> Void {
5728+
#if arch(wasm32)
5729+
OptionalHolder.bridgeJSLiftParameter(_self).nullableGreeter = Optional<Greeter>.bridgeJSLiftParameter(valueIsSome, valueValue)
5730+
#else
5731+
fatalError("Only available on WebAssembly")
5732+
#endif
5733+
}
5734+
5735+
@_expose(wasm, "bjs_OptionalHolder_undefinedNumber_get")
5736+
@_cdecl("bjs_OptionalHolder_undefinedNumber_get")
5737+
public func _bjs_OptionalHolder_undefinedNumber_get(_ _self: UnsafeMutableRawPointer) -> Void {
5738+
#if arch(wasm32)
5739+
let ret = OptionalHolder.bridgeJSLiftParameter(_self).undefinedNumber
5740+
return ret.bridgeJSLowerReturn()
5741+
#else
5742+
fatalError("Only available on WebAssembly")
5743+
#endif
5744+
}
5745+
5746+
@_expose(wasm, "bjs_OptionalHolder_undefinedNumber_set")
5747+
@_cdecl("bjs_OptionalHolder_undefinedNumber_set")
5748+
public func _bjs_OptionalHolder_undefinedNumber_set(_ _self: UnsafeMutableRawPointer, _ valueIsDefined: Int32, _ valueValue: Float64) -> Void {
5749+
#if arch(wasm32)
5750+
OptionalHolder.bridgeJSLiftParameter(_self).undefinedNumber = JSUndefinedOr<Double>.bridgeJSLiftParameter(valueIsDefined, valueValue)
5751+
#else
5752+
fatalError("Only available on WebAssembly")
5753+
#endif
5754+
}
5755+
5756+
@_expose(wasm, "bjs_OptionalHolder_deinit")
5757+
@_cdecl("bjs_OptionalHolder_deinit")
5758+
public func _bjs_OptionalHolder_deinit(_ pointer: UnsafeMutableRawPointer) -> Void {
5759+
#if arch(wasm32)
5760+
Unmanaged<OptionalHolder>.fromOpaque(pointer).release()
5761+
#else
5762+
fatalError("Only available on WebAssembly")
5763+
#endif
5764+
}
5765+
5766+
extension OptionalHolder: ConvertibleToJSValue, _BridgedSwiftHeapObject {
5767+
var jsValue: JSValue {
5768+
return .object(JSObject(id: UInt32(bitPattern: _bjs_OptionalHolder_wrap(Unmanaged.passRetained(self).toOpaque()))))
5769+
}
5770+
}
5771+
5772+
#if arch(wasm32)
5773+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalHolder_wrap")
5774+
fileprivate func _bjs_OptionalHolder_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32
5775+
#else
5776+
fileprivate func _bjs_OptionalHolder_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 {
5777+
fatalError("Only available on WebAssembly")
5778+
}
5779+
#endif
5780+
56225781
@_expose(wasm, "bjs_OptionalPropertyHolder_init")
56235782
@_cdecl("bjs_OptionalPropertyHolder_init")
56245783
public func _bjs_OptionalPropertyHolder_init(_ optionalNameIsSome: Int32, _ optionalNameBytes: Int32, _ optionalNameLength: Int32) -> UnsafeMutableRawPointer {

0 commit comments

Comments
 (0)