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
97 changes: 55 additions & 42 deletions Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -827,15 +827,15 @@ struct StackCodegen {
accessor: String,
varPrefix: String
) -> [CodeBlockItemSyntax] {
var statements: [CodeBlockItemSyntax] = []
let elemVar = "__bjs_elem_\(varPrefix)"
statements.append("for \(raw: elemVar) in \(raw: accessor) {")
statements.append(
" _swift_js_push_i32((\(raw: elemVar) as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())"
)
statements.append("}")
statements.append("_swift_js_push_i32(Int32(\(raw: accessor).count))")
return statements
return [
"""
for \(raw: elemVar) in \(raw: accessor) {
_swift_js_push_i32((\(raw: elemVar) as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())
}
""",
"_swift_js_push_i32(Int32(\(raw: accessor).count))",
]
}

private func lowerDictionaryStatements(
Expand Down Expand Up @@ -866,49 +866,58 @@ struct StackCodegen {
accessor: String,
varPrefix: String
) -> [CodeBlockItemSyntax] {
var statements: [CodeBlockItemSyntax] = []
let pairVarName = "__bjs_kv_\(varPrefix)"
statements.append("for \(raw: pairVarName) in \(raw: accessor) {")
statements.append("let __bjs_key_\(raw: varPrefix) = \(raw: pairVarName).key")
statements.append("let __bjs_value_\(raw: varPrefix) = \(raw: pairVarName).value")

let keyStatements = lowerStatements(
for: .string,
accessor: "__bjs_key_\(varPrefix)",
varPrefix: "\(varPrefix)_key"
let keyVarName = "__bjs_key_\(varPrefix)"
let valueVarName = "__bjs_value_\(varPrefix)"

// The dispatch in `lowerDictionaryStatements` routes only .nullable and .closure value
// types into this helper, both of which produce single-line lowering statements, so we can
// join their descriptions into the for-body as plain lines without worrying about nested
// multi-statement lowering.
var bodyLines: [String] = [
"let \(keyVarName) = \(pairVarName).key",
"let \(valueVarName) = \(pairVarName).value",
]
bodyLines.append(
contentsOf: lowerStatements(
for: .string,
accessor: keyVarName,
varPrefix: "\(varPrefix)_key"
).map { $0.description }
)
for stmt in keyStatements {
statements.append(stmt)
}

let valueStatements = lowerStatements(
for: valueType,
accessor: "__bjs_value_\(varPrefix)",
varPrefix: "\(varPrefix)_value"
bodyLines.append(
contentsOf: lowerStatements(
for: valueType,
accessor: valueVarName,
varPrefix: "\(varPrefix)_value"
).map { $0.description }
)
for stmt in valueStatements {
statements.append(stmt)
}
let body = bodyLines.joined(separator: "\n ")

statements.append("}")
statements.append("_swift_js_push_i32(Int32(\(raw: accessor).count))")
return statements
return [
"""
for \(raw: pairVarName) in \(raw: accessor) {
\(raw: body)
}
""",
"_swift_js_push_i32(Int32(\(raw: accessor).count))",
]
}

private func lowerProtocolDictionaryStatements(
accessor: String,
varPrefix: String
) -> [CodeBlockItemSyntax] {
var statements: [CodeBlockItemSyntax] = []
let pairVar = "__bjs_kv_\(varPrefix)"
statements.append("for \(raw: pairVar) in \(raw: accessor) {")
statements.append(" \(raw: pairVar).key.bridgeJSStackPush()")
statements.append(
" _swift_js_push_i32((\(raw: pairVar).value as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())"
)
statements.append("}")
statements.append("_swift_js_push_i32(Int32(\(raw: accessor).count))")
return statements
return [
"""
for \(raw: pairVar) in \(raw: accessor) {
\(raw: pairVar).key.bridgeJSStackPush()
_swift_js_push_i32((\(raw: pairVar).value as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())
}
""",
"_swift_js_push_i32(Int32(\(raw: accessor).count))",
]
}
}

Expand Down Expand Up @@ -1073,7 +1082,9 @@ struct EnumCodegen {
accessor: paramName,
varPrefix: paramName
)
printer.write(multilineString: CodeBlockItemListSyntax(statements).description)
for statement in statements {
printer.write(multilineString: statement.description)
}
}
}

Expand Down Expand Up @@ -1207,7 +1218,9 @@ struct StructCodegen {
accessor: accessor,
varPrefix: property.name
)
printer.write(multilineString: CodeBlockItemListSyntax(statements).description)
for statement in statements {
printer.write(multilineString: statement.description)
}
}

return printer.lines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@
}
}

@JS struct Counters {
var name: String
var counts: [String: Int?]
}

@JS func mirrorDictionary(_ values: [String: Int]) -> [String: Int]
@JS func optionalDictionary(_ values: [String: String]?) -> [String: String]?
@JS func nestedDictionary(_ values: [String: [Int]]) -> [String: [Int]]
@JS func boxDictionary(_ boxes: [String: Box]) -> [String: Box]
@JS func optionalBoxDictionary(_ boxes: [String: Box?]) -> [String: Box?]
@JS func roundtripCounters(_ counters: Counters) -> Counters

@JSFunction func importMirrorDictionary(_ values: [String: Double]) throws(JSException) -> [String: Double]
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,12 @@ import JavaScriptKit
@JS
var delegates: [MyViewControllerDelegate]

@JS
var delegatesByName: [String: MyViewControllerDelegate]

@JS init(delegates: [MyViewControllerDelegate]) {
self.delegates = delegates
self.delegatesByName = [:]
}

@JS func notifyAll() {
Expand All @@ -114,3 +118,7 @@ import JavaScriptKit
}

@JS func processDelegates(_ delegates: [MyViewControllerDelegate]) -> [MyViewControllerDelegate]

@JS func processDelegatesByName(
_ delegates: [String: MyViewControllerDelegate]
) -> [String: MyViewControllerDelegate]
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,78 @@
}
}
}
},
{
"abiName" : "bjs_roundtripCounters",
"effects" : {
"isAsync" : false,
"isStatic" : false,
"isThrows" : false
},
"name" : "roundtripCounters",
"parameters" : [
{
"label" : "_",
"name" : "counters",
"type" : {
"swiftStruct" : {
"_0" : "Counters"
}
}
}
],
"returnType" : {
"swiftStruct" : {
"_0" : "Counters"
}
}
}
],
"protocols" : [

],
"structs" : [
{
"methods" : [

],
"name" : "Counters",
"properties" : [
{
"isReadonly" : true,
"isStatic" : false,
"name" : "name",
"type" : {
"string" : {

}
}
},
{
"isReadonly" : true,
"isStatic" : false,
"name" : "counts",
"type" : {
"dictionary" : {
"_0" : {
"nullable" : {
"_0" : {
"integer" : {
"_0" : {
"isSigned" : true,
"width" : "word"
}
}
},
"_1" : "null"
}
}
}
}
}
],
"swiftCallName" : "Counters"
}
]
},
"imported" : {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,57 @@
extension Counters: _BridgedSwiftStruct {
@_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Counters {
let counts = [String: Optional<Int>].bridgeJSStackPop()
let name = String.bridgeJSStackPop()
return Counters(name: name, counts: counts)
}

@_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() {
self.name.bridgeJSStackPush()
for __bjs_kv_counts in self.counts {
let __bjs_key_counts = __bjs_kv_counts.key
let __bjs_value_counts = __bjs_kv_counts.value
__bjs_key_counts.bridgeJSStackPush()
__bjs_value_counts.bridgeJSStackPush()
}
_swift_js_push_i32(Int32(self.counts.count))
}

init(unsafelyCopying jsObject: JSObject) {
_bjs_struct_lower_Counters(jsObject.bridgeJSLowerParameter())
self = Self.bridgeJSStackPop()
}

func toJSObject() -> JSObject {
let __bjs_self = self
__bjs_self.bridgeJSStackPush()
return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Counters()))
}
}

#if arch(wasm32)
@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Counters")
fileprivate func _bjs_struct_lower_Counters_extern(_ objectId: Int32) -> Void
#else
fileprivate func _bjs_struct_lower_Counters_extern(_ objectId: Int32) -> Void {
fatalError("Only available on WebAssembly")
}
#endif
@inline(never) fileprivate func _bjs_struct_lower_Counters(_ objectId: Int32) -> Void {
return _bjs_struct_lower_Counters_extern(objectId)
}

#if arch(wasm32)
@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Counters")
fileprivate func _bjs_struct_lift_Counters_extern() -> Int32
#else
fileprivate func _bjs_struct_lift_Counters_extern() -> Int32 {
fatalError("Only available on WebAssembly")
}
#endif
@inline(never) fileprivate func _bjs_struct_lift_Counters() -> Int32 {
return _bjs_struct_lift_Counters_extern()
}

@_expose(wasm, "bjs_mirrorDictionary")
@_cdecl("bjs_mirrorDictionary")
public func _bjs_mirrorDictionary() -> Void {
Expand Down Expand Up @@ -53,6 +107,17 @@ public func _bjs_optionalBoxDictionary() -> Void {
#endif
}

@_expose(wasm, "bjs_roundtripCounters")
@_cdecl("bjs_roundtripCounters")
public func _bjs_roundtripCounters() -> Void {
#if arch(wasm32)
let ret = roundtripCounters(_: Counters.bridgeJSLiftParameter())
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs_Box_deinit")
@_cdecl("bjs_Box_deinit")
public func _bjs_Box_deinit(_ pointer: UnsafeMutableRawPointer) -> Void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,20 @@
}
}
}
},
{
"isReadonly" : false,
"isStatic" : false,
"name" : "delegatesByName",
"type" : {
"dictionary" : {
"_0" : {
"swiftProtocol" : {
"_0" : "MyViewControllerDelegate"
}
}
}
}
}
],
"swiftCallName" : "DelegateManager"
Expand Down Expand Up @@ -502,6 +516,39 @@
}
}
}
},
{
"abiName" : "bjs_processDelegatesByName",
"effects" : {
"isAsync" : false,
"isStatic" : false,
"isThrows" : false
},
"name" : "processDelegatesByName",
"parameters" : [
{
"label" : "_",
"name" : "delegates",
"type" : {
"dictionary" : {
"_0" : {
"swiftProtocol" : {
"_0" : "MyViewControllerDelegate"
}
}
}
}
}
],
"returnType" : {
"dictionary" : {
"_0" : {
"swiftProtocol" : {
"_0" : "MyViewControllerDelegate"
}
}
}
}
}
],
"protocols" : [
Expand Down
Loading
Loading