Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit57a6fa2

Browse files
Merge pull request#409 from swiftwasm/yt/bjs-fix-swift-class
BridgeJS: Change `@JS init` to generate `static init()` methods instead of `constructor` in JS
2 parentscc50be3 +ed482fe commit57a6fa2

File tree

13 files changed

+308
-25
lines changed

13 files changed

+308
-25
lines changed

‎CONTRIBUTING.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ Tests for `PackageToJS` plugin:
7171
swifttest --package-path ./Plugins/PackageToJS
7272
```
7373

74+
Testsfor`BridgeJS` plugin:
75+
76+
```bash
77+
swifttest --package-path ./Plugins/BridgeJS
78+
```
79+
80+
To update snapshottest files when expected output changes:
81+
82+
```bash
83+
UPDATE_SNAPSHOTS=1 swifttest --package-path ./Plugins/BridgeJS
84+
```
85+
7486
### Editing `./Runtime` directory
7587

7688
The`./Runtime` directory contains the JavaScript runtime that interacts with the JavaScript environment and Swift code.

‎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}=awaitinit({});
33

44
constGreeter=exports.Greeter;
5-
constgreeter=newGreeter("World");
5+
constgreeter=Greeter.init("World");
66
constcircle=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=newexports.PlayBridgeJS();
55+
this.playBridgeJS=exports.PlayBridgeJS.init();
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: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ struct BridgeJSLink {
4343
letswiftHeapObjectClassJs="""
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+
4650
constructor(pointer, deinit) {
4751
this.pointer = pointer;
4852
this.hasReleased = false;
@@ -401,7 +405,7 @@ struct BridgeJSLink {
401405
bodyLines.append("swift.memory.release(retId);")
402406
returnExpr="ret"
403407
case.swiftHeapObject(let name):
404-
bodyLines.append("const ret =new\(name)(\(call));")
408+
bodyLines.append("const ret =\(name).__construct(\(call));")
405409
returnExpr="ret"
406410
}
407411
return returnExpr
@@ -484,23 +488,37 @@ struct BridgeJSLink {
484488
dtsExportEntryLines.append("\(klass.name): {")
485489
jsLines.append("class\(klass.name) extends SwiftHeapObject {")
486490

491+
// Always add __construct and constructor methods for all classes
492+
varconstructorLines:[String]=[]
493+
constructorLines.append("static __construct(ptr) {")
494+
constructorLines.append(
495+
"return new\(klass.name)(ptr, instance.exports.bjs_\(klass.name)_deinit);".indent(count:4)
496+
)
497+
constructorLines.append("}")
498+
constructorLines.append("")
499+
constructorLines.append("constructor(pointer, deinit) {")
500+
constructorLines.append("super(pointer, deinit);".indent(count:4))
501+
constructorLines.append("}")
502+
jsLines.append(contentsOf: constructorLines.map{ $0.indent(count:4)})
503+
487504
iflet constructor:ExportedConstructor= klass.constructor{
488505
letthunkBuilder=ExportedThunkBuilder(effects: constructor.effects)
489506
forparamin constructor.parameters{
490507
thunkBuilder.lowerParameter(param: param)
491508
}
492509
varfuncLines:[String]=[]
493-
funcLines.append("constructor(\(constructor.parameters.map{ $0.name}.joined(separator:","))) {")
510+
funcLines.append("")
511+
funcLines.append("static init(\(constructor.parameters.map{ $0.name}.joined(separator:","))) {")
494512
letreturnExpr= thunkBuilder.callConstructor(abiName: constructor.abiName)
495513
funcLines.append(contentsOf: thunkBuilder.bodyLines.map{ $0.indent(count:4)})
496514
funcLines.append(contentsOf: thunkBuilder.cleanupLines.map{ $0.indent(count:4)})
497515
funcLines.append(contentsOf: thunkBuilder.checkExceptionLines().map{ $0.indent(count:4)})
498-
funcLines.append("super(\(returnExpr), instance.exports.bjs_\(klass.name)_deinit);".indent(count:4))
516+
funcLines.append("return\(klass.name).__construct(\(returnExpr));".indent(count:4))
499517
funcLines.append("}")
500518
jsLines.append(contentsOf: funcLines.map{ $0.indent(count:4)})
501519

502520
dtsExportEntryLines.append(
503-
"new\(renderTSSignature(parameters: constructor.parameters, returnType:.swiftHeapObject(klass.name)));"
521+
"init\(renderTSSignature(parameters: constructor.parameters, returnType:.swiftHeapObject(klass.name)));"
504522
.indent(count:4)
505523
)
506524
}

‎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
exporttypeExports={
5353
Greeter:{
54-
new(name:string):Greeter;
54+
init(name:string):Greeter;
5555
}
5656
Converter:{
57-
new():Converter;
57+
init():Converter;
5858
}
5959
UUID:{
6060
}

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ export async function createInstantiator(options, swift) {
6060
constjs=swift.memory.heap;
6161
/// Represents a Swift heap object like a class instance or an actor instance.
6262
classSwiftHeapObject{
63+
static__construct(ptr,deinit){
64+
returnnewSwiftHeapObject(ptr,deinit);
65+
}
66+
6367
constructor(pointer,deinit){
6468
this.pointer=pointer;
6569
this.hasReleased=false;
@@ -76,12 +80,20 @@ export async function createInstantiator(options, swift) {
7680
}
7781
}
7882
classGreeterextendsSwiftHeapObject{
79-
constructor(name){
83+
static__construct(ptr){
84+
returnnewGreeter(ptr,instance.exports.bjs_Greeter_deinit);
85+
}
86+
87+
constructor(pointer,deinit){
88+
super(pointer,deinit);
89+
}
90+
91+
staticinit(name){
8092
constnameBytes=textEncoder.encode(name);
8193
constnameId=swift.memory.retain(nameBytes);
8294
constret=instance.exports.bjs_Greeter_init(nameId,nameBytes.length);
8395
swift.memory.release(nameId);
84-
super(ret,instance.exports.bjs_Greeter_deinit);
96+
returnGreeter.__construct(ret);
8597
}
8698
greet(){
8799
instance.exports.bjs_Greeter_greet(this.pointer);
@@ -91,9 +103,17 @@ export async function createInstantiator(options, swift) {
91103
}
92104
}
93105
classConverterextendsSwiftHeapObject{
94-
constructor(){
106+
static__construct(ptr){
107+
returnnewConverter(ptr,instance.exports.bjs_Converter_deinit);
108+
}
109+
110+
constructor(pointer,deinit){
111+
super(pointer,deinit);
112+
}
113+
114+
staticinit(){
95115
constret=instance.exports.bjs_Converter_init();
96-
super(ret,instance.exports.bjs_Converter_deinit);
116+
returnConverter.__construct(ret);
97117
}
98118
toString(value){
99119
instance.exports.bjs_Converter_toString(this.pointer,value);
@@ -103,6 +123,13 @@ export async function createInstantiator(options, swift) {
103123
}
104124
}
105125
classUUIDextendsSwiftHeapObject{
126+
static__construct(ptr){
127+
returnnewUUID(ptr,instance.exports.bjs_UUID_deinit);
128+
}
129+
130+
constructor(pointer,deinit){
131+
super(pointer,deinit);
132+
}
106133
uuidString(){
107134
instance.exports.bjs_UUID_uuidString(this.pointer);
108135
constret=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
exporttypeExports={
1919
Greeter:{
20-
new(name:string):Greeter;
20+
init(name:string):Greeter;
2121
}
2222
takeGreeter(greeter:Greeter):void;
2323
}

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ export async function createInstantiator(options, swift) {
6060
constjs=swift.memory.heap;
6161
/// Represents a Swift heap object like a class instance or an actor instance.
6262
classSwiftHeapObject{
63+
static__construct(ptr,deinit){
64+
returnnewSwiftHeapObject(ptr,deinit);
65+
}
66+
6367
constructor(pointer,deinit){
6468
this.pointer=pointer;
6569
this.hasReleased=false;
@@ -76,12 +80,20 @@ export async function createInstantiator(options, swift) {
7680
}
7781
}
7882
classGreeterextendsSwiftHeapObject{
79-
constructor(name){
83+
static__construct(ptr){
84+
returnnewGreeter(ptr,instance.exports.bjs_Greeter_deinit);
85+
}
86+
87+
constructor(pointer,deinit){
88+
super(pointer,deinit);
89+
}
90+
91+
staticinit(name){
8092
constnameBytes=textEncoder.encode(name);
8193
constnameId=swift.memory.retain(nameBytes);
8294
constret=instance.exports.bjs_Greeter_init(nameId,nameBytes.length);
8395
swift.memory.release(nameId);
84-
super(ret,instance.exports.bjs_Greeter_deinit);
96+
returnGreeter.__construct(ret);
8597
}
8698
greet(){
8799
instance.exports.bjs_Greeter_greet(this.pointer);

‎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 #"diff-c82eee18ce9b73c4bdde0a1aff6a34427b9e1ac5a4628e0bad177ca69e9e9b80-133-133-0" data-selected="false" role="gridcell" tabindex="-1" valign="top">133
133
import {init }from"./.build/plugins/PackageToJS/outputs/Package/index.js";
134134
const { exports }=awaitinit({});
135135

136-
const cart=newexports.ShoppingCart();
136+
const cart=exports.ShoppingCart.init();
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
exporttypeExports= {
160160
ShoppingCart: {
161-
new():ShoppingCart;
161+
init():ShoppingCart;
162162
}
163163
}
164164
```
@@ -175,8 +175,8 @@ You can export functions to specific namespaces by providing a namespace paramet
175175
importJavaScriptKit
176176

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

‎Tests/BridgeJSRuntimeTests/ExportAPITests.swift‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,47 @@ struct TestError: Error {
7474
g.changeName(name: name)
7575
}
7676

77+
// Test class without @JS init constructor
78+
@JSclassCalculator{
79+
nonisolated(unsafe)staticvaronDeinit:()->Void={}
80+
81+
@JSfunc square(value:Int)->Int{
82+
return value* value
83+
}
84+
85+
@JSfunc add(a:Int, b:Int)->Int{
86+
return a+ b
87+
}
88+
89+
deinit{
90+
Self.onDeinit()
91+
}
92+
}
93+
94+
@JSfunc createCalculator()->Calculator{
95+
returnCalculator()
96+
}
97+
98+
@JSfunc useCalculator(calc:Calculator, x:Int, y:Int)->Int{
99+
return calc.add(a: calc.square(value: x), b: y)
100+
}
101+
77102
classExportAPITests:XCTestCase{
78103
func testAll(){
79104
varhasDeinitGreeter=false
105+
varhasDeinitCalculator=false
106+
80107
Greeter.onDeinit={
81108
hasDeinitGreeter=true
82109
}
110+
111+
Calculator.onDeinit={
112+
hasDeinitCalculator=true
113+
}
114+
83115
runJsWorks()
84-
XCTAssertTrue(hasDeinitGreeter)
116+
117+
XCTAssertTrue(hasDeinitGreeter,"Greeter (with @JS init) should have been deinitialized")
118+
XCTAssertTrue(hasDeinitCalculator,"Calculator (without @JS init) should have been deinitialized")
85119
}
86120
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp