Skip to content

Commit 72fc65f

Browse files
authored
Merge pull request #921 from ahoppen/merge-main-6.1-2025-02-04
Merge `main` into `release/6.1`
2 parents 8c4e008 + 5e2fa1d commit 72fc65f

File tree

6 files changed

+159
-19
lines changed

6 files changed

+159
-19
lines changed

Documentation/Configuration.md

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,40 @@ top-level keys and values:
137137

138138
---
139139

140-
## FIXME: fileScopedDeclarationPrivacy
140+
## `fileScopedDeclarationPrivacy`
141+
**type:** object
142+
143+
**description:** Declarations at file scope with effective private access should be consistently declared as either `fileprivate` or `private`, determined by configuration.
144+
145+
- `accessLevel` _(string)_: The formal access level to use when encountering a file-scoped declaration with effective private access. Allowed values are `private` and `fileprivate`.
146+
147+
**default:** `{ "accessLevel" : "private" }`
141148

142149
---
143150

144-
### FIXME: indentSwitchCaseLabels
151+
### `indentSwitchCaseLabels`
152+
**type:** boolean
153+
154+
**description:** Determines if `case` statements should be indented compared to the containing `switch` block.
155+
156+
When `false`, the correct form is:
157+
```swift
158+
switch someValue {
159+
case someCase:
160+
someStatement
161+
...
162+
}
163+
```
164+
When `true`, the correct form is:
165+
```swift
166+
switch someValue {
167+
case someCase:
168+
someStatement
169+
...
170+
}
171+
```
172+
173+
**default:** `false`
145174

146175
---
147176

@@ -154,7 +183,14 @@ top-level keys and values:
154183

155184
---
156185

157-
### FIXME: noAssignmentInExpressions
186+
### `noAssignmentInExpressions`
187+
**type:** object
188+
189+
**description:** Assignment expressions must be their own statements. Assignment should not be used in an expression context that expects a `Void` value. For example, assigning a variable within a `return` statement existing a `Void` function is prohibited.
190+
191+
- `allowedFunctions` _(strings array)_: A list of function names where assignments are allowed to be embedded in expressions that are passed as parameters to that function.
192+
193+
**default:** `{ "allowedFunctions" : ["XCTAssertNoThrow"] }`
158194

159195
---
160196

@@ -167,7 +203,51 @@ top-level keys and values:
167203

168204
---
169205

170-
### FIXME: reflowMultilineStringLiterals
206+
### `reflowMultilineStringLiterals`
207+
**type:** `string`
208+
209+
**description:** Determines how multiline string literals should reflow when formatted.
210+
211+
- `never`: Never reflow multiline string literals.
212+
- `onlyLinesOverLength`: Reflow lines in string literal that exceed the maximum line length.
213+
For example with a line length of 10:
214+
```swift
215+
"""
216+
an escape\
217+
line break
218+
a hard line break
219+
"""
220+
```
221+
will be formatted as:
222+
```swift
223+
"""
224+
an esacpe\
225+
line break
226+
a hard \
227+
line break
228+
"""
229+
```
230+
- `always`: Always reflow multiline string literals, this will ignore existing escaped newlines in the literal and reflow each line. Hard linebreaks are still respected.
231+
For example, with a line length of 10:
232+
```swift
233+
"""
234+
one \
235+
word \
236+
a line.
237+
this is too long.
238+
"""
239+
```
240+
will be formatted as:
241+
```swift
242+
"""
243+
one word \
244+
a line.
245+
this is \
246+
too long.
247+
"""
248+
```
249+
250+
**default:** `"never"`
171251

172252
---
173253

Sources/SwiftFormat/PrettyPrint/PrettyPrintBuffer.swift

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,21 @@ struct PrettyPrintBuffer {
119119
consecutiveNewlineCount = 0
120120
pendingSpaces = 0
121121

122-
// In case of comments, we may get a multi-line string.
123-
// To account for that case, we need to correct the lineNumber count.
124-
// The new column is only the position within the last line.
125-
let lines = text.split(separator: "\n")
126-
lineNumber += lines.count - 1
127-
if lines.count > 1 {
128-
// in case we have inserted new lines, we need to reset the column
129-
column = lines.last?.count ?? 0
122+
// In case of comments, we may get a multi-line string. To account for that case, we need to correct the
123+
// `lineNumber` count. The new `column` is the position within the last line.
124+
125+
var lastNewlineIndex: String.Index? = nil
126+
for i in text.utf8.indices {
127+
if text.utf8[i] == UInt8(ascii: "\n") {
128+
lastNewlineIndex = i
129+
lineNumber += 1
130+
}
131+
}
132+
133+
if let lastNewlineIndex {
134+
column = text.distance(from: text.utf8.index(after: lastNewlineIndex), to: text.endIndex)
130135
} else {
131-
// in case it is an end of line comment or a single line comment,
132-
// we just add to the current column
133-
column += lines.last?.count ?? 0
136+
column += text.count
134137
}
135138
}
136139

Sources/SwiftFormat/PrettyPrint/WhitespaceLinter.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,16 @@ public class WhitespaceLinter {
339339
startingAt offset: Int,
340340
in data: [UTF8.CodeUnit]
341341
) -> ArraySlice<UTF8.CodeUnit> {
342+
func isWhitespace(_ char: UTF8.CodeUnit) -> Bool {
343+
switch char {
344+
case UInt8(ascii: " "), UInt8(ascii: "\n"), UInt8(ascii: "\t"), UInt8(ascii: "\r"), /*VT*/ 0x0B, /*FF*/ 0x0C:
345+
return true
346+
default:
347+
return false
348+
}
349+
}
342350
guard
343-
let whitespaceEnd =
344-
data[offset...].firstIndex(where: { !UnicodeScalar($0).properties.isWhitespace })
351+
let whitespaceEnd = data[offset...].firstIndex(where: { !isWhitespace($0) })
345352
else {
346353
return data[offset..<data.endIndex]
347354
}

Sources/swift-format/Frontend/Frontend.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,23 @@ class Frontend {
9797

9898
/// Runs the linter or formatter over the inputs.
9999
final func run() {
100-
if lintFormatOptions.paths.isEmpty {
100+
if lintFormatOptions.paths == ["-"] {
101+
processStandardInput()
102+
} else if lintFormatOptions.paths.isEmpty {
103+
diagnosticsEngine.emitWarning(
104+
"""
105+
Running swift-format without input paths is deprecated and will be removed in the future.
106+
107+
Please update your invocation to do either of the following:
108+
109+
- Pass `-` to read from stdin (e.g., `cat MyFile.swift | swift-format -`).
110+
- Pass one or more paths to Swift source files or directories containing
111+
Swift source files. When passing directories, make sure to include the
112+
`--recursive` flag.
113+
114+
For more information, use the `--help` option.
115+
"""
116+
)
101117
processStandardInput()
102118
} else {
103119
processURLs(

Sources/swift-format/Subcommands/LintFormatOptions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ struct LintFormatOptions: ParsableArguments {
108108
var experimentalFeatures: [String] = []
109109

110110
/// The list of paths to Swift source files that should be formatted or linted.
111-
@Argument(help: "Zero or more input filenames.")
111+
@Argument(help: "Zero or more input filenames. Use `-` for stdin.")
112112
var paths: [String] = []
113113

114114
@Flag(help: .hidden) var debugDisablePrettyPrint: Bool = false

Tests/SwiftFormatTests/PrettyPrint/LineNumbersTests.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,38 @@ final class LineNumbersTests: PrettyPrintTestCase {
8181
]
8282
)
8383
}
84+
85+
func testCharacterVsCodepoint() {
86+
let input =
87+
"""
88+
let fo = 1 // 🤥
89+
90+
"""
91+
92+
assertPrettyPrintEqual(
93+
input: input,
94+
expected: input,
95+
linelength: 16,
96+
whitespaceOnly: true,
97+
findings: []
98+
)
99+
}
100+
101+
func testCharacterVsCodepointMultiline() {
102+
let input =
103+
#"""
104+
/// This is a multiline
105+
/// comment that is in 🤥
106+
/// fact perfectly sized
107+
108+
"""#
109+
110+
assertPrettyPrintEqual(
111+
input: input,
112+
expected: input,
113+
linelength: 25,
114+
whitespaceOnly: true,
115+
findings: []
116+
)
117+
}
84118
}

0 commit comments

Comments
 (0)