diff --git a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/processor.js b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/processor.js index 53216a78c..ed332dd3c 100644 --- a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/processor.js +++ b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/processor.js @@ -261,6 +261,7 @@ export class TypeProcessor { if (!isExported) return; const fromArg = this.renderDefaultJSImportFromArgument(); + const isConst = (node.declarationList.flags & ts.NodeFlags.Const) !== 0; for (const decl of node.declarationList.declarations) { if (!ts.isIdentifier(decl.name)) continue; @@ -270,13 +271,30 @@ export class TypeProcessor { const swiftVarName = this.renderIdentifier(swiftName); const type = this.checker.getTypeAtLocation(decl); - const swiftType = this.visitType(type, decl); /** @type {string[]} */ const args = []; const jsNameArg = this.renderOptionalJSNameArg(jsName, swiftName); if (jsNameArg) args.push(jsNameArg); if (fromArg) args.push(fromArg); + const callSignatures = type.getCallSignatures(); + + if (isConst && callSignatures.length > 0) { + const signature = callSignatures[0]; + const parameters = signature.getParameters(); + const parameterNameMap = this.buildParameterNameMap(parameters); + const params = this.renderParameters(parameters, decl); + const returnType = this.visitType(signature.getReturnType(), decl); + const effects = this.renderEffects({ isAsync: false }); + const annotation = this.renderMacroAnnotation("JSFunction", args); + + this.emitDocComment(decl, { indent: "", parameterNameMap }); + this.swiftLines.push(`${annotation} func ${swiftVarName}(${params}) ${effects} -> ${returnType}`); + this.swiftLines.push(""); + continue; + } + + const swiftType = this.visitType(type, decl); const annotation = this.renderMacroAnnotation("JSGetter", args); this.emitDocComment(decl, { indent: "" }); diff --git a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/__snapshots__/ts2swift.test.js.snap b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/__snapshots__/ts2swift.test.js.snap index 85d1da0de..223927700 100644 --- a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/__snapshots__/ts2swift.test.js.snap +++ b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/__snapshots__/ts2swift.test.js.snap @@ -48,6 +48,22 @@ exports[`ts2swift > snapshots Swift output for Async.d.ts > Async 1`] = ` " `; +exports[`ts2swift > snapshots Swift output for CallableConst.d.ts > CallableConst 1`] = ` +"// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// \`swift package bridge-js\`. + +@_spi(BridgeJS) import JavaScriptKit + +@JSFunction func fetch(_ url: String) throws(JSException) -> Response + +@JSClass struct Response { +} +" +`; + exports[`ts2swift > snapshots Swift output for Documentation.d.ts > Documentation 1`] = ` "// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, // DO NOT EDIT. diff --git a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/fixtures/CallableConst.d.ts b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/fixtures/CallableConst.d.ts new file mode 100644 index 000000000..3df79d597 --- /dev/null +++ b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/fixtures/CallableConst.d.ts @@ -0,0 +1,2 @@ +export interface Response {} +export const fetch: (url: string) => Response;