From 41868b35cb703b44ce8db3fc1896bc3f91af011d Mon Sep 17 00:00:00 2001 From: Marcelo Fabri Date: Sat, 5 Jan 2019 19:21:18 -0800 Subject: [PATCH] Improvements on unused_control_flow_label correction --- Rules.md | 2 +- .../Lint/UnusedControlFlowLabelRule.swift | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Rules.md b/Rules.md index 43d0637fdc..06dffb7167 100644 --- a/Rules.md +++ b/Rules.md @@ -21544,7 +21544,7 @@ func foo () { Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version --- | --- | --- | --- | --- | --- -`unused_control_flow_label` | Enabled | No | lint | No | 3.0.0 +`unused_control_flow_label` | Enabled | Yes | lint | No | 3.0.0 Unused control flow label should be removed. diff --git a/Source/SwiftLintFramework/Rules/Lint/UnusedControlFlowLabelRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnusedControlFlowLabelRule.swift index 5c530313f9..5934962c1e 100644 --- a/Source/SwiftLintFramework/Rules/Lint/UnusedControlFlowLabelRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/UnusedControlFlowLabelRule.swift @@ -98,19 +98,18 @@ public struct UnusedControlFlowLabelRule: ASTRule, ConfigurationProviderRule, Au } public func correct(file: File) -> [Correction] { - let matches = violationRanges(in: file) - .filter { !file.ruleEnabled(violatingRanges: [$0], for: self).isEmpty } - guard !matches.isEmpty else { return [] } + let violatingRanges = file.ruleEnabled(violatingRanges: violationRanges(in: file), for: self) + guard !violatingRanges.isEmpty else { return [] } let description = type(of: self).description var corrections = [Correction]() var contents = file.contents - for range in matches { + for range in violatingRanges.reversed() { var rangeToRemove = range - if let byteRange = file.contents.bridge().NSRangeToByteRange(start: range.location, length: range.length), - let nextToken = file.syntaxMap.tokens.first(where: { $0.offset > byteRange.location }), - let nextTokenCharacterLocation = file.contents.bridge().byteRangeToNSRange(start: nextToken.offset, length: 0) { - rangeToRemove.length = nextTokenCharacterLocation.location - range.location + if let byteRange = contents.bridge().NSRangeToByteRange(start: range.location, length: range.length), + let nextToken = file.syntaxMap.tokens.firstToken(afterByteOffset: byteRange.location), + let nextTokenLocation = contents.bridge().byteRangeToNSRange(start: nextToken.offset, length: 0) { + rangeToRemove.length = nextTokenLocation.location - range.location } contents = contents.bridge().replacingCharacters(in: rangeToRemove, with: "") @@ -137,11 +136,13 @@ public struct UnusedControlFlowLabelRule: ASTRule, ConfigurationProviderRule, Au } let pattern = "(?:break|continue)\\s+\(tokenContent)\\b" - guard file.match(pattern: pattern, with: [.keyword, .identifier], range: range).isEmpty else { - return [] + guard file.match(pattern: pattern, with: [.keyword, .identifier], range: range).isEmpty, + let violationRange = contents.byteRangeToNSRange(start: firstToken.offset, + length: firstToken.length) else { + return [] } - return [file.contents.bridge().byteRangeToNSRange(start: firstToken.offset, length: firstToken.length)!] + return [violationRange] } private func violationRanges(in file: File, dictionary: [String: SourceKitRepresentable]) -> [NSRange] { @@ -170,7 +171,7 @@ private extension NSString { } } -extension Collection where Element == SyntaxToken { +private extension Collection where Element == SyntaxToken { func firstToken(afterByteOffset byteOffset: Int) -> SyntaxToken? { return first(where: { $0.offset > byteOffset }) }