Skip to content

Commit bd933df

Browse files
BridgeJS: Split out core functionality into BridgeJSCore
To import them from the Web playground
1 parent 81bafa7 commit bd933df

File tree

10 files changed

+107
-92
lines changed

10 files changed

+107
-92
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
struct BridgeJSCoreError: Swift.Error, CustomStringConvertible {
2+
let description: String
3+
4+
init(_ message: String) {
5+
self.description = message
6+
}
7+
}

Plugins/BridgeJS/Sources/BridgeJSTool/ExportSwift.swift renamed to Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import SwiftBasicFormat
22
import SwiftSyntax
33
import SwiftSyntaxBuilder
4-
import class Foundation.FileManager
54

65
/// Exports Swift functions and classes to JavaScript
76
///
@@ -34,7 +33,7 @@ class ExportSwift {
3433

3534
let errors = try parseSingleFile(sourceFile)
3635
if errors.count > 0 {
37-
throw BridgeJSToolError(
36+
throw BridgeJSCoreError(
3837
errors.map { $0.formattedDescription(fileName: inputFilePath) }
3938
.joined(separator: "\n")
4039
)

Plugins/BridgeJS/Sources/BridgeJSTool/ImportTS.swift renamed to Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 2 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import SwiftBasicFormat
22
import SwiftSyntax
33
import SwiftSyntaxBuilder
4-
import Foundation
54

65
/// Imports TypeScript declarations and generates Swift bridge code
76
///
@@ -28,46 +27,6 @@ struct ImportTS {
2827
self.skeleton.children.append(skeleton)
2928
}
3029

31-
/// Processes a TypeScript definition file and extracts its API information
32-
mutating func addSourceFile(_ sourceFile: String, tsconfigPath: String) throws {
33-
let nodePath = try which("node")
34-
let ts2skeletonPath = URL(fileURLWithPath: #filePath)
35-
.deletingLastPathComponent()
36-
.deletingLastPathComponent()
37-
.appendingPathComponent("JavaScript")
38-
.appendingPathComponent("bin")
39-
.appendingPathComponent("ts2skeleton.js")
40-
let arguments = [ts2skeletonPath.path, sourceFile, "--project", tsconfigPath]
41-
42-
progress.print("Running ts2skeleton...")
43-
progress.print(" \(([nodePath.path] + arguments).joined(separator: " "))")
44-
45-
let process = Process()
46-
let stdoutPipe = Pipe()
47-
nonisolated(unsafe) var stdoutData = Data()
48-
49-
process.executableURL = nodePath
50-
process.arguments = arguments
51-
process.standardOutput = stdoutPipe
52-
53-
stdoutPipe.fileHandleForReading.readabilityHandler = { handle in
54-
let data = handle.availableData
55-
if data.count > 0 {
56-
stdoutData.append(data)
57-
}
58-
}
59-
try process.forwardTerminationSignals {
60-
try process.run()
61-
process.waitUntilExit()
62-
}
63-
64-
if process.terminationStatus != 0 {
65-
throw BridgeJSToolError("ts2skeleton returned \(process.terminationStatus)")
66-
}
67-
let skeleton = try JSONDecoder().decode(ImportedFileSkeleton.self, from: stdoutData)
68-
self.addSkeleton(skeleton)
69-
}
70-
7130
/// Finalizes the import process and generates Swift code
7231
func finalize() throws -> String? {
7332
var decls: [DeclSyntax] = []
@@ -178,7 +137,7 @@ struct ImportTS {
178137
)
179138
abiParameterSignatures.append((param.name, .i32))
180139
case .swiftHeapObject(_):
181-
throw BridgeJSToolError("swiftHeapObject is not supported in imported signatures")
140+
throw BridgeJSCoreError("swiftHeapObject is not supported in imported signatures")
182141
case .void:
183142
break
184143
}
@@ -226,7 +185,7 @@ struct ImportTS {
226185
body.append("return JSObject(id: UInt32(bitPattern: ret))")
227186
}
228187
case .swiftHeapObject(_):
229-
throw BridgeJSToolError("swiftHeapObject is not supported in imported signatures")
188+
throw BridgeJSCoreError("swiftHeapObject is not supported in imported signatures")
230189
case .void:
231190
break
232191
}
@@ -529,29 +488,3 @@ struct ImportTS {
529488
return Trivia(pieces: lines.flatMap { [TriviaPiece.docLineComment("/// \($0)"), .newlines(1)] })
530489
}
531490
}
532-
533-
extension Foundation.Process {
534-
// Monitor termination/interrruption signals to forward them to child process
535-
func setSignalForwarding(_ signalNo: Int32) -> DispatchSourceSignal {
536-
let signalSource = DispatchSource.makeSignalSource(signal: signalNo)
537-
signalSource.setEventHandler { [self] in
538-
signalSource.cancel()
539-
kill(processIdentifier, signalNo)
540-
}
541-
signalSource.resume()
542-
return signalSource
543-
}
544-
545-
func forwardTerminationSignals(_ body: () throws -> Void) rethrows {
546-
let sources = [
547-
setSignalForwarding(SIGINT),
548-
setSignalForwarding(SIGTERM),
549-
]
550-
defer {
551-
for source in sources {
552-
source.cancel()
553-
}
554-
}
555-
try body()
556-
}
557-
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
struct ProgressReporting {
2+
let print: (String) -> Void
3+
4+
init(verbose: Bool) {
5+
self.init(print: verbose ? { Swift.print($0) } : { _ in })
6+
}
7+
8+
private init(print: @escaping (String) -> Void) {
9+
self.print = print
10+
}
11+
12+
static var silent: ProgressReporting {
13+
return ProgressReporting(print: { _ in })
14+
}
15+
16+
func print(_ message: String) {
17+
self.print(message)
18+
}
19+
}

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import Foundation
1+
import class Foundation.JSONDecoder
2+
import struct Foundation.Data
23

34
struct BridgeJSLink {
45
/// The exported skeletons
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../BridgeJSCore

Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
@preconcurrency import func Foundation.exit
22
@preconcurrency import func Foundation.fputs
3+
@preconcurrency import func Foundation.kill
34
@preconcurrency import var Foundation.stderr
5+
@preconcurrency import var Foundation.SIGINT
6+
@preconcurrency import var Foundation.SIGTERM
47
@preconcurrency import struct Foundation.URL
58
@preconcurrency import struct Foundation.Data
69
@preconcurrency import class Foundation.JSONEncoder
710
@preconcurrency import class Foundation.FileManager
811
@preconcurrency import class Foundation.JSONDecoder
912
@preconcurrency import class Foundation.ProcessInfo
13+
@preconcurrency import class Foundation.Process
14+
@preconcurrency import class Foundation.Pipe
15+
import protocol Dispatch.DispatchSourceSignal
16+
import class Dispatch.DispatchSource
1017
import SwiftParser
1118

1219
/// BridgeJS Tool
@@ -247,38 +254,86 @@ internal func which(_ executable: String) throws -> URL {
247254
throw BridgeJSToolError("Executable \(executable) not found in PATH")
248255
}
249256

250-
struct BridgeJSToolError: Swift.Error, CustomStringConvertible {
251-
let description: String
257+
extension ImportTS {
258+
/// Processes a TypeScript definition file and extracts its API information
259+
mutating func addSourceFile(_ sourceFile: String, tsconfigPath: String) throws {
260+
let nodePath = try which("node")
261+
let ts2skeletonPath = URL(fileURLWithPath: #filePath)
262+
.deletingLastPathComponent()
263+
.deletingLastPathComponent()
264+
.appendingPathComponent("JavaScript")
265+
.appendingPathComponent("bin")
266+
.appendingPathComponent("ts2skeleton.js")
267+
let arguments = [ts2skeletonPath.path, sourceFile, "--project", tsconfigPath]
268+
269+
progress.print("Running ts2skeleton...")
270+
progress.print(" \(([nodePath.path] + arguments).joined(separator: " "))")
271+
272+
let process = Process()
273+
let stdoutPipe = Pipe()
274+
nonisolated(unsafe) var stdoutData = Data()
275+
276+
process.executableURL = nodePath
277+
process.arguments = arguments
278+
process.standardOutput = stdoutPipe
279+
280+
stdoutPipe.fileHandleForReading.readabilityHandler = { handle in
281+
let data = handle.availableData
282+
if data.count > 0 {
283+
stdoutData.append(data)
284+
}
285+
}
286+
try process.forwardTerminationSignals {
287+
try process.run()
288+
process.waitUntilExit()
289+
}
252290

253-
init(_ message: String) {
254-
self.description = message
291+
if process.terminationStatus != 0 {
292+
throw BridgeJSCoreError("ts2skeleton returned \(process.terminationStatus)")
293+
}
294+
let skeleton = try JSONDecoder().decode(ImportedFileSkeleton.self, from: stdoutData)
295+
self.addSkeleton(skeleton)
255296
}
256297
}
257298

258-
private func printStderr(_ message: String) {
259-
fputs(message + "\n", stderr)
260-
}
261-
262-
struct ProgressReporting {
263-
let print: (String) -> Void
264-
265-
init(verbose: Bool) {
266-
self.init(print: verbose ? { Swift.print($0) } : { _ in })
299+
extension Foundation.Process {
300+
// Monitor termination/interrruption signals to forward them to child process
301+
func setSignalForwarding(_ signalNo: Int32) -> DispatchSourceSignal {
302+
let signalSource = DispatchSource.makeSignalSource(signal: signalNo)
303+
signalSource.setEventHandler { [self] in
304+
signalSource.cancel()
305+
kill(processIdentifier, signalNo)
306+
}
307+
signalSource.resume()
308+
return signalSource
267309
}
268310

269-
private init(print: @escaping (String) -> Void) {
270-
self.print = print
311+
func forwardTerminationSignals(_ body: () throws -> Void) rethrows {
312+
let sources = [
313+
setSignalForwarding(SIGINT),
314+
setSignalForwarding(SIGTERM),
315+
]
316+
defer {
317+
for source in sources {
318+
source.cancel()
319+
}
320+
}
321+
try body()
271322
}
323+
}
272324

273-
static var silent: ProgressReporting {
274-
return ProgressReporting(print: { _ in })
275-
}
325+
struct BridgeJSToolError: Swift.Error, CustomStringConvertible {
326+
let description: String
276327

277-
func print(_ message: String) {
278-
self.print(message)
328+
init(_ message: String) {
329+
self.description = message
279330
}
280331
}
281332

333+
private func printStderr(_ message: String) {
334+
fputs(message + "\n", stderr)
335+
}
336+
282337
// MARK: - Minimal Argument Parsing
283338

284339
struct OptionRule {

0 commit comments

Comments
 (0)