Skip to content

Commit 7c58d26

Browse files
authored
Merge pull request #2618 from rintaro/cshims-unified
[CompilerPlugin] Updates after Foundation removal
2 parents df88f3f + f0b5d16 commit 7c58d26

File tree

13 files changed

+280
-240
lines changed

13 files changed

+280
-240
lines changed

Package.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ let package = Package(
3434
name: "_SwiftSyntaxCShims"
3535
),
3636

37-
.target(
38-
name: "_AtomicBool"
39-
),
40-
4137
.target(
4238
name: "_InstructionCounter"
4339
),
@@ -77,7 +73,7 @@ let package = Package(
7773

7874
.target(
7975
name: "SwiftCompilerPlugin",
80-
dependencies: ["SwiftCompilerPluginMessageHandling", "SwiftSyntaxMacros", "_SwiftSyntaxCShims"],
76+
dependencies: ["SwiftCompilerPluginMessageHandling", "SwiftSyntaxMacros"],
8177
exclude: ["CMakeLists.txt"]
8278
),
8379

@@ -91,6 +87,7 @@ let package = Package(
9187
.target(
9288
name: "SwiftCompilerPluginMessageHandling",
9389
dependencies: [
90+
"_SwiftSyntaxCShims",
9491
"SwiftDiagnostics",
9592
"SwiftOperators",
9693
"SwiftParser",
@@ -131,7 +128,7 @@ let package = Package(
131128

132129
.target(
133130
name: "SwiftSyntax",
134-
dependencies: ["_AtomicBool", "SwiftSyntax509", "SwiftSyntax510", "SwiftSyntax600"],
131+
dependencies: ["_SwiftSyntaxCShims", "SwiftSyntax509", "SwiftSyntax510", "SwiftSyntax600"],
135132
exclude: ["CMakeLists.txt"],
136133
swiftSettings: swiftSyntaxSwiftSettings
137134
),

Sources/SwiftCompilerPlugin/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,4 @@ add_swift_syntax_library(SwiftCompilerPlugin
1414
target_link_swift_syntax_libraries(SwiftCompilerPlugin PUBLIC
1515
SwiftSyntaxMacros
1616
SwiftCompilerPluginMessageHandling
17-
_SwiftSyntaxCShims
1817
)

Sources/SwiftCompilerPlugin/CompilerPlugin.swift

Lines changed: 4 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,13 @@
99
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12-
// NOTE: This basic plugin mechanism is mostly copied from
13-
// https://github.com/apple/swift-package-manager/blob/main/Sources/PackagePlugin/Plugin.swift
1412

1513
#if swift(>=6.0)
16-
private import _SwiftSyntaxCShims
1714
public import SwiftSyntaxMacros
1815
@_spi(PluginMessage) private import SwiftCompilerPluginMessageHandling
19-
#if canImport(Darwin)
20-
private import Darwin
21-
#elseif canImport(Glibc)
22-
private import Glibc
23-
#elseif canImport(ucrt)
24-
private import ucrt
25-
#endif
2616
#else
27-
import _SwiftSyntaxCShims
2817
import SwiftSyntaxMacros
2918
@_spi(PluginMessage) import SwiftCompilerPluginMessageHandling
30-
#if canImport(Darwin)
31-
import Darwin
32-
#elseif canImport(Glibc)
33-
import Glibc
34-
#elseif canImport(ucrt)
35-
import ucrt
36-
#endif
3719
#endif
3820

3921
//
@@ -122,167 +104,20 @@ struct MacroProviderAdapter<Plugin: CompilerPlugin>: PluginProvider {
122104
}
123105
}
124106

125-
#if canImport(ucrt)
126-
private let dup = _dup(_:)
127-
private let fileno = _fileno(_:)
128-
private let dup2 = _dup2(_:_:)
129-
private let close = _close(_:)
130-
private let read = _read(_:_:_:)
131-
private let write = _write(_:_:_:)
132-
#endif
133-
134107
extension CompilerPlugin {
135108

136-
/// Main entry point of the plugin — sets up a communication channel with
137-
/// the plugin host and runs the main message loop.
109+
/// Main entry point of the plugin — sets up a standard I/O communication
110+
/// channel with the plugin host and runs the main message loop.
138111
public static func main() throws {
139-
let stdin = _ss_stdin()
140-
let stdout = _ss_stdout()
141-
let stderr = _ss_stderr()
142-
143-
// Duplicate the `stdin` file descriptor, which we will then use for
144-
// receiving messages from the plugin host.
145-
let inputFD = dup(fileno(stdin))
146-
guard inputFD >= 0 else {
147-
internalError("Could not duplicate `stdin`: \(describe(errno: _ss_errno())).")
148-
}
149-
150-
// Having duplicated the original standard-input descriptor, we close
151-
// `stdin` so that attempts by the plugin to read console input (which
152-
// are usually a mistake) return errors instead of blocking.
153-
guard close(fileno(stdin)) >= 0 else {
154-
internalError("Could not close `stdin`: \(describe(errno: _ss_errno())).")
155-
}
156-
157-
// Duplicate the `stdout` file descriptor, which we will then use for
158-
// sending messages to the plugin host.
159-
let outputFD = dup(fileno(stdout))
160-
guard outputFD >= 0 else {
161-
internalError("Could not dup `stdout`: \(describe(errno: _ss_errno())).")
162-
}
163-
164-
// Having duplicated the original standard-output descriptor, redirect
165-
// `stdout` to `stderr` so that all free-form text output goes there.
166-
guard dup2(fileno(stderr), fileno(stdout)) >= 0 else {
167-
internalError("Could not dup2 `stdout` to `stderr`: \(describe(errno: _ss_errno())).")
168-
}
169-
170-
#if canImport(ucrt)
171-
// Set I/O to binary mode. Avoid CRLF translation, and Ctrl+Z (0x1A) as EOF.
172-
_ = _setmode(inputFD, _O_BINARY)
173-
_ = _setmode(outputFD, _O_BINARY)
174-
#endif
175-
176-
// Open a message channel for communicating with the plugin host.
177-
let connection = PluginHostConnection(
178-
inputStream: inputFD,
179-
outputStream: outputFD
180-
)
181-
182-
// Handle messages from the host until the input stream is closed,
183-
// indicating that we're done.
112+
let connection = try StandardIOMessageConnection()
184113
let provider = MacroProviderAdapter(plugin: Self())
185114
let impl = CompilerPluginMessageListener(connection: connection, provider: provider)
186115
do {
187116
try impl.main()
188117
} catch {
189118
// Emit a diagnostic and indicate failure to the plugin host,
190119
// and exit with an error code.
191-
internalError(String(describing: error))
120+
fatalError("Internal Error: \(error)")
192121
}
193122
}
194-
195-
// Private function to report internal errors and then exit.
196-
fileprivate static func internalError(_ message: String) -> Never {
197-
fputs("Internal Error: \(message)\n", _ss_stderr())
198-
exit(1)
199-
}
200-
}
201-
202-
internal struct PluginHostConnection: MessageConnection {
203-
// File descriptor for input from the host.
204-
fileprivate let inputStream: CInt
205-
// File descriptor for output to the host.
206-
fileprivate let outputStream: CInt
207-
208-
func sendMessage<TX: Encodable>(_ message: TX) throws {
209-
// Encode the message as JSON.
210-
let payload = try JSON.encode(message)
211-
212-
// Write the header (a 64-bit length field in little endian byte order).
213-
let count = payload.count
214-
var header = UInt64(count).littleEndian
215-
try withUnsafeBytes(of: &header) { try _write(outputStream, contentsOf: $0) }
216-
217-
// Write the JSON payload.
218-
try payload.withUnsafeBytes { try _write(outputStream, contentsOf: $0) }
219-
}
220-
221-
func waitForNextMessage<RX: Decodable>(_ ty: RX.Type) throws -> RX? {
222-
// Read the header (a 64-bit length field in little endian byte order).
223-
var header: UInt64 = 0
224-
do {
225-
try withUnsafeMutableBytes(of: &header) { try _read(inputStream, into: $0) }
226-
} catch IOError.readReachedEndOfInput {
227-
// Connection closed.
228-
return nil
229-
}
230-
231-
// Read the JSON payload.
232-
let count = Int(UInt64(littleEndian: header))
233-
let data = UnsafeMutableRawBufferPointer.allocate(byteCount: count, alignment: 1)
234-
defer { data.deallocate() }
235-
try _read(inputStream, into: data)
236-
237-
// Decode and return the message.
238-
return try JSON.decode(ty, from: UnsafeBufferPointer(data.bindMemory(to: UInt8.self)))
239-
}
240-
}
241-
242-
/// Write the buffer to the file descriptor. Throws an error on failure.
243-
private func _write(_ fd: CInt, contentsOf buffer: UnsafeRawBufferPointer) throws {
244-
guard var ptr = buffer.baseAddress else { return }
245-
let endPtr = ptr.advanced(by: buffer.count)
246-
while ptr != endPtr {
247-
switch write(fd, ptr, numericCast(endPtr - ptr)) {
248-
case -1: throw IOError.writeFailed(errno: _ss_errno())
249-
case 0: throw IOError.writeFailed(errno: 0) /* unreachable */
250-
case let n: ptr += Int(n)
251-
}
252-
}
253-
}
254-
255-
/// Fill the buffer from the file descriptor. Throws an error on failure.
256-
/// If the file descriptor reached the end-of-file before filling up the entire
257-
/// buffer, throws IOError.readReachedEndOfInput
258-
private func _read(_ fd: CInt, into buffer: UnsafeMutableRawBufferPointer) throws {
259-
guard var ptr = buffer.baseAddress else { return }
260-
let endPtr = ptr.advanced(by: buffer.count)
261-
while ptr != endPtr {
262-
switch read(fd, ptr, numericCast(endPtr - ptr)) {
263-
case -1: throw IOError.readFailed(errno: _ss_errno())
264-
case 0: throw IOError.readReachedEndOfInput
265-
case let n: ptr += Int(n)
266-
}
267-
}
268-
}
269-
270-
private enum IOError: Error, CustomStringConvertible {
271-
case readReachedEndOfInput
272-
case readFailed(errno: CInt)
273-
case writeFailed(errno: CInt)
274-
275-
var description: String {
276-
switch self {
277-
case .readReachedEndOfInput: "read(2) reached end-of-file"
278-
case .readFailed(let errno): "read(2) failed: \(describe(errno: errno))"
279-
case .writeFailed(let errno): "write(2) failed: \(describe(errno: errno))"
280-
}
281-
}
282-
}
283-
284-
// Private function to construct an error message from an `errno` code.
285-
private func describe(errno: CInt) -> String {
286-
if let cStr = strerror(errno) { return String(cString: cStr) }
287-
return String(describing: errno)
288123
}

Sources/SwiftCompilerPluginMessageHandling/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ add_swift_syntax_library(SwiftCompilerPluginMessageHandling
1717
JSON/JSON.swift
1818
JSON/JSONDecoding.swift
1919
JSON/JSONEncoding.swift
20+
StandardIOMessageConnection.swift
2021
)
2122

2223
target_link_swift_syntax_libraries(SwiftCompilerPluginMessageHandling PUBLIC
@@ -26,4 +27,9 @@ target_link_swift_syntax_libraries(SwiftCompilerPluginMessageHandling PUBLIC
2627
SwiftParser
2728
SwiftSyntaxMacros
2829
SwiftSyntaxMacroExpansion
29-
SwiftOperators)
30+
SwiftOperators
31+
)
32+
33+
target_link_swift_syntax_libraries(SwiftCompilerPluginMessageHandling PRIVATE
34+
_SwiftSyntaxCShims
35+
)

Sources/SwiftCompilerPluginMessageHandling/JSON/JSONDecoding.swift

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#if swift(>=6.0)
14-
#if canImport(Darwin)
15-
private import Darwin
16-
#elseif canImport(Glibc)
17-
private import Glibc
18-
#elseif canImport(ucrt)
19-
private import ucrt
20-
#endif
14+
private import _SwiftSyntaxCShims
2115
#else
22-
#if canImport(Darwin)
23-
import Darwin
24-
#elseif canImport(Glibc)
25-
import Glibc
26-
#elseif canImport(ucrt)
27-
import ucrt
28-
#endif
16+
@_implementationOnly import _SwiftSyntaxCShims
2917
#endif
3018

3119
func decodeFromJSON<T: Decodable>(json: UnsafeBufferPointer<UInt8>) throws -> T {

0 commit comments

Comments
 (0)