Skip to content

Commit 8ada387

Browse files
authored
Ignore locally defined count identifiers in empty_count rule (#6202)
1 parent 025a7bf commit 8ada387

File tree

4 files changed

+48
-7
lines changed

4 files changed

+48
-7
lines changed

BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ swift_library(
123123
visibility = ["//visibility:public"],
124124
deps = [
125125
":SwiftLintCore",
126+
"@SwiftSyntax//:SwiftLexicalLookup_opt",
126127
],
127128
)
128129

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
improvements done in the [SwiftSyntax](https://github.com/swiftlang/swift-syntax)
4040
library.
4141

42+
* Ignore locally defined `count` identifiers in `empty_count` rule.
43+
[SimplyDanny](https://github.com/SimplyDanny)
44+
[#5326](https://github.com/realm/SwiftLint/issues/5326)
45+
4246
* The `private_swiftui_state` rule now applies to `ViewModifier` types.
4347
[mt00chikin](https://github.com/mt00chikin)
4448

Package.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ let package = Package(
107107
),
108108
.target(
109109
name: "SwiftLintBuiltInRules",
110-
dependencies: ["SwiftLintCore"],
110+
dependencies: [
111+
.product(name: "SwiftLexicalLookup", package: "swift-syntax"),
112+
"SwiftLintCore",
113+
],
111114
swiftSettings: swiftFeatures + strictConcurrency
112115
),
113116
.target(

Source/SwiftLintBuiltInRules/Rules/Performance/EmptyCountRule.swift

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@_spi(Experimental)
2+
import SwiftLexicalLookup
13
import SwiftLintCore
24
import SwiftSyntax
35

@@ -22,6 +24,14 @@ struct EmptyCountRule: Rule {
2224
Example("order.discount == 0"),
2325
Example("let rule = #Rule(Tips.Event(id: \"someTips\")) { $0.donations.count == 0 }"),
2426
Example("#Rule(param1: \"param1\")", excludeFromDocumentation: true),
27+
Example("func isEmpty(count: Int) -> Bool { count == 0 }"),
28+
Example("""
29+
var isEmpty: Bool {
30+
let count = 0
31+
return count == 0
32+
}
33+
"""),
34+
Example("{ count in count == 0 }()"),
2535
],
2636
triggeringExamples: [
2737
Example("[Int]().↓count == 0"),
@@ -50,7 +60,18 @@ struct EmptyCountRule: Rule {
5060
doSomething()
5161
return $0.donations.↓count == 0
5262
}
53-
""", excludeFromDocumentation: true),
63+
""", excludeFromDocumentation: true),
64+
Example("""
65+
extension E {
66+
var isEmpty: Bool { ↓count == 0 }
67+
}
68+
""", excludeFromDocumentation: true),
69+
Example(
70+
"""
71+
struct S {
72+
var isEmpty: Bool { ↓count == 0 }
73+
}
74+
""", excludeFromDocumentation: true),
5475
],
5576
corrections: [
5677
Example("[].↓count == 0"):
@@ -146,19 +167,31 @@ private extension EmptyCountRule {
146167
}
147168

148169
private extension ExprSyntax {
170+
var isNonLocalCountIdentifier: Bool {
171+
guard let declRef = self.as(DeclReferenceExprSyntax.self),
172+
declRef.argumentNames == nil,
173+
declRef.baseName.tokenKind == .identifier("count") else {
174+
return false
175+
}
176+
let result = lookup(Identifier(canonicalName: "count"))
177+
return result.isEmpty || !result.contains { result in
178+
switch result {
179+
case .fromScope: true
180+
default: false
181+
}
182+
}
183+
}
184+
149185
func countCallPosition(onlyAfterDot: Bool) -> AbsolutePosition? {
150186
if let expr = self.as(MemberAccessExprSyntax.self) {
151187
if expr.declName.argumentNames == nil, expr.declName.baseName.tokenKind == .identifier("count") {
152188
return expr.declName.baseName.positionAfterSkippingLeadingTrivia
153189
}
154-
155190
return nil
156191
}
157-
158-
if !onlyAfterDot, let expr = self.as(DeclReferenceExprSyntax.self) {
159-
return expr.baseName.tokenKind == .identifier("count") ? expr.positionAfterSkippingLeadingTrivia : nil
192+
if !onlyAfterDot, isNonLocalCountIdentifier {
193+
return positionAfterSkippingLeadingTrivia
160194
}
161-
162195
return nil
163196
}
164197
}

0 commit comments

Comments
 (0)