Skip to content

Merge main into release/6.0 #760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
eec6403
Handle indented block comments with ASCII art correctly.
shawnhyam May 28, 2024
6640067
Support for formatting a selection (given as an array of ranges) <htt…
DaveEwing Mar 21, 2024
88beb85
Some small refectorings and updates from review feedback. Add a few m…
DaveEwing Jun 3, 2024
0c0977d
Change the `--offsets` argument to take a single pair of offsets, and…
DaveEwing Jun 4, 2024
2541a14
Fix `@_expose` attribute argument spacing
kateinoigakukun Jun 14, 2024
53279ee
Merge pull request #708 from apple/dewing/FormatRanges
allevato Jun 14, 2024
ee3a4be
Merge pull request #750 from kateinoigakukun/katei/fix-expose-attribute
allevato Jun 17, 2024
d46e30f
Merge pull request #746 from shawnhyam/handle-block-comment-indentation
allevato Jun 17, 2024
95d85a2
add support for riscv64
futurejones Jun 18, 2024
ae0922d
Delete CODE_OF_CONDUCT.md
parispittman Jun 24, 2024
981c130
Delete CONTRIBUTING.md
parispittman Jun 24, 2024
1ca1b53
Update README.md
parispittman Jun 24, 2024
824ac89
Merge pull request #753 from swiftlang/parispittman-patch-1
shahmishal Jun 25, 2024
ee5e8c6
Merge pull request #755 from swiftlang/parispittman-patch-3
shahmishal Jun 25, 2024
cef7eca
Update links for repositories moved to the swiftlang org on GitHub
ahoppen Jun 25, 2024
56fa13b
Update README.md to mention that swift-format is included in Xcode 16
ahoppen Jun 25, 2024
4cd4380
Merge pull request #754 from swiftlang/parispittman-patch-2
ahoppen Jun 25, 2024
0ac5bbc
Merge pull request #757 from ahoppen/swiftlang-migration
ahoppen Jun 25, 2024
16dc01a
Merge pull request #756 from ahoppen/swift-format-in-xcode
ahoppen Jun 25, 2024
8be2ab2
Merge pull request #752 from futurejones/add-riscv64-support
ahoppen Jun 26, 2024
c44c92b
Merge branch 'main' into 6.0/cherry-pick-2024-06-27
ahoppen Jun 27, 2024
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
55 changes: 0 additions & 55 deletions CODE_OF_CONDUCT.md

This file was deleted.

11 changes: 0 additions & 11 deletions CONTRIBUTING.md

This file was deleted.

28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ For example, if you are using Xcode 13.3 (Swift 5.6), you will need
## Getting swift-format

If you are mainly interested in using swift-format (rather than developing it),
then you can get swift-format either via [Homebrew](https://brew.sh/) or by checking out the
source and building it.
then you can get it in three different ways:

### Included in Xcode

Xcode 16 and above include swift-format in the toolchain. You can run `swift-format` from anywhere on the system using `swift format` (notice the space instead of dash). To find the path at which `swift-format` is installed, run `xcrun --find swift-format`.

### Installing via Homebrew

Expand Down Expand Up @@ -251,3 +254,24 @@ been merged into `main`.

If you are interested in developing `swift-format`, there is additional
documentation about that [here](Documentation/Development.md).

## Contributing

Contributions to Swift are welcomed and encouraged! Please see the
[Contributing to Swift guide](https://swift.org/contributing/).

Before submitting the pull request, please make sure you have [tested your
changes](https://github.com/apple/swift/blob/main/docs/ContinuousIntegration.md)
and that they follow the Swift project [guidelines for contributing
code](https://swift.org/contributing/#contributing-code).

To be a truly great community, [Swift.org](https://swift.org/) needs to welcome
developers from all walks of life, with different backgrounds, and with a wide
range of experience. A diverse and friendly community will have more great
ideas, more unique perspectives, and produce more great code. We will work
diligently to make the Swift community welcoming to everyone.

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/).
63 changes: 63 additions & 0 deletions Sources/SwiftFormat/API/Selection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 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 SwiftSyntax

/// The selection as given on the command line - an array of offets and lengths
public enum Selection {
case infinite
case ranges([Range<AbsolutePosition>])

/// Create a selection from an array of utf8 ranges. An empty array means an infinite selection.
public init(offsetRanges: [Range<Int>]) {
if offsetRanges.isEmpty {
self = .infinite
} else {
let ranges = offsetRanges.map {
AbsolutePosition(utf8Offset: $0.lowerBound) ..< AbsolutePosition(utf8Offset: $0.upperBound)
}
self = .ranges(ranges)
}
}

public func contains(_ position: AbsolutePosition) -> Bool {
switch self {
case .infinite:
return true
case .ranges(let ranges):
return ranges.contains { $0.contains(position) }
}
}

public func overlapsOrTouches(_ range: Range<AbsolutePosition>) -> Bool {
switch self {
case .infinite:
return true
case .ranges(let ranges):
return ranges.contains { $0.overlapsOrTouches(range) }
}
}
}


public extension Syntax {
/// - Returns: `true` if the node is _completely_ inside any range in the selection
func isInsideSelection(_ selection: Selection) -> Bool {
switch selection {
case .infinite:
return true
case .ranges(let ranges):
return ranges.contains { return $0.lowerBound <= position && endPosition <= $0.upperBound }
}
}
}
28 changes: 13 additions & 15 deletions Sources/SwiftFormat/API/SwiftFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Copyright (c) 2014 - 2024 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
Expand Down Expand Up @@ -70,6 +70,7 @@ public final class SwiftFormatter {
try format(
source: String(contentsOf: url, encoding: .utf8),
assumingFileURL: url,
selection: .infinite,
to: &outputStream,
parsingDiagnosticHandler: parsingDiagnosticHandler)
}
Expand All @@ -86,6 +87,7 @@ public final class SwiftFormatter {
/// - url: A file URL denoting the filename/path that should be assumed for this syntax tree,
/// which is associated with any diagnostics emitted during formatting. If this is nil, a
/// dummy value will be used.
/// - selection: The ranges to format
/// - outputStream: A value conforming to `TextOutputStream` to which the formatted output will
/// be written.
/// - parsingDiagnosticHandler: An optional callback that will be notified if there are any
Expand All @@ -94,6 +96,7 @@ public final class SwiftFormatter {
public func format<Output: TextOutputStream>(
source: String,
assumingFileURL url: URL?,
selection: Selection,
to outputStream: inout Output,
parsingDiagnosticHandler: ((Diagnostic, SourceLocation) -> Void)? = nil
) throws {
Expand All @@ -108,8 +111,8 @@ public final class SwiftFormatter {
assumingFileURL: url,
parsingDiagnosticHandler: parsingDiagnosticHandler)
try format(
syntax: sourceFile, operatorTable: .standardOperators, assumingFileURL: url, source: source,
to: &outputStream)
syntax: sourceFile, source: source, operatorTable: .standardOperators, assumingFileURL: url,
selection: selection, to: &outputStream)
}

/// Formats the given Swift syntax tree and writes the result to an output stream.
Expand All @@ -122,32 +125,26 @@ public final class SwiftFormatter {
///
/// - Parameters:
/// - syntax: The Swift syntax tree to be converted to source code and formatted.
/// - source: The original Swift source code used to build the syntax tree.
/// - operatorTable: The table that defines the operators and their precedence relationships.
/// This must be the same operator table that was used to fold the expressions in the `syntax`
/// argument.
/// - url: A file URL denoting the filename/path that should be assumed for this syntax tree,
/// which is associated with any diagnostics emitted during formatting. If this is nil, a
/// dummy value will be used.
/// - selection: The ranges to format
/// - outputStream: A value conforming to `TextOutputStream` to which the formatted output will
/// be written.
/// - Throws: If an unrecoverable error occurs when formatting the code.
public func format<Output: TextOutputStream>(
syntax: SourceFileSyntax, operatorTable: OperatorTable, assumingFileURL url: URL?,
to outputStream: inout Output
) throws {
try format(
syntax: syntax, operatorTable: operatorTable, assumingFileURL: url, source: nil,
to: &outputStream)
}

private func format<Output: TextOutputStream>(
syntax: SourceFileSyntax, operatorTable: OperatorTable,
assumingFileURL url: URL?, source: String?, to outputStream: inout Output
syntax: SourceFileSyntax, source: String, operatorTable: OperatorTable,
assumingFileURL url: URL?, selection: Selection, to outputStream: inout Output
) throws {
let assumedURL = url ?? URL(fileURLWithPath: "source")
let context = Context(
configuration: configuration, operatorTable: operatorTable, findingConsumer: findingConsumer,
fileURL: assumedURL, sourceFileSyntax: syntax, source: source, ruleNameCache: ruleNameCache)
fileURL: assumedURL, selection: selection, sourceFileSyntax: syntax, source: source,
ruleNameCache: ruleNameCache)
let pipeline = FormatPipeline(context: context)
let transformedSyntax = pipeline.rewrite(Syntax(syntax))

Expand All @@ -158,6 +155,7 @@ public final class SwiftFormatter {

let printer = PrettyPrinter(
context: context,
source: source,
node: transformedSyntax,
printTokenStream: debugOptions.contains(.dumpTokenStream),
whitespaceOnly: false)
Expand Down
6 changes: 4 additions & 2 deletions Sources/SwiftFormat/API/SwiftLinter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,18 @@ public final class SwiftLinter {
/// - Throws: If an unrecoverable error occurs when formatting the code.
public func lint(
syntax: SourceFileSyntax,
source: String,
operatorTable: OperatorTable,
assumingFileURL url: URL
) throws {
try lint(syntax: syntax, operatorTable: operatorTable, assumingFileURL: url, source: nil)
try lint(syntax: syntax, operatorTable: operatorTable, assumingFileURL: url, source: source)
}

private func lint(
syntax: SourceFileSyntax,
operatorTable: OperatorTable,
assumingFileURL url: URL,
source: String?
source: String
) throws {
let context = Context(
configuration: configuration, operatorTable: operatorTable, findingConsumer: findingConsumer,
Expand All @@ -145,6 +146,7 @@ public final class SwiftLinter {
// pretty-printer.
let printer = PrettyPrinter(
context: context,
source: source,
node: Syntax(syntax),
printTokenStream: debugOptions.contains(.dumpTokenStream),
whitespaceOnly: true)
Expand Down
1 change: 1 addition & 0 deletions Sources/SwiftFormat/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ add_library(SwiftFormat
API/Finding.swift
API/FindingCategorizing.swift
API/Indent.swift
API/Selection.swift
API/SwiftFormatError.swift
API/SwiftFormatter.swift
API/SwiftLinter.swift
Expand Down
13 changes: 10 additions & 3 deletions Sources/SwiftFormat/Core/Context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Copyright (c) 2014 - 2024 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
Expand Down Expand Up @@ -39,6 +39,9 @@ public final class Context {
/// The configuration for this run of the pipeline, provided by a configuration JSON file.
let configuration: Configuration

/// The selection to process
let selection: Selection

/// Defines the operators and their precedence relationships that were used during parsing.
let operatorTable: OperatorTable

Expand Down Expand Up @@ -66,6 +69,7 @@ public final class Context {
operatorTable: OperatorTable,
findingConsumer: ((Finding) -> Void)?,
fileURL: URL,
selection: Selection = .infinite,
sourceFileSyntax: SourceFileSyntax,
source: String? = nil,
ruleNameCache: [ObjectIdentifier: String]
Expand All @@ -74,6 +78,7 @@ public final class Context {
self.operatorTable = operatorTable
self.findingEmitter = FindingEmitter(consumer: findingConsumer)
self.fileURL = fileURL
self.selection = selection
self.importsXCTest = .notDetermined
let tree = source.map { Parser.parse(source: $0) } ?? sourceFileSyntax
self.sourceLocationConverter =
Expand All @@ -86,8 +91,10 @@ public final class Context {
}

/// Given a rule's name and the node it is examining, determine if the rule is disabled at this
/// location or not.
func isRuleEnabled<R: Rule>(_ rule: R.Type, node: Syntax) -> Bool {
/// location or not. Also makes sure the entire node is contained inside any selection.
func shouldFormat<R: Rule>(_ rule: R.Type, node: Syntax) -> Bool {
guard node.isInsideSelection(selection) else { return false }

let loc = node.startLocation(converter: self.sourceLocationConverter)

assert(
Expand Down
Loading