Skip to content

Commit 304ee67

Browse files
BridgeJS: Add support for imported TypeScript constructors
1 parent 86a532e commit 304ee67

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,11 @@ struct BridgeJSLink {
396396
}
397397
}
398398

399+
func callConstructor(name: String) {
400+
let call = "new options.imports.\(name)(\(parameterForwardings.joined(separator: ", ")))"
401+
bodyLines.append("let ret = \(call);")
402+
}
403+
399404
func callMethod(name: String, returnType: BridgeType) {
400405
let call = "swift.memory.getObject(self).\(name)(\(parameterForwardings.joined(separator: ", ")))"
401406
if returnType == .void {
@@ -481,6 +486,13 @@ struct BridgeJSLink {
481486
importObjectBuilder: ImportObjectBuilder,
482487
type: ImportedTypeSkeleton
483488
) throws {
489+
if let constructor = type.constructor {
490+
try renderImportedConstructor(
491+
importObjectBuilder: importObjectBuilder,
492+
type: type,
493+
constructor: constructor
494+
)
495+
}
484496
for property in type.properties {
485497
let getterAbiName = property.getterAbiName(context: type)
486498
let (js, dts) = try renderImportedProperty(
@@ -518,6 +530,31 @@ struct BridgeJSLink {
518530
}
519531
}
520532

533+
func renderImportedConstructor(
534+
importObjectBuilder: ImportObjectBuilder,
535+
type: ImportedTypeSkeleton,
536+
constructor: ImportedConstructorSkeleton
537+
) throws {
538+
let thunkBuilder = ImportedThunkBuilder()
539+
for param in constructor.parameters {
540+
thunkBuilder.liftParameter(param: param)
541+
}
542+
let returnType = BridgeType.jsObject(type.name)
543+
thunkBuilder.callConstructor(name: type.name)
544+
let returnExpr = try thunkBuilder.lowerReturnValue(returnType: returnType)
545+
let abiName = constructor.abiName(context: type)
546+
let funcLines = thunkBuilder.renderFunction(
547+
name: abiName,
548+
returnExpr: returnExpr
549+
)
550+
importObjectBuilder.assignToImportObject(name: abiName, function: funcLines)
551+
importObjectBuilder.appendDts([
552+
"\(type.name): {",
553+
"new\(renderTSSignature(parameters: constructor.parameters, returnType: returnType));".indent(count: 4),
554+
"}"
555+
])
556+
}
557+
521558
func renderImportedProperty(
522559
property: ImportedPropertySkeleton,
523560
abiName: String,
@@ -577,8 +614,8 @@ extension BridgeType {
577614
return "number"
578615
case .bool:
579616
return "boolean"
580-
case .jsObject:
581-
return "any"
617+
case .jsObject(let name):
618+
return name ?? "any"
582619
case .swiftHeapObject(let name):
583620
return name
584621
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
export type Exports = {
88
}
99
export type Imports = {
10-
returnAnimatable(): any;
10+
returnAnimatable(): Animatable;
1111
}
1212
export function createInstantiator(options: {
1313
imports: Imports;

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
export type Exports = {
88
}
99
export type Imports = {
10+
Greeter: {
11+
new(name: string): Greeter;
12+
}
1013
}
1114
export function createInstantiator(options: {
1215
imports: Imports;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ export async function createInstantiator(options, swift) {
3636
tmpRetBytes = undefined;
3737
}
3838
const TestModule = importObject["TestModule"] = {};
39+
TestModule["bjs_Greeter_init"] = function bjs_Greeter_init(name) {
40+
const nameObject = swift.memory.getObject(name);
41+
swift.memory.release(name);
42+
let ret = new options.imports.Greeter(nameObject);
43+
return swift.memory.retain(ret);
44+
}
3945
TestModule["bjs_Greeter_greet"] = function bjs_Greeter_greet(self) {
4046
let ret = swift.memory.getObject(self).greet();
4147
tmpRetBytes = textEncoder.encode(ret);

0 commit comments

Comments
 (0)