Skip to content

Commit 3172157

Browse files
authored
Merge branch 'apple:main' into fixMorePostfixPoundIfs
2 parents 4fd796f + 3cd655f commit 3172157

File tree

88 files changed

+2517
-2278
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2517
-2278
lines changed

Documentation/Configuration.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ top-level keys and values:
7979
true, a line break is forced before the "." of the component and after the component's
8080
closing delimiter (i.e. right paren, right bracket, right brace, etc.).
8181

82+
* `spacesAroundRangeFormationOperators` _(boolean)_: Determines whether whitespace should be forced
83+
before and after the range formation operators `...` and `..<`.
84+
8285
> TODO: Add support for enabling/disabling specific syntax transformations in
8386
> the pipeline.
8487

Documentation/PrettyPrinter.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,15 @@ Tokens = [docBlock(" Doc Block comment\n * Second line *")]
233233
Verbatim tokens are used to print text verbatim without any formatting apart
234234
from applying a global indentation. They have a length set to the maximum line
235235
width. They are typically used to handle syntax types that are classed as
236-
"unknown" by SwiftSyntax. In these cases, we don't have access to the
236+
"unexpected" by SwiftSyntax. In these cases, we don't have access to the
237237
substructure of the syntax node a manner useful for formatting, so we print them
238238
verbatim. The indentation for verbatim tokens is applied to the first line of
239239
the text. The relative indentation of subsequent lines is preserved unless they
240240
have less indentation than the first line, in which case we set the indentation
241241
of those lines equal to the first.
242242

243243
```
244-
// Consider "ifnt", an unknown syntax structure:
244+
// Consider "ifnt", an unexpected syntax structure:
245245
246246
if someCondition {
247247
ifnt anotherCondition {

Package.swift

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import PackageDescription
1717
let package = Package(
1818
name: "swift-format",
1919
platforms: [
20+
.iOS("13.0"),
2021
.macOS("10.15")
2122
],
2223
products: [
@@ -32,6 +33,14 @@ let package = Package(
3233
name: "SwiftFormatConfiguration",
3334
targets: ["SwiftFormatConfiguration"]
3435
),
36+
.plugin(
37+
name: "FormatPlugin",
38+
targets: ["Format Source Code"]
39+
),
40+
.plugin(
41+
name: "LintPlugin",
42+
targets: ["Lint Source Code"]
43+
),
3544
],
3645
dependencies: [
3746
// See the "Dependencies" section below.
@@ -46,7 +55,9 @@ let package = Package(
4655
"SwiftFormatRules",
4756
"SwiftFormatWhitespaceLinter",
4857
.product(name: "SwiftSyntax", package: "swift-syntax"),
58+
.product(name: "SwiftOperators", package: "swift-syntax"),
4959
.product(name: "SwiftParser", package: "swift-syntax"),
60+
.product(name: "SwiftParserDiagnostics", package: "swift-syntax"),
5061
]
5162
),
5263
.target(
@@ -56,6 +67,7 @@ let package = Package(
5667
name: "SwiftFormatCore",
5768
dependencies: [
5869
"SwiftFormatConfiguration",
70+
.product(name: "SwiftOperators", package: "swift-syntax"),
5971
.product(name: "SwiftSyntax", package: "swift-syntax"),
6072
]
6173
),
@@ -65,14 +77,19 @@ let package = Package(
6577
),
6678
.target(
6779
name: "SwiftFormatPrettyPrint",
68-
dependencies: ["SwiftFormatCore", "SwiftFormatConfiguration"]
80+
dependencies: [
81+
"SwiftFormatCore",
82+
"SwiftFormatConfiguration",
83+
.product(name: "SwiftOperators", package: "swift-syntax"),
84+
]
6985
),
7086
.target(
7187
name: "SwiftFormatTestSupport",
7288
dependencies: [
7389
"SwiftFormatCore",
7490
"SwiftFormatRules",
7591
"SwiftFormatConfiguration",
92+
.product(name: "SwiftOperators", package: "swift-syntax"),
7693
]
7794
),
7895
.target(
@@ -82,7 +99,32 @@ let package = Package(
8299
.product(name: "SwiftSyntax", package: "swift-syntax"),
83100
]
84101
),
85-
102+
.plugin(
103+
name: "Format Source Code",
104+
capability: .command(
105+
intent: .sourceCodeFormatting(),
106+
permissions: [
107+
.writeToPackageDirectory(reason: "This command formats the Swift source files")
108+
]
109+
),
110+
dependencies: [
111+
.target(name: "swift-format")
112+
],
113+
path: "Plugins/FormatPlugin"
114+
),
115+
.plugin(
116+
name: "Lint Source Code",
117+
capability: .command(
118+
intent: .custom(
119+
verb: "lint-source-code",
120+
description: "Lint source code for a specified target."
121+
)
122+
),
123+
dependencies: [
124+
.target(name: "swift-format")
125+
],
126+
path: "Plugins/LintPlugin"
127+
),
86128
.executableTarget(
87129
name: "generate-pipeline",
88130
dependencies: [
@@ -105,14 +147,6 @@ let package = Package(
105147
]
106148
),
107149

108-
.testTarget(
109-
name: "SwiftFormatTests",
110-
dependencies: [
111-
"SwiftFormat",
112-
.product(name: "SwiftSyntax", package: "swift-syntax"),
113-
.product(name: "SwiftParser", package: "swift-syntax"),
114-
]
115-
),
116150
.testTarget(
117151
name: "SwiftFormatConfigurationTests",
118152
dependencies: ["SwiftFormatConfiguration"]
@@ -144,6 +178,7 @@ let package = Package(
144178
"SwiftFormatRules",
145179
"SwiftFormatTestSupport",
146180
.product(name: "SwiftSyntax", package: "swift-syntax"),
181+
.product(name: "SwiftOperators", package: "swift-syntax"),
147182
.product(name: "SwiftParser", package: "swift-syntax"),
148183
]
149184
),
@@ -180,15 +215,17 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
180215
package.dependencies += [
181216
.package(
182217
url: "https://github.com/apple/swift-argument-parser.git",
183-
branch: "main"
218+
// This should be kept in sync with the same dependency used by
219+
// swift-syntax.
220+
Version("1.0.1")..<Version("1.2.0")
184221
),
185222
.package(
186223
url: "https://github.com/apple/swift-syntax.git",
187224
branch: "main"
188225
),
189226
.package(
190227
url: "https://github.com/apple/swift-tools-support-core.git",
191-
branch: "main"
228+
exact: Version("0.4.0")
192229
),
193230
]
194231
} else {

Plugins/FormatPlugin/plugin.swift

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import PackagePlugin
2+
import Foundation
3+
4+
@main
5+
struct FormatPlugin {
6+
func format(tool: PluginContext.Tool, targetDirectories: [String], configurationFilePath: String?) throws {
7+
let swiftFormatExec = URL(fileURLWithPath: tool.path.string)
8+
9+
var arguments: [String] = ["format"]
10+
11+
arguments.append(contentsOf: targetDirectories)
12+
13+
arguments.append(contentsOf: ["--recursive", "--parallel", "--in-place"])
14+
15+
if let configurationFilePath = configurationFilePath {
16+
arguments.append(contentsOf: ["--configuration", configurationFilePath])
17+
}
18+
19+
let process = try Process.run(swiftFormatExec, arguments: arguments)
20+
process.waitUntilExit()
21+
22+
if process.terminationReason == .exit && process.terminationStatus == 0 {
23+
print("Formatted the source code.")
24+
}
25+
else {
26+
let problem = "\(process.terminationReason):\(process.terminationStatus)"
27+
Diagnostics.error("swift-format invocation failed: \(problem)")
28+
}
29+
}
30+
}
31+
32+
extension FormatPlugin: CommandPlugin {
33+
func performCommand(
34+
context: PluginContext,
35+
arguments: [String]
36+
) async throws {
37+
let swiftFormatTool = try context.tool(named: "swift-format")
38+
39+
var argExtractor = ArgumentExtractor(arguments)
40+
let targetNames = argExtractor.extractOption(named: "target")
41+
let targetsToFormat = try context.package.targets(named: targetNames)
42+
43+
let configurationFilePath = argExtractor.extractOption(named: "configuration").first
44+
45+
let sourceCodeTargets = targetsToFormat.compactMap{ $0 as? SourceModuleTarget }
46+
47+
try format(
48+
tool: swiftFormatTool,
49+
targetDirectories: sourceCodeTargets.map(\.directory.string),
50+
configurationFilePath: configurationFilePath
51+
)
52+
}
53+
}
54+
55+
#if canImport(XcodeProjectPlugin)
56+
import XcodeProjectPlugin
57+
58+
extension FormatPlugin: XcodeCommandPlugin {
59+
func performCommand(context: XcodeProjectPlugin.XcodePluginContext, arguments: [String]) throws {
60+
let swiftFormatTool = try context.tool(named: "swift-format")
61+
62+
var argExtractor = ArgumentExtractor(arguments)
63+
let configurationFilePath = argExtractor.extractOption(named: "configuration").first
64+
65+
try format(
66+
tool: swiftFormatTool,
67+
targetDirectories: [context.xcodeProject.directory.string],
68+
configurationFilePath: configurationFilePath
69+
)
70+
}
71+
}
72+
#endif

Plugins/LintPlugin/plugin.swift

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import PackagePlugin
2+
import Foundation
3+
4+
@main
5+
struct LintPlugin {
6+
func lint(tool: PluginContext.Tool, targetDirectories: [String], configurationFilePath: String?) throws {
7+
let swiftFormatExec = URL(fileURLWithPath: tool.path.string)
8+
9+
var arguments: [String] = ["lint"]
10+
11+
arguments.append(contentsOf: targetDirectories)
12+
13+
arguments.append(contentsOf: ["--recursive", "--parallel", "--strict"])
14+
15+
if let configurationFilePath = configurationFilePath {
16+
arguments.append(contentsOf: ["--configuration", configurationFilePath])
17+
}
18+
19+
let process = try Process.run(swiftFormatExec, arguments: arguments)
20+
process.waitUntilExit()
21+
22+
if process.terminationReason == .exit && process.terminationStatus == 0 {
23+
print("Linted the source code.")
24+
}
25+
else {
26+
let problem = "\(process.terminationReason):\(process.terminationStatus)"
27+
Diagnostics.error("swift-format invocation failed: \(problem)")
28+
}
29+
}
30+
}
31+
32+
extension LintPlugin: CommandPlugin {
33+
func performCommand(
34+
context: PluginContext,
35+
arguments: [String]
36+
) async throws {
37+
let swiftFormatTool = try context.tool(named: "swift-format")
38+
39+
// Extract the arguments that specify what targets to format.
40+
var argExtractor = ArgumentExtractor(arguments)
41+
let targetNames = argExtractor.extractOption(named: "target")
42+
let targetsToFormat = try context.package.targets(named: targetNames)
43+
44+
let configurationFilePath = argExtractor.extractOption(named: "configuration").first
45+
46+
let sourceCodeTargets = targetsToFormat.compactMap { $0 as? SourceModuleTarget }
47+
48+
try lint(
49+
tool: swiftFormatTool,
50+
targetDirectories: sourceCodeTargets.map(\.directory.string),
51+
configurationFilePath: configurationFilePath
52+
)
53+
}
54+
}
55+
56+
#if canImport(XcodeProjectPlugin)
57+
import XcodeProjectPlugin
58+
59+
extension LintPlugin: XcodeCommandPlugin {
60+
func performCommand(context: XcodeProjectPlugin.XcodePluginContext, arguments: [String]) throws {
61+
let swiftFormatTool = try context.tool(named: "swift-format")
62+
var argExtractor = ArgumentExtractor(arguments)
63+
let configurationFilePath = argExtractor.extractOption(named: "configuration").first
64+
65+
try lint(
66+
tool: swiftFormatTool,
67+
targetDirectories: [context.xcodeProject.directory.string],
68+
configurationFilePath: configurationFilePath
69+
)
70+
}
71+
}
72+
#endif

README.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,19 @@ invoked via an [API](#api-usage).
1313
> and the code is provided so that it can be tested on real-world code and
1414
> experiments can be made by modifying it.
1515
16-
## Matching swift-format to Your Swift Version
17-
18-
`swift-format` depends on [SwiftSyntax](https://github.com/apple/swift-syntax)
19-
and the standalone parsing library that is distributed as part of the Swift
20-
toolchain, so you should check out and build `swift-format` from the release
16+
## Matching swift-format to Your Swift Version (Swift 5.7 and earlier)
17+
18+
> NOTE: `swift-format` on the `main` branch now uses a version of
19+
> [SwiftSyntax](https://github.com/apple/swift-syntax) whose parser has been
20+
> rewritten in Swift and no longer has dependencies on libraries in the
21+
> Swift toolchain. This allows `swift-format` to be built, developed, and
22+
> run using any version of Swift that can compile it, decoupling it from
23+
> the version that supported a particular syntax.
24+
25+
`swift-format` versions 0.50700.0 and earlier depend on versions of
26+
[SwiftSyntax](https://github.com/apple/swift-syntax) that used a standalone
27+
parsing library distributed as part of the Swift toolchain. When using these
28+
versions, you should check out and build `swift-format` from the release
2129
tag or branch that is compatible with the version of Swift you are using.
2230

2331
The major and minor version components of `swift-format` and SwiftSyntax must
@@ -28,6 +36,7 @@ Swift toolchain that is installed and used to build and run the formatter:
2836
| Xcode Release | Swift Version | `swift-format` Branch / Tags |
2937
|:----------------|:-----------------------|:---------------------------------|
3038
|| Swift at `main` | `main` |
39+
| Xcode 14.0 | Swift 5.7 | `release/5.7` / `0.50700.x` |
3140
| Xcode 13.3 | Swift 5.6 | `release/5.6` / `0.50600.x` |
3241
| Xcode 13.0–13.2 | Swift 5.5 | `swift-5.5-branch` / `0.50500.x` |
3342
| Xcode 12.5 | Swift 5.4 | `swift-5.4-branch` / `0.50400.x` |
@@ -45,7 +54,7 @@ then once you have identified the version you need, you can check out the
4554
source and build it using the following commands:
4655

4756
```sh
48-
VERSION=0.50600.0 # replace this with the version you need
57+
VERSION=0.50700.0 # replace this with the version you need
4958
git clone https://github.com/apple/swift-format.git
5059
cd swift-format
5160
git checkout "tags/$VERSION"
@@ -59,7 +68,7 @@ want to do.
5968
Once the build has finished, the `swift-format` executable will be located at
6069
`.build/release/swift-format`.
6170

62-
To test that the formatter was built succesfully and is compatible with your
71+
To test that the formatter was built successfully and is compatible with your
6372
Swift toolchain, you can also run the following command:
6473

6574
```sh

0 commit comments

Comments
 (0)