Skip to content

Commit e5ac91a

Browse files
Enabled import-side arrays. Updated Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift to allow array lowering/lifting (stack-based, no ABI params) and to handle stack-only parameters in CallJSEmission. Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift now lifts array parameters and lowers array returns for imported JS functions using existing array fragments. Sources/JavaScriptKit/BridgeJSIntrinsics.swift gives Array stack bridging conformance plus import helpers (bridgeJSLowerParameter, bridgeJSLiftReturn, bridgeJSLowerStackReturn), covering nested arrays. Added Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ImportArray.swift with corresponding snapshots for JSFunction array imports.
Tests: `UPDATE_SNAPSHOTS=1 swift test --package-path ./Plugins/BridgeJS --filter BridgeJSCodegenTests` followed by `swift test --package-path ./Plugins/BridgeJS --filter BridgeJSCodegenTests` (pass). Next steps: 1) Run the full BridgeJS test suite (`swift test --package-path ./Plugins/BridgeJS`) to ensure wider coverage. 2) Consider runtime-side coverage (e.g., `make unittest` with `JAVASCRIPTKIT_EXPERIMENTAL_BRIDGEJS=1`) if you want to exercise the new import path end-to-end.
1 parent d35ef58 commit e5ac91a

6 files changed

Lines changed: 164 additions & 15 deletions

File tree

Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,6 @@ public struct ImportTS {
9393
func lowerParameter(param: Parameter) throws {
9494
let loweringInfo = try param.type.loweringParameterInfo(context: context)
9595

96-
// Generate destructured variable names for all lowered parameters
97-
let destructuredNames = loweringInfo.loweredParameters.map {
98-
"\(param.name)\($0.name.capitalizedFirstLetter)"
99-
}
100-
10196
let initializerExpr: ExprSyntax
10297
switch param.type {
10398
case .closure(let signature):
@@ -108,6 +103,34 @@ public struct ImportTS {
108103
initializerExpr = ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()")
109104
}
110105

106+
if loweringInfo.loweredParameters.isEmpty {
107+
body.append(
108+
CodeBlockItemSyntax(
109+
item: .decl(
110+
DeclSyntax(
111+
VariableDeclSyntax(
112+
bindingSpecifier: .keyword(.let),
113+
bindings: PatternBindingListSyntax {
114+
PatternBindingSyntax(
115+
pattern: PatternSyntax(
116+
IdentifierPatternSyntax(identifier: .wildcardToken())
117+
),
118+
initializer: InitializerClauseSyntax(value: initializerExpr)
119+
)
120+
}
121+
)
122+
)
123+
)
124+
)
125+
)
126+
return
127+
}
128+
129+
// Generate destructured variable names for all lowered parameters
130+
let destructuredNames = loweringInfo.loweredParameters.map {
131+
"\(param.name)\($0.name.capitalizedFirstLetter)"
132+
}
133+
111134
// Always add destructuring statement to body (unified for single and multiple)
112135
let pattern: PatternSyntax
113136
if destructuredNames.count == 1 {
@@ -937,7 +960,7 @@ extension BridgeType {
937960
case .array:
938961
switch context {
939962
case .importTS:
940-
throw BridgeJSCoreError("Array types are not yet supported in TypeScript imports")
963+
return LoweringParameterInfo(loweredParameters: [])
941964
case .exportSwift:
942965
return LoweringParameterInfo(loweredParameters: [])
943966
}
@@ -1029,7 +1052,7 @@ extension BridgeType {
10291052
case .array:
10301053
switch context {
10311054
case .importTS:
1032-
throw BridgeJSCoreError("Array types are not yet supported in TypeScript imports")
1055+
return LiftingReturnInfo(valueToLift: nil)
10331056
case .exportSwift:
10341057
return LiftingReturnInfo(valueToLift: nil)
10351058
}

Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,9 +1555,7 @@ struct IntrinsicJSFragment: Sendable {
15551555
case .array(let elementType):
15561556
switch context {
15571557
case .importTS:
1558-
throw BridgeJSLinkError(
1559-
message: "Arrays are not yet supported to be passed as parameters to imported JS functions"
1560-
)
1558+
return try arrayLift(elementType: elementType)
15611559
case .exportSwift:
15621560
return try arrayLift(elementType: elementType)
15631561
}
@@ -1637,9 +1635,7 @@ struct IntrinsicJSFragment: Sendable {
16371635
case .array(let elementType):
16381636
switch context {
16391637
case .importTS:
1640-
throw BridgeJSLinkError(
1641-
message: "Arrays are not yet supported to be returned from imported JS functions"
1642-
)
1638+
return try arrayLower(elementType: elementType)
16431639
case .exportSwift:
16441640
return try arrayLower(elementType: elementType)
16451641
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@JSFunction func roundtrip(_ items: [Int]) throws(JSException) -> [Int]
2+
@JSFunction func logStrings(_ items: [String]) throws(JSException)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"exported" : {
3+
"classes" : [
4+
5+
],
6+
"enums" : [
7+
8+
],
9+
"exposeToGlobal" : false,
10+
"functions" : [
11+
12+
],
13+
"protocols" : [
14+
15+
],
16+
"structs" : [
17+
18+
]
19+
},
20+
"imported" : {
21+
"children" : [
22+
{
23+
"functions" : [
24+
{
25+
"name" : "roundtrip",
26+
"parameters" : [
27+
{
28+
"name" : "items",
29+
"type" : {
30+
"array" : {
31+
"_0" : {
32+
"int" : {
33+
34+
}
35+
}
36+
}
37+
}
38+
}
39+
],
40+
"returnType" : {
41+
"array" : {
42+
"_0" : {
43+
"int" : {
44+
45+
}
46+
}
47+
}
48+
}
49+
},
50+
{
51+
"name" : "logStrings",
52+
"parameters" : [
53+
{
54+
"name" : "items",
55+
"type" : {
56+
"array" : {
57+
"_0" : {
58+
"string" : {
59+
60+
}
61+
}
62+
}
63+
}
64+
}
65+
],
66+
"returnType" : {
67+
"void" : {
68+
69+
}
70+
}
71+
}
72+
],
73+
"types" : [
74+
75+
]
76+
}
77+
]
78+
},
79+
"moduleName" : "TestModule"
80+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#if arch(wasm32)
2+
@_extern(wasm, module: "TestModule", name: "bjs_roundtrip")
3+
fileprivate func bjs_roundtrip() -> Void
4+
#else
5+
fileprivate func bjs_roundtrip() -> Void {
6+
fatalError("Only available on WebAssembly")
7+
}
8+
#endif
9+
10+
func _$roundtrip(_ items: [Int]) throws(JSException) -> [Int] {
11+
let _ = items.bridgeJSLowerParameter()
12+
let ret = bjs_roundtrip()
13+
if let error = _swift_js_take_exception() {
14+
throw error
15+
}
16+
return [Int].bridgeJSLiftReturn()
17+
}
18+
19+
#if arch(wasm32)
20+
@_extern(wasm, module: "TestModule", name: "bjs_logStrings")
21+
fileprivate func bjs_logStrings() -> Void
22+
#else
23+
fileprivate func bjs_logStrings() -> Void {
24+
fatalError("Only available on WebAssembly")
25+
}
26+
#endif
27+
28+
func _$logStrings(_ items: [String]) throws(JSException) -> Void {
29+
let _ = items.bridgeJSLowerParameter()
30+
bjs_logStrings()
31+
if let error = _swift_js_take_exception() {
32+
throw error
33+
}
34+
}

Sources/JavaScriptKit/BridgeJSIntrinsics.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,9 @@ extension Optional where Wrapped: _BridgedSwiftStruct {
17921792

17931793
// MARK: - Array Support
17941794

1795-
extension Array where Element: _BridgedSwiftStackType, Element.StackLiftResult == Element {
1795+
extension Array: _BridgedSwiftStackType where Element: _BridgedSwiftStackType, Element.StackLiftResult == Element {
1796+
public typealias StackLiftResult = [Element]
1797+
17961798
@_spi(BridgeJS) public static func bridgeJSLiftParameter() -> [Element] {
17971799
let count = Int(_swift_js_pop_i32())
17981800
var result: [Element] = []
@@ -1804,10 +1806,22 @@ extension Array where Element: _BridgedSwiftStackType, Element.StackLiftResult =
18041806
return result
18051807
}
18061808

1807-
@_spi(BridgeJS) public func bridgeJSLowerReturn() {
1809+
@_spi(BridgeJS) public static func bridgeJSLiftReturn() -> [Element] {
1810+
bridgeJSLiftParameter()
1811+
}
1812+
1813+
@_spi(BridgeJS) public consuming func bridgeJSLowerStackReturn() {
1814+
bridgeJSLowerReturn()
1815+
}
1816+
1817+
@_spi(BridgeJS) public consuming func bridgeJSLowerReturn() {
18081818
for elem in self {
18091819
elem.bridgeJSLowerStackReturn()
18101820
}
18111821
_swift_js_push_i32(Int32(self.count))
18121822
}
1823+
1824+
@_spi(BridgeJS) public consuming func bridgeJSLowerParameter() {
1825+
bridgeJSLowerReturn()
1826+
}
18131827
}

0 commit comments

Comments
 (0)