Merge pull request #2543 from BenStaveleyTaylor/issue_2538

Issue 2538: vertical_whitespace_between_cases gives false warning if blank line has whitespace
This commit is contained in:
Marcelo Fabri
2019-01-06 12:50:08 -08:00
committed by GitHub
3 changed files with 49 additions and 4 deletions
+5
View File
@@ -47,6 +47,11 @@
types.
[Marcelo Fabri](https://github.com/marcelofabri)
[#2539](https://github.com/realm/SwiftLint/issues/2539)
* Fix false positives on `vertical_whitespace_between_cases` rule when a blank
line is present but it contains trailing whitespace.
[Ben Staveley-Taylor](https://github.com/BenStaveleyTaylor)
[#2538](https://github.com/realm/SwiftLint/issues/2538)
## 0.29.2: Washateria
+10
View File
@@ -22412,6 +22412,16 @@ default: print("x is invalid")
}
```
```swift
switch x {
case 1:
print("one")
default:
print("not one")
}
```
</details>
<details>
<summary>Triggering Examples</summary>
@@ -46,6 +46,15 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule {
default: print("x is invalid")
}
"""
,
// Testing handling of trailing spaces: do not convert to """ style
"switch x { \n" +
"case 1: \n" +
" print(\"one\") \n" +
" \n" +
"default: \n" +
" print(\"not one\") \n" +
"} "
]
private static let violatingToValidExamples: [String: String] = [
@@ -104,6 +113,27 @@ public struct VerticalWhitespaceBetweenCasesRule: ConfigurationProviderRule {
]
private let pattern = "([^\\n{][ \\t]*\\n)([ \\t]*(?:case[^\\n]+|default):[ \\t]*\\n)"
private func violationRanges(in file: File) -> [NSRange] {
return file.violatingRanges(for: pattern).filter {
!isFalsePositive(in: file, range: $0)
}
}
private func isFalsePositive(in file: File, range: NSRange) -> Bool {
// Regex incorrectly flags blank lines that contain trailing whitespace (#2538)
let patternRegex = regex(pattern)
let substring = file.contents.substring(from: range.location, length: range.length)
guard let matchResult = patternRegex.firstMatch(in: substring, options: [], range: substring.fullNSRange),
matchResult.numberOfRanges > 1 else {
return false
}
let matchFirstRange = matchResult.range(at: 1)
let matchFirstString = substring.substring(from: matchFirstRange.location, length: matchFirstRange.length)
let isAllWhitespace = matchFirstString.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
return isAllWhitespace
}
}
extension VerticalWhitespaceBetweenCasesRule: OptInRule, AutomaticTestableRule {
@@ -119,10 +149,10 @@ extension VerticalWhitespaceBetweenCasesRule: OptInRule, AutomaticTestableRule {
public func validate(file: File) -> [StyleViolation] {
let patternRegex = regex(pattern)
return file.violatingRanges(for: pattern).compactMap { violationRange in
return violationRanges(in: file).compactMap { violationRange in
let substring = file.contents.substring(from: violationRange.location, length: violationRange.length)
let substringRange = NSRange(location: 0, length: substring.count)
guard let matchResult = patternRegex.firstMatch(in: substring, options: [], range: substringRange) else {
guard let matchResult = patternRegex.firstMatch(in: substring, options: [],
range: substring.fullNSRange) else {
return nil
}
@@ -140,7 +170,7 @@ extension VerticalWhitespaceBetweenCasesRule: OptInRule, AutomaticTestableRule {
extension VerticalWhitespaceBetweenCasesRule: CorrectableRule {
public func correct(file: File) -> [Correction] {
let violatingRanges = file.ruleEnabled(violatingRanges: file.violatingRanges(for: pattern), for: self)
let violatingRanges = file.ruleEnabled(violatingRanges: violationRanges(in: file), for: self)
guard !violatingRanges.isEmpty else { return [] }
let patternRegex = regex(pattern)