diff --git a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/cli.js b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/cli.js index 25d88b82..c7ac7905 100644 --- a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/cli.js +++ b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/cli.js @@ -122,14 +122,30 @@ export function run(filePaths, options) { } const program = TypeProcessor.createProgram([...filePaths, ...globalFiles], configParseResult.options); - const diagnostics = program.getSemanticDiagnostics(); - if (diagnostics.length > 0) { + + const formatDiagnostics = (diagnostics, kind) => { + if (diagnostics.length === 0) return null; const message = ts.formatDiagnosticsWithColorAndContext(diagnostics, { getCanonicalFileName: (fileName) => fileName, getNewLine: () => ts.sys.newLine, getCurrentDirectory: () => ts.sys.getCurrentDirectory(), }); - throw new Error(`TypeScript semantic errors:\n${message}`); + return `${kind} errors:\n${message}`; + }; + + const syntaxErrors = formatDiagnostics(program.getSyntacticDiagnostics(), "TypeScript syntax"); + if (syntaxErrors) { + throw new Error(syntaxErrors); + } + + const optionErrors = formatDiagnostics(program.getOptionsDiagnostics(), "TypeScript option"); + if (optionErrors) { + throw new Error(optionErrors); + } + + const semanticErrors = formatDiagnostics(program.getSemanticDiagnostics(), "TypeScript semantic"); + if (semanticErrors) { + throw new Error(semanticErrors); } const prelude = [ @@ -244,6 +260,13 @@ export function main(args) { cleanup(); } } + + if (swiftOutput.length === 0) { + diagnosticEngine.print( + "warning", + "No Swift declarations were generated. This usually means the .d.ts contained constructs that BridgeJS cannot import." + ); + } // Write to file or stdout if (options.values.output && options.values.output !== "-") { if (swiftOutput.length > 0) { diff --git a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/ts2swift.test.js b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/ts2swift.test.js index 8ca1df7c..d0ccf220 100644 --- a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/ts2swift.test.js +++ b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/ts2swift.test.js @@ -1,8 +1,9 @@ // @ts-check import { describe, it, expect } from 'vitest'; -import { readdirSync } from 'fs'; +import { readdirSync, mkdtempSync, writeFileSync, rmSync } from 'fs'; import { fileURLToPath } from 'url'; import path from 'path'; +import os from 'os'; import { run } from '../src/cli.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -38,4 +39,15 @@ describe('ts2swift', () => { expect(swiftOutput).toMatchSnapshot(name); }); } + + it('reports TypeScript syntax errors via thrown message', () => { + const tmpDir = mkdtempSync(path.join(os.tmpdir(), 'ts2swift-invalid-')); + const invalidPath = path.join(tmpDir, 'invalid.d.ts'); + writeFileSync(invalidPath, 'function foo(x'); + try { + expect(() => runTs2Swift(invalidPath)).toThrowError(/TypeScript syntax errors/); + } finally { + rmSync(tmpDir, { recursive: true, force: true }); + } + }); });