Skip to content

Commit 9de0623

Browse files
committed
Introduce a new executable, swift-help, which prints help info for tools
swift-help is extremely simple, but it allows -help handling to more easily fit into the driver's Job model. A new SwiftOptions module contains the option types and definitions which are shared with the driver.
1 parent c835d02 commit 9de0623

28 files changed

+217
-69
lines changed

Package.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@ let package = Package(
1010
.executable(
1111
name: "swift-driver",
1212
targets: ["swift-driver"]),
13+
.executable(
14+
name: "swift-help",
15+
targets: ["swift-help"]),
1316
.library(
1417
name: "SwiftDriver",
1518
targets: ["SwiftDriver"]),
19+
.library(
20+
name: "SwiftOptions",
21+
targets: ["SwiftOptions"]),
1622
],
1723
dependencies: [
1824
.package(url: "https://github.com/apple/swift-tools-support-core.git", .branch("master")),
@@ -23,16 +29,29 @@ let package = Package(
2329
/// The driver library.
2430
.target(
2531
name: "SwiftDriver",
26-
dependencies: ["SwiftToolsSupport-auto", "llbuildSwift", "Yams"]),
32+
dependencies: ["SwiftOptions", "SwiftToolsSupport-auto", "llbuildSwift", "Yams"]),
2733
.testTarget(
2834
name: "SwiftDriverTests",
2935
dependencies: ["SwiftDriver", "swift-driver"]),
3036

37+
/// The options library.
38+
.target(
39+
name: "SwiftOptions",
40+
dependencies: ["SwiftToolsSupport-auto"]),
41+
.testTarget(
42+
name: "SwiftOptionsTests",
43+
dependencies: ["SwiftOptions"]),
44+
3145
/// The primary driver executable.
3246
.target(
3347
name: "swift-driver",
3448
dependencies: ["SwiftDriver"]),
3549

50+
/// The help executable.
51+
.target(
52+
name: "swift-help",
53+
dependencies: ["SwiftOptions"]),
54+
3655
/// The `makeOptions` utility (for importing option definitions).
3756
.target(
3857
name: "makeOptions",

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ $ swift build -Xcc -I/path/to/build/Ninja-ReleaseAssert/swift-.../include --prod
102102
Then, run `makeOptions` and redirect the output to overwrite `Options.swift`:
103103

104104
```
105-
$ .build/path/to/makeOptions > Sources/SwiftDriver/Options/Options.swift
105+
$ .build/path/to/makeOptions > Sources/SwiftOptions/Options.swift
106106
```
107107

108108
### Development Plan

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import TSCBasic
1313
import TSCUtility
1414
import Foundation
15+
import SwiftOptions
1516

1617
/// How should the Swift module output be handled?
1718
public enum ModuleOutput: Equatable {
@@ -595,11 +596,6 @@ extension Driver {
595596
return try exec(path: toolchain.getToolPath(.swiftCompiler).pathString, args: driverKind.usageArgs + parsedOptions.commandLine)
596597
}
597598

598-
if parsedOptions.contains(.help) || parsedOptions.contains(.helpHidden) {
599-
optionTable.printHelp(driverKind: driverKind, includeHidden: parsedOptions.contains(.helpHidden))
600-
return
601-
}
602-
603599
if parsedOptions.hasArgument(.v) {
604600
try printVersion(outputStream: &stderrStream)
605601
}

Sources/SwiftDriver/Incremental Compilation/IncrementalCompilation.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
1313
import Foundation
14+
import SwiftOptions
1415

1516
// FIXME: rename to something like IncrementalCompilationInitialState
1617
public struct IncrementalCompilation {

Sources/SwiftDriver/Jobs/CommandLineArguments.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13+
import SwiftOptions
1314

1415
/// Utilities for manipulating a list of command line arguments, including
1516
/// constructing one from a set of ParsedOptions.

Sources/SwiftDriver/Jobs/CompileJob.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13+
import SwiftOptions
1314

1415
extension Driver {
1516
/// Add the appropriate compile mode option to the command line for a compile job.

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13+
import SwiftOptions
1314

1415
extension DarwinToolchain {
1516
private func findARCLiteLibPath() throws -> AbsolutePath? {

Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13+
import SwiftOptions
1314

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

Sources/SwiftDriver/Jobs/Job.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public struct Job: Codable, Equatable, Hashable {
3030
case verifyDebugInfo = "verify-debug-info"
3131
case printTargetInfo = "print-target-info"
3232
case versionRequest = "version-request"
33+
case help
3334
}
3435

3536
public enum ArgTemplate: Equatable, Hashable {

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,19 @@ extension Driver {
191191
requiresInPlaceExecution: true)
192192
}
193193

194+
if parsedOptions.contains(.help) || parsedOptions.contains(.helpHidden) {
195+
var commandLine: [Job.ArgTemplate] = [.flag("-tool=\(driverKind.rawValue)")]
196+
if parsedOptions.contains(.helpHidden) {
197+
commandLine.append(.flag("-show-hidden"))
198+
}
199+
return Job(kind: .help,
200+
tool: .absolute(try toolchain.getToolPath(.swiftHelp)),
201+
commandLine: commandLine,
202+
inputs: [],
203+
outputs: [],
204+
requiresInPlaceExecution: true)
205+
}
206+
194207
return nil
195208
}
196209

Sources/SwiftDriver/Jobs/Toolchain+InterpreterSupport.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212
//
1313
import TSCBasic
14+
import SwiftOptions
1415

1516
extension Toolchain {
1617
func addPathEnvironmentVariableIfNeeded(

Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13+
import SwiftOptions
1314

1415
extension Toolchain {
1516
// MARK: - Path computation

Sources/SwiftDriver/Toolchains/DarwinToolchain.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ public final class DarwinToolchain: Toolchain {
6262
return try lookup(executable: "lldb")
6363
case .dwarfdump:
6464
return try lookup(executable: "dwarfdump")
65+
case .swiftHelp:
66+
return try lookup(executable: "swift-help")
6567
}
6668
}
6769

Sources/SwiftDriver/Toolchains/GenericUnixToolchain.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public final class GenericUnixToolchain: Toolchain {
6161
return try lookup(executable: "lldb")
6262
case .dwarfdump:
6363
return try lookup(executable: "dwarfdump")
64+
case .swiftHelp:
65+
return try lookup(executable: "swift-help")
6466
}
6567
}
6668

Sources/SwiftDriver/Toolchains/Toolchain.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212
import Foundation
1313
import TSCBasic
14+
import SwiftOptions
1415

1516
public enum Tool {
1617
case swiftCompiler
@@ -21,6 +22,7 @@ public enum Tool {
2122
case dsymutil
2223
case lldb
2324
case dwarfdump
25+
case swiftHelp
2426
}
2527

2628
/// Describes a toolchain, which includes information about compilers, linkers

Sources/SwiftDriver/Utilities/Diagnostics.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import TSCBasic
13+
import SwiftOptions
1314

1415
public typealias Diagnostic = TSCBasic.Diagnostic
1516
public typealias DiagnosticData = TSCBasic.DiagnosticData

Sources/SwiftDriver/Driver/DriverKind.swift renamed to Sources/SwiftOptions/DriverKind.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
/// Describes which mode the driver is in.
14-
public enum DriverKind {
15-
case interactive
16-
case batch
17-
case moduleWrap
18-
case frontend
19-
case autolinkExtract
20-
case indent
14+
public enum DriverKind: String {
15+
case interactive = "swift"
16+
case batch = "swiftc"
17+
case moduleWrap = "swift-modulewrap"
18+
case frontend = "swift-frontend"
19+
case autolinkExtract = "swift-autolink-extract"
20+
case indent = "swift-indent"
2121

2222
/// Returns true if driver kind is Swift compiler.
23-
var isSwiftCompiler: Bool {
23+
public var isSwiftCompiler: Bool {
2424
return self == .interactive || self == .batch
2525
}
2626
}

Sources/SwiftDriver/Options/Option.swift renamed to Sources/SwiftOptions/Option.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ public struct OptionAttributes: OptionSet, Hashable {
1717
self.rawValue = rawValue
1818
}
1919

20-
static let helpHidden = OptionAttributes(rawValue: 0x1)
21-
static let frontend = OptionAttributes(rawValue: 0x2)
22-
static let noDriver = OptionAttributes(rawValue: 0x4)
23-
static let noInteractive = OptionAttributes(rawValue: 0x8)
24-
static let noBatch = OptionAttributes(rawValue: 0x10)
25-
static let doesNotAffectIncrementalBuild = OptionAttributes(rawValue: 0x20)
26-
static let autolinkExtract = OptionAttributes(rawValue: 0x40)
27-
static let moduleWrap = OptionAttributes(rawValue: 0x80)
28-
static let indent = OptionAttributes(rawValue: 0x100)
29-
static let argumentIsPath = OptionAttributes(rawValue: 0x200)
30-
static let moduleInterface = OptionAttributes(rawValue: 0x400)
20+
public static let helpHidden = OptionAttributes(rawValue: 0x1)
21+
public static let frontend = OptionAttributes(rawValue: 0x2)
22+
public static let noDriver = OptionAttributes(rawValue: 0x4)
23+
public static let noInteractive = OptionAttributes(rawValue: 0x8)
24+
public static let noBatch = OptionAttributes(rawValue: 0x10)
25+
public static let doesNotAffectIncrementalBuild = OptionAttributes(rawValue: 0x20)
26+
public static let autolinkExtract = OptionAttributes(rawValue: 0x40)
27+
public static let moduleWrap = OptionAttributes(rawValue: 0x80)
28+
public static let indent = OptionAttributes(rawValue: 0x100)
29+
public static let argumentIsPath = OptionAttributes(rawValue: 0x200)
30+
public static let moduleInterface = OptionAttributes(rawValue: 0x400)
3131
}
3232

3333
/// Describes a command-line option.

Sources/SwiftDriver/Options/ParsedOptions.swift renamed to Sources/SwiftOptions/ParsedOptions.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public struct ParsedOption {
1818
case multiple([String])
1919

2020
/// Retrieve the single-string argument.
21-
var asSingle: String {
21+
public var asSingle: String {
2222
switch self {
2323
case .single(let result):
2424
return result
@@ -29,7 +29,7 @@ public struct ParsedOption {
2929
}
3030

3131
/// Retrieve multiple string arguments.
32-
var asMultiple: [String] {
32+
public var asMultiple: [String] {
3333
switch self {
3434
case .multiple(let result):
3535
return result
@@ -48,6 +48,12 @@ public struct ParsedOption {
4848

4949
/// The index in the command line where this argument appeared.
5050
public let index: Int
51+
52+
public init(option: Option, argument: Argument, index: Int) {
53+
self.option = option
54+
self.argument = argument
55+
self.index = index
56+
}
5157
}
5258

5359
extension ParsedOption: CustomStringConvertible {

Sources/swift-help/main.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===--------------- main.swift - Swift Help Main Entrypoint --------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
import SwiftOptions
13+
import TSCBasic
14+
import TSCLibc
15+
import TSCUtility
16+
17+
extension DriverKind: StringEnumArgument {
18+
public static var completion: ShellCompletion { .none }
19+
}
20+
21+
struct Options {
22+
var driverKind: DriverKind = .interactive
23+
var showHidden: Bool = false
24+
}
25+
26+
var args = CommandLine.arguments.dropFirst()
27+
let driverOptionTable = OptionTable()
28+
let parser = ArgumentParser(commandName: "swift help",
29+
usage: " ",
30+
overview: "Swift help tool",
31+
seeAlso: nil)
32+
let binder = ArgumentBinder<Options>()
33+
binder.bind(option: parser.add(option: "-show-hidden",
34+
usage: "List hidden (unsupported) options"),
35+
to: { $0.showHidden = $1 })
36+
binder.bind(option: parser.add(option: "-tool", kind: DriverKind.self,
37+
usage: "The tool to list options of"),
38+
to: { $0.driverKind = $1 })
39+
40+
do {
41+
let parseResult = try parser.parse(Array(CommandLine.arguments.dropFirst()))
42+
var options = Options()
43+
try binder.fill(parseResult: parseResult, into: &options)
44+
45+
// Print the option table.
46+
driverOptionTable.printHelp(driverKind: options.driverKind,
47+
includeHidden: options.showHidden)
48+
} catch {
49+
stderrStream <<< "error: " <<< error.localizedDescription
50+
stderrStream.flush()
51+
exit(EXIT_FAILURE)
52+
}

0 commit comments

Comments
 (0)