diff --git a/Package.swift b/Package.swift index 53db4bb27..8cb21d947 100644 --- a/Package.swift +++ b/Package.swift @@ -19,102 +19,11 @@ var products: [Product] = [ name: "swift-format", targets: ["swift-format"] ), - .library( - name: "SwiftFormat", - targets: ["SwiftFormat"] - ), - .plugin( - name: "FormatPlugin", - targets: ["Format Source Code"] - ), - .plugin( - name: "LintPlugin", - targets: ["Lint Source Code"] - ), ] var targets: [Target] = [ - .target( - name: "_SwiftFormatInstructionCounter", - exclude: ["CMakeLists.txt"] - ), - - .target( - name: "SwiftFormat", - dependencies: [ - .product(name: "Markdown", package: "swift-markdown") - ] - + swiftSyntaxDependencies([ - "SwiftOperators", "SwiftParser", "SwiftParserDiagnostics", "SwiftSyntax", "SwiftSyntaxBuilder", - ]), - exclude: ["CMakeLists.txt"] - ), - .target( - name: "_SwiftFormatTestSupport", - dependencies: [ - "SwiftFormat" - ] - + swiftSyntaxDependencies([ - "SwiftOperators", "SwiftParser", "SwiftParserDiagnostics", "SwiftSyntax", "SwiftSyntaxBuilder", - ]) - ), - .plugin( - name: "Format Source Code", - capability: .command( - intent: .sourceCodeFormatting(), - permissions: [ - .writeToPackageDirectory(reason: "This command formats the Swift source files") - ] - ), - dependencies: [ - .target(name: "swift-format") - ], - path: "Plugins/FormatPlugin" - ), - .plugin( - name: "Lint Source Code", - capability: .command( - intent: .custom( - verb: "lint-source-code", - description: "Lint source code for a specified target." - ) - ), - dependencies: [ - .target(name: "swift-format") - ], - path: "Plugins/LintPlugin" - ), - .executableTarget( - name: "generate-swift-format", - dependencies: [ - "SwiftFormat" - ] - ), .executableTarget( - name: "swift-format", - dependencies: [ - "_SwiftFormatInstructionCounter", - "SwiftFormat", - .product(name: "ArgumentParser", package: "swift-argument-parser"), - ] + swiftSyntaxDependencies(["SwiftParser", "SwiftSyntax"]), - exclude: ["CMakeLists.txt"], - linkerSettings: swiftformatLinkSettings - ), - - .testTarget( - name: "SwiftFormatPerformanceTests", - dependencies: [ - "SwiftFormat", - "_SwiftFormatTestSupport", - ] + swiftSyntaxDependencies(["SwiftParser", "SwiftSyntax"]) - ), - .testTarget( - name: "SwiftFormatTests", - dependencies: [ - "SwiftFormat", - "_SwiftFormatTestSupport", - .product(name: "Markdown", package: "swift-markdown"), - ] + swiftSyntaxDependencies(["SwiftOperators", "SwiftParser", "SwiftSyntax", "SwiftSyntaxBuilder"]) + name: "swift-format" ), ] diff --git a/README.md b/README.md index 77342ff5c..d04833cb8 100644 --- a/README.md +++ b/README.md @@ -281,3 +281,4 @@ To give clarity of what is expected of our members, Swift has adopted the code of conduct defined by the Contributor Covenant. This document is used across many open source communities, and we think it articulates our values well. For more, see the [Code of Conduct](https://swift.org/code-of-conduct/). + diff --git a/Sources/swift-format/Frontend/ConfigurationLoader.swift b/Sources/swift-format/Frontend/ConfigurationLoader.swift index 57d9bb63b..6d836f384 100644 --- a/Sources/swift-format/Frontend/ConfigurationLoader.swift +++ b/Sources/swift-format/Frontend/ConfigurationLoader.swift @@ -1,49 +1,49 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import Foundation -import SwiftFormat +// import Foundation +// import SwiftFormat -/// Loads formatter configurations, caching them in memory so that multiple operations in the same -/// directory do not repeatedly hit the file system. -struct ConfigurationLoader { - /// The cache of previously loaded configurations. - private var cache = [String: Configuration]() +// /// Loads formatter configurations, caching them in memory so that multiple operations in the same +// /// directory do not repeatedly hit the file system. +// struct ConfigurationLoader { +// /// The cache of previously loaded configurations. +// private var cache = [String: Configuration]() - /// Returns the configuration found by walking up the file tree from `url`. - /// This function works for both files and directories. - /// - /// If no configuration file was found during the search, this method returns nil. - /// - /// - Throws: If a configuration file was found but an error occurred loading it. - mutating func configuration(forPath url: URL) throws -> Configuration? { - guard let configurationFileURL = Configuration.url(forConfigurationFileApplyingTo: url) - else { - return nil - } - return try configuration(at: configurationFileURL) - } +// /// Returns the configuration found by walking up the file tree from `url`. +// /// This function works for both files and directories. +// /// +// /// If no configuration file was found during the search, this method returns nil. +// /// +// /// - Throws: If a configuration file was found but an error occurred loading it. +// mutating func configuration(forPath url: URL) throws -> Configuration? { +// guard let configurationFileURL = Configuration.url(forConfigurationFileApplyingTo: url) +// else { +// return nil +// } +// return try configuration(at: configurationFileURL) +// } - /// Returns the configuration associated with the configuration file at the given URL. - /// - /// - Throws: If an error occurred loading the configuration. - mutating func configuration(at url: URL) throws -> Configuration { - let cacheKey = url.absoluteURL.standardized.path - if let cachedConfiguration = cache[cacheKey] { - return cachedConfiguration - } +// /// Returns the configuration associated with the configuration file at the given URL. +// /// +// /// - Throws: If an error occurred loading the configuration. +// mutating func configuration(at url: URL) throws -> Configuration { +// let cacheKey = url.absoluteURL.standardized.path +// if let cachedConfiguration = cache[cacheKey] { +// return cachedConfiguration +// } - let configuration = try Configuration(contentsOf: url) - cache[cacheKey] = configuration - return configuration - } -} +// let configuration = try Configuration(contentsOf: url) +// cache[cacheKey] = configuration +// return configuration +// } +// } diff --git a/Sources/swift-format/Frontend/FormatFrontend.swift b/Sources/swift-format/Frontend/FormatFrontend.swift index a205b6405..4ae280549 100644 --- a/Sources/swift-format/Frontend/FormatFrontend.swift +++ b/Sources/swift-format/Frontend/FormatFrontend.swift @@ -1,93 +1,93 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import Foundation -import SwiftDiagnostics -import SwiftFormat -import SwiftSyntax +// import Foundation +// import SwiftDiagnostics +// import SwiftFormat +// import SwiftSyntax -/// The frontend for formatting operations. -class FormatFrontend: Frontend { - /// Whether or not to format the Swift file in-place. - private let inPlace: Bool +// /// The frontend for formatting operations. +// class FormatFrontend: Frontend { +// /// Whether or not to format the Swift file in-place. +// private let inPlace: Bool - init(configurationOptions: ConfigurationOptions, lintFormatOptions: LintFormatOptions, inPlace: Bool) { - self.inPlace = inPlace - super.init(configurationOptions: configurationOptions, lintFormatOptions: lintFormatOptions) - } +// init(configurationOptions: ConfigurationOptions, lintFormatOptions: LintFormatOptions, inPlace: Bool) { +// self.inPlace = inPlace +// super.init(configurationOptions: configurationOptions, lintFormatOptions: lintFormatOptions) +// } - override func processFile(_ fileToProcess: FileToProcess) { - // In format mode, the diagnostics engine is reserved for fatal messages. Pass nil as the - // finding consumer to ignore findings emitted while the syntax tree is processed because they - // will be fixed automatically if they can be, or ignored otherwise. - let formatter = SwiftFormatter(configuration: fileToProcess.configuration, findingConsumer: nil) - formatter.debugOptions = debugOptions +// override func processFile(_ fileToProcess: FileToProcess) { +// // In format mode, the diagnostics engine is reserved for fatal messages. Pass nil as the +// // finding consumer to ignore findings emitted while the syntax tree is processed because they +// // will be fixed automatically if they can be, or ignored otherwise. +// let formatter = SwiftFormatter(configuration: fileToProcess.configuration, findingConsumer: nil) +// formatter.debugOptions = debugOptions - let url = fileToProcess.url - guard let source = fileToProcess.sourceText else { - diagnosticsEngine.emitError( - "Unable to format \(url.relativePath): file is not readable or does not exist." - ) - return - } +// let url = fileToProcess.url +// guard let source = fileToProcess.sourceText else { +// diagnosticsEngine.emitError( +// "Unable to format \(url.relativePath): file is not readable or does not exist." +// ) +// return +// } - let diagnosticHandler: (SwiftDiagnostics.Diagnostic, SourceLocation) -> () = { - (diagnostic, location) in - guard !self.lintFormatOptions.ignoreUnparsableFiles else { - // No diagnostics should be emitted in this mode. - return - } - self.diagnosticsEngine.consumeParserDiagnostic(diagnostic, location) - } - var stdoutStream = FileHandleTextOutputStream(FileHandle.standardOutput) - do { - if inPlace { - var buffer = "" - try formatter.format( - source: source, - assumingFileURL: url, - selection: fileToProcess.selection, - experimentalFeatures: Set(lintFormatOptions.experimentalFeatures), - to: &buffer, - parsingDiagnosticHandler: diagnosticHandler - ) +// let diagnosticHandler: (SwiftDiagnostics.Diagnostic, SourceLocation) -> () = { +// (diagnostic, location) in +// guard !self.lintFormatOptions.ignoreUnparsableFiles else { +// // No diagnostics should be emitted in this mode. +// return +// } +// self.diagnosticsEngine.consumeParserDiagnostic(diagnostic, location) +// } +// var stdoutStream = FileHandleTextOutputStream(FileHandle.standardOutput) +// do { +// if inPlace { +// var buffer = "" +// try formatter.format( +// source: source, +// assumingFileURL: url, +// selection: fileToProcess.selection, +// experimentalFeatures: Set(lintFormatOptions.experimentalFeatures), +// to: &buffer, +// parsingDiagnosticHandler: diagnosticHandler +// ) - if buffer != source { - let bufferData = buffer.data(using: .utf8)! // Conversion to UTF-8 cannot fail - try bufferData.write(to: url, options: .atomic) - } - } else { - try formatter.format( - source: source, - assumingFileURL: url, - selection: fileToProcess.selection, - experimentalFeatures: Set(lintFormatOptions.experimentalFeatures), - to: &stdoutStream, - parsingDiagnosticHandler: diagnosticHandler - ) - } - } catch SwiftFormatError.fileContainsInvalidSyntax { - guard !lintFormatOptions.ignoreUnparsableFiles else { - guard !inPlace else { - // For in-place mode, nothing is expected to stdout and the file shouldn't be modified. - return - } - stdoutStream.write(source) - return - } - // Otherwise, relevant diagnostics about the problematic nodes have already been emitted; we - // don't need to print anything else. - } catch { - diagnosticsEngine.emitError("Unable to format \(url.relativePath): \(error.localizedDescription).") - } - } -} +// if buffer != source { +// let bufferData = buffer.data(using: .utf8)! // Conversion to UTF-8 cannot fail +// try bufferData.write(to: url, options: .atomic) +// } +// } else { +// try formatter.format( +// source: source, +// assumingFileURL: url, +// selection: fileToProcess.selection, +// experimentalFeatures: Set(lintFormatOptions.experimentalFeatures), +// to: &stdoutStream, +// parsingDiagnosticHandler: diagnosticHandler +// ) +// } +// } catch SwiftFormatError.fileContainsInvalidSyntax { +// guard !lintFormatOptions.ignoreUnparsableFiles else { +// guard !inPlace else { +// // For in-place mode, nothing is expected to stdout and the file shouldn't be modified. +// return +// } +// stdoutStream.write(source) +// return +// } +// // Otherwise, relevant diagnostics about the problematic nodes have already been emitted; we +// // don't need to print anything else. +// } catch { +// diagnosticsEngine.emitError("Unable to format \(url.relativePath): \(error.localizedDescription).") +// } +// } +// } diff --git a/Sources/swift-format/Frontend/Frontend.swift b/Sources/swift-format/Frontend/Frontend.swift index e1007414b..cae17b8b7 100644 --- a/Sources/swift-format/Frontend/Frontend.swift +++ b/Sources/swift-format/Frontend/Frontend.swift @@ -1,325 +1,325 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation -@_spi(Internal) import SwiftFormat -import SwiftParser -import SwiftSyntax - -class Frontend { - /// Provides formatter configurations for given `.swift` source files, configuration files or configuration strings. - struct ConfigurationProvider { - /// Loads formatter configuration files and chaches them in memory. - private var configurationLoader: ConfigurationLoader = ConfigurationLoader() - - /// The diagnostic engine to which warnings and errors will be emitted. - private let diagnosticsEngine: DiagnosticsEngine - - /// Creates a new instance with the given options. - /// - /// - Parameter diagnosticsEngine: The diagnostic engine to which warnings and errors will be emitted. - init(diagnosticsEngine: DiagnosticsEngine) { - self.diagnosticsEngine = diagnosticsEngine - } - - /// Checks if all the rules in the given configuration are supported by the registry. - /// - /// If there are any rules that are not supported, they are emitted as a warning. - private func checkForUnrecognizedRules(in configuration: Configuration) { - // If any rules in the decoded configuration are not supported by the registry, - // emit them into the diagnosticsEngine as warnings. - // That way they will be printed out, but we'll continue execution on the valid rules. - let invalidRules = configuration.rules.filter { !RuleRegistry.rules.keys.contains($0.key) } - for rule in invalidRules { - diagnosticsEngine.emitWarning("Configuration contains an unrecognized rule: \(rule.key)", location: nil) - } - } - - /// Returns the configuration that applies to the given `.swift` source file, when an explicit - /// configuration path is also perhaps provided. - /// - /// This method also checks for unrecognized rules within the configuration. - /// - /// - Parameters: - /// - pathOrString: A string containing either the path to a configuration file that will be - /// loaded, JSON configuration data directly, or `nil` to try to infer it from - /// `swiftFileURL`. - /// - swiftFileURL: The path to a `.swift` file, which will be used to infer the path to the - /// configuration file if `configurationFilePath` is nil. - /// - /// - Returns: If successful, the returned configuration is the one loaded from `pathOrString` if - /// it was provided, or by searching in paths inferred by `swiftFileURL` if one exists, or the - /// default configuration otherwise. If an error occurred when reading the configuration, a - /// diagnostic is emitted and `nil` is returned. If neither `pathOrString` nor `swiftFileURL` - /// were provided, a default `Configuration()` will be returned. - mutating func provide( - forConfigPathOrString pathOrString: String?, - orForSwiftFileAt swiftFileURL: URL? - ) -> Configuration? { - if let pathOrString = pathOrString { - // If an explicit configuration file path was given, try to load it and fail if it cannot be - // loaded. (Do not try to fall back to a path inferred from the source file path.) - let configurationFileURL = URL(fileURLWithPath: pathOrString) - do { - let configuration = try configurationLoader.configuration(at: configurationFileURL) - self.checkForUnrecognizedRules(in: configuration) - return configuration - } catch { - // If we failed to load this from the path, try interpreting the string as configuration - // data itself because the user might have written something like `--configuration '{...}'`, - let data = pathOrString.data(using: .utf8)! - if let configuration = try? Configuration(data: data) { - return configuration - } - - // Fail if the configuration flag was neither a valid file path nor valid configuration - // data. - diagnosticsEngine.emitError("Unable to read configuration: \(error.localizedDescription)") - return nil - } - } - - // If no explicit configuration file path was given but a `.swift` source file path was given, - // then try to load the configuration by inferring it based on the source file path. - if let swiftFileURL = swiftFileURL { - do { - if let configuration = try configurationLoader.configuration(forPath: swiftFileURL) { - self.checkForUnrecognizedRules(in: configuration) - return configuration - } - // Fall through to the default return at the end of the function. - } catch { - diagnosticsEngine.emitError( - "Unable to read configuration for \(swiftFileURL.relativePath): \(error.localizedDescription)" - ) - return nil - } - } else { - // If reading from stdin and no explicit configuration file was given, - // walk up the file tree from the cwd to find a config. - - let cwd = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) - // Definitely a Swift file. Definitely not a directory. Shhhhhh. - do { - if let configuration = try configurationLoader.configuration(forPath: cwd) { - self.checkForUnrecognizedRules(in: configuration) - return configuration - } - } catch { - diagnosticsEngine.emitError( - "Unable to read configuration for \(cwd.relativePath): \(error.localizedDescription)" - ) - return nil - } - } - - // An explicit configuration has not been given, and one cannot be found. - // Return the default configuration. - return Configuration() - } - } - - /// Represents a file to be processed by the frontend and any file-specific options associated - /// with it. - final class FileToProcess { - /// An open file handle to the source code of the file. - private let fileHandle: FileHandle - - /// A file URL representing the path to the source file being processed. - /// - /// It is the responsibility of the specific frontend to make guarantees about the validity of - /// this path. For example, the formatting frontend ensures that it is a path to an existing - /// file only when doing in-place formatting (so that the file can be replaced). In other - /// situations, it may correspond to a different file than the underlying file handle (if - /// standard input is used with the `--assume-filename` flag), or it may not be a valid path at - /// all (the string `""`). - let url: URL - - /// The configuration that should applied for this file. - let configuration: Configuration - - /// the selected ranges to process - let selection: Selection - - /// Returns the string contents of the file. - /// - /// The contents of the file are assumed to be UTF-8 encoded. If there is an error decoding the - /// contents, `nil` will be returned. - lazy var sourceText: String? = { - let sourceData = fileHandle.readDataToEndOfFile() - defer { fileHandle.closeFile() } - return String(data: sourceData, encoding: .utf8) - }() - - init( - fileHandle: FileHandle, - url: URL, - configuration: Configuration, - selection: Selection = .infinite - ) { - self.fileHandle = fileHandle - self.url = url - self.configuration = configuration - self.selection = selection - } - } - - /// Prints diagnostics to standard error, optionally with color. - final let diagnosticPrinter: StderrDiagnosticPrinter - - /// The diagnostic engine to which warnings and errors will be emitted. - final let diagnosticsEngine: DiagnosticsEngine - - /// Options that control the tool's configuration. - final let configurationOptions: ConfigurationOptions - - /// Options that apply during formatting or linting. - final let lintFormatOptions: LintFormatOptions - - /// The provider for formatter configurations. - final var configurationProvider: ConfigurationProvider - - /// Advanced options that are useful for developing/debugging but otherwise not meant for general - /// use. - final var debugOptions: DebugOptions { - [ - lintFormatOptions.debugDisablePrettyPrint ? .disablePrettyPrint : [], - lintFormatOptions.debugDumpTokenStream ? .dumpTokenStream : [], - ] - } - - /// Creates a new frontend with the given options. - /// - /// - Parameter lintFormatOptions: Options that apply during formatting or linting. - init(configurationOptions: ConfigurationOptions, lintFormatOptions: LintFormatOptions) { - self.configurationOptions = configurationOptions - self.lintFormatOptions = lintFormatOptions - - self.diagnosticPrinter = StderrDiagnosticPrinter( - colorMode: lintFormatOptions.colorDiagnostics.map { $0 ? .on : .off } ?? .auto - ) - self.diagnosticsEngine = DiagnosticsEngine(diagnosticsHandlers: [diagnosticPrinter.printDiagnostic]) - self.configurationProvider = ConfigurationProvider(diagnosticsEngine: self.diagnosticsEngine) - } - - /// Runs the linter or formatter over the inputs. - final func run() { - if lintFormatOptions.paths == ["-"] { - processStandardInput() - } else if lintFormatOptions.paths.isEmpty { - diagnosticsEngine.emitWarning( - """ - Running swift-format without input paths is deprecated and will be removed in the future. - - Please update your invocation to do either of the following: - - - Pass `-` to read from stdin (e.g., `cat MyFile.swift | swift-format -`). - - Pass one or more paths to Swift source files or directories containing - Swift source files. When passing directories, make sure to include the - `--recursive` flag. - - For more information, use the `--help` option. - """ - ) - processStandardInput() - } else { - processURLs( - lintFormatOptions.paths.map(URL.init(fileURLWithPath:)), - parallel: lintFormatOptions.parallel - ) - } - } - - /// Called by the frontend to process a single file. - /// - /// Subclasses must override this method to provide the actual linting or formatting logic. - /// - /// - Parameter fileToProcess: A `FileToProcess` that contains information about the file to be - /// processed. - func processFile(_ fileToProcess: FileToProcess) { - fatalError("Must be overridden by subclasses.") - } - - /// Processes source content from standard input. - private func processStandardInput() { - let assumedUrl = lintFormatOptions.assumeFilename.map(URL.init(fileURLWithPath:)) - - guard - let configuration = configurationProvider.provide( - forConfigPathOrString: configurationOptions.configuration, - orForSwiftFileAt: assumedUrl - ) - else { - // Already diagnosed in the called method. - return - } - - let fileToProcess = FileToProcess( - fileHandle: FileHandle.standardInput, - url: assumedUrl ?? URL(fileURLWithPath: ""), - configuration: configuration, - selection: Selection(offsetRanges: lintFormatOptions.offsets) - ) - processFile(fileToProcess) - } - - /// Processes source content from a list of files and/or directories provided as file URLs. - private func processURLs(_ urls: [URL], parallel: Bool) { - precondition( - !urls.isEmpty, - "processURLs(_:) should only be called when 'urls' is non-empty." - ) - - if parallel { - let filesToProcess = - FileIterator(urls: urls, followSymlinks: lintFormatOptions.followSymlinks) - .compactMap(openAndPrepareFile) - DispatchQueue.concurrentPerform(iterations: filesToProcess.count) { index in - processFile(filesToProcess[index]) - } - } else { - FileIterator(urls: urls, followSymlinks: lintFormatOptions.followSymlinks) - .lazy - .compactMap(openAndPrepareFile) - .forEach(processFile) - } - } - - /// Read and prepare the file at the given path for processing, optionally synchronizing - /// diagnostic output. - private func openAndPrepareFile(at url: URL) -> FileToProcess? { - guard let sourceFile = try? FileHandle(forReadingFrom: url) else { - diagnosticsEngine.emitError( - "Unable to open \(url.relativePath): file is not readable or does not exist" - ) - return nil - } - - guard - let configuration = configurationProvider.provide( - forConfigPathOrString: configurationOptions.configuration, - orForSwiftFileAt: url - ) - else { - // Already diagnosed in the called method. - return nil - } - - return FileToProcess( - fileHandle: sourceFile, - url: url, - configuration: configuration, - selection: Selection(offsetRanges: lintFormatOptions.offsets) - ) - } - -} +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// + +// import Foundation +// @_spi(Internal) import SwiftFormat +// import SwiftParser +// import SwiftSyntax + +// class Frontend { +// /// Provides formatter configurations for given `.swift` source files, configuration files or configuration strings. +// struct ConfigurationProvider { +// /// Loads formatter configuration files and chaches them in memory. +// private var configurationLoader: ConfigurationLoader = ConfigurationLoader() + +// /// The diagnostic engine to which warnings and errors will be emitted. +// private let diagnosticsEngine: DiagnosticsEngine + +// /// Creates a new instance with the given options. +// /// +// /// - Parameter diagnosticsEngine: The diagnostic engine to which warnings and errors will be emitted. +// init(diagnosticsEngine: DiagnosticsEngine) { +// self.diagnosticsEngine = diagnosticsEngine +// } + +// /// Checks if all the rules in the given configuration are supported by the registry. +// /// +// /// If there are any rules that are not supported, they are emitted as a warning. +// private func checkForUnrecognizedRules(in configuration: Configuration) { +// // If any rules in the decoded configuration are not supported by the registry, +// // emit them into the diagnosticsEngine as warnings. +// // That way they will be printed out, but we'll continue execution on the valid rules. +// let invalidRules = configuration.rules.filter { !RuleRegistry.rules.keys.contains($0.key) } +// for rule in invalidRules { +// diagnosticsEngine.emitWarning("Configuration contains an unrecognized rule: \(rule.key)", location: nil) +// } +// } + +// /// Returns the configuration that applies to the given `.swift` source file, when an explicit +// /// configuration path is also perhaps provided. +// /// +// /// This method also checks for unrecognized rules within the configuration. +// /// +// /// - Parameters: +// /// - pathOrString: A string containing either the path to a configuration file that will be +// /// loaded, JSON configuration data directly, or `nil` to try to infer it from +// /// `swiftFileURL`. +// /// - swiftFileURL: The path to a `.swift` file, which will be used to infer the path to the +// /// configuration file if `configurationFilePath` is nil. +// /// +// /// - Returns: If successful, the returned configuration is the one loaded from `pathOrString` if +// /// it was provided, or by searching in paths inferred by `swiftFileURL` if one exists, or the +// /// default configuration otherwise. If an error occurred when reading the configuration, a +// /// diagnostic is emitted and `nil` is returned. If neither `pathOrString` nor `swiftFileURL` +// /// were provided, a default `Configuration()` will be returned. +// mutating func provide( +// forConfigPathOrString pathOrString: String?, +// orForSwiftFileAt swiftFileURL: URL? +// ) -> Configuration? { +// if let pathOrString = pathOrString { +// // If an explicit configuration file path was given, try to load it and fail if it cannot be +// // loaded. (Do not try to fall back to a path inferred from the source file path.) +// let configurationFileURL = URL(fileURLWithPath: pathOrString) +// do { +// let configuration = try configurationLoader.configuration(at: configurationFileURL) +// self.checkForUnrecognizedRules(in: configuration) +// return configuration +// } catch { +// // If we failed to load this from the path, try interpreting the string as configuration +// // data itself because the user might have written something like `--configuration '{...}'`, +// let data = pathOrString.data(using: .utf8)! +// if let configuration = try? Configuration(data: data) { +// return configuration +// } + +// // Fail if the configuration flag was neither a valid file path nor valid configuration +// // data. +// diagnosticsEngine.emitError("Unable to read configuration: \(error.localizedDescription)") +// return nil +// } +// } + +// // If no explicit configuration file path was given but a `.swift` source file path was given, +// // then try to load the configuration by inferring it based on the source file path. +// if let swiftFileURL = swiftFileURL { +// do { +// if let configuration = try configurationLoader.configuration(forPath: swiftFileURL) { +// self.checkForUnrecognizedRules(in: configuration) +// return configuration +// } +// // Fall through to the default return at the end of the function. +// } catch { +// diagnosticsEngine.emitError( +// "Unable to read configuration for \(swiftFileURL.relativePath): \(error.localizedDescription)" +// ) +// return nil +// } +// } else { +// // If reading from stdin and no explicit configuration file was given, +// // walk up the file tree from the cwd to find a config. + +// let cwd = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) +// // Definitely a Swift file. Definitely not a directory. Shhhhhh. +// do { +// if let configuration = try configurationLoader.configuration(forPath: cwd) { +// self.checkForUnrecognizedRules(in: configuration) +// return configuration +// } +// } catch { +// diagnosticsEngine.emitError( +// "Unable to read configuration for \(cwd.relativePath): \(error.localizedDescription)" +// ) +// return nil +// } +// } + +// // An explicit configuration has not been given, and one cannot be found. +// // Return the default configuration. +// return Configuration() +// } +// } + +// /// Represents a file to be processed by the frontend and any file-specific options associated +// /// with it. +// final class FileToProcess { +// /// An open file handle to the source code of the file. +// private let fileHandle: FileHandle + +// /// A file URL representing the path to the source file being processed. +// /// +// /// It is the responsibility of the specific frontend to make guarantees about the validity of +// /// this path. For example, the formatting frontend ensures that it is a path to an existing +// /// file only when doing in-place formatting (so that the file can be replaced). In other +// /// situations, it may correspond to a different file than the underlying file handle (if +// /// standard input is used with the `--assume-filename` flag), or it may not be a valid path at +// /// all (the string `""`). +// let url: URL + +// /// The configuration that should applied for this file. +// let configuration: Configuration + +// /// the selected ranges to process +// let selection: Selection + +// /// Returns the string contents of the file. +// /// +// /// The contents of the file are assumed to be UTF-8 encoded. If there is an error decoding the +// /// contents, `nil` will be returned. +// lazy var sourceText: String? = { +// let sourceData = fileHandle.readDataToEndOfFile() +// defer { fileHandle.closeFile() } +// return String(data: sourceData, encoding: .utf8) +// }() + +// init( +// fileHandle: FileHandle, +// url: URL, +// configuration: Configuration, +// selection: Selection = .infinite +// ) { +// self.fileHandle = fileHandle +// self.url = url +// self.configuration = configuration +// self.selection = selection +// } +// } + +// /// Prints diagnostics to standard error, optionally with color. +// final let diagnosticPrinter: StderrDiagnosticPrinter + +// /// The diagnostic engine to which warnings and errors will be emitted. +// final let diagnosticsEngine: DiagnosticsEngine + +// /// Options that control the tool's configuration. +// final let configurationOptions: ConfigurationOptions + +// /// Options that apply during formatting or linting. +// final let lintFormatOptions: LintFormatOptions + +// /// The provider for formatter configurations. +// final var configurationProvider: ConfigurationProvider + +// /// Advanced options that are useful for developing/debugging but otherwise not meant for general +// /// use. +// final var debugOptions: DebugOptions { +// [ +// lintFormatOptions.debugDisablePrettyPrint ? .disablePrettyPrint : [], +// lintFormatOptions.debugDumpTokenStream ? .dumpTokenStream : [], +// ] +// } + +// /// Creates a new frontend with the given options. +// /// +// /// - Parameter lintFormatOptions: Options that apply during formatting or linting. +// init(configurationOptions: ConfigurationOptions, lintFormatOptions: LintFormatOptions) { +// self.configurationOptions = configurationOptions +// self.lintFormatOptions = lintFormatOptions + +// self.diagnosticPrinter = StderrDiagnosticPrinter( +// colorMode: lintFormatOptions.colorDiagnostics.map { $0 ? .on : .off } ?? .auto +// ) +// self.diagnosticsEngine = DiagnosticsEngine(diagnosticsHandlers: [diagnosticPrinter.printDiagnostic]) +// self.configurationProvider = ConfigurationProvider(diagnosticsEngine: self.diagnosticsEngine) +// } + +// /// Runs the linter or formatter over the inputs. +// final func run() { +// if lintFormatOptions.paths == ["-"] { +// processStandardInput() +// } else if lintFormatOptions.paths.isEmpty { +// diagnosticsEngine.emitWarning( +// """ +// Running swift-format without input paths is deprecated and will be removed in the future. + +// Please update your invocation to do either of the following: + +// - Pass `-` to read from stdin (e.g., `cat MyFile.swift | swift-format -`). +// - Pass one or more paths to Swift source files or directories containing +// Swift source files. When passing directories, make sure to include the +// `--recursive` flag. + +// For more information, use the `--help` option. +// """ +// ) +// processStandardInput() +// } else { +// processURLs( +// lintFormatOptions.paths.map(URL.init(fileURLWithPath:)), +// parallel: lintFormatOptions.parallel +// ) +// } +// } + +// /// Called by the frontend to process a single file. +// /// +// /// Subclasses must override this method to provide the actual linting or formatting logic. +// /// +// /// - Parameter fileToProcess: A `FileToProcess` that contains information about the file to be +// /// processed. +// func processFile(_ fileToProcess: FileToProcess) { +// fatalError("Must be overridden by subclasses.") +// } + +// /// Processes source content from standard input. +// private func processStandardInput() { +// let assumedUrl = lintFormatOptions.assumeFilename.map(URL.init(fileURLWithPath:)) + +// guard +// let configuration = configurationProvider.provide( +// forConfigPathOrString: configurationOptions.configuration, +// orForSwiftFileAt: assumedUrl +// ) +// else { +// // Already diagnosed in the called method. +// return +// } + +// let fileToProcess = FileToProcess( +// fileHandle: FileHandle.standardInput, +// url: assumedUrl ?? URL(fileURLWithPath: ""), +// configuration: configuration, +// selection: Selection(offsetRanges: lintFormatOptions.offsets) +// ) +// processFile(fileToProcess) +// } + +// /// Processes source content from a list of files and/or directories provided as file URLs. +// private func processURLs(_ urls: [URL], parallel: Bool) { +// precondition( +// !urls.isEmpty, +// "processURLs(_:) should only be called when 'urls' is non-empty." +// ) + +// if parallel { +// let filesToProcess = +// FileIterator(urls: urls, followSymlinks: lintFormatOptions.followSymlinks) +// .compactMap(openAndPrepareFile) +// DispatchQueue.concurrentPerform(iterations: filesToProcess.count) { index in +// processFile(filesToProcess[index]) +// } +// } else { +// FileIterator(urls: urls, followSymlinks: lintFormatOptions.followSymlinks) +// .lazy +// .compactMap(openAndPrepareFile) +// .forEach(processFile) +// } +// } + +// /// Read and prepare the file at the given path for processing, optionally synchronizing +// /// diagnostic output. +// private func openAndPrepareFile(at url: URL) -> FileToProcess? { +// guard let sourceFile = try? FileHandle(forReadingFrom: url) else { +// diagnosticsEngine.emitError( +// "Unable to open \(url.relativePath): file is not readable or does not exist" +// ) +// return nil +// } + +// guard +// let configuration = configurationProvider.provide( +// forConfigPathOrString: configurationOptions.configuration, +// orForSwiftFileAt: url +// ) +// else { +// // Already diagnosed in the called method. +// return nil +// } + +// return FileToProcess( +// fileHandle: sourceFile, +// url: url, +// configuration: configuration, +// selection: Selection(offsetRanges: lintFormatOptions.offsets) +// ) +// } + +// } diff --git a/Sources/swift-format/Frontend/LintFrontend.swift b/Sources/swift-format/Frontend/LintFrontend.swift index c231266a7..9e1b40502 100644 --- a/Sources/swift-format/Frontend/LintFrontend.swift +++ b/Sources/swift-format/Frontend/LintFrontend.swift @@ -1,58 +1,58 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import Foundation -import SwiftDiagnostics -import SwiftFormat -import SwiftSyntax +// import Foundation +// import SwiftDiagnostics +// import SwiftFormat +// import SwiftSyntax -/// The frontend for linting operations. -class LintFrontend: Frontend { - override func processFile(_ fileToProcess: FileToProcess) { - let linter = SwiftLinter( - configuration: fileToProcess.configuration, - findingConsumer: diagnosticsEngine.consumeFinding - ) - linter.debugOptions = debugOptions +// /// The frontend for linting operations. +// class LintFrontend: Frontend { +// override func processFile(_ fileToProcess: FileToProcess) { +// let linter = SwiftLinter( +// configuration: fileToProcess.configuration, +// findingConsumer: diagnosticsEngine.consumeFinding +// ) +// linter.debugOptions = debugOptions - let url = fileToProcess.url - guard let source = fileToProcess.sourceText else { - diagnosticsEngine.emitError( - "Unable to lint \(url.relativePath): file is not readable or does not exist." - ) - return - } +// let url = fileToProcess.url +// guard let source = fileToProcess.sourceText else { +// diagnosticsEngine.emitError( +// "Unable to lint \(url.relativePath): file is not readable or does not exist." +// ) +// return +// } - do { - try linter.lint( - source: source, - assumingFileURL: url, - experimentalFeatures: Set(lintFormatOptions.experimentalFeatures) - ) { (diagnostic, location) in - guard !self.lintFormatOptions.ignoreUnparsableFiles else { - // No diagnostics should be emitted in this mode. - return - } - self.diagnosticsEngine.consumeParserDiagnostic(diagnostic, location) - } - } catch SwiftFormatError.fileContainsInvalidSyntax { - guard !lintFormatOptions.ignoreUnparsableFiles else { - // The caller wants to silently ignore this error. - return - } - // Otherwise, relevant diagnostics about the problematic nodes have already been emitted; we - // don't need to print anything else. - } catch { - diagnosticsEngine.emitError("Unable to lint \(url.relativePath): \(error.localizedDescription).") - } - } -} +// do { +// try linter.lint( +// source: source, +// assumingFileURL: url, +// experimentalFeatures: Set(lintFormatOptions.experimentalFeatures) +// ) { (diagnostic, location) in +// guard !self.lintFormatOptions.ignoreUnparsableFiles else { +// // No diagnostics should be emitted in this mode. +// return +// } +// self.diagnosticsEngine.consumeParserDiagnostic(diagnostic, location) +// } +// } catch SwiftFormatError.fileContainsInvalidSyntax { +// guard !lintFormatOptions.ignoreUnparsableFiles else { +// // The caller wants to silently ignore this error. +// return +// } +// // Otherwise, relevant diagnostics about the problematic nodes have already been emitted; we +// // don't need to print anything else. +// } catch { +// diagnosticsEngine.emitError("Unable to lint \(url.relativePath): \(error.localizedDescription).") +// } +// } +// } diff --git a/Sources/swift-format/PrintVersion.swift b/Sources/swift-format/PrintVersion.swift index 15b90e48a..4a8b6fb28 100644 --- a/Sources/swift-format/PrintVersion.swift +++ b/Sources/swift-format/PrintVersion.swift @@ -1,16 +1,16 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -func printVersionInformation() { - // TODO: Automate updates to this somehow. - print("main") -} +// func printVersionInformation() { +// // TODO: Automate updates to this somehow. +// print("main") +// } diff --git a/Sources/swift-format/Subcommands/ConfigurationOptions.swift b/Sources/swift-format/Subcommands/ConfigurationOptions.swift index 1025715e9..5c4a5854a 100644 --- a/Sources/swift-format/Subcommands/ConfigurationOptions.swift +++ b/Sources/swift-format/Subcommands/ConfigurationOptions.swift @@ -1,28 +1,28 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import ArgumentParser +// import ArgumentParser -/// Common arguments used by the `lint`, `format` and `dump-configuration` subcommands. -struct ConfigurationOptions: ParsableArguments { - /// The path to the JSON configuration file that should be loaded. - /// - /// If not specified, the default configuration will be used. - @Option( - name: .customLong("configuration"), - help: """ - The path to a JSON file containing the configuration of the linter/formatter or a JSON string containing the \ - configuration directly. - """ - ) - var configuration: String? -} +// /// Common arguments used by the `lint`, `format` and `dump-configuration` subcommands. +// struct ConfigurationOptions: ParsableArguments { +// /// The path to the JSON configuration file that should be loaded. +// /// +// /// If not specified, the default configuration will be used. +// @Option( +// name: .customLong("configuration"), +// help: """ +// The path to a JSON file containing the configuration of the linter/formatter or a JSON string containing the \ +// configuration directly. +// """ +// ) +// var configuration: String? +// } diff --git a/Sources/swift-format/Subcommands/DumpConfiguration.swift b/Sources/swift-format/Subcommands/DumpConfiguration.swift index 3104ed588..78131d1c1 100644 --- a/Sources/swift-format/Subcommands/DumpConfiguration.swift +++ b/Sources/swift-format/Subcommands/DumpConfiguration.swift @@ -1,73 +1,73 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import ArgumentParser -import Foundation -import SwiftFormat +// import ArgumentParser +// import Foundation +// import SwiftFormat -extension SwiftFormatCommand { - /// Dumps the tool's configuration in JSON format to standard output. - struct DumpConfiguration: ParsableCommand { - static var configuration = CommandConfiguration( - abstract: "Dump the configuration in JSON format to standard output", - discussion: """ - Without any options, dumps the default configuration. When '--effective' is set, dumps the configuration that \ - would be used if swift-format was executed from the current working directory (cwd), incorporating \ - configuration files found in the cwd or its parents, or input from the '--configuration' option. - """ - ) +// extension SwiftFormatCommand { +// /// Dumps the tool's configuration in JSON format to standard output. +// struct DumpConfiguration: ParsableCommand { +// static var configuration = CommandConfiguration( +// abstract: "Dump the configuration in JSON format to standard output", +// discussion: """ +// Without any options, dumps the default configuration. When '--effective' is set, dumps the configuration that \ +// would be used if swift-format was executed from the current working directory (cwd), incorporating \ +// configuration files found in the cwd or its parents, or input from the '--configuration' option. +// """ +// ) - /// Whether or not to dump the effective configuration. - @Flag(name: .shortAndLong, help: "Dump the effective instead of the default configuration.") - var effective: Bool = false +// /// Whether or not to dump the effective configuration. +// @Flag(name: .shortAndLong, help: "Dump the effective instead of the default configuration.") +// var effective: Bool = false - @OptionGroup() - var configurationOptions: ConfigurationOptions +// @OptionGroup() +// var configurationOptions: ConfigurationOptions - func validate() throws { - if configurationOptions.configuration != nil && !effective { - throw ValidationError("'--configuration' is only valid in combination with '--effective'") - } - } +// func validate() throws { +// if configurationOptions.configuration != nil && !effective { +// throw ValidationError("'--configuration' is only valid in combination with '--effective'") +// } +// } - func run() throws { - let diagnosticPrinter = StderrDiagnosticPrinter(colorMode: .auto) - let diagnosticsEngine = DiagnosticsEngine(diagnosticsHandlers: [diagnosticPrinter.printDiagnostic]) +// func run() throws { +// let diagnosticPrinter = StderrDiagnosticPrinter(colorMode: .auto) +// let diagnosticsEngine = DiagnosticsEngine(diagnosticsHandlers: [diagnosticPrinter.printDiagnostic]) - let configuration: Configuration - if effective { - var configurationProvider = Frontend.ConfigurationProvider(diagnosticsEngine: diagnosticsEngine) +// let configuration: Configuration +// if effective { +// var configurationProvider = Frontend.ConfigurationProvider(diagnosticsEngine: diagnosticsEngine) - guard - let effectiveConfiguration = configurationProvider.provide( - forConfigPathOrString: configurationOptions.configuration, - orForSwiftFileAt: nil - ) - else { - // Already diagnosed in the called method through the diagnosticsEngine. - throw ExitCode.failure - } +// guard +// let effectiveConfiguration = configurationProvider.provide( +// forConfigPathOrString: configurationOptions.configuration, +// orForSwiftFileAt: nil +// ) +// else { +// // Already diagnosed in the called method through the diagnosticsEngine. +// throw ExitCode.failure +// } - configuration = effectiveConfiguration - } else { - configuration = Configuration() - } +// configuration = effectiveConfiguration +// } else { +// configuration = Configuration() +// } - do { - print(try configuration.asJsonString()) - } catch { - diagnosticsEngine.emitError("\(error.localizedDescription)") - throw ExitCode.failure - } - } - } -} +// do { +// print(try configuration.asJsonString()) +// } catch { +// diagnosticsEngine.emitError("\(error.localizedDescription)") +// throw ExitCode.failure +// } +// } +// } +// } diff --git a/Sources/swift-format/Subcommands/Format.swift b/Sources/swift-format/Subcommands/Format.swift index 59da36ffb..bae58ad22 100644 --- a/Sources/swift-format/Subcommands/Format.swift +++ b/Sources/swift-format/Subcommands/Format.swift @@ -1,59 +1,59 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import ArgumentParser - -extension SwiftFormatCommand { - /// Formats one or more files containing Swift code. - struct Format: ParsableCommand { - static var configuration = CommandConfiguration( - abstract: "Format Swift source code", - discussion: "When no files are specified, it expects the source from standard input." - ) - - /// Whether or not to format the Swift file in-place. - /// - /// If specified, the current file is overwritten when formatting. - @Flag( - name: .shortAndLong, - help: "Overwrite the current file when formatting." - ) - var inPlace: Bool = false - - @OptionGroup() - var configurationOptions: ConfigurationOptions - - @OptionGroup() - var formatOptions: LintFormatOptions - - @OptionGroup(visibility: .hidden) - var performanceMeasurementOptions: PerformanceMeasurementsOptions - - func validate() throws { - if inPlace && formatOptions.paths.isEmpty { - throw ValidationError("'--in-place' is only valid when formatting files") - } - } - - func run() throws { - try performanceMeasurementOptions.printingInstructionCountIfRequested() { - let frontend = FormatFrontend( - configurationOptions: configurationOptions, - lintFormatOptions: formatOptions, - inPlace: inPlace - ) - frontend.run() - if frontend.diagnosticsEngine.hasErrors { throw ExitCode.failure } - } - } - } -} +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// + +// import ArgumentParser + +// extension SwiftFormatCommand { +// /// Formats one or more files containing Swift code. +// struct Format: ParsableCommand { +// static var configuration = CommandConfiguration( +// abstract: "Format Swift source code", +// discussion: "When no files are specified, it expects the source from standard input." +// ) + +// /// Whether or not to format the Swift file in-place. +// /// +// /// If specified, the current file is overwritten when formatting. +// @Flag( +// name: .shortAndLong, +// help: "Overwrite the current file when formatting." +// ) +// var inPlace: Bool = false + +// @OptionGroup() +// var configurationOptions: ConfigurationOptions + +// @OptionGroup() +// var formatOptions: LintFormatOptions + +// @OptionGroup(visibility: .hidden) +// var performanceMeasurementOptions: PerformanceMeasurementsOptions + +// func validate() throws { +// if inPlace && formatOptions.paths.isEmpty { +// throw ValidationError("'--in-place' is only valid when formatting files") +// } +// } + +// func run() throws { +// try performanceMeasurementOptions.printingInstructionCountIfRequested() { +// let frontend = FormatFrontend( +// configurationOptions: configurationOptions, +// lintFormatOptions: formatOptions, +// inPlace: inPlace +// ) +// frontend.run() +// if frontend.diagnosticsEngine.hasErrors { throw ExitCode.failure } +// } +// } +// } +// } diff --git a/Sources/swift-format/Subcommands/Lint.swift b/Sources/swift-format/Subcommands/Lint.swift index 0f6c9bfaf..a8552e15e 100644 --- a/Sources/swift-format/Subcommands/Lint.swift +++ b/Sources/swift-format/Subcommands/Lint.swift @@ -1,57 +1,57 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import ArgumentParser - -extension SwiftFormatCommand { - /// Emits style diagnostics for one or more files containing Swift code. - struct Lint: ParsableCommand { - static var configuration = CommandConfiguration( - abstract: "Diagnose style issues in Swift source code", - discussion: "When no files are specified, it expects the source from standard input." - ) - - @OptionGroup() - var configurationOptions: ConfigurationOptions - - @OptionGroup() - var lintOptions: LintFormatOptions - - @Flag( - name: .shortAndLong, - help: "Fail on warnings. Deprecated: All findings are treated as errors now." - ) - var strict: Bool = false - - @OptionGroup(visibility: .hidden) - var performanceMeasurementOptions: PerformanceMeasurementsOptions - - func run() throws { - try performanceMeasurementOptions.printingInstructionCountIfRequested { - let frontend = LintFrontend(configurationOptions: configurationOptions, lintFormatOptions: lintOptions) - - if strict { - frontend.diagnosticsEngine.emitWarning( - """ - Running swift-format with --strict is deprecated and will be removed in the future. - """ - ) - } - frontend.run() - - if frontend.diagnosticsEngine.hasErrors { - throw ExitCode.failure - } - } - } - } -} +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// + +// import ArgumentParser + +// extension SwiftFormatCommand { +// /// Emits style diagnostics for one or more files containing Swift code. +// struct Lint: ParsableCommand { +// static var configuration = CommandConfiguration( +// abstract: "Diagnose style issues in Swift source code", +// discussion: "When no files are specified, it expects the source from standard input." +// ) + +// @OptionGroup() +// var configurationOptions: ConfigurationOptions + +// @OptionGroup() +// var lintOptions: LintFormatOptions + +// @Flag( +// name: .shortAndLong, +// help: "Fail on warnings. Deprecated: All findings are treated as errors now." +// ) +// var strict: Bool = false + +// @OptionGroup(visibility: .hidden) +// var performanceMeasurementOptions: PerformanceMeasurementsOptions + +// func run() throws { +// try performanceMeasurementOptions.printingInstructionCountIfRequested { +// let frontend = LintFrontend(configurationOptions: configurationOptions, lintFormatOptions: lintOptions) + +// if strict { +// frontend.diagnosticsEngine.emitWarning( +// """ +// Running swift-format with --strict is deprecated and will be removed in the future. +// """ +// ) +// } +// frontend.run() + +// if frontend.diagnosticsEngine.hasErrors { +// throw ExitCode.failure +// } +// } +// } +// } +// } diff --git a/Sources/swift-format/Subcommands/LintFormatOptions.swift b/Sources/swift-format/Subcommands/LintFormatOptions.swift index 25fdcaf68..385600d71 100644 --- a/Sources/swift-format/Subcommands/LintFormatOptions.swift +++ b/Sources/swift-format/Subcommands/LintFormatOptions.swift @@ -1,149 +1,149 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import ArgumentParser -import Foundation - -/// Common arguments used by the `lint` and `format` subcommands. -struct LintFormatOptions: ParsableArguments { - /// A list of comma-separated "start:end" pairs specifying UTF-8 offsets of the ranges to format. - /// - /// If not specified, the whole file will be formatted. - @Option( - name: .long, - help: """ - A "start:end" pair specifying UTF-8 offsets of the range to format. Multiple ranges can be - formatted by specifying several --offsets arguments. - """ - ) - var offsets: [Range] = [] - - /// The filename for the source code when reading from standard input, to include in diagnostic - /// messages. - /// - /// If not specified and standard input is used, a dummy filename is used for diagnostic messages - /// about the source from standard input. - @Option(help: "When using standard input, the filename of the source to include in diagnostics.") - var assumeFilename: String? - - /// Whether or not to run the formatter/linter recursively. - /// - /// If set, we recursively run on all ".swift" files in any provided directories. - @Flag( - name: .shortAndLong, - help: "Recursively run on '.swift' files in any provided directories." - ) - var recursive: Bool = false - - /// Whether unparsable files, due to syntax errors or unrecognized syntax, should be ignored or - /// treated as containing an error. When ignored, unparsable files are output verbatim in format - /// mode and no diagnostics are raised in lint mode. When not ignored, unparsable files raise a - /// diagnostic in both format and lint mode. - @Flag( - help: """ - Ignores unparsable files, disabling all diagnostics and formatting for files that contain \ - invalid syntax. - """ - ) - var ignoreUnparsableFiles: Bool = false - - /// Whether or not to run the formatter/linter in parallel. - @Flag( - name: .shortAndLong, - help: "Process files in parallel, simultaneously across multiple cores." - ) - var parallel: Bool = false - - /// Whether colors should be used in diagnostics printed to standard error. - /// - /// If nil, color usage will be automatically detected based on whether standard error is - /// connected to a terminal or not. - @Flag( - inversion: .prefixedNo, - help: """ - Enables or disables color diagnostics when printing to standard error. The default behavior \ - if this flag is omitted is to use colors if standard error is connected to a terminal, and \ - to not use colors otherwise. - """ - ) - var colorDiagnostics: Bool? - - /// Whether symlinks should be followed. - @Flag( - help: """ - Follow symbolic links passed on the command line, or found during directory traversal when \ - using `-r/--recursive`. - """ - ) - var followSymlinks: Bool = false - - @Option( - name: .customLong("enable-experimental-feature"), - help: """ - The name of an experimental swift-syntax parser feature that should be enabled by \ - swift-format. Multiple features can be enabled by specifying this flag multiple times. - """ - ) - var experimentalFeatures: [String] = [] - - /// The list of paths to Swift source files that should be formatted or linted. - @Argument(help: "Zero or more input filenames. Use `-` for stdin.") - var paths: [String] = [] - - @Flag(help: .hidden) var debugDisablePrettyPrint: Bool = false - @Flag(help: .hidden) var debugDumpTokenStream: Bool = false - - mutating func validate() throws { - if recursive && paths.isEmpty { - throw ValidationError("'--recursive' is only valid when formatting or linting files") - } - - if assumeFilename != nil && !(paths.isEmpty || paths == ["-"]) { - throw ValidationError("'--assume-filename' is only valid when reading from stdin") - } - - if !offsets.isEmpty && paths.count > 1 { - throw ValidationError("'--offsets' is only valid when processing a single file") - } - - if !paths.isEmpty && !recursive { - for path in paths { - var isDir: ObjCBool = false - if FileManager.default.fileExists(atPath: path, isDirectory: &isDir), isDir.boolValue { - throw ValidationError( - """ - '\(path)' is a path to a directory, not a Swift source file. - Use the '--recursive' option to handle directories. - """ - ) - } - } - } - } -} - -extension Range { - public init?(argument: String) { - let pair = argument.components(separatedBy: ":") - if pair.count == 2, let start = Int(pair[0]), let end = Int(pair[1]), start <= end { - self = start..=6) -extension Range: @retroactive ExpressibleByArgument {} -#else -extension Range: ExpressibleByArgument {} -#endif +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// + +// import ArgumentParser +// import Foundation + +// /// Common arguments used by the `lint` and `format` subcommands. +// struct LintFormatOptions: ParsableArguments { +// /// A list of comma-separated "start:end" pairs specifying UTF-8 offsets of the ranges to format. +// /// +// /// If not specified, the whole file will be formatted. +// @Option( +// name: .long, +// help: """ +// A "start:end" pair specifying UTF-8 offsets of the range to format. Multiple ranges can be +// formatted by specifying several --offsets arguments. +// """ +// ) +// var offsets: [Range] = [] + +// /// The filename for the source code when reading from standard input, to include in diagnostic +// /// messages. +// /// +// /// If not specified and standard input is used, a dummy filename is used for diagnostic messages +// /// about the source from standard input. +// @Option(help: "When using standard input, the filename of the source to include in diagnostics.") +// var assumeFilename: String? + +// /// Whether or not to run the formatter/linter recursively. +// /// +// /// If set, we recursively run on all ".swift" files in any provided directories. +// @Flag( +// name: .shortAndLong, +// help: "Recursively run on '.swift' files in any provided directories." +// ) +// var recursive: Bool = false + +// /// Whether unparsable files, due to syntax errors or unrecognized syntax, should be ignored or +// /// treated as containing an error. When ignored, unparsable files are output verbatim in format +// /// mode and no diagnostics are raised in lint mode. When not ignored, unparsable files raise a +// /// diagnostic in both format and lint mode. +// @Flag( +// help: """ +// Ignores unparsable files, disabling all diagnostics and formatting for files that contain \ +// invalid syntax. +// """ +// ) +// var ignoreUnparsableFiles: Bool = false + +// /// Whether or not to run the formatter/linter in parallel. +// @Flag( +// name: .shortAndLong, +// help: "Process files in parallel, simultaneously across multiple cores." +// ) +// var parallel: Bool = false + +// /// Whether colors should be used in diagnostics printed to standard error. +// /// +// /// If nil, color usage will be automatically detected based on whether standard error is +// /// connected to a terminal or not. +// @Flag( +// inversion: .prefixedNo, +// help: """ +// Enables or disables color diagnostics when printing to standard error. The default behavior \ +// if this flag is omitted is to use colors if standard error is connected to a terminal, and \ +// to not use colors otherwise. +// """ +// ) +// var colorDiagnostics: Bool? + +// /// Whether symlinks should be followed. +// @Flag( +// help: """ +// Follow symbolic links passed on the command line, or found during directory traversal when \ +// using `-r/--recursive`. +// """ +// ) +// var followSymlinks: Bool = false + +// @Option( +// name: .customLong("enable-experimental-feature"), +// help: """ +// The name of an experimental swift-syntax parser feature that should be enabled by \ +// swift-format. Multiple features can be enabled by specifying this flag multiple times. +// """ +// ) +// var experimentalFeatures: [String] = [] + +// /// The list of paths to Swift source files that should be formatted or linted. +// @Argument(help: "Zero or more input filenames. Use `-` for stdin.") +// var paths: [String] = [] + +// @Flag(help: .hidden) var debugDisablePrettyPrint: Bool = false +// @Flag(help: .hidden) var debugDumpTokenStream: Bool = false + +// mutating func validate() throws { +// if recursive && paths.isEmpty { +// throw ValidationError("'--recursive' is only valid when formatting or linting files") +// } + +// if assumeFilename != nil && !(paths.isEmpty || paths == ["-"]) { +// throw ValidationError("'--assume-filename' is only valid when reading from stdin") +// } + +// if !offsets.isEmpty && paths.count > 1 { +// throw ValidationError("'--offsets' is only valid when processing a single file") +// } + +// if !paths.isEmpty && !recursive { +// for path in paths { +// var isDir: ObjCBool = false +// if FileManager.default.fileExists(atPath: path, isDirectory: &isDir), isDir.boolValue { +// throw ValidationError( +// """ +// '\(path)' is a path to a directory, not a Swift source file. +// Use the '--recursive' option to handle directories. +// """ +// ) +// } +// } +// } +// } +// } + +// extension Range { +// public init?(argument: String) { +// let pair = argument.components(separatedBy: ":") +// if pair.count == 2, let start = Int(pair[0]), let end = Int(pair[1]), start <= end { +// self = start..=6) +// extension Range: @retroactive ExpressibleByArgument {} +// #else +// extension Range: ExpressibleByArgument {} +// #endif diff --git a/Sources/swift-format/Subcommands/PerformanceMeasurement.swift b/Sources/swift-format/Subcommands/PerformanceMeasurement.swift index a230aa052..96e3e93e9 100644 --- a/Sources/swift-format/Subcommands/PerformanceMeasurement.swift +++ b/Sources/swift-format/Subcommands/PerformanceMeasurement.swift @@ -1,33 +1,33 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import ArgumentParser -import _SwiftFormatInstructionCounter +// import ArgumentParser +// import _SwiftFormatInstructionCounter -struct PerformanceMeasurementsOptions: ParsableArguments { - @Flag(help: "Measure number of instructions executed by swift-format") - var measureInstructions = false +// struct PerformanceMeasurementsOptions: ParsableArguments { +// @Flag(help: "Measure number of instructions executed by swift-format") +// var measureInstructions = false - /// If `measureInstructions` is set, execute `body` and print the number of instructions - /// executed by it. Otherwise, just execute `body` - func printingInstructionCountIfRequested(_ body: () throws -> T) rethrows -> T { - if !measureInstructions { - return try body() - } else { - let startInstructions = getInstructionsExecuted() - defer { - print("Instructions executed: \(getInstructionsExecuted() - startInstructions)") - } - return try body() - } - } -} +// /// If `measureInstructions` is set, execute `body` and print the number of instructions +// /// executed by it. Otherwise, just execute `body` +// func printingInstructionCountIfRequested(_ body: () throws -> T) rethrows -> T { +// if !measureInstructions { +// return try body() +// } else { +// let startInstructions = getInstructionsExecuted() +// defer { +// print("Instructions executed: \(getInstructionsExecuted() - startInstructions)") +// } +// return try body() +// } +// } +// } diff --git a/Sources/swift-format/SwiftFormatCommand.swift b/Sources/swift-format/SwiftFormatCommand.swift index 5b814a159..09e78d0ee 100644 --- a/Sources/swift-format/SwiftFormatCommand.swift +++ b/Sources/swift-format/SwiftFormatCommand.swift @@ -10,23 +10,9 @@ // //===----------------------------------------------------------------------===// -import ArgumentParser - -/// Collects the command line options that were passed to `swift-format` and dispatches to the -/// appropriate subcommand. @main -struct SwiftFormatCommand: ParsableCommand { - static var configuration = CommandConfiguration( - commandName: "swift-format", - abstract: "Format or lint Swift source code", - subcommands: [ - DumpConfiguration.self, - Format.self, - Lint.self, - ], - defaultSubcommand: Format.self - ) +struct SwiftFormatCommand { + static func main() { - @OptionGroup() - var versionOptions: VersionOptions + } } diff --git a/Sources/swift-format/Utilities/Diagnostic.swift b/Sources/swift-format/Utilities/Diagnostic.swift index 636190046..c5b603fab 100644 --- a/Sources/swift-format/Utilities/Diagnostic.swift +++ b/Sources/swift-format/Utilities/Diagnostic.swift @@ -1,80 +1,80 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import SwiftFormat -import SwiftSyntax +// import SwiftFormat +// import SwiftSyntax -/// Diagnostic data that retains the separation of a finding category (if present) from the rest of -/// the message, allowing diagnostic printers that want to print those values separately to do so. -struct Diagnostic { - /// The severity of the diagnostic. - enum Severity { - case note - case warning - case error - } +// /// Diagnostic data that retains the separation of a finding category (if present) from the rest of +// /// the message, allowing diagnostic printers that want to print those values separately to do so. +// struct Diagnostic { +// /// The severity of the diagnostic. +// enum Severity { +// case note +// case warning +// case error +// } - /// Represents the location of a diagnostic. - struct Location { - /// The file path associated with the diagnostic. - var file: String +// /// Represents the location of a diagnostic. +// struct Location { +// /// The file path associated with the diagnostic. +// var file: String - /// The 1-based line number where the diagnostic occurred. - var line: Int +// /// The 1-based line number where the diagnostic occurred. +// var line: Int - /// The 1-based column number where the diagnostic occurred. - var column: Int +// /// The 1-based column number where the diagnostic occurred. +// var column: Int - /// Creates a new diagnostic location from the given source location. - init(_ sourceLocation: SourceLocation) { - self.file = sourceLocation.file - self.line = sourceLocation.line - self.column = sourceLocation.column - } +// /// Creates a new diagnostic location from the given source location. +// init(_ sourceLocation: SourceLocation) { +// self.file = sourceLocation.file +// self.line = sourceLocation.line +// self.column = sourceLocation.column +// } - /// Creates a new diagnostic location with the given finding location. - init(_ findingLocation: Finding.Location) { - self.file = findingLocation.file - self.line = findingLocation.line - self.column = findingLocation.column - } - } +// /// Creates a new diagnostic location with the given finding location. +// init(_ findingLocation: Finding.Location) { +// self.file = findingLocation.file +// self.line = findingLocation.line +// self.column = findingLocation.column +// } +// } - /// The severity of the diagnostic. - var severity: Severity +// /// The severity of the diagnostic. +// var severity: Severity - /// The location where the diagnostic occurred, if known. - var location: Location? +// /// The location where the diagnostic occurred, if known. +// var location: Location? - /// The category of the diagnostic, if any. - var category: String? +// /// The category of the diagnostic, if any. +// var category: String? - /// The message text associated with the diagnostic. - var message: String +// /// The message text associated with the diagnostic. +// var message: String - var description: String { - if let category = category { - return "[\(category)] \(message)" - } else { - return message - } - } +// var description: String { +// if let category = category { +// return "[\(category)] \(message)" +// } else { +// return message +// } +// } - /// Creates a new diagnostic with the given severity, location, optional category, and - /// message. - init(severity: Severity, location: Location?, category: String? = nil, message: String) { - self.severity = severity - self.location = location - self.category = category - self.message = message - } -} +// /// Creates a new diagnostic with the given severity, location, optional category, and +// /// message. +// init(severity: Severity, location: Location?, category: String? = nil, message: String) { +// self.severity = severity +// self.location = location +// self.category = category +// self.message = message +// } +// } diff --git a/Sources/swift-format/Utilities/DiagnosticsEngine.swift b/Sources/swift-format/Utilities/DiagnosticsEngine.swift index d014c8129..9437bdd1d 100644 --- a/Sources/swift-format/Utilities/DiagnosticsEngine.swift +++ b/Sources/swift-format/Utilities/DiagnosticsEngine.swift @@ -1,144 +1,144 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import SwiftDiagnostics -import SwiftFormat -import SwiftSyntax +// import SwiftDiagnostics +// import SwiftFormat +// import SwiftSyntax -/// Unifies the handling of findings from the linter, parsing errors from the syntax parser, and -/// generic errors from the frontend so that they are emitted in a uniform fashion. -final class DiagnosticsEngine { - /// The handler functions that will be called to process diagnostics that are emitted. - private let handlers: [(Diagnostic) -> Void] +// /// Unifies the handling of findings from the linter, parsing errors from the syntax parser, and +// /// generic errors from the frontend so that they are emitted in a uniform fashion. +// final class DiagnosticsEngine { +// /// The handler functions that will be called to process diagnostics that are emitted. +// private let handlers: [(Diagnostic) -> Void] - /// A Boolean value indicating whether any errors were emitted by the diagnostics engine. - private(set) var hasErrors: Bool +// /// A Boolean value indicating whether any errors were emitted by the diagnostics engine. +// private(set) var hasErrors: Bool - /// A Boolean value indicating whether any warnings were emitted by the diagnostics engine. - private(set) var hasWarnings: Bool +// /// A Boolean value indicating whether any warnings were emitted by the diagnostics engine. +// private(set) var hasWarnings: Bool - /// Creates a new diagnostics engine with the given diagnostic handlers. - /// - /// - Parameter diagnosticsHandlers: An array of functions, each of which takes a `Diagnostic` as - /// its sole argument and returns `Void`. The functions are called whenever a diagnostic is - /// received by the engine. - init(diagnosticsHandlers: [(Diagnostic) -> Void]) { - self.handlers = diagnosticsHandlers - self.hasErrors = false - self.hasWarnings = false - } +// /// Creates a new diagnostics engine with the given diagnostic handlers. +// /// +// /// - Parameter diagnosticsHandlers: An array of functions, each of which takes a `Diagnostic` as +// /// its sole argument and returns `Void`. The functions are called whenever a diagnostic is +// /// received by the engine. +// init(diagnosticsHandlers: [(Diagnostic) -> Void]) { +// self.handlers = diagnosticsHandlers +// self.hasErrors = false +// self.hasWarnings = false +// } - /// Emits the diagnostic by passing it to the registered handlers, and tracks whether it was an - /// error or warning diagnostic. - private func emit(_ diagnostic: Diagnostic) { - switch diagnostic.severity { - case .error: self.hasErrors = true - case .warning: self.hasWarnings = true - default: break - } +// /// Emits the diagnostic by passing it to the registered handlers, and tracks whether it was an +// /// error or warning diagnostic. +// private func emit(_ diagnostic: Diagnostic) { +// switch diagnostic.severity { +// case .error: self.hasErrors = true +// case .warning: self.hasWarnings = true +// default: break +// } - for handler in handlers { - handler(diagnostic) - } - } +// for handler in handlers { +// handler(diagnostic) +// } +// } - /// Emits a generic error message. - /// - /// - Parameters: - /// - message: The message associated with the error. - /// - location: The location in the source code associated with the error, or nil if there is no - /// location associated with the error. - func emitError(_ message: String, location: SourceLocation? = nil) { - emit( - Diagnostic( - severity: .error, - location: location.map(Diagnostic.Location.init), - message: message - ) - ) - } +// /// Emits a generic error message. +// /// +// /// - Parameters: +// /// - message: The message associated with the error. +// /// - location: The location in the source code associated with the error, or nil if there is no +// /// location associated with the error. +// func emitError(_ message: String, location: SourceLocation? = nil) { +// emit( +// Diagnostic( +// severity: .error, +// location: location.map(Diagnostic.Location.init), +// message: message +// ) +// ) +// } - /// Emits a generic warning message. - /// - /// - Parameters: - /// - message: The message associated with the error. - /// - location: The location in the source code associated with the error, or nil if there is no - /// location associated with the error. - func emitWarning(_ message: String, location: SourceLocation? = nil) { - emit( - Diagnostic( - severity: .warning, - location: location.map(Diagnostic.Location.init), - message: message - ) - ) - } +// /// Emits a generic warning message. +// /// +// /// - Parameters: +// /// - message: The message associated with the error. +// /// - location: The location in the source code associated with the error, or nil if there is no +// /// location associated with the error. +// func emitWarning(_ message: String, location: SourceLocation? = nil) { +// emit( +// Diagnostic( +// severity: .warning, +// location: location.map(Diagnostic.Location.init), +// message: message +// ) +// ) +// } - /// Emits a finding from the linter and any of its associated notes as diagnostics. - /// - /// - Parameter finding: The finding that should be emitted. - func consumeFinding(_ finding: Finding) { - emit(diagnosticMessage(for: finding)) +// /// Emits a finding from the linter and any of its associated notes as diagnostics. +// /// +// /// - Parameter finding: The finding that should be emitted. +// func consumeFinding(_ finding: Finding) { +// emit(diagnosticMessage(for: finding)) - for note in finding.notes { - emit( - Diagnostic( - severity: .note, - location: note.location.map(Diagnostic.Location.init), - message: "\(note.message)" - ) - ) - } - } +// for note in finding.notes { +// emit( +// Diagnostic( +// severity: .note, +// location: note.location.map(Diagnostic.Location.init), +// message: "\(note.message)" +// ) +// ) +// } +// } - /// Emits a diagnostic from the syntax parser and any of its associated notes. - /// - /// - Parameter diagnostic: The syntax parser diagnostic that should be emitted. - func consumeParserDiagnostic( - _ diagnostic: SwiftDiagnostics.Diagnostic, - _ location: SourceLocation - ) { - emit(diagnosticMessage(for: diagnostic.diagMessage, at: location)) - } +// /// Emits a diagnostic from the syntax parser and any of its associated notes. +// /// +// /// - Parameter diagnostic: The syntax parser diagnostic that should be emitted. +// func consumeParserDiagnostic( +// _ diagnostic: SwiftDiagnostics.Diagnostic, +// _ location: SourceLocation +// ) { +// emit(diagnosticMessage(for: diagnostic.diagMessage, at: location)) +// } - /// Converts a diagnostic message from the syntax parser into a diagnostic message that can be - /// used by the `TSCBasic` diagnostics engine and returns it. - private func diagnosticMessage( - for message: SwiftDiagnostics.DiagnosticMessage, - at location: SourceLocation - ) -> Diagnostic { - let severity: Diagnostic.Severity - switch message.severity { - case .error: severity = .error - case .warning: severity = .warning - case .note: severity = .note - case .remark: severity = .note // should we model this? - } - return Diagnostic( - severity: severity, - location: Diagnostic.Location(location), - category: nil, - message: message.message - ) - } +// /// Converts a diagnostic message from the syntax parser into a diagnostic message that can be +// /// used by the `TSCBasic` diagnostics engine and returns it. +// private func diagnosticMessage( +// for message: SwiftDiagnostics.DiagnosticMessage, +// at location: SourceLocation +// ) -> Diagnostic { +// let severity: Diagnostic.Severity +// switch message.severity { +// case .error: severity = .error +// case .warning: severity = .warning +// case .note: severity = .note +// case .remark: severity = .note // should we model this? +// } +// return Diagnostic( +// severity: severity, +// location: Diagnostic.Location(location), +// category: nil, +// message: message.message +// ) +// } - /// Converts a lint finding into a diagnostic message that can be used by the `TSCBasic` - /// diagnostics engine and returns it. - private func diagnosticMessage(for finding: Finding) -> Diagnostic { - return Diagnostic( - severity: .error, - location: finding.location.map(Diagnostic.Location.init), - category: "\(finding.category)", - message: "\(finding.message.text)" - ) - } -} +// /// Converts a lint finding into a diagnostic message that can be used by the `TSCBasic` +// /// diagnostics engine and returns it. +// private func diagnosticMessage(for finding: Finding) -> Diagnostic { +// return Diagnostic( +// severity: .error, +// location: finding.location.map(Diagnostic.Location.init), +// category: "\(finding.category)", +// message: "\(finding.message.text)" +// ) +// } +// } diff --git a/Sources/swift-format/Utilities/FileHandleTextOutputStream.swift b/Sources/swift-format/Utilities/FileHandleTextOutputStream.swift index b36480ef2..6cef7bb95 100644 --- a/Sources/swift-format/Utilities/FileHandleTextOutputStream.swift +++ b/Sources/swift-format/Utilities/FileHandleTextOutputStream.swift @@ -1,29 +1,29 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import Foundation +// import Foundation -/// Wraps a `FileHandle` so that it can be used by APIs that take a `TextOutputStream`-conforming -/// type as an input. -struct FileHandleTextOutputStream: TextOutputStream { - /// The underlying file handle to which the text will be written. - private var fileHandle: FileHandle +// /// Wraps a `FileHandle` so that it can be used by APIs that take a `TextOutputStream`-conforming +// /// type as an input. +// struct FileHandleTextOutputStream: TextOutputStream { +// /// The underlying file handle to which the text will be written. +// private var fileHandle: FileHandle - /// Creates a new output stream that writes to the given file handle. - init(_ fileHandle: FileHandle) { - self.fileHandle = fileHandle - } +// /// Creates a new output stream that writes to the given file handle. +// init(_ fileHandle: FileHandle) { +// self.fileHandle = fileHandle +// } - func write(_ string: String) { - fileHandle.write(string.data(using: .utf8)!) // Conversion to UTF-8 cannot fail - } -} +// func write(_ string: String) { +// fileHandle.write(string.data(using: .utf8)!) // Conversion to UTF-8 cannot fail +// } +// } diff --git a/Sources/swift-format/Utilities/StderrDiagnosticPrinter.swift b/Sources/swift-format/Utilities/StderrDiagnosticPrinter.swift index f7730f00c..1d11d9873 100644 --- a/Sources/swift-format/Utilities/StderrDiagnosticPrinter.swift +++ b/Sources/swift-format/Utilities/StderrDiagnosticPrinter.swift @@ -1,94 +1,94 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import Dispatch -import Foundation +// import Dispatch +// import Foundation -/// Manages printing of diagnostics to standard error. -final class StderrDiagnosticPrinter { - /// Determines how colors are used in printed diagnostics. - enum ColorMode { - /// Colors are used if stderr is detected to be connected to a TTY; otherwise, colors will not - /// be used (for example, if stderr is redirected to a file). - case auto +// /// Manages printing of diagnostics to standard error. +// final class StderrDiagnosticPrinter { +// /// Determines how colors are used in printed diagnostics. +// enum ColorMode { +// /// Colors are used if stderr is detected to be connected to a TTY; otherwise, colors will not +// /// be used (for example, if stderr is redirected to a file). +// case auto - /// Colors will not be used. - case off +// /// Colors will not be used. +// case off - /// Colors will always be used. - case on - } +// /// Colors will always be used. +// case on +// } - /// Definitions of the ANSI "Select Graphic Rendition" sequences used in diagnostics. - private enum ANSISGR: String { - case boldRed = "1;31" - case boldYellow = "1;33" - case boldMagenta = "1;35" - case boldWhite = "1;37" - case boldGray = "1;90" - case reset = "0" - } +// /// Definitions of the ANSI "Select Graphic Rendition" sequences used in diagnostics. +// private enum ANSISGR: String { +// case boldRed = "1;31" +// case boldYellow = "1;33" +// case boldMagenta = "1;35" +// case boldWhite = "1;37" +// case boldGray = "1;90" +// case reset = "0" +// } - /// The queue used to synchronize printing uninterrupted diagnostic messages. - private let printQueue = DispatchQueue(label: "com.apple.swift-format.StderrDiagnosticPrinter") +// /// The queue used to synchronize printing uninterrupted diagnostic messages. +// private let printQueue = DispatchQueue(label: "com.apple.swift-format.StderrDiagnosticPrinter") - /// Indicates whether colors should be used when printing diagnostics. - private let useColors: Bool +// /// Indicates whether colors should be used when printing diagnostics. +// private let useColors: Bool - /// Creates a new standard error diagnostic printer with the given color mode. - init(colorMode: ColorMode) { - switch colorMode { - case .auto: - useColors = isTTY(FileHandle.standardError) - case .off: - useColors = false - case .on: - useColors = true - } - } +// /// Creates a new standard error diagnostic printer with the given color mode. +// init(colorMode: ColorMode) { +// switch colorMode { +// case .auto: +// useColors = isTTY(FileHandle.standardError) +// case .off: +// useColors = false +// case .on: +// useColors = true +// } +// } - /// Prints a diagnostic to standard error. - func printDiagnostic(_ diagnostic: Diagnostic) { - printQueue.sync { - let stderr = FileHandleTextOutputStream(FileHandle.standardError) +// /// Prints a diagnostic to standard error. +// func printDiagnostic(_ diagnostic: Diagnostic) { +// printQueue.sync { +// let stderr = FileHandleTextOutputStream(FileHandle.standardError) - stderr.write("\(ansiSGR(.boldWhite))\(description(of: diagnostic.location)): ") +// stderr.write("\(ansiSGR(.boldWhite))\(description(of: diagnostic.location)): ") - switch diagnostic.severity { - case .error: stderr.write("\(ansiSGR(.boldRed))error: ") - case .warning: stderr.write("\(ansiSGR(.boldMagenta))warning: ") - case .note: stderr.write("\(ansiSGR(.boldGray))note: ") - } +// switch diagnostic.severity { +// case .error: stderr.write("\(ansiSGR(.boldRed))error: ") +// case .warning: stderr.write("\(ansiSGR(.boldMagenta))warning: ") +// case .note: stderr.write("\(ansiSGR(.boldGray))note: ") +// } - if let category = diagnostic.category { - stderr.write("\(ansiSGR(.boldYellow))[\(category)] ") - } - stderr.write("\(ansiSGR(.boldWhite))\(diagnostic.message)\(ansiSGR(.reset))\n") - } - } +// if let category = diagnostic.category { +// stderr.write("\(ansiSGR(.boldYellow))[\(category)] ") +// } +// stderr.write("\(ansiSGR(.boldWhite))\(diagnostic.message)\(ansiSGR(.reset))\n") +// } +// } - /// Returns a string representation of the given diagnostic location, or a fallback string if the - /// location was not known. - private func description(of location: Diagnostic.Location?) -> String { - if let location = location { - return "\(location.file):\(location.line):\(location.column)" - } - return "" - } +// /// Returns a string representation of the given diagnostic location, or a fallback string if the +// /// location was not known. +// private func description(of location: Diagnostic.Location?) -> String { +// if let location = location { +// return "\(location.file):\(location.line):\(location.column)" +// } +// return "" +// } - /// Returns the complete ANSI sequence used to enable the given SGR if colors are enabled in the - /// printer, or the empty string if colors are not enabled. - private func ansiSGR(_ ansiSGR: ANSISGR) -> String { - guard useColors else { return "" } - return "\u{001b}[\(ansiSGR.rawValue)m" - } -} +// /// Returns the complete ANSI sequence used to enable the given SGR if colors are enabled in the +// /// printer, or the empty string if colors are not enabled. +// private func ansiSGR(_ ansiSGR: ANSISGR) -> String { +// guard useColors else { return "" } +// return "\u{001b}[\(ansiSGR.rawValue)m" +// } +// } diff --git a/Sources/swift-format/Utilities/TTY.swift b/Sources/swift-format/Utilities/TTY.swift index 263770e28..83aacf464 100644 --- a/Sources/swift-format/Utilities/TTY.swift +++ b/Sources/swift-format/Utilities/TTY.swift @@ -1,33 +1,33 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import Foundation +// import Foundation -#if os(Android) -import Android -#endif +// #if os(Android) +// import Android +// #endif -/// Returns a value indicating whether or not the stream is a TTY. -func isTTY(_ fileHandle: FileHandle) -> Bool { - // The implementation of this function is adapted from `TerminalController.swift` in - // swift-tools-support-core. - #if os(Windows) - // The TSC implementation of this function only returns `.file` or `.dumb` for Windows, - // neither of which is a TTY. - return false - #else - if ProcessInfo.processInfo.environment["TERM"] == "dumb" { - return false - } - return isatty(fileHandle.fileDescriptor) != 0 - #endif -} +// /// Returns a value indicating whether or not the stream is a TTY. +// func isTTY(_ fileHandle: FileHandle) -> Bool { +// // The implementation of this function is adapted from `TerminalController.swift` in +// // swift-tools-support-core. +// #if os(Windows) +// // The TSC implementation of this function only returns `.file` or `.dumb` for Windows, +// // neither of which is a TTY. +// return false +// #else +// if ProcessInfo.processInfo.environment["TERM"] == "dumb" { +// return false +// } +// return isatty(fileHandle.fileDescriptor) != 0 +// #endif +// } diff --git a/Sources/swift-format/VersionOptions.swift b/Sources/swift-format/VersionOptions.swift index 21afa50b8..2bf8893f5 100644 --- a/Sources/swift-format/VersionOptions.swift +++ b/Sources/swift-format/VersionOptions.swift @@ -1,26 +1,26 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// +// //===----------------------------------------------------------------------===// +// // +// // This source file is part of the Swift.org open source project +// // +// // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// // Licensed under Apache License v2.0 with Runtime Library Exception +// // +// // See https://swift.org/LICENSE.txt for license information +// // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// // +// //===----------------------------------------------------------------------===// -import ArgumentParser +// import ArgumentParser -/// Encapsulates `--version` flag behavior. -struct VersionOptions: ParsableArguments { - @Flag(name: .shortAndLong, help: "Print the version and exit") - var version: Bool = false +// /// Encapsulates `--version` flag behavior. +// struct VersionOptions: ParsableArguments { +// @Flag(name: .shortAndLong, help: "Print the version and exit") +// var version: Bool = false - func validate() throws { - if version { - printVersionInformation() - throw ExitCode.success - } - } -} +// func validate() throws { +// if version { +// printVersionInformation() +// throw ExitCode.success +// } +// } +// }