Skip to content

Commit 80de55b

Browse files
Merge pull request #411 from swiftwasm/yt/restore-new-style-ctor
2 parents d8523db + 87f0a4d commit 80de55b

File tree

9 files changed

+46
-66
lines changed

9 files changed

+46
-66
lines changed

Examples/ExportSwift/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { init } from "./.build/plugins/PackageToJS/outputs/Package/index.js";
22
const { exports } = await init({});
33

44
const Greeter = exports.Greeter;
5-
const greeter = Greeter.init("World");
5+
const greeter = new Greeter("World");
66
const circle = exports.renderCircleSVG(100);
77

88
// Display the results

Examples/PlayBridgeJS/Sources/JavaScript/app.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class BridgeJSPlayground {
5252
createTS2Skeleton: this.createTS2Skeleton
5353
}
5454
});
55-
this.playBridgeJS = exports.PlayBridgeJS.init();
55+
this.playBridgeJS = new exports.PlayBridgeJS();
5656
console.log('BridgeJS initialized successfully');
5757
} catch (error) {
5858
console.error('Failed to initialize BridgeJS:', error);
@@ -162,4 +162,4 @@ export class BridgeJSPlayground {
162162
hideError() {
163163
this.errorDisplay.classList.remove('show');
164164
}
165-
}
165+
}

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@ struct BridgeJSLink {
4343
let swiftHeapObjectClassJs = """
4444
/// Represents a Swift heap object like a class instance or an actor instance.
4545
class SwiftHeapObject {
46-
static __construct(ptr, deinit) {
47-
return new SwiftHeapObject(ptr, deinit);
48-
}
49-
50-
constructor(pointer, deinit) {
51-
this.pointer = pointer;
52-
this.hasReleased = false;
53-
this.deinit = deinit;
54-
this.registry = new FinalizationRegistry((pointer) => {
46+
static __wrap(pointer, deinit, prototype) {
47+
const obj = Object.create(prototype);
48+
obj.pointer = pointer;
49+
obj.hasReleased = false;
50+
obj.deinit = deinit;
51+
obj.registry = new FinalizationRegistry((pointer) => {
5552
deinit(pointer);
5653
});
57-
this.registry.register(this, this.pointer);
54+
obj.registry.register(this, obj.pointer);
55+
return obj;
5856
}
5957
6058
release() {
@@ -525,13 +523,11 @@ struct BridgeJSLink {
525523
var constructorLines: [String] = []
526524
constructorLines.append("static __construct(ptr) {")
527525
constructorLines.append(
528-
"return new \(klass.name)(ptr, instance.exports.bjs_\(klass.name)_deinit);".indent(count: 4)
526+
"return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_\(klass.name)_deinit, \(klass.name).prototype);"
527+
.indent(count: 4)
529528
)
530529
constructorLines.append("}")
531530
constructorLines.append("")
532-
constructorLines.append("constructor(pointer, deinit) {")
533-
constructorLines.append("super(pointer, deinit);".indent(count: 4))
534-
constructorLines.append("}")
535531
jsLines.append(contentsOf: constructorLines.map { $0.indent(count: 4) })
536532

537533
if let constructor: ExportedConstructor = klass.constructor {
@@ -541,7 +537,7 @@ struct BridgeJSLink {
541537
}
542538
var funcLines: [String] = []
543539
funcLines.append("")
544-
funcLines.append("static init(\(constructor.parameters.map { $0.name }.joined(separator: ", "))) {")
540+
funcLines.append("constructor(\(constructor.parameters.map { $0.name }.joined(separator: ", "))) {")
545541
let returnExpr = thunkBuilder.callConstructor(abiName: constructor.abiName)
546542
funcLines.append(contentsOf: thunkBuilder.bodyLines.map { $0.indent(count: 4) })
547543
funcLines.append(contentsOf: thunkBuilder.cleanupLines.map { $0.indent(count: 4) })
@@ -551,7 +547,7 @@ struct BridgeJSLink {
551547
jsLines.append(contentsOf: funcLines.map { $0.indent(count: 4) })
552548

553549
dtsExportEntryLines.append(
554-
"init\(renderTSSignature(parameters: constructor.parameters, returnType: .swiftHeapObject(klass.name)));"
550+
"constructor\(renderTSSignature(parameters: constructor.parameters, returnType: .swiftHeapObject(klass.name)));"
555551
.indent(count: 4)
556552
)
557553
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ export interface UUID extends SwiftHeapObject {
5151
}
5252
export type Exports = {
5353
Greeter: {
54-
init(name: string): Greeter;
54+
constructor(name: string): Greeter;
5555
}
5656
Converter: {
57-
init(): Converter;
57+
constructor(): Converter;
5858
}
5959
UUID: {
6060
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,16 @@ export async function createInstantiator(options, swift) {
6060
const js = swift.memory.heap;
6161
/// Represents a Swift heap object like a class instance or an actor instance.
6262
class SwiftHeapObject {
63-
static __construct(ptr, deinit) {
64-
return new SwiftHeapObject(ptr, deinit);
65-
}
66-
67-
constructor(pointer, deinit) {
68-
this.pointer = pointer;
69-
this.hasReleased = false;
70-
this.deinit = deinit;
71-
this.registry = new FinalizationRegistry((pointer) => {
63+
static __wrap(pointer, deinit, prototype) {
64+
const obj = Object.create(prototype);
65+
obj.pointer = pointer;
66+
obj.hasReleased = false;
67+
obj.deinit = deinit;
68+
obj.registry = new FinalizationRegistry((pointer) => {
7269
deinit(pointer);
7370
});
74-
this.registry.register(this, this.pointer);
71+
obj.registry.register(this, obj.pointer);
72+
return obj;
7573
}
7674

7775
release() {
@@ -81,14 +79,11 @@ export async function createInstantiator(options, swift) {
8179
}
8280
class Greeter extends SwiftHeapObject {
8381
static __construct(ptr) {
84-
return new Greeter(ptr, instance.exports.bjs_Greeter_deinit);
82+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Greeter_deinit, Greeter.prototype);
8583
}
8684

87-
constructor(pointer, deinit) {
88-
super(pointer, deinit);
89-
}
9085

91-
static init(name) {
86+
constructor(name) {
9287
const nameBytes = textEncoder.encode(name);
9388
const nameId = swift.memory.retain(nameBytes);
9489
const ret = instance.exports.bjs_Greeter_init(nameId, nameBytes.length);
@@ -104,14 +99,11 @@ export async function createInstantiator(options, swift) {
10499
}
105100
class Converter extends SwiftHeapObject {
106101
static __construct(ptr) {
107-
return new Converter(ptr, instance.exports.bjs_Converter_deinit);
102+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Converter_deinit, Converter.prototype);
108103
}
109104

110-
constructor(pointer, deinit) {
111-
super(pointer, deinit);
112-
}
113105

114-
static init() {
106+
constructor() {
115107
const ret = instance.exports.bjs_Converter_init();
116108
return Converter.__construct(ret);
117109
}
@@ -124,12 +116,9 @@ export async function createInstantiator(options, swift) {
124116
}
125117
class UUID extends SwiftHeapObject {
126118
static __construct(ptr) {
127-
return new UUID(ptr, instance.exports.bjs_UUID_deinit);
119+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_UUID_deinit, UUID.prototype);
128120
}
129121

130-
constructor(pointer, deinit) {
131-
super(pointer, deinit);
132-
}
133122
uuidString() {
134123
instance.exports.bjs_UUID_uuidString(this.pointer);
135124
const ret = tmpRetString;

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export interface Greeter extends SwiftHeapObject {
1717
}
1818
export type Exports = {
1919
Greeter: {
20-
init(name: string): Greeter;
20+
constructor(name: string): Greeter;
2121
}
2222
takeGreeter(greeter: Greeter): void;
2323
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,16 @@ export async function createInstantiator(options, swift) {
6060
const js = swift.memory.heap;
6161
/// Represents a Swift heap object like a class instance or an actor instance.
6262
class SwiftHeapObject {
63-
static __construct(ptr, deinit) {
64-
return new SwiftHeapObject(ptr, deinit);
65-
}
66-
67-
constructor(pointer, deinit) {
68-
this.pointer = pointer;
69-
this.hasReleased = false;
70-
this.deinit = deinit;
71-
this.registry = new FinalizationRegistry((pointer) => {
63+
static __wrap(pointer, deinit, prototype) {
64+
const obj = Object.create(prototype);
65+
obj.pointer = pointer;
66+
obj.hasReleased = false;
67+
obj.deinit = deinit;
68+
obj.registry = new FinalizationRegistry((pointer) => {
7269
deinit(pointer);
7370
});
74-
this.registry.register(this, this.pointer);
71+
obj.registry.register(this, obj.pointer);
72+
return obj;
7573
}
7674

7775
release() {
@@ -81,14 +79,11 @@ export async function createInstantiator(options, swift) {
8179
}
8280
class Greeter extends SwiftHeapObject {
8381
static __construct(ptr) {
84-
return new Greeter(ptr, instance.exports.bjs_Greeter_deinit);
82+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Greeter_deinit, Greeter.prototype);
8583
}
8684

87-
constructor(pointer, deinit) {
88-
super(pointer, deinit);
89-
}
9085

91-
static init(name) {
86+
constructor(name) {
9287
const nameBytes = textEncoder.encode(name);
9388
const nameId = swift.memory.retain(nameBytes);
9489
const ret = instance.exports.bjs_Greeter_init(nameId, nameBytes.length);

Sources/JavaScriptKit/Documentation.docc/Articles/Exporting-Swift-to-JavaScript.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ In JavaScript:
133133
import { init } from "./.build/plugins/PackageToJS/outputs/Package/index.js";
134134
const { exports } = await init({});
135135

136-
const cart = exports.ShoppingCart.init();
136+
const cart = new exports.ShoppingCart();
137137
cart.addItem("Laptop", 999.99, 1);
138138
cart.addItem("Mouse", 24.99, 2);
139139
console.log(`Items in cart: ${cart.getItemCount()}`);
@@ -158,7 +158,7 @@ export interface ShoppingCart extends SwiftHeapObject {
158158

159159
export type Exports = {
160160
ShoppingCart: {
161-
init(): ShoppingCart;
161+
new(): ShoppingCart;
162162
}
163163
}
164164
```
@@ -175,8 +175,8 @@ You can export functions to specific namespaces by providing a namespace paramet
175175
import JavaScriptKit
176176

177177
// Export a function to a custom namespace
178-
@JS(namespace: "MyModule.Utils") func namespacedFunction() -> String {
179-
return "namespaced"
178+
@JS(namespace: "MyModule.Utils") func namespacedFunction() -> String {
179+
return "namespaced"
180180
}
181181
```
182182

Tests/prelude.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) {
115115
assert.equal(exports.roundTripString(v), v);
116116
}
117117

118-
const g = exports.Greeter.init("John");
118+
const g = new exports.Greeter("John");
119119
assert.equal(g.greet(), "Hello, John!");
120120
g.changeName("Jane");
121121
assert.equal(g.greet(), "Hello, Jane!");

0 commit comments

Comments
 (0)