Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 1 addition & 92 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
),
]

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/).

88 changes: 44 additions & 44 deletions Sources/swift-format/Frontend/ConfigurationLoader.swift
Original file line number Diff line number Diff line change
@@ -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
// }
// }
172 changes: 86 additions & 86 deletions Sources/swift-format/Frontend/FormatFrontend.swift
Original file line number Diff line number Diff line change
@@ -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).")
// }
// }
// }
Loading
Loading