Skip to content

Commit

Permalink
Silence pattern_matching_keywords rule when an identifier is refere…
Browse files Browse the repository at this point in the history
…nced in the argument list (#5375)
  • Loading branch information
SimplyDanny authored Dec 4, 2023
1 parent e4e22b5 commit f369caa
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 30 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
are defined in a tuple like `let (a, b) = (5, 10)` or `let a = (2, 3)`.
[Martin Redington](https://github.com/mildm8nnered)
[#5305](https://github.com/realm/SwiftLint/pull/5305)

* Silence `pattern_matching_keywords` rule when an identifier is referenced
in the argument list of a matching enum case.
[SimplyDanny](https://github.com/SimplyDanny)
[#3852](https://github.com/realm/SwiftLint/pull/3852)

## 0.54.0: Macro-Economic Forces

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,31 @@ struct PatternMatchingKeywordsRule: OptInRule {
Example("case .foo(let x, var y)"),
Example("case var (x, y)"),
Example("case .foo(var x)"),
Example("case var .foo(x, y)")
Example("case var .foo(x, y)"),
Example("case (y, let x, z)")
].map(wrapInSwitch),
triggeringExamples: [
Example("case (↓let x, ↓let y)"),
Example("case (↓let x, ↓let y, .foo)"),
Example("case (↓let x, ↓let y, _)"),
Example("case (↓let x, ↓let y, f())"),
Example("case (↓let x, ↓let y, s.f())"),
Example("case (↓let x, ↓let y, s.t)"),
Example("case .foo(↓let x, ↓let y)"),
Example("case (.yamlParsing(↓let x), .yamlParsing(↓let y))"),
Example("case (↓var x, ↓var y)"),
Example("case .foo(↓var x, ↓var y)"),
Example("case (.yamlParsing(↓var x), .yamlParsing(↓var y))")
].map(wrapInSwitch)
)

private static func wrapInSwitch(_ example: Example) -> Example {
example.with(code: """
switch foo {
\(example.code): break
}
""")
}
}

private extension PatternMatchingKeywordsRule {
Expand All @@ -47,27 +59,14 @@ private extension PatternMatchingKeywordsRule {

private final class TupleVisitor<Configuration: RuleConfiguration>: ViolationsSyntaxVisitor<Configuration> {
override func visitPost(_ node: LabeledExprListSyntax) {
let list = node.flatteningEnumPatterns()
.compactMap { elem in
elem.expression.asValueBindingPattern()
}

guard list.count > 1,
let firstLetOrVar = list.first?.bindingSpecifier.tokenKind else {
let list = node.flatteningEnumPatterns().map(\.expression.categorized)
if list.contains(where: \.isReference) {
return
}

let hasViolation = list.allSatisfy { elem in
elem.bindingSpecifier.tokenKind == firstLetOrVar
}

guard hasViolation else {
return
let specifiers = list.compactMap { if case let .binding(specifier) = $0 { specifier } else { nil } }
if specifiers.count > 1, specifiers.allSatisfy({ $0.tokenKind == specifiers.first?.tokenKind }) {
violations.append(contentsOf: specifiers.map(\.positionAfterSkippingLeadingTrivia))
}

violations.append(contentsOf: list.compactMap { elem in
return elem.bindingSpecifier.positionAfterSkippingLeadingTrivia
})
}
}

Expand All @@ -84,20 +83,27 @@ private extension LabeledExprListSyntax {
}
}

private extension ExprSyntax {
func asValueBindingPattern() -> ValueBindingPatternSyntax? {
if let pattern = self.as(PatternExprSyntax.self) {
return pattern.pattern.as(ValueBindingPatternSyntax.self)
}
private enum ArgumentType {
case binding(specifier: TokenSyntax)
case reference
case constant

return nil
var isReference: Bool {
switch self {
case .reference: true
default: false
}
}
}

private func wrapInSwitch(_ example: Example) -> Example {
return example.with(code: """
switch foo {
\(example.code): break
private extension ExprSyntax {
var categorized: ArgumentType {
if let binding = `as`(PatternExprSyntax.self)?.pattern.as(ValueBindingPatternSyntax.self) {
return .binding(specifier: binding.bindingSpecifier)
}
""")
if `is`(DeclReferenceExprSyntax.self) {
return .reference
}
return .constant
}
}

0 comments on commit f369caa

Please sign in to comment.