Skip to content

Commit e4a1a48

Browse files
committed
implement review comments
1 parent 3abb809 commit e4a1a48

15 files changed

+157
-73
lines changed

Plugins/SharedPackagePluginExtensions/PackageManager+getSymbolGraphsForDocC.swift

+2-6
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,10 @@ extension PackageManager {
3939
context: PluginContext,
4040
verbose: Bool,
4141
snippetExtractor: SnippetExtractor?,
42-
arguments: Arguments
42+
symbolGraphOptions: SymbolGraphOptions
4343
) throws -> DocCSymbolGraphResult {
4444
// First generate the primary symbol graphs containing information about the
45-
// symbols defined in the target itself.
46-
47-
var symbolGraphOptions = target.defaultSymbolGraphOptions(in: context.package)
48-
symbolGraphOptions.override(with: arguments)
49-
45+
// symbols defined in the target itself.
5046
if verbose {
5147
print("symbol graph options: '\(symbolGraphOptions)'")
5248
}

Plugins/SharedPackagePluginExtensions/SymbolGraphOptions+override.swift

+6-11
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,15 @@
99
import PackagePlugin
1010

1111
extension PackageManager.SymbolGraphOptions {
12-
/// Overrides individual values in the `SymbolGraphOptions`
13-
/// according to the given `arguments`.
14-
mutating func override(with arguments: Arguments) {
15-
for argument in arguments {
16-
switch argument {
17-
case "--emit-extension-block-symbols":
12+
/// Overrides individual values in the `PackageManager.SymbolGraphOptions`
13+
/// according to the given configurable subset of `SymbolGraphOptions`.
14+
mutating func override(with configuration: SymbolGraphOptions) {
15+
if configuration.emitExtensionBlockSymbols {
1816
#if swift(>=5.8)
19-
self.emitExtensionBlocks = true
17+
self.emitExtensionBlocks = true
2018
#else
21-
print("warning: detected '--emit-extension-block-symbols' option, which is incompatible with your swift version (required: 5.8)")
19+
print("warning: detected '--include-extended-types' option, which is incompatible with your swift version (required: 5.8)")
2220
#endif
23-
default:
24-
print("warning: detected unknown dump-symbol-graph option '\(argument)'")
25-
}
2621
}
2722
}
2823
}

Plugins/SharedPackagePluginExtensions/Target+defaultSymbolGraphOptions.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ extension SwiftSourceModuleTarget {
3636

3737
#if swift(<5.8)
3838
private extension PackageManager.SymbolGraphOptions {
39-
/// A copatibility layer for lower Swift versions which discards unknown parameters.
39+
/// A compatibility layer for lower Swift versions which discards unknown parameters.
4040
init(minimumAccessLevel: PackagePlugin.PackageManager.SymbolGraphOptions.AccessLevel = .public,
4141
includeSynthesized: Bool = false,
4242
includeSPI: Bool = false,

Plugins/Swift-DocC Convert/SwiftDocCConvert.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,16 @@ import PackagePlugin
6565
}
6666

6767
print("Generating documentation for '\(target.name)'...")
68+
69+
var options = target.defaultSymbolGraphOptions(in: context.package)
70+
options.override(with: parsedArguments.dumpSymbolGraphOptions())
6871

6972
let symbolGraphs = try packageManager.doccSymbolGraphs(
7073
for: target,
7174
context: context,
7275
verbose: verbose,
7376
snippetExtractor: snippetExtractor,
74-
arguments: parsedArguments.dumpSymbolGraphArguments()
77+
symbolGraphOptions: options
7578
)
7679

7780
if try FileManager.default.contentsOfDirectory(atPath: symbolGraphs.targetSymbolGraphsDirectory.path).isEmpty {

Plugins/Swift-DocC Preview/SwiftDocCPreview.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,15 @@ import PackagePlugin
7979
let snippetExtractor: SnippetExtractor? = nil
8080
#endif
8181

82+
var options = target.defaultSymbolGraphOptions(in: context.package)
83+
options.override(with: parsedArguments.dumpSymbolGraphOptions())
84+
8285
let symbolGraphs = try packageManager.doccSymbolGraphs(
8386
for: target,
8487
context: context,
8588
verbose: verbose,
8689
snippetExtractor: snippetExtractor,
87-
arguments: parsedArguments.dumpSymbolGraphArguments()
90+
symbolGraphOptions: options
8891
)
8992

9093
if try FileManager.default.contentsOfDirectory(atPath: symbolGraphs.targetSymbolGraphsDirectory.path).isEmpty {

Sources/SwiftDocCPluginUtilities/HelpInformation.swift

+20-7
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,19 @@ public enum HelpInformation {
4343
helpText = previewPluginHelpOverview
4444
}
4545

46-
var supportedPluginFlags = [
46+
var supportedPluginFlags: [HelpTextProvider] = [
4747
PluginFlag.disableIndex,
4848
]
4949

50+
// stops 'not mutated' warning for Swift 5.7 and lower
51+
supportedPluginFlags += []
52+
5053
#if swift(>=5.8)
5154
supportedPluginFlags += [PluginFlag.extendedTypes]
5255
#endif
5356

5457
for flag in supportedPluginFlags {
55-
helpText += """
56-
\(flag.parsedValues.sorted().joined(separator: ", "))
57-
\(flag.abstract)
58-
\(flag.description)
59-
60-
"""
58+
helpText += flag.helpText
6159
}
6260

6361
let doccHelp = try _doccHelp(pluginAction, doccExecutableURL)
@@ -141,3 +139,18 @@ private extension Process {
141139
}
142140
}
143141

142+
private protocol HelpTextProvider {
143+
var helpText: String { get }
144+
}
145+
146+
extension PluginFlag: HelpTextProvider {
147+
var helpText: String {
148+
"""
149+
\(self.parsedValues.sorted().joined(separator: ", "))
150+
\(self.abstract)
151+
\(self.description)
152+
153+
"""
154+
}
155+
}
156+

Sources/SwiftDocCPluginUtilities/ParsedArguments.swift

+23-7
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ public struct ParsedArguments {
2424
/// In practice, however we won't invoke the `dump-symbol-graph` command via the command line,
2525
/// but via the `PackagePlugin` API. Thus, these arguments have to be parsed later on and converted to
2626
/// `PackageManager.SymbolGraphOptions`.
27-
public func dumpSymbolGraphArguments() -> Arguments {
27+
public func dumpSymbolGraphOptions() -> SymbolGraphOptions {
2828
var dumpSymbolGraphArguments = arguments.filter(for: .dumpSymbolGraph)
29+
var dumpSymbolGraphConfiguration = SymbolGraphOptions()
2930

30-
for argumentsTransformer in Self.argumentsTransformers {
31-
dumpSymbolGraphArguments = argumentsTransformer.transform(dumpSymbolGraphArguments)
31+
for transformer in Self.argumentsTransformers {
32+
transformer.transform(arguments: &dumpSymbolGraphArguments, configuration: &dumpSymbolGraphConfiguration)
3233
}
3334

34-
return dumpSymbolGraphArguments
35+
return dumpSymbolGraphConfiguration
3536
}
3637

3738
/// Returns the arguments that should be passed to `docc` to invoke the given plugin action.
@@ -151,10 +152,12 @@ public struct ParsedArguments {
151152
// Add any required options that are specific to the kind of target being built
152153
doccArguments = targetKind.addRequiredOptions(to: doccArguments)
153154

155+
var configuration: () = Void()
156+
154157
// Apply any argument transformations. This allows for custom
155158
// flags that are specific to the plugin and not built-in to `docc`.
156-
for argumentsTransformer in Self.argumentsTransformers {
157-
doccArguments = argumentsTransformer.transform(doccArguments)
159+
for transformer in Self.argumentsTransformers {
160+
transformer.transform(arguments: &doccArguments, configuration: &configuration)
158161
}
159162

160163
// If we were given a catalog path, prepend it to the set of arguments.
@@ -201,7 +204,7 @@ private extension ParsedArguments {
201204
///
202205
/// If `flags` is `nil`, this `ArgumentConsumer` is assumed to
203206
/// consume all flags not consumed by any of the other `ArgumentConsumer`s.
204-
var flags: [PluginFlag]? {
207+
var flags: [FlagParser]? {
205208
switch self {
206209
case .dumpSymbolGraph:
207210
return [
@@ -214,16 +217,29 @@ private extension ParsedArguments {
214217
}
215218
}
216219

220+
private protocol FlagParser {
221+
var parsedValues: Set<String> { get }
222+
}
223+
224+
extension PluginFlag: FlagParser { }
225+
217226
private extension Arguments {
218227
/// Returns the subset of arguments which are applicable to the given `consumer`.
219228
func filter(for consumer: ParsedArguments.ArgumentConsumer) -> Arguments {
220229
if let flagsToInclude = consumer.flags {
230+
// If the consumer can provide a complete list of valid flags,
231+
// we only include elements that are included in one of these flags'
232+
// `parsedValues`, i.e. if one of these flags can be applied to the
233+
// element.
221234
return self.filter { argument in
222235
flagsToInclude.contains(where: { flag in
223236
flag.parsedValues.contains(argument)
224237
})
225238
}
226239
} else {
240+
// If the consumer cannot provide a complete list of valid flags, (which
241+
// should only happen for the `.docc` case) we return all elements
242+
// that are not applicable to any of the other `ArgumentConsumer`s.
227243
let flagsToExclude = ParsedArguments.ArgumentConsumer.allCases.compactMap(\.flags).flatMap { $0 }
228244
return self.filter { argument in
229245
!flagsToExclude.contains(where: { flag in

Sources/SwiftDocCPluginUtilities/PluginFlags/ArgumentsTransforming.swift

+25-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,30 @@
66
// See https://swift.org/LICENSE.txt for license information
77
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
88

9-
/// Transforms a set of arguments.
9+
/// A type-erased ``ArgumentsTransformer``.
1010
protocol ArgumentsTransforming {
11-
/// Apply the transformation to the given arguments.
12-
func transform(_ arguments: Arguments) -> Arguments
11+
/// Apply the transformation to the given arguments and configuration if the `Configuration` is compatible
12+
/// with the implementation.
13+
func transform<Configuration>(arguments: inout Arguments, configuration: inout Configuration)
14+
}
15+
16+
/// Transforms a set of arguments, transferring information to a typed configuration.
17+
protocol ArgumentsTransformer: ArgumentsTransforming {
18+
associatedtype Configuration
19+
/// Apply the transformation to the given arguments and configuration.
20+
func transform(arguments: inout Arguments, configuration: inout Configuration)
21+
}
22+
23+
extension ArgumentsTransformer {
24+
func transform<C>(arguments: inout Arguments, configuration: inout C) {
25+
guard var typedConfig = configuration as? Configuration,
26+
// we need strict type-equality as otherwise the transformed
27+
// `typedConfig` might not conform to `C`
28+
C.self == Configuration.self else {
29+
return
30+
}
31+
32+
self.transform(arguments: &arguments, configuration: &typedConfig)
33+
configuration = typedConfig as! C
34+
}
1335
}

Sources/SwiftDocCPluginUtilities/PluginFlags/DisableIndexFlag.swift

+3-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// See https://swift.org/LICENSE.txt for license information
77
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
88

9-
extension PluginFlag {
9+
extension PluginFlag where Configuration == Void {
1010
/// Disables indexing for the produced DocC archive.
1111
///
1212
/// Removes the `--index` flag from a given set of arguments if the `--disable-index` flag
@@ -20,11 +20,9 @@ extension PluginFlag {
2020
description: """
2121
Produces a DocC archive that is best-suited for hosting online but incompatible with Xcode.
2222
""",
23-
argumentTransformation: { arguments in
23+
transformation: { arguments, _ in
2424
// Filter out any --index flags from the parsed arguments.
25-
return arguments.filter { argument in
26-
argument != "--index"
27-
}
25+
arguments.removeAll(where: { $0 == "--index" })
2826
}
2927
)
3028
}

Sources/SwiftDocCPluginUtilities/PluginFlags/ExtendedTypesFlag.swift

+11-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// See https://swift.org/LICENSE.txt for license information
77
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
88

9-
extension PluginFlag {
9+
extension PluginFlag where Configuration == SymbolGraphOptions {
1010
/// Include extended types in documentation archives.
1111
///
1212
/// Enables the extension block symbol format when calling the
@@ -16,14 +16,22 @@ extension PluginFlag {
1616
/// be hidden from the `--help` command for lower toolchain versions.
1717
/// However, we do not hide the flag entirely, because this enables us to give
1818
/// a more precise warning when accidentally used with Swift 5.7 or lower.
19-
static let extendedTypes = PluginFlag(
19+
static let extendedTypes: Self = PluginFlag(
2020
parsedValues: [
2121
"--include-extended-types",
2222
],
2323
abstract: "Include extended types from other modules in the produced DocC archive.",
2424
description: """
2525
Allows documenting symbols that a target adds to its dependencies.
2626
""",
27-
argumentTransformation: { $0 + ["--emit-extension-block-symbols"] }
27+
transformation: { _, options in
28+
options.emitExtensionBlockSymbols = true
29+
}
2830
)
2931
}
32+
33+
/// The subset of `PackagePlugin.SymbolGraphOptions` that can be configured in
34+
/// this plugin.
35+
public struct SymbolGraphOptions {
36+
var emitExtensionBlockSymbols = false
37+
}

Sources/SwiftDocCPluginUtilities/PluginFlags/PluginFlag.swift

+9-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/// A command-line flag for the docc plugin.
1010
///
1111
/// Plugin flags are distinct from options that are for the docc command-line tool itself.
12-
struct PluginFlag: ArgumentsTransforming {
12+
struct PluginFlag<Configuration>: ArgumentsTransformer {
1313
/// The string values that will be parsed when detecting this flag.
1414
///
1515
/// For example, this might be `["--disable-index"]`.
@@ -21,7 +21,7 @@ struct PluginFlag: ArgumentsTransforming {
2121
/// An expanded, user-facing description of this flag.
2222
let description: String
2323

24-
let argumentTransformation: (Arguments) -> Arguments
24+
let transformation: (inout Arguments, inout Configuration) -> Void
2525

2626
/// Transforms the given set of arguments if they include any of this flag's
2727
/// parsed values.
@@ -30,20 +30,20 @@ struct PluginFlag: ArgumentsTransforming {
3030
/// and the given parsed arguments contain `["--disable-index", "--index"]`,
3131
/// then the transformation would both consume the `"--disable-index"` flag
3232
/// and remove the `"--index"` flag since indexing should be disabled.
33-
func transform(_ arguments: Arguments) -> Arguments {
33+
func transform(arguments: inout Arguments, configuration: inout Configuration) {
3434
guard !parsedValues.isDisjoint(with: arguments) else {
3535
// The given parsed arguments do not contain any of this flags
3636
// parsed values so just return.
37-
return arguments
37+
return
3838
}
3939

4040
// Consume the current flag
41-
let arguments = arguments.filter { argument in
42-
!parsedValues.contains(argument)
41+
arguments.removeAll { argument in
42+
parsedValues.contains(argument)
4343
}
4444

4545
// Apply the flag to the set of arguments
46-
return argumentTransformation(arguments)
46+
transformation(&arguments, &configuration)
4747
}
4848

4949
/// Create a new command-line flag.
@@ -58,11 +58,11 @@ struct PluginFlag: ArgumentsTransforming {
5858
parsedValues: Set<String>,
5959
abstract: String,
6060
description: String,
61-
argumentTransformation: @escaping (Arguments) -> Arguments
61+
transformation: @escaping (inout Arguments, inout Configuration) -> Void
6262
) {
6363
self.parsedValues = parsedValues
6464
self.abstract = abstract
6565
self.description = description
66-
self.argumentTransformation = argumentTransformation
66+
self.transformation = transformation
6767
}
6868
}

Tests/SwiftDocCPluginUtilitiesTests/ParsedArgumentsTests.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,13 @@ final class ParsedArgumentsTests: XCTestCase {
462462
func testDumpSymbolGraphArguments() {
463463
let dumpSymbolGraphArguments = ParsedArguments(["--include-extended-types"])
464464

465-
XCTAssertEqual(dumpSymbolGraphArguments.dumpSymbolGraphArguments(), ["--emit-extension-block-symbols"])
465+
XCTAssertEqual(dumpSymbolGraphArguments.dumpSymbolGraphOptions().emitExtensionBlockSymbols, true)
466466
}
467467

468468
func testDumpSymbolGraphArgumentsWithDocCArguments() {
469469
let dumpSymbolGraphArguments = ParsedArguments(["--fallback-default-module-kind", "Executable"])
470470

471471

472-
XCTAssertTrue(dumpSymbolGraphArguments.dumpSymbolGraphArguments().isEmpty)
472+
XCTAssertEqual(dumpSymbolGraphArguments.dumpSymbolGraphOptions().emitExtensionBlockSymbols, false)
473473
}
474474
}

Tests/SwiftDocCPluginUtilitiesTests/PluginFlags/DisableIndexFlagTests.swift

+9
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,12 @@ final class DisableIndexFlagTests: XCTestCase {
6666
)
6767
}
6868
}
69+
70+
private extension PluginFlag where Configuration == Void {
71+
func transform(_ arguments: Arguments) -> Arguments {
72+
var arguments = arguments
73+
var configuration: () = Void()
74+
self.transform(arguments: &arguments, configuration: &configuration)
75+
return arguments
76+
}
77+
}

0 commit comments

Comments
 (0)