File: SymbolGraphExtract.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (111 lines) | stat: -rw-r--r-- 4,425 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import ArgumentParser
import Basics
import PackageGraph
import PackageModel
import SPMBuildCore

#if USE_IMPL_ONLY_IMPORTS
@_implementationOnly import DriverSupport
#else
import DriverSupport
#endif

import class Basics.AsyncProcess
import struct Basics.AsyncProcessResult

/// A wrapper for swift-symbolgraph-extract tool.
package struct SymbolGraphExtract {
    let fileSystem: FileSystem
    let tool: AbsolutePath
    let observabilityScope: ObservabilityScope
    
    var skipSynthesizedMembers = false
    var minimumAccessLevel = AccessLevel.public
    var skipInheritedDocs = false
    var includeSPISymbols = false
    var emitExtensionBlockSymbols = false
    var outputFormat = OutputFormat.json(pretty: false)

    /// Access control levels.
    public enum AccessLevel: String, RawRepresentable, CaseIterable, ExpressibleByArgument {
        // The cases reflect those found in `include/swift/AST/AttrKind.h` of the swift compiler (at commit 03f55d7bb4204ca54841218eb7cc175ae798e3bd)
        case `private`, `fileprivate`, `internal`, `public`, `open`
    }

    /// Output format of the generated symbol graph.
    public enum OutputFormat {
        /// JSON format, optionally "pretty-printed" be more human-readable.
        case json(pretty: Bool)
    }
    
    /// Creates a symbol graph for `module` in `outputDirectory` using the build information from `buildPlan`.
    /// The `outputDirection` determines how the output from the tool subprocess is handled, and `verbosity` specifies
    /// how much console output to ask the tool to emit.
    package func extractSymbolGraph(
        module: ResolvedModule,
        buildPlan: BuildPlan,
        buildParameters: BuildParameters,
        outputRedirection: AsyncProcess.OutputRedirection = .none,
        outputDirectory: AbsolutePath,
        verboseOutput: Bool
    ) throws -> AsyncProcessResult {
        try self.fileSystem.createDirectory(outputDirectory, recursive: true)

        // Construct arguments for extracting symbols for a single target.
        var commandLine = [self.tool.pathString]
        commandLine += try buildPlan.symbolGraphExtractArguments(for: module)

        // FIXME: everything here should be in symbolGraphExtractArguments
        commandLine += ["-module-name", module.c99name]
        commandLine += try buildParameters.tripleArgs(for: module)
        commandLine += ["-module-cache-path", try buildParameters.moduleCache.pathString]
        if verboseOutput {
            commandLine += ["-v"]
        }
        commandLine += ["-minimum-access-level", minimumAccessLevel.rawValue]
        if skipSynthesizedMembers {
            commandLine += ["-skip-synthesized-members"]
        }
        if skipInheritedDocs {
            commandLine += ["-skip-inherited-docs"]
        }
        if includeSPISymbols {
            commandLine += ["-include-spi-symbols"]
        }
        
        let extensionBlockSymbolsFlag = emitExtensionBlockSymbols ? "-emit-extension-block-symbols" : "-omit-extension-block-symbols"
        if DriverSupport.checkSupportedFrontendFlags(flags: [extensionBlockSymbolsFlag.trimmingCharacters(in: ["-"])], toolchain: buildParameters.toolchain, fileSystem: fileSystem) {
            commandLine += [extensionBlockSymbolsFlag]
        } else {
            observabilityScope.emit(warning: "dropped \(extensionBlockSymbolsFlag) flag because it is not supported by this compiler version")
        }
        
        switch outputFormat {
        case .json(let pretty):
            if pretty {
                commandLine += ["-pretty-print"]
            }
        }
        commandLine += ["-output-dir", outputDirectory.pathString]

        // Run the extraction.
        let process = AsyncProcess(
            arguments: commandLine,
            outputRedirection: outputRedirection
        )
        try process.launch()
        return try process.waitUntilExit()
    }
}