Skip to content

Commit ec01ba7

Browse files
authored
Merge pull request #5 from apple/master
merge upstream
2 parents 0f431c1 + 74980ca commit ec01ba7

31 files changed

+239
-102
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ Similarly, one can use the new Swift driver within Xcode by adding a custom buil
3636

3737
The new Swift driver is a work in progress, and there are numerous places for anyone with an interest to contribute! This section covers testing, miscellaneous development tips and tricks, and a rough development plan showing what work still needs to be done.
3838

39+
### Driver Documentation
40+
41+
For a conceptual overview of the driver, see [The Swift Driver, Compilation Model, and Command-Line Experience](https://github.com/apple/swift/blob/master/docs/Driver.md). To learn more about the internals, see [Driver Design & Internals](https://github.com/apple/swift/blob/master/docs/DriverInternals.rst) and [Parseable Driver Output](https://github.com/apple/swift/blob/master/docs/DriverParseableOutput.rst).
42+
3943
### Testing
4044

4145
Test using command-line SwiftPM or Xcode.

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public struct Driver {
4343
enum Error: Swift.Error {
4444
case invalidDriverName(String)
4545
case invalidInput(String)
46+
case subcommandPassedToDriver
4647
}
4748

4849
/// The set of environment variables that are visible to the driver and
@@ -193,11 +194,15 @@ public struct Driver {
193194
diagnosticsHandler: @escaping DiagnosticsEngine.DiagnosticsHandler = Driver.stderrDiagnosticsHandler
194195
) throws {
195196
self.env = env
196-
197-
// FIXME: Determine if we should run as subcommand.
198197

199198
self.diagnosticEngine = DiagnosticsEngine(handlers: [diagnosticsHandler])
199+
200+
if case .subcommand = try Self.invocationRunMode(forArgs: args).mode {
201+
throw Error.subcommandPassedToDriver
202+
}
203+
200204
var args = try Self.expandResponseFiles(args, diagnosticsEngine: self.diagnosticEngine)[...]
205+
201206
self.driverKind = try Self.determineDriverKind(args: &args)
202207
self.optionTable = OptionTable()
203208
self.parsedOptions = try optionTable.parse(Array(args))
@@ -351,6 +356,54 @@ public struct Driver {
351356
}
352357
}
353358

359+
extension Driver {
360+
361+
public enum InvocationRunMode: Equatable {
362+
case normal(isRepl: Bool)
363+
case subcommand(String)
364+
}
365+
366+
/// Determines whether the given arguments constitute a normal invocation,
367+
/// or whether they invoke a subcommand.
368+
///
369+
/// Returns the invocation mode along with the arguments modified for that mode.
370+
public static func invocationRunMode(
371+
forArgs args: [String]
372+
) throws -> (mode: InvocationRunMode, args: [String]) {
373+
374+
assert(!args.isEmpty)
375+
376+
let execName = try VirtualPath(path: args[0]).basenameWithoutExt
377+
378+
// If we are not run as 'swift' or there are no program arguments, always invoke as normal.
379+
guard execName == "swift", args.count > 1 else { return (.normal(isRepl: false), args) }
380+
381+
// Otherwise, we have a program argument.
382+
let firstArg = args[1]
383+
384+
// If it looks like an option or a path, then invoke in interactive mode with the arguments as given.
385+
if firstArg.hasPrefix("-") || firstArg.hasPrefix("/") || firstArg.contains(".") {
386+
return (.normal(isRepl: false), args)
387+
}
388+
389+
// Otherwise, we should have some sort of subcommand.
390+
391+
var updatedArgs = args
392+
393+
// If it is the "built-in" 'repl', then use the normal driver.
394+
if firstArg == "repl" {
395+
updatedArgs.remove(at: 1)
396+
return (.normal(isRepl: true), updatedArgs)
397+
}
398+
399+
let subcommand = "swift-\(firstArg)"
400+
401+
updatedArgs.replaceSubrange(0...1, with: [subcommand])
402+
403+
return (.subcommand(subcommand), updatedArgs)
404+
}
405+
}
406+
354407
// MARK: - Response files.
355408
extension Driver {
356409
/// Tokenize a single line in a response file.

Sources/SwiftDriver/Driver/DriverKind.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12-
/// Describes which mode the driver is in, which dictates
12+
13+
/// Describes which mode the driver is in.
1314
public enum DriverKind {
1415
case interactive
1516
case batch

Sources/SwiftDriver/Driver/OutputFileMap.swift

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,12 @@ public struct OutputFileMap: Equatable {
3131
return output
3232
}
3333

34-
// Create a temporary file
35-
let baseName: String
36-
switch inputFile {
37-
case .absolute(let path):
38-
baseName = path.basenameWithoutExt
39-
case .relative(let path), .temporary(let path):
40-
baseName = path.basenameWithoutExt
41-
case .standardInput:
42-
baseName = ""
43-
case .standardOutput:
34+
if inputFile == .standardOutput {
4435
fatalError("Standard output cannot be an input file")
4536
}
4637

4738
// Form the virtual path.
48-
return .temporary(RelativePath(baseName.appendingFileTypeExtension(outputType)))
39+
return .temporary(RelativePath(inputFile.basenameWithoutExt.appendingFileTypeExtension(outputType)))
4940
}
5041

5142
public func existingOutput(inputFile: VirtualPath, outputType: FileType) -> VirtualPath? {

Sources/SwiftDriver/Driver/ToolExecutionDelegate.swift

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
1313

14+
#if canImport(Darwin)
15+
import Darwin.C
16+
#elseif os(Windows)
17+
import MSVCRT
18+
import WinSDK
19+
#elseif canImport(Glibc)
20+
import Glibc
21+
#else
22+
#error("Missing libc or equivalent")
23+
#endif
24+
1425
/// Delegate for printing execution information on the command-line.
1526
public struct ToolExecutionDelegate: JobExecutorDelegate {
1627
public enum Mode {
@@ -43,7 +54,7 @@ public struct ToolExecutionDelegate: JobExecutorDelegate {
4354
commandArguments: arguments[1...].map{ String($0) }
4455
)
4556

46-
let message = ParsableMessage.beganMessage(name: job.kind.rawValue, msg: beganMessage)
57+
let message = ParsableMessage(name: job.kind.rawValue, kind: .began(beganMessage))
4758
emit(message)
4859
}
4960
}
@@ -58,18 +69,20 @@ public struct ToolExecutionDelegate: JobExecutorDelegate {
5869
}
5970

6071
case .parsableOutput:
72+
let output = (try? result.utf8Output() + result.utf8stderrOutput()).flatMap { $0.isEmpty ? nil : $0 }
73+
let message: ParsableMessage
74+
6175
switch result.exitStatus {
6276
case .terminated(let code):
63-
let output = (try? result.utf8Output() + result.utf8stderrOutput()) ?? ""
64-
let finishedMessage = FinishedMessage(exitStatus: Int(code), pid: pid, output: output.isEmpty ? nil : output)
65-
let message = ParsableMessage.finishedMessage(name: job.kind.rawValue, msg: finishedMessage)
66-
emit(message)
77+
let finishedMessage = FinishedMessage(exitStatus: Int(code), pid: pid, output: output)
78+
message = ParsableMessage(name: job.kind.rawValue, kind: .finished(finishedMessage))
6779

68-
case .signalled:
69-
// FIXME: Implement this.
70-
break
80+
case .signalled(let signal):
81+
let errorMessage = strsignal(signal).map { String(cString: $0) } ?? ""
82+
let signalledMessage = SignalledMessage(pid: pid, output: output, errorMessage: errorMessage, signal: Int(signal))
83+
message = ParsableMessage(name: job.kind.rawValue, kind: .signalled(signalledMessage))
7184
}
72-
85+
emit(message)
7386
}
7487
}
7588

Sources/SwiftDriver/Execution/ParsableOutput.swift

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,23 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12-
import TSCBasic
1312

1413
import Foundation
1514

1615
public struct ParsableMessage {
1716
public enum Kind {
1817
case began(BeganMessage)
1918
case finished(FinishedMessage)
20-
case signalled
19+
case signalled(SignalledMessage)
2120
case skipped
2221
}
2322

2423
public let name: String
2524
public let kind: Kind
2625

27-
public static func beganMessage(
28-
name: String,
29-
msg: BeganMessage
30-
) -> ParsableMessage {
31-
return ParsableMessage(name: name, kind: .began(msg))
32-
}
33-
34-
public static func finishedMessage(
35-
name: String,
36-
msg: FinishedMessage
37-
) -> ParsableMessage {
38-
return ParsableMessage(name: name, kind: .finished(msg))
26+
public init(name: String, kind: Kind) {
27+
self.name = name
28+
self.kind = kind
3929
}
4030

4131
public func toJSON() throws -> Data {
@@ -109,6 +99,27 @@ public struct FinishedMessage: Encodable {
10999
}
110100
}
111101

102+
public struct SignalledMessage: Encodable {
103+
let pid: Int
104+
let output: String?
105+
let errorMessage: String
106+
let signal: Int
107+
108+
public init(pid: Int, output: String?, errorMessage: String, signal: Int) {
109+
self.pid = pid
110+
self.output = output
111+
self.errorMessage = errorMessage
112+
self.signal = signal
113+
}
114+
115+
private enum CodingKeys: String, CodingKey {
116+
case pid
117+
case output
118+
case errorMessage = "error-message"
119+
case signal
120+
}
121+
}
122+
112123
extension ParsableMessage: Encodable {
113124
enum CodingKeys: CodingKey {
114125
case name
@@ -126,8 +137,9 @@ extension ParsableMessage: Encodable {
126137
case .finished(let msg):
127138
try container.encode("finished", forKey: .kind)
128139
try msg.encode(to: encoder)
129-
case .signalled:
130-
break
140+
case .signalled(let msg):
141+
try container.encode("signalled", forKey: .kind)
142+
try msg.encode(to: encoder)
131143
case .skipped:
132144
break
133145
}

Sources/SwiftDriver/Execution/llbuild.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,7 @@
1212

1313
// FIXME: This is directly copied from SwiftPM, consider moving this to llbuild.
1414

15-
// We either export the llbuildSwift shared library or the llbuild framework.
16-
#if canImport(llbuildSwift)
1715
@_exported import llbuildSwift
18-
@_exported import llbuild
19-
#else
20-
@_exported import llbuild
21-
#endif
2216

2317
import Foundation
2418

Sources/SwiftDriver/Incremental Compilation/IncrementalCompilation.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13-
import TSCUtility
1413
import Foundation
1514

1615
// FIXME: rename to something like IncrementalCompilationInitialState

Sources/SwiftDriver/Incremental Compilation/InputIInfoMap.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13-
import TSCUtility
1413
import Foundation
1514
@_implementationOnly import Yams
1615

@@ -173,7 +172,4 @@ extension Diagnostic.Message {
173172
static func remark_could_not_read_build_record(_ error: Error) -> Diagnostic.Message {
174173
.remark("Incremental compilation could not read build record: \(error.localizedDescription).")
175174
}
176-
static var remark_incremental_compilation_not_implemented_yet: Diagnostic.Message {
177-
.remark("Incremental compilation not implemented yet")
178-
}
179175
}

Sources/SwiftDriver/Incremental Compilation/InputInfo.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12-
import TSCBasic
13-
import TSCUtility
1412
import Foundation
1513

1614
public struct InputInfo: Equatable {
@@ -22,8 +20,6 @@ public struct InputInfo: Equatable {
2220
self.status = status
2321
self.previousModTime = previousModTime
2422
}
25-
26-
static let newlyAdded = Self(status: .newlyAdded, previousModTime: Date.distantFuture)
2723
}
2824

2925
public extension InputInfo {

Sources/SwiftDriver/Jobs/AutolinkExtractJob.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13-
import TSCUtility
1413

1514
extension Driver {
1615
mutating func autolinkExtractJob(inputs: [TypedVirtualPath]) throws -> Job? {

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13-
import TSCUtility
1413

1514
extension DarwinToolchain {
1615
private func findARCLiteLibPath() throws -> AbsolutePath? {

Sources/SwiftDriver/Jobs/GenerateDSYMJob.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12-
import TSCBasic
13-
import TSCUtility
1412

1513
extension Driver {
1614
func generateDSYMJob(inputs: [TypedVirtualPath]) throws -> Job {

Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13-
import TSCUtility
1413

1514
extension GenericUnixToolchain {
1615
private func defaultLinker(for targetTriple: Triple) -> String? {

Sources/SwiftDriver/Jobs/Job.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,6 @@ extension Job: CustomStringConvertible {
8383
}
8484
}
8585

86-
/// The type of action.
87-
enum ActionType {
88-
case compile
89-
case mergeModule
90-
case dynamicLink
91-
case generateDSYM
92-
case generatePCH
93-
case verifyDebugInfo
94-
}
95-
9686
// MARK: - Job.ArgTemplate + Codable
9787

9888
extension Job.ArgTemplate: Codable {

Sources/SwiftDriver/Jobs/MergeModuleJob.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12-
import TSCBasic
1312

1413
extension Driver {
1514
mutating func mergeModuleJob(inputs allInputs: [TypedVirtualPath]) throws -> Job {

Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13-
import TSCUtility
1413

1514
extension Toolchain {
1615
// MARK: - Path computation

Sources/SwiftDriver/Options/Option.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ extension Option {
130130
}
131131

132132
extension Option {
133-
/// Whether this option is accepted by the
134-
public func isAcceptedBy(_ driverKind: DriverKind) -> Bool {
133+
/// Whether this option is accepted by a driver of the given kind.
134+
public func isAccepted(by driverKind: DriverKind) -> Bool {
135135
switch driverKind {
136136
case .autolinkExtract:
137137
return attributes.contains(.autolinkExtract)

0 commit comments

Comments
 (0)