Skip to content

Commit 069f2b6

Browse files
committedMar 20, 2025··
Remove severity
Instead of making the severity configurable, this patch removes severity all together and treats every finding as an error. Issue: #879
1 parent 2d964e4 commit 069f2b6

16 files changed

+41
-85
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
swift-format.xcodeproj/
55
Package.resolved
66
/.vscode
7+
.index-build

‎Documentation/RuleDocumentation.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Use the rules below in the `rules` block of your `.swift-format`
66
configuration file, as described in
7-
[Configuration](Configuration.md). All of these rules can be
7+
[Configuration](Documentation/Configuration.md). All of these rules can be
88
applied in the linter, but only some of them can format your source code
99
automatically.
1010

‎Sources/SwiftFormat/API/Finding.swift

+1-13
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@
1212

1313
/// A problem with the style or syntax of the source code discovered during linting or formatting.
1414
public struct Finding {
15-
/// The severity of a finding.
16-
public enum Severity {
17-
case warning
18-
case error
19-
case refactoring
20-
case convention
21-
}
2215

2316
/// The file path and location in that file where a finding was encountered.
2417
public struct Location {
@@ -83,27 +76,22 @@ public struct Finding {
8376
/// The finding's message.
8477
public let message: Message
8578

86-
/// The severity of the finding.
87-
public let severity: Severity
88-
8979
/// The optional location of the finding.
9080
public let location: Location?
9181

9282
/// Notes that provide additional detail about the finding.
9383
public let notes: [Note]
9484

95-
/// Creates a new finding with the given category, message, severity, optional location, and
85+
/// Creates a new finding with the given category, message, optional location, and
9686
/// notes.
9787
init(
9888
category: FindingCategorizing,
9989
message: Message,
100-
severity: Finding.Severity,
10190
location: Location? = nil,
10291
notes: [Note] = []
10392
) {
10493
self.category = category
10594
self.message = message
106-
self.severity = severity
10795
self.location = location
10896
self.notes = notes
10997
}

‎Sources/SwiftFormat/API/FindingCategorizing.swift

-8
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,5 @@
1717
/// to be displayed as part of the diagnostic message when the finding is presented to the user.
1818
/// For example, the category `Indentation` in the message `[Indentation] Indent by 2 spaces`.
1919
public protocol FindingCategorizing: CustomStringConvertible {
20-
/// The default severity of findings emitted in this category.
21-
///
22-
/// By default, all findings are warnings. Individual categories may choose to override this to
23-
/// make the findings in those categories more severe.
24-
var defaultSeverity: Finding.Severity { get }
25-
}
2620

27-
extension FindingCategorizing {
28-
public var defaultSeverity: Finding.Severity { .warning }
2921
}

‎Sources/SwiftFormat/Core/FindingEmitter.swift

-3
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,10 @@ final class FindingEmitter {
4848
) {
4949
guard let consumer = self.consumer else { return }
5050

51-
// TODO: Provide a way via the formatter configuration for users to customize the severity of
52-
// findings based on their category, falling back to the default if it isn't overridden.
5351
consumer(
5452
Finding(
5553
category: category,
5654
message: message,
57-
severity: category.defaultSeverity,
5855
location: location,
5956
notes: notes
6057
)

‎Sources/SwiftFormat/Core/Parsing.swift

+2-30
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,9 @@ func parseAndEmitDiagnostics(
6363
for diagnostic in diagnostics {
6464
let location = diagnostic.location(converter: expectedConverter)
6565

66-
// Downgrade editor placeholders to warnings, because it is useful to support formatting
66+
// Ignore editor placeholders, because it is useful to support formatting
6767
// in-progress files that contain those.
68-
if diagnostic.diagnosticID == StaticTokenError.editorPlaceholder.diagnosticID {
69-
parsingDiagnosticHandler(downgradedToWarning(diagnostic), location)
70-
} else {
68+
if diagnostic.diagnosticID != StaticTokenError.editorPlaceholder.diagnosticID {
7169
parsingDiagnosticHandler(diagnostic, location)
7270
hasErrors = true
7371
}
@@ -79,29 +77,3 @@ func parseAndEmitDiagnostics(
7977
}
8078
return sourceFile
8179
}
82-
83-
// Wraps a `DiagnosticMessage` but forces its severity to be that of a warning instead of an error.
84-
struct DowngradedDiagnosticMessage: DiagnosticMessage {
85-
var originalDiagnostic: DiagnosticMessage
86-
87-
var message: String { originalDiagnostic.message }
88-
89-
var diagnosticID: SwiftDiagnostics.MessageID { originalDiagnostic.diagnosticID }
90-
91-
var severity: DiagnosticSeverity { .warning }
92-
}
93-
94-
/// Returns a new `Diagnostic` that is identical to the given diagnostic, except that its severity
95-
/// has been downgraded to a warning.
96-
func downgradedToWarning(_ diagnostic: Diagnostic) -> Diagnostic {
97-
// `Diagnostic` is immutable, so create a new one with the same values except for the
98-
// severity-downgraded message.
99-
return Diagnostic(
100-
node: diagnostic.node,
101-
position: diagnostic.position,
102-
message: DowngradedDiagnosticMessage(originalDiagnostic: diagnostic.diagMessage),
103-
highlights: diagnostic.highlights,
104-
notes: diagnostic.notes,
105-
fixIts: diagnostic.fixIts
106-
)
107-
}

‎Sources/SwiftFormat/Core/Rule.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ extension Rule {
6262
public func diagnose<SyntaxType: SyntaxProtocol>(
6363
_ message: Finding.Message,
6464
on node: SyntaxType?,
65-
severity: Finding.Severity? = nil,
6665
anchor: FindingAnchor = .start,
6766
notes: [Finding.Note] = []
6867
) {
@@ -86,7 +85,7 @@ extension Rule {
8685
syntaxLocation = nil
8786
}
8887

89-
let category = RuleBasedFindingCategory(ruleType: type(of: self), severity: severity)
88+
let category = RuleBasedFindingCategory(ruleType: type(of: self))
9089
context.findingEmitter.emit(
9190
message,
9291
category: category,

‎Sources/SwiftFormat/Core/RuleBasedFindingCategory.swift

+1-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ struct RuleBasedFindingCategory: FindingCategorizing {
2222

2323
var description: String { ruleType.ruleName }
2424

25-
var severity: Finding.Severity?
26-
2725
/// Creates a finding category that wraps the given rule type.
28-
init(ruleType: Rule.Type, severity: Finding.Severity? = nil) {
26+
init(ruleType: Rule.Type) {
2927
self.ruleType = ruleType
30-
self.severity = severity
3128
}
3229
}

‎Sources/SwiftFormat/Rules/OmitExplicitReturns.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public final class OmitExplicitReturns: SyntaxFormatRule {
3434
}
3535

3636
funcDecl.body?.statements = rewrapReturnedExpression(returnStmt)
37-
diagnose(.omitReturnStatement, on: returnStmt, severity: .refactoring)
37+
diagnose(.omitReturnStatement, on: returnStmt)
3838
return DeclSyntax(funcDecl)
3939
}
4040

@@ -78,7 +78,7 @@ public final class OmitExplicitReturns: SyntaxFormatRule {
7878
}
7979

8080
closureExpr.statements = rewrapReturnedExpression(returnStmt)
81-
diagnose(.omitReturnStatement, on: returnStmt, severity: .refactoring)
81+
diagnose(.omitReturnStatement, on: returnStmt)
8282
return ExprSyntax(closureExpr)
8383
}
8484

@@ -111,7 +111,7 @@ public final class OmitExplicitReturns: SyntaxFormatRule {
111111

112112
getter.body?.statements = rewrapReturnedExpression(returnStmt)
113113

114-
diagnose(.omitReturnStatement, on: returnStmt, severity: .refactoring)
114+
diagnose(.omitReturnStatement, on: returnStmt)
115115

116116
accessors[getterAt] = getter
117117
var newBlock = accessorBlock
@@ -123,7 +123,7 @@ public final class OmitExplicitReturns: SyntaxFormatRule {
123123
return nil
124124
}
125125

126-
diagnose(.omitReturnStatement, on: returnStmt, severity: .refactoring)
126+
diagnose(.omitReturnStatement, on: returnStmt)
127127

128128
var newBlock = accessorBlock
129129
newBlock.accessors = .getter(rewrapReturnedExpression(returnStmt))

‎Sources/SwiftFormat/Rules/TypeNamesShouldBeCapitalized.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public final class TypeNamesShouldBeCapitalized: SyntaxLintRule {
6161
if let firstChar = name.text[leadingUnderscores.endIndex...].first,
6262
firstChar.uppercased() != String(firstChar)
6363
{
64-
diagnose(.capitalizeTypeName(name: name.text, kind: kind), on: name, severity: .convention)
64+
diagnose(.capitalizeTypeName(name: name.text, kind: kind), on: name)
6565
}
6666
}
6767
}

‎Sources/_SwiftFormatTestSupport/Configuration+Testing.swift

+7
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,11 @@ extension Configuration {
4444
config.indentBlankLines = false
4545
return config
4646
}
47+
48+
public static func forTesting(enabledRule: String) -> Configuration {
49+
var config = Configuration.forTesting
50+
config.rules = config.rules.mapValues({ _ in false })
51+
config.rules[enabledRule] = true
52+
return config
53+
}
4754
}

‎Sources/swift-format/Subcommands/Lint.swift

+10-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ extension SwiftFormatCommand {
2828

2929
@Flag(
3030
name: .shortAndLong,
31-
help: "Fail on warnings."
31+
help: "Fail on warnings. Deprecated: All findings are treated as errors now."
3232
)
3333
var strict: Bool = false
3434

@@ -38,9 +38,17 @@ extension SwiftFormatCommand {
3838
func run() throws {
3939
try performanceMeasurementOptions.printingInstructionCountIfRequested {
4040
let frontend = LintFrontend(configurationOptions: configurationOptions, lintFormatOptions: lintOptions)
41+
42+
if strict {
43+
frontend.diagnosticsEngine.emitWarning(
44+
"""
45+
Running swift-format with --strict is deprecated and will be removed in the future.
46+
"""
47+
)
48+
}
4149
frontend.run()
4250

43-
if frontend.diagnosticsEngine.hasErrors || strict && frontend.diagnosticsEngine.hasWarnings {
51+
if frontend.diagnosticsEngine.hasErrors {
4452
throw ExitCode.failure
4553
}
4654
}

‎Sources/swift-format/Utilities/DiagnosticsEngine.swift

+1-8
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,8 @@ final class DiagnosticsEngine {
134134
/// Converts a lint finding into a diagnostic message that can be used by the `TSCBasic`
135135
/// diagnostics engine and returns it.
136136
private func diagnosticMessage(for finding: Finding) -> Diagnostic {
137-
let severity: Diagnostic.Severity
138-
switch finding.severity {
139-
case .error: severity = .error
140-
case .warning: severity = .warning
141-
case .refactoring: severity = .warning
142-
case .convention: severity = .warning
143-
}
144137
return Diagnostic(
145-
severity: severity,
138+
severity: .error,
146139
location: finding.location.map(Diagnostic.Location.init),
147140
category: "\(finding.category)",
148141
message: "\(finding.message.text)"

‎Tests/SwiftFormatTests/Rules/FileScopedDeclarationPrivacyTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ final class FileScopedDeclarationPrivacyTests: LintOrFormatRuleTestCase {
179179
findingsProvider: (String, String) -> [FindingSpec]
180180
) {
181181
for testConfig in testConfigurations {
182-
var configuration = Configuration.forTesting
182+
var configuration = Configuration.forTesting(enabledRule: FileScopedDeclarationPrivacy.self.ruleName)
183183
configuration.fileScopedDeclarationPrivacy.accessLevel = testConfig.desired
184184

185185
let substitutedInput = source.replacingOccurrences(of: "$access$", with: testConfig.original)

‎Tests/SwiftFormatTests/Rules/LintOrFormatRuleTestCase.swift

+3-8
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ class LintOrFormatRuleTestCase: DiagnosingTestCase {
4949
var emittedFindings = [Finding]()
5050

5151
// Force the rule to be enabled while we test it.
52-
var configuration = Configuration.forTesting
53-
configuration.rules[type.ruleName] = true
52+
let configuration = Configuration.forTesting(enabledRule: type.ruleName)
5453
let context = makeContext(
5554
sourceFileSyntax: sourceFileSyntax,
5655
configuration: configuration,
@@ -59,8 +58,6 @@ class LintOrFormatRuleTestCase: DiagnosingTestCase {
5958
)
6059

6160
var emittedPipelineFindings = [Finding]()
62-
// Disable default rules, so only select rule runs in pipeline
63-
configuration.rules = [type.ruleName: true]
6461
let pipeline = SwiftLinter(
6562
configuration: configuration,
6663
findingConsumer: { emittedPipelineFindings.append($0) }
@@ -118,8 +115,8 @@ class LintOrFormatRuleTestCase: DiagnosingTestCase {
118115
var emittedFindings = [Finding]()
119116

120117
// Force the rule to be enabled while we test it.
121-
var configuration = configuration ?? Configuration.forTesting
122-
configuration.rules[formatType.ruleName] = true
118+
let configuration = configuration ?? Configuration.forTesting(enabledRule: formatType.ruleName)
119+
123120
let context = makeContext(
124121
sourceFileSyntax: sourceFileSyntax,
125122
configuration: configuration,
@@ -162,8 +159,6 @@ class LintOrFormatRuleTestCase: DiagnosingTestCase {
162159
)
163160

164161
var emittedPipelineFindings = [Finding]()
165-
// Disable default rules, so only select rule runs in pipeline
166-
configuration.rules = [formatType.ruleName: true]
167162
let pipeline = SwiftFormatter(
168163
configuration: configuration,
169164
findingConsumer: { emittedPipelineFindings.append($0) }

‎api-breakages.txt

+7
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@ API breakage: enumelement SwiftFormatError.unsupportedConfigurationVersion has b
77
API breakage: class UseLetInEveryBoundCaseVariable has changed its super class from SwiftFormat.SyntaxLintRule to SwiftFormat.SyntaxFormatRule
88
API breakage: func UseLetInEveryBoundCaseVariable.visit(_:) has return type change from SwiftSyntax.SyntaxVisitorContinueKind to SwiftSyntax.MatchingPatternConditionSyntax
99
API breakage: func UseLetInEveryBoundCaseVariable.visit(_:) has parameter 0 type change from SwiftSyntax.ValueBindingPatternSyntax to SwiftSyntax.MatchingPatternConditionSyntax
10+
API breakage: func Rule.diagnose(_:on:severity:anchor:notes:) has parameter 2 type change from SwiftFormat.Finding.Severity? to SwiftFormat.FindingAnchor
11+
API breakage: func Rule.diagnose(_:on:severity:anchor:notes:) has parameter 3 type change from SwiftFormat.FindingAnchor to [SwiftFormat.Finding.Note]
12+
API breakage: enum Finding.Severity has been removed
13+
API breakage: var Finding.severity has been removed
14+
API breakage: var FindingCategorizing.defaultSeverity has been removed
15+
API breakage: var FindingCategorizing.defaultSeverity has been removed
16+
API breakage: func Rule.diagnose(_:on:severity:anchor:notes:) has been renamed to func diagnose(_:on:anchor:notes:)

0 commit comments

Comments
 (0)
Please sign in to comment.