Files
SwiftLint/Source/SwiftLintBuiltInRules/Rules/Performance/EmptyStringRule.swift
T
Danny Mösch 3f039f26d5 Connect configs with their referencing rules to have some context in error logging (#5017)
With the binding of configurations to their associated rule types
"unknown configuration" errors can be made more specific mentioning
also the rule's identifier in the printed message.
2023-05-19 20:58:24 +02:00

49 lines
1.7 KiB
Swift

import SwiftSyntax
struct EmptyStringRule: ConfigurationProviderRule, OptInRule, SwiftSyntaxRule {
var configuration = SeverityConfiguration<Self>(.warning)
static let description = RuleDescription(
identifier: "empty_string",
name: "Empty String",
description: "Prefer checking `isEmpty` over comparing `string` to an empty string literal",
kind: .performance,
nonTriggeringExamples: [
Example("myString.isEmpty"),
Example("!myString.isEmpty"),
Example("\"\"\"\nfoo==\n\"\"\"")
],
triggeringExamples: [
Example(#"myString↓ == """#),
Example(#"myString↓ != """#),
Example(#"myString↓=="""#),
Example(##"myString↓ == #""#"##),
Example(###"myString↓ == ##""##"###)
]
)
func makeVisitor(file: SwiftLintFile) -> ViolationsSyntaxVisitor {
Visitor(viewMode: .sourceAccurate)
}
}
private extension EmptyStringRule {
final class Visitor: ViolationsSyntaxVisitor {
override func visitPost(_ node: StringLiteralExprSyntax) {
guard
// Empty string literal: `""`, `#""#`, etc.
node.segments.onlyElement?.contentLength == .zero,
let previousToken = node.previousToken(viewMode: .sourceAccurate),
// On the rhs of an `==` or `!=` operator
previousToken.tokenKind.isEqualityComparison,
let secondPreviousToken = previousToken.previousToken(viewMode: .sourceAccurate)
else {
return
}
let violationPosition = secondPreviousToken.endPositionBeforeTrailingTrivia
violations.append(violationPosition)
}
}
}