Skip to content

Commit 877d4fb

Browse files
authored
Merge pull request swiftlang#235 from dabelknap/rule-whitelist
Use a whitelisting model for configuring which rules to use.
2 parents 602585b + d04100a commit 877d4fb

File tree

6 files changed

+113
-3
lines changed

6 files changed

+113
-3
lines changed

Sources/SwiftFormat/PopulatePipeline.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ func populate(_ pipeline: Pipeline) {
117117
pipeline.addFormatter(
118118
OneVariableDeclarationPerLine.self,
119119
for:
120-
AccessorBlockSyntax.self,
121120
ClosureExprSyntax.self,
122121
CodeBlockSyntax.self,
123122
SourceFileSyntax.self
@@ -152,7 +151,7 @@ func populate(_ pipeline: Pipeline) {
152151
pipeline.addFormatter(
153152
UseSingleLinePropertyGetter.self,
154153
for:
155-
AccessorBlockSyntax.self
154+
PatternBindingSyntax.self
156155
)
157156

158157
pipeline.addFormatter(

Sources/SwiftFormatConfiguration/Configuration.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,18 @@ public class Configuration: Codable {
2828
case respectsExistingLineBreaks
2929
case blankLineBetweenMembers
3030
case surroundSymbolsWithBackticks
31+
case rules
3132
}
3233

3334
/// The version of this configuration.
3435
private let version: Int
3536

3637
/// MARK: Common configuration
3738

39+
/// The dictionary containing the rule names that we wish to run on. A rule is not used if it is
40+
/// marked as `false`, or if it is missing from the dictionary.
41+
public var rules: [String: Bool] = [:]
42+
3843
/// The maximum number of consecutive blank lines that may appear in a file.
3944
public var maximumBlankLines = 1
4045

@@ -68,6 +73,7 @@ public class Configuration: Codable {
6873
/// Constructs a Configuration with all default values.
6974
public init() {
7075
self.version = highestSupportedConfigurationVersion
76+
self.rules = RuleRegistry.rules
7177
}
7278

7379
public required init(from decoder: Decoder) throws {
@@ -101,6 +107,7 @@ public class Configuration: Codable {
101107
self.blankLineBetweenMembers = try container.decodeIfPresent(
102108
BlankLineBetweenMembersConfiguration.self, forKey: .blankLineBetweenMembers)
103109
?? BlankLineBetweenMembersConfiguration()
110+
self.rules = try container.decodeIfPresent([String: Bool].self, forKey: .rules) ?? [:]
104111
}
105112

106113
public func encode(to encoder: Encoder) throws {
@@ -113,6 +120,7 @@ public class Configuration: Codable {
113120
try container.encode(indentation, forKey: .indentation)
114121
try container.encode(respectsExistingLineBreaks, forKey: .respectsExistingLineBreaks)
115122
try container.encode(blankLineBetweenMembers, forKey: .blankLineBetweenMembers)
123+
try container.encode(rules, forKey: .rules)
116124
}
117125
}
118126

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// This file is automatically generated with generate-pipeline. Do Not Edit!
14+
15+
enum RuleRegistry {
16+
static let rules: [String: Bool] = [
17+
"UseOnlyUTF8": true,
18+
"UseSpecialEscapeSequences": true,
19+
"BlankLineBetweenMembers": true,
20+
"DoNotUseSemicolons": true,
21+
"FullyIndirectEnum": true,
22+
"GroupNumericLiterals": true,
23+
"MultiLineTrailingCommas": true,
24+
"NoAccessLevelOnExtensionDeclaration": true,
25+
"NoBlockComments": true,
26+
"NoCasesWithOnlyFallthrough": true,
27+
"NoEmptyAssociatedValues": true,
28+
"NoEmptyTrailingClosureParentheses": true,
29+
"NoLabelsInCasePatterns": true,
30+
"NoParensAroundConditions": true,
31+
"NoVoidReturnOnFunctionSignature": true,
32+
"OneCasePerLine": true,
33+
"OneVariableDeclarationPerLine": true,
34+
"OrderedImports": true,
35+
"ReturnVoidInsteadOfEmptyTuple": true,
36+
"UseEnumForNamespacing": true,
37+
"UseShorthandTypeNames": true,
38+
"UseSingleLinePropertyGetter": true,
39+
"UseTripleSlashForDocumentationComments": true,
40+
"AllPublicDeclarationsHaveDocumentation": true,
41+
"AlwaysUseLowerCamelCase": true,
42+
"AmbiguousTrailingClosureOverload": true,
43+
"AvoidInitializersForLiterals": true,
44+
"BeginDocumentationCommentWithOneLineSummary": true,
45+
"CaseIndentLevelEqualsSwitch": true,
46+
"DontRepeatTypeInStaticProperties": true,
47+
"IdentifiersMustBeASCII": true,
48+
"NeverForceUnwrap": true,
49+
"NeverUseForceTry": true,
50+
"NeverUseImplicitlyUnwrappedOptionals": true,
51+
"NoLeadingUnderscores": true,
52+
"OnlyOneTrailingClosureArgument": true,
53+
"UseLetInEveryBoundCaseVariable": true,
54+
"UseSynthesizedInitializer": true,
55+
"ValidateDocumentationComments": true,
56+
]
57+
}

Sources/SwiftFormatCore/FormatPipeline.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public final class FormatPipeline: SyntaxRewriter, Pipeline {
4949
public func addFormatter(_ formatType: SyntaxFormatRule.Type, for syntaxTypes: Syntax.Type...) {
5050
for type in syntaxTypes {
5151
let formatter = formatType.init(context: context)
52-
52+
guard let enabled = context.configuration.rules[formatter.ruleName], enabled else { continue }
5353
// TODO(b/77533378): Respect priority of inserted Formatting passes. Should this be sorted on
5454
// insertion based on the priority of the pass type?
5555
passMap[SyntaxType(type: type), default: []].append(formatter.visit)

Sources/SwiftFormatCore/LintPipeline.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public final class LintPipeline: SyntaxVisitor, Pipeline {
5151
public func addLinter(_ lintRule: SyntaxLintRule.Type, for syntaxTypes: Syntax.Type...) {
5252
for type in syntaxTypes {
5353
let rule = lintRule.init(context: context)
54+
guard let enabled = context.configuration.rules[rule.ruleName], enabled else { continue }
5455
passMap[SyntaxType(type: type), default: []].append(.linter(rule))
5556
}
5657
}
@@ -64,6 +65,7 @@ public final class LintPipeline: SyntaxVisitor, Pipeline {
6465
public func addFormatter(_ formatRule: SyntaxFormatRule.Type, for syntaxTypes: Syntax.Type...) {
6566
for type in syntaxTypes {
6667
let rule = formatRule.init(context: context)
68+
guard let enabled = context.configuration.rules[rule.ruleName], enabled else { continue }
6769
passMap[SyntaxType(type: type), default: []].append(.formatter(rule))
6870
}
6971
}

Sources/generate-pipeline/main.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ let sourcesDir = URL(fileURLWithPath: #file)
1919
let rulesDir = sourcesDir.appendingPathComponent("SwiftFormatRules")
2020
let outputFile = sourcesDir.appendingPathComponent("SwiftFormat")
2121
.appendingPathComponent("PopulatePipeline.swift")
22+
let ruleRegistryFile = sourcesDir.appendingPathComponent("SwiftFormatConfiguration")
23+
.appendingPathComponent("RuleRegistry.swift")
2224
let fm = FileManager.default
2325

2426
// These rules will not be added to the pipeline
@@ -182,3 +184,45 @@ for (className, types) in registry.lintingPasses.sorted(by: { $0.key < $1.key })
182184
)
183185
}
184186
handle.write("}\n")
187+
188+
// Generate rule registry dictionary for configuration
189+
190+
// Delete the existing ruleRegistry file.
191+
if fm.fileExists(atPath: ruleRegistryFile.path) {
192+
try fm.removeItem(at: ruleRegistryFile)
193+
}
194+
fm.createFile(atPath: ruleRegistryFile.path, contents: nil, attributes: nil)
195+
let registryHandle = try FileHandle(forWritingTo: ruleRegistryFile)
196+
197+
registryHandle.write(
198+
"""
199+
//===----------------------------------------------------------------------===//
200+
//
201+
// This source file is part of the Swift.org open source project
202+
//
203+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
204+
// Licensed under Apache License v2.0 with Runtime Library Exception
205+
//
206+
// See https://swift.org/LICENSE.txt for license information
207+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
208+
//
209+
//===----------------------------------------------------------------------===//
210+
211+
// This file is automatically generated with generate-pipeline. Do Not Edit!
212+
213+
enum RuleRegistry {
214+
static let rules: [String: Bool] = [
215+
216+
"""
217+
)
218+
219+
for fileRule in registry.filePasses.sorted() {
220+
registryHandle.write(" \"\(fileRule)\": true,\n")
221+
}
222+
for (className, _) in registry.formattingPasses.sorted(by: { $0.key < $1.key }) {
223+
registryHandle.write(" \"\(className)\": true,\n")
224+
}
225+
for (className, _) in registry.lintingPasses.sorted(by: { $0.key < $1.key }) {
226+
registryHandle.write(" \"\(className)\": true,\n")
227+
}
228+
registryHandle.write(" ]\n}\n")

0 commit comments

Comments
 (0)