From 38eb3eda4fe758ab2f43be74328aede0eb25c3ff Mon Sep 17 00:00:00 2001 From: Marcelo Fabri Date: Mon, 10 Feb 2020 00:51:53 -0800 Subject: [PATCH] Fix false positive in `empty_string` rule with multiline literals Fixes #3100 --- CHANGELOG.md | 5 +++++ .../Rules/Performance/EmptyStringRule.swift | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f03ca97abed..72faf702c36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -95,6 +95,11 @@ [Marcelo Fabri](https://github.com/marcelofabri) [#3079](https://github.com/realm/SwiftLint/issues/3079) +* Fix false positive in `empty_string` rule when using multiline string + literals. + [Marcelo Fabri](https://github.com/marcelofabri) + [#3100](https://github.com/realm/SwiftLint/issues/3100) + ## 0.38.2: Machine Repair Manual #### Breaking diff --git a/Source/SwiftLintFramework/Rules/Performance/EmptyStringRule.swift b/Source/SwiftLintFramework/Rules/Performance/EmptyStringRule.swift index 1662df55ace..93a47aaed5a 100644 --- a/Source/SwiftLintFramework/Rules/Performance/EmptyStringRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/EmptyStringRule.swift @@ -12,7 +12,8 @@ public struct EmptyStringRule: ConfigurationProviderRule, OptInRule, AutomaticTe kind: .performance, nonTriggeringExamples: [ Example("myString.isEmpty"), - Example("!myString.isEmpty") + Example("!myString.isEmpty"), + Example("\"\"\"\nfoo==\n\"\"\"") ], triggeringExamples: [ Example("myString↓ == \"\""), @@ -22,10 +23,16 @@ public struct EmptyStringRule: ConfigurationProviderRule, OptInRule, AutomaticTe public func validate(file: SwiftLintFile) -> [StyleViolation] { let pattern = "\\b\\s*(==|!=)\\s*\"\"" - return file.match(pattern: pattern, with: [.string]).map { - StyleViolation(ruleDescription: type(of: self).description, - severity: configuration.severity, - location: Location(file: file, characterOffset: $0.location)) + return file.match(pattern: pattern, with: [.string]).compactMap { range in + guard let byteRange = file.stringView.NSRangeToByteRange(NSRange(location: range.location, length: 1)), + case let kinds = file.syntaxMap.kinds(inByteRange: byteRange), + kinds.isEmpty else { + return nil + } + + return StyleViolation(ruleDescription: type(of: self).description, + severity: configuration.severity, + location: Location(file: file, characterOffset: range.location)) } } }