Skip to content

Commit 4a3cbb1

Browse files
BridgeJS: Support properties in TypeScript classes
1 parent c5a0b87 commit 4a3cbb1

File tree

9 files changed

+130
-9
lines changed

9 files changed

+130
-9
lines changed

Plugins/BridgeJS/Sources/JavaScript/src/processor.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ export class TypeProcessor {
238238

239239
for (const member of node.members) {
240240
if (ts.isPropertyDeclaration(member)) {
241-
// TODO
241+
const property = this.visitPropertyDecl(member);
242+
if (property) properties.push(property);
242243
} else if (ts.isMethodDeclaration(member)) {
243244
const decl = this.visitFunctionLikeDecl(member);
244245
if (decl) methods.push(decl);

Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/TypeScriptClass.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export class Greeter {
2+
name: string;
3+
readonly age: number;
24
constructor(name: string);
35
greet(): string;
46
changeName(name: string): void;

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ export async function createInstantiator(options, swift) {
4242
let ret = new options.imports.Greeter(nameObject);
4343
return swift.memory.retain(ret);
4444
}
45+
TestModule["bjs_Greeter_name_get"] = function bjs_Greeter_name_get(self) {
46+
let ret = swift.memory.getObject(self).name;
47+
tmpRetBytes = textEncoder.encode(ret);
48+
return tmpRetBytes.length;
49+
}
50+
TestModule["bjs_Greeter_name_set"] = function bjs_Greeter_name_set(self, newValue) {
51+
const newValueObject = swift.memory.getObject(newValue);
52+
swift.memory.release(newValue);
53+
swift.memory.getObject(self).name = newValueObject;
54+
}
55+
TestModule["bjs_Greeter_age_get"] = function bjs_Greeter_age_get(self) {
56+
let ret = swift.memory.getObject(self).age;
57+
return ret;
58+
}
4559
TestModule["bjs_Greeter_greet"] = function bjs_Greeter_greet(self) {
4660
let ret = swift.memory.getObject(self).greet();
4761
tmpRetBytes = textEncoder.encode(ret);

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,36 @@ struct Greeter {
3737
self.this = JSObject(id: UInt32(bitPattern: ret))
3838
}
3939

40+
var name: String {
41+
get {
42+
@_extern(wasm, module: "Check", name: "bjs_Greeter_name_get")
43+
func bjs_Greeter_name_get(_ self: Int32) -> Int32
44+
let ret = bjs_Greeter_name_get(Int32(bitPattern: self.this.id))
45+
return String(unsafeUninitializedCapacity: Int(ret)) { b in
46+
_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret))
47+
return Int(ret)
48+
}
49+
}
50+
nonmutating set {
51+
@_extern(wasm, module: "Check", name: "bjs_Greeter_name_set")
52+
func bjs_Greeter_name_set(_ self: Int32, _ newValue: Int32) -> Void
53+
var newValue = newValue
54+
let newValueId = newValue.withUTF8 { b in
55+
_make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
56+
}
57+
bjs_Greeter_name_set(Int32(bitPattern: self.this.id), newValueId)
58+
}
59+
}
60+
61+
var age: Double {
62+
get {
63+
@_extern(wasm, module: "Check", name: "bjs_Greeter_age_get")
64+
func bjs_Greeter_age_get(_ self: Int32) -> Float64
65+
let ret = bjs_Greeter_age_get(Int32(bitPattern: self.this.id))
66+
return Double(ret)
67+
}
68+
}
69+
4070
func greet() -> String {
4171
@_extern(wasm, module: "Check", name: "bjs_Greeter_greet")
4272
func bjs_Greeter_greet(_ self: Int32) -> Int32

Tests/BridgeJSRuntimeTests/Generated/ImportTS.swift

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,54 @@ struct JsGreeter {
6060
self.this = JSObject(id: UInt32(bitPattern: this))
6161
}
6262

63-
init(_ name: String) {
63+
init(_ name: String, _ prefix: String) {
6464
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_init")
65-
func bjs_JsGreeter_init(_ name: Int32) -> Int32
65+
func bjs_JsGreeter_init(_ name: Int32, _ prefix: Int32) -> Int32
6666
var name = name
6767
let nameId = name.withUTF8 { b in
6868
_make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
6969
}
70-
let ret = bjs_JsGreeter_init(nameId)
70+
var prefix = prefix
71+
let prefixId = prefix.withUTF8 { b in
72+
_make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
73+
}
74+
let ret = bjs_JsGreeter_init(nameId, prefixId)
7175
self.this = JSObject(id: UInt32(bitPattern: ret))
7276
}
7377

78+
var name: String {
79+
get {
80+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_name_get")
81+
func bjs_JsGreeter_name_get(_ self: Int32) -> Int32
82+
let ret = bjs_JsGreeter_name_get(Int32(bitPattern: self.this.id))
83+
return String(unsafeUninitializedCapacity: Int(ret)) { b in
84+
_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret))
85+
return Int(ret)
86+
}
87+
}
88+
nonmutating set {
89+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_name_set")
90+
func bjs_JsGreeter_name_set(_ self: Int32, _ newValue: Int32) -> Void
91+
var newValue = newValue
92+
let newValueId = newValue.withUTF8 { b in
93+
_make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
94+
}
95+
bjs_JsGreeter_name_set(Int32(bitPattern: self.this.id), newValueId)
96+
}
97+
}
98+
99+
var prefix: String {
100+
get {
101+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_prefix_get")
102+
func bjs_JsGreeter_prefix_get(_ self: Int32) -> Int32
103+
let ret = bjs_JsGreeter_prefix_get(Int32(bitPattern: self.this.id))
104+
return String(unsafeUninitializedCapacity: Int(ret)) { b in
105+
_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret))
106+
return Int(ret)
107+
}
108+
}
109+
}
110+
74111
func greet() -> String {
75112
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_greet")
76113
func bjs_JsGreeter_greet(_ self: Int32) -> Int32

Tests/BridgeJSRuntimeTests/Generated/JavaScript/ImportTS.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@
7777
"type" : {
7878
"string" : {
7979

80+
}
81+
}
82+
},
83+
{
84+
"name" : "prefix",
85+
"type" : {
86+
"string" : {
87+
8088
}
8189
}
8290
}
@@ -115,7 +123,24 @@
115123
],
116124
"name" : "JsGreeter",
117125
"properties" : [
126+
{
127+
"isReadonly" : false,
128+
"name" : "name",
129+
"type" : {
130+
"string" : {
118131

132+
}
133+
}
134+
},
135+
{
136+
"isReadonly" : true,
137+
"name" : "prefix",
138+
"type" : {
139+
"string" : {
140+
141+
}
142+
}
143+
}
119144
]
120145
}
121146
]

Tests/BridgeJSRuntimeTests/ImportAPITests.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,15 @@ class ImportAPITests: XCTestCase {
3636
}
3737

3838
func testClass() {
39-
let greeter = JsGreeter("Alice")
39+
let greeter = JsGreeter("Alice", "Hello")
4040
XCTAssertEqual(greeter.greet(), "Hello, Alice!")
4141
greeter.changeName("Bob")
4242
XCTAssertEqual(greeter.greet(), "Hello, Bob!")
43+
44+
greeter.name = "Charlie"
45+
XCTAssertEqual(greeter.greet(), "Hello, Charlie!")
46+
XCTAssertEqual(greeter.name, "Charlie")
47+
48+
XCTAssertEqual(greeter.prefix, "Hello")
4349
}
4450
}

Tests/BridgeJSRuntimeTests/bridge-js.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ export function jsRoundTripBool(v: boolean): boolean
44
export function jsRoundTripString(v: string): string
55

66
export class JsGreeter {
7-
constructor(name: string);
7+
name: string;
8+
readonly prefix: string;
9+
constructor(name: string, prefix: string);
810
greet(): string;
911
changeName(name: string): void;
1012
}

Tests/prelude.mjs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ export async function setupOptions(options, context) {
2020
return v;
2121
},
2222
JsGreeter: class {
23-
/** @param {string} name */
24-
constructor(name) {
23+
/**
24+
* @param {string} name
25+
* @param {string} prefix
26+
*/
27+
constructor(name, prefix) {
2528
this.name = name;
29+
this.prefix = prefix;
2630
}
2731
greet() {
28-
return `Hello, ${this.name}!`;
32+
return `${this.prefix}, ${this.name}!`;
2933
}
3034
/** @param {string} name */
3135
changeName(name) {

0 commit comments

Comments
 (0)