Skip to content

Commit 8df0593

Browse files
BridgeJS: Split setter into a separate function
To mark it `throws`
1 parent 1a83f72 commit 8df0593

File tree

6 files changed

+187
-166
lines changed

6 files changed

+187
-166
lines changed

Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,6 @@
66

77
@_spi(BridgeJS) import JavaScriptKit
88

9-
@_expose(wasm, "bjs_PlayBridgeJS_init")
10-
@_cdecl("bjs_PlayBridgeJS_init")
11-
public func _bjs_PlayBridgeJS_init() -> UnsafeMutableRawPointer {
12-
#if arch(wasm32)
13-
let ret = PlayBridgeJS()
14-
return Unmanaged.passRetained(ret).toOpaque()
15-
#else
16-
fatalError("Only available on WebAssembly")
17-
#endif
18-
}
19-
20-
@_expose(wasm, "bjs_PlayBridgeJS_update")
21-
@_cdecl("bjs_PlayBridgeJS_update")
22-
public func _bjs_PlayBridgeJS_update(_self: UnsafeMutableRawPointer, swiftSourceBytes: Int32, swiftSourceLen: Int32, dtsSourceBytes: Int32, dtsSourceLen: Int32) -> UnsafeMutableRawPointer {
23-
#if arch(wasm32)
24-
do {
25-
let swiftSource = String(unsafeUninitializedCapacity: Int(swiftSourceLen)) { b in
26-
_swift_js_init_memory(swiftSourceBytes, b.baseAddress.unsafelyUnwrapped)
27-
return Int(swiftSourceLen)
28-
}
29-
let dtsSource = String(unsafeUninitializedCapacity: Int(dtsSourceLen)) { b in
30-
_swift_js_init_memory(dtsSourceBytes, b.baseAddress.unsafelyUnwrapped)
31-
return Int(dtsSourceLen)
32-
}
33-
let ret = try Unmanaged<PlayBridgeJS>.fromOpaque(_self).takeUnretainedValue().update(swiftSource: swiftSource, dtsSource: dtsSource)
34-
return Unmanaged.passRetained(ret).toOpaque()
35-
} catch let error {
36-
if let error = error.thrownValue.object {
37-
withExtendedLifetime(error) {
38-
_swift_js_throw(Int32(bitPattern: $0.id))
39-
}
40-
} else {
41-
let jsError = JSError(message: String(describing: error))
42-
withExtendedLifetime(jsError.jsObject) {
43-
_swift_js_throw(Int32(bitPattern: $0.id))
44-
}
45-
}
46-
return UnsafeMutableRawPointer(bitPattern: -1).unsafelyUnwrapped
47-
}
48-
#else
49-
fatalError("Only available on WebAssembly")
50-
#endif
51-
}
52-
53-
@_expose(wasm, "bjs_PlayBridgeJS_deinit")
54-
@_cdecl("bjs_PlayBridgeJS_deinit")
55-
public func _bjs_PlayBridgeJS_deinit(pointer: UnsafeMutableRawPointer) {
56-
Unmanaged<PlayBridgeJS>.fromOpaque(pointer).release()
57-
}
58-
599
@_expose(wasm, "bjs_PlayBridgeJSOutput_outputJs")
6010
@_cdecl("bjs_PlayBridgeJSOutput_outputJs")
6111
public func _bjs_PlayBridgeJSOutput_outputJs(_self: UnsafeMutableRawPointer) -> Void {
@@ -112,4 +62,54 @@ public func _bjs_PlayBridgeJSOutput_exportSwiftGlue(_self: UnsafeMutableRawPoint
11262
@_cdecl("bjs_PlayBridgeJSOutput_deinit")
11363
public func _bjs_PlayBridgeJSOutput_deinit(pointer: UnsafeMutableRawPointer) {
11464
Unmanaged<PlayBridgeJSOutput>.fromOpaque(pointer).release()
65+
}
66+
67+
@_expose(wasm, "bjs_PlayBridgeJS_init")
68+
@_cdecl("bjs_PlayBridgeJS_init")
69+
public func _bjs_PlayBridgeJS_init() -> UnsafeMutableRawPointer {
70+
#if arch(wasm32)
71+
let ret = PlayBridgeJS()
72+
return Unmanaged.passRetained(ret).toOpaque()
73+
#else
74+
fatalError("Only available on WebAssembly")
75+
#endif
76+
}
77+
78+
@_expose(wasm, "bjs_PlayBridgeJS_update")
79+
@_cdecl("bjs_PlayBridgeJS_update")
80+
public func _bjs_PlayBridgeJS_update(_self: UnsafeMutableRawPointer, swiftSourceBytes: Int32, swiftSourceLen: Int32, dtsSourceBytes: Int32, dtsSourceLen: Int32) -> UnsafeMutableRawPointer {
81+
#if arch(wasm32)
82+
do {
83+
let swiftSource = String(unsafeUninitializedCapacity: Int(swiftSourceLen)) { b in
84+
_swift_js_init_memory(swiftSourceBytes, b.baseAddress.unsafelyUnwrapped)
85+
return Int(swiftSourceLen)
86+
}
87+
let dtsSource = String(unsafeUninitializedCapacity: Int(dtsSourceLen)) { b in
88+
_swift_js_init_memory(dtsSourceBytes, b.baseAddress.unsafelyUnwrapped)
89+
return Int(dtsSourceLen)
90+
}
91+
let ret = try Unmanaged<PlayBridgeJS>.fromOpaque(_self).takeUnretainedValue().update(swiftSource: swiftSource, dtsSource: dtsSource)
92+
return Unmanaged.passRetained(ret).toOpaque()
93+
} catch let error {
94+
if let error = error.thrownValue.object {
95+
withExtendedLifetime(error) {
96+
_swift_js_throw(Int32(bitPattern: $0.id))
97+
}
98+
} else {
99+
let jsError = JSError(message: String(describing: error))
100+
withExtendedLifetime(jsError.jsObject) {
101+
_swift_js_throw(Int32(bitPattern: $0.id))
102+
}
103+
}
104+
return UnsafeMutableRawPointer(bitPattern: -1).unsafelyUnwrapped
105+
}
106+
#else
107+
fatalError("Only available on WebAssembly")
108+
#endif
109+
}
110+
111+
@_expose(wasm, "bjs_PlayBridgeJS_deinit")
112+
@_cdecl("bjs_PlayBridgeJS_deinit")
113+
public func _bjs_PlayBridgeJS_deinit(pointer: UnsafeMutableRawPointer) {
114+
Unmanaged<PlayBridgeJS>.fromOpaque(pointer).release()
115115
}

Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.ExportSwift.json

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,5 @@
11
{
22
"classes" : [
3-
{
4-
"constructor" : {
5-
"abiName" : "bjs_PlayBridgeJS_init",
6-
"effects" : {
7-
"isAsync" : false,
8-
"isThrows" : false
9-
},
10-
"parameters" : [
11-
12-
]
13-
},
14-
"methods" : [
15-
{
16-
"abiName" : "bjs_PlayBridgeJS_update",
17-
"effects" : {
18-
"isAsync" : false,
19-
"isThrows" : true
20-
},
21-
"name" : "update",
22-
"parameters" : [
23-
{
24-
"label" : "swiftSource",
25-
"name" : "swiftSource",
26-
"type" : {
27-
"string" : {
28-
29-
}
30-
}
31-
},
32-
{
33-
"label" : "dtsSource",
34-
"name" : "dtsSource",
35-
"type" : {
36-
"string" : {
37-
38-
}
39-
}
40-
}
41-
],
42-
"returnType" : {
43-
"swiftHeapObject" : {
44-
"_0" : "PlayBridgeJSOutput"
45-
}
46-
}
47-
}
48-
],
49-
"name" : "PlayBridgeJS"
50-
},
513
{
524
"methods" : [
535
{
@@ -116,6 +68,54 @@
11668
}
11769
],
11870
"name" : "PlayBridgeJSOutput"
71+
},
72+
{
73+
"constructor" : {
74+
"abiName" : "bjs_PlayBridgeJS_init",
75+
"effects" : {
76+
"isAsync" : false,
77+
"isThrows" : false
78+
},
79+
"parameters" : [
80+
81+
]
82+
},
83+
"methods" : [
84+
{
85+
"abiName" : "bjs_PlayBridgeJS_update",
86+
"effects" : {
87+
"isAsync" : false,
88+
"isThrows" : true
89+
},
90+
"name" : "update",
91+
"parameters" : [
92+
{
93+
"label" : "swiftSource",
94+
"name" : "swiftSource",
95+
"type" : {
96+
"string" : {
97+
98+
}
99+
}
100+
},
101+
{
102+
"label" : "dtsSource",
103+
"name" : "dtsSource",
104+
"type" : {
105+
"string" : {
106+
107+
}
108+
}
109+
}
110+
],
111+
"returnType" : {
112+
"swiftHeapObject" : {
113+
"_0" : "PlayBridgeJSOutput"
114+
}
115+
}
116+
}
117+
],
118+
"name" : "PlayBridgeJS"
119119
}
120120
],
121121
"functions" : [

Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ struct ImportTS {
281281
)
282282
}
283283
}
284-
)
284+
),
285+
effectSpecifiers: ImportTS.buildFunctionEffect(throws: true, async: false)
285286
),
286287
bodyBuilder: {
287288
self.renderImportDecl()
@@ -365,38 +366,33 @@ struct ImportTS {
365366
try builder.liftReturnValue(returnType: property.type)
366367
return AccessorDeclSyntax(
367368
accessorSpecifier: .keyword(.get),
369+
effectSpecifiers: Self.buildAccessorEffect(throws: true, async: false),
368370
body: CodeBlockSyntax {
369371
builder.renderImportDecl()
370372
builder.body
371373
}
372374
)
373375
}
374376

375-
func renderSetterDecl(property: ImportedPropertySkeleton) throws -> AccessorDeclSyntax {
377+
func renderSetterDecl(property: ImportedPropertySkeleton) throws -> DeclSyntax {
376378
let builder = ImportedThunkBuilder(
377379
moduleName: moduleName,
378380
abiName: property.setterAbiName(context: type)
379381
)
382+
let newValue = Parameter(label: nil, name: "newValue", type: property.type)
380383
try builder.lowerParameter(param: Parameter(label: nil, name: "self", type: .jsObject(name)))
381-
try builder.lowerParameter(param: Parameter(label: nil, name: "newValue", type: property.type))
384+
try builder.lowerParameter(param: newValue)
382385
builder.call(returnType: .void)
383-
return AccessorDeclSyntax(
384-
modifier: DeclModifierSyntax(name: .keyword(.nonmutating)),
385-
accessorSpecifier: .keyword(.set),
386-
body: CodeBlockSyntax {
387-
builder.renderImportDecl()
388-
builder.body
389-
}
386+
return builder.renderThunkDecl(
387+
name: "set\(property.name.capitalizedFirstLetter())",
388+
parameters: [newValue],
389+
returnType: .void
390390
)
391391
}
392392

393393
func renderPropertyDecl(property: ImportedPropertySkeleton) throws -> [DeclSyntax] {
394-
var accessorDecls: [AccessorDeclSyntax] = []
395-
accessorDecls.append(try renderGetterDecl(property: property))
396-
if !property.isReadonly {
397-
accessorDecls.append(try renderSetterDecl(property: property))
398-
}
399-
return [
394+
let accessorDecls: [AccessorDeclSyntax] = [try renderGetterDecl(property: property)]
395+
var decls: [DeclSyntax] = [
400396
DeclSyntax(
401397
VariableDeclSyntax(
402398
leadingTrivia: Self.renderDocumentation(documentation: property.documentation),
@@ -419,6 +415,10 @@ struct ImportTS {
419415
)
420416
)
421417
]
418+
if !property.isReadonly {
419+
decls.append(try renderSetterDecl(property: property))
420+
}
421+
return decls
422422
}
423423
let classDecl = try StructDeclSyntax(
424424
leadingTrivia: Self.renderDocumentation(documentation: type.documentation),
@@ -483,4 +483,23 @@ struct ImportTS {
483483
) : nil,
484484
)
485485
}
486+
static func buildAccessorEffect(throws: Bool, async: Bool) -> AccessorEffectSpecifiersSyntax {
487+
return AccessorEffectSpecifiersSyntax(
488+
asyncSpecifier: `async` ? .keyword(.async) : nil,
489+
throwsClause: `throws`
490+
? ThrowsClauseSyntax(
491+
throwsSpecifier: .keyword(.throws),
492+
leftParen: .leftParenToken(),
493+
type: IdentifierTypeSyntax(name: .identifier("JSException")),
494+
rightParen: .rightParenToken()
495+
) : nil,
496+
)
497+
}
498+
}
499+
500+
extension String {
501+
func capitalizedFirstLetter() -> String {
502+
guard !isEmpty else { return self }
503+
return prefix(1).uppercased() + dropFirst()
504+
}
486505
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct Greeter {
1717
self.this = JSObject(id: UInt32(bitPattern: this))
1818
}
1919

20-
init(_ name: String) {
20+
init(_ name: String) throws(JSException) {
2121
#if arch(wasm32)
2222
@_extern(wasm, module: "Check", name: "bjs_Greeter_init")
2323
func bjs_Greeter_init(_ name: Int32) -> Int32
@@ -35,7 +35,7 @@ struct Greeter {
3535
}
3636

3737
var name: String {
38-
get {
38+
get throws(JSException) {
3939
#if arch(wasm32)
4040
@_extern(wasm, module: "Check", name: "bjs_Greeter_name_get")
4141
func bjs_Greeter_name_get(_ self: Int32) -> Int32
@@ -50,25 +50,26 @@ struct Greeter {
5050
return Int(ret)
5151
}
5252
}
53-
nonmutating set {
54-
#if arch(wasm32)
55-
@_extern(wasm, module: "Check", name: "bjs_Greeter_name_set")
56-
func bjs_Greeter_name_set(_ self: Int32, _ newValue: Int32) -> Void
57-
#else
58-
func bjs_Greeter_name_set(_ self: Int32, _ newValue: Int32) -> Void {
59-
fatalError("Only available on WebAssembly")
60-
}
61-
#endif
62-
var newValue = newValue
63-
let newValueId = newValue.withUTF8 { b in
64-
_swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
65-
}
66-
bjs_Greeter_name_set(Int32(bitPattern: self.this.id), newValueId)
53+
}
54+
55+
func setName(_ newValue: String) throws(JSException) -> Void {
56+
#if arch(wasm32)
57+
@_extern(wasm, module: "Check", name: "bjs_Greeter_name_set")
58+
func bjs_Greeter_name_set(_ self: Int32, _ newValue: Int32) -> Void
59+
#else
60+
func bjs_Greeter_name_set(_ self: Int32, _ newValue: Int32) -> Void {
61+
fatalError("Only available on WebAssembly")
62+
}
63+
#endif
64+
var newValue = newValue
65+
let newValueId = newValue.withUTF8 { b in
66+
_swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
6767
}
68+
bjs_Greeter_name_set(Int32(bitPattern: self.this.id), newValueId)
6869
}
6970

7071
var age: Double {
71-
get {
72+
get throws(JSException) {
7273
#if arch(wasm32)
7374
@_extern(wasm, module: "Check", name: "bjs_Greeter_age_get")
7475
func bjs_Greeter_age_get(_ self: Int32) -> Float64

0 commit comments

Comments
 (0)