Skip to content

Commit

Permalink
Merge pull request #1 from SDGGiesbrecht/trailing-comma-autocorrect
Browse files Browse the repository at this point in the history
Simplified Offset Processing
  • Loading branch information
sammy-SC authored Mar 27, 2017
2 parents 3d09483 + 0a15729 commit e70af82
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 58 deletions.
31 changes: 13 additions & 18 deletions Source/SwiftLintFramework/Rules/TrailingCommaRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public struct TrailingCommaRule: ASTRule, CorrectableRule, ConfigurationProvider
"let foo = [1: 2, 2: 3↓, ]\n",
"struct Bar {\n let foo = [1: 2, 2: 3↓, ]\n}\n",
"let foo = [1, 2, 3↓,] + [4, 5, 6↓,]\n",
"let example = [ 1,\n2↓,\n // 3,\n]"
"let example = [ 1,\n2↓,\n // 3,\n]",
"let foo = [\"אבג\", \"αβγ\", \"🇺🇸\"↓,]\n"
// "foo([1: \"\\(error)\"↓,])\n"
],
corrections: [
Expand All @@ -51,6 +52,7 @@ public struct TrailingCommaRule: ASTRule, CorrectableRule, ConfigurationProvider
"let foo = [1: 2, 2: 3↓, ]\n": "let foo = [1: 2, 2: 3 ]\n",
"struct Bar {\n let foo = [1: 2, 2: 3↓, ]\n}\n": "struct Bar {\n let foo = [1: 2, 2: 3 ]\n}\n",
"let foo = [1, 2, 3↓,] + [4, 5, 6↓,]\n": "let foo = [1, 2, 3] + [4, 5, 6]\n",
"let example = [ 1,\n2↓,\n // 3,\n]": "let example = [ 1,\n2\n // 3,\n]",
"let foo = [\"אבג\", \"αβγ\", \"🇺🇸\"↓,]\n": "let foo = [\"אבג\", \"αβγ\", \"🇺🇸\"]\n"
]
)
Expand Down Expand Up @@ -160,38 +162,31 @@ public struct TrailingCommaRule: ASTRule, CorrectableRule, ConfigurationProvider

public func correct(file: File) -> [Correction] {
let violations = violationRanges(in: file, dictionary: file.structure.dictionary)
let correctedViolations = violations.map { range -> NSRange in
let index = file.contents.utf8.index(file.contents.utf8.startIndex,
offsetBy: range.location)
let index16 = index.samePosition(in: file.contents.utf16)!
let correctedCharacterOffset = file.contents.utf16.distance(from: file.contents.utf16.startIndex,
to: index16)
return NSRange(location: correctedCharacterOffset, length: range.length)
let correctedViolations = violations.map {
file.contents.bridge().byteRangeToNSRange(start: $0.location, length: $0.length)!
}

let matches = file.ruleEnabled(violatingRanges: correctedViolations, for: self).map { $0.location }
let matches = file.ruleEnabled(violatingRanges: correctedViolations, for: self)

if matches.isEmpty { return [] }

var correctedContents = file.contents
let correctedContents = NSMutableString(string: file.contents)

matches.reversed().forEach { offset in
let index = correctedContents.utf16.index(correctedContents.utf16.startIndex, offsetBy: offset)
let correctedIndex = index.samePosition(in: correctedContents)!
matches.reversed().forEach { range in
if configuration.mandatoryComma {
correctedContents.characters.insert(",", at: correctedIndex)
correctedContents.insert(",", at: range.location)
} else {
correctedContents.characters.remove(at: correctedIndex)
correctedContents.deleteCharacters(in: range)
}
}

let description = type(of: self).description
let corrections = matches.map { offset -> Correction in
let location = Location(file: file, characterOffset: offset)
let corrections = matches.map { range -> Correction in
let location = Location(file: file, characterOffset: range.location)
return Correction(ruleDescription: description, location: location)
}

file.write(correctedContents)
file.write(correctedContents as String)

return corrections
}
Expand Down
7 changes: 3 additions & 4 deletions Tests/SwiftLintFrameworkTests/TestHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ private func render(locations: [Location], in contents: String) -> String {
var contents = contents.bridge().lines().map { $0.content }
for location in locations.sorted(by: > ) {
guard let line = location.line, let character = location.character else { continue }
var content = contents[line - 1]
let index = content.index(content.startIndex, offsetBy: character - 1)
content.insert("", at: index)
contents[line - 1] = content
let content = NSMutableString(string: contents[line - 1])
content.insert("", at: character - 1)
contents[line - 1] = content as String
}
return (["```"] + contents + ["```"]).joined(separator: "\n")
}
Expand Down
75 changes: 39 additions & 36 deletions Tests/SwiftLintFrameworkTests/TrailingCommaRuleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,44 +26,47 @@ class TrailingCommaRuleTests: XCTestCase {
)
}

private let mandatoryCommaRuleDescription = RuleDescription(
identifier: TrailingCommaRule.description.identifier,
name: TrailingCommaRule.description.name,
description: TrailingCommaRule.description.description,
nonTriggeringExamples: [
"let foo = []\n",
"let foo = [:]\n",
"let foo = [1, 2, 3,]\n",
"let foo = [1, 2, 3, ]\n",
"let foo = [1, 2, 3 ,]\n",
"let foo = [1: 2, 2: 3, ]\n",
"struct Bar {\n let foo = [1: 2, 2: 3,]\n}\n",
"let foo = [Void]()\n",
"let foo = [(Void, Void)]()\n",
"let foo = [1, 2, 3]\n",
"let foo = [1: 2, 2: 3]\n",
"let foo = [1: 2, 2: 3 ]\n",
"struct Bar {\n let foo = [1: 2, 2: 3]\n}\n",
"let foo = [1, 2, 3] + [4, 5, 6]\n"
],
triggeringExamples: [
"let foo = [1, 2,\n 3↓]\n",
"let foo = [1: 2,\n 2: 3↓]\n",
"let foo = [1: 2,\n 2: 3↓ ]\n",
"struct Bar {\n let foo = [1: 2,\n 2: 3↓]\n}\n",
"let foo = [1, 2,\n 3↓] + [4,\n 5, 6↓]\n",
"let foo = [\"אבג\", \"αβγ\",\n\"🇺🇸\"↓]\n"
],
corrections: [
"let foo = [1, 2,\n 3↓]\n": "let foo = [1, 2,\n 3,]\n",
"let foo = [1: 2,\n 2: 3↓]\n": "let foo = [1: 2,\n 2: 3,]\n",
"let foo = [1: 2,\n 2: 3↓ ]\n": "let foo = [1: 2,\n 2: 3, ]\n",
"struct Bar {\n let foo = [1: 2,\n 2: 3↓]\n}\n": "struct Bar {\n let foo = [1: 2,\n 2: 3,]\n}\n",
"let foo = [1, 2,\n 3↓] + [4,\n 5, 6↓]\n": "let foo = [1, 2,\n 3,] + [4,\n 5, 6,]\n",
"let foo = [\"אבג\", \"αβγ\",\n\"🇺🇸\"↓]\n": "let foo = [\"אבג\", \"αβγ\",\n\"🇺🇸\",]\n"
]
)

func testTrailingCommaRuleWithMandatoryComma() {
// Verify TrailingCommaRule with test values for when mandatory_comma is true.
let ruleDescription = RuleDescription(
identifier: TrailingCommaRule.description.identifier,
name: TrailingCommaRule.description.name,
description: TrailingCommaRule.description.description,
nonTriggeringExamples: [
"let foo = []\n",
"let foo = [:]\n",
"let foo = [1, 2, 3,]\n",
"let foo = [1, 2, 3, ]\n",
"let foo = [1, 2, 3 ,]\n",
"let foo = [1: 2, 2: 3, ]\n",
"struct Bar {\n let foo = [1: 2, 2: 3,]\n}\n",
"let foo = [Void]()\n",
"let foo = [(Void, Void)]()\n",
"let foo = [1, 2, 3]\n",
"let foo = [1: 2, 2: 3]\n",
"let foo = [1: 2, 2: 3 ]\n",
"struct Bar {\n let foo = [1: 2, 2: 3]\n}\n",
"let foo = [1, 2, 3] + [4, 5, 6]\n"
],
triggeringExamples: [
"let foo = [1, 2,\n 3↓]\n",
"let foo = [1: 2,\n 2: 3↓]\n",
"let foo = [1: 2,\n 2: 3↓ ]\n",
"struct Bar {\n let foo = [1: 2,\n 2: 3↓]\n}\n",
"let foo = [1, 2,\n 3↓] + [4,\n 5, 6↓]\n"
],
corrections: [
"let foo = [1, 2,\n 3↓]\n": "let foo = [1, 2,\n 3,]\n",
"let foo = [1: 2,\n 2: 3↓]\n": "let foo = [1: 2,\n 2: 3,]\n",
"let foo = [1: 2,\n 2: 3↓ ]\n": "let foo = [1: 2,\n 2: 3, ]\n",
"struct Bar {\n let foo = [1: 2,\n 2: 3↓]\n}\n": "struct Bar {\n let foo = [1: 2,\n 2: 3,]\n}\n",
"let foo = [1, 2,\n 3↓] + [4,\n 5, 6↓]\n": "let foo = [1, 2,\n 3,] + [4,\n 5, 6,]\n"
]

)
let ruleDescription = mandatoryCommaRuleDescription
let ruleConfiguration = ["mandatory_comma": true]

verifyRule(ruleDescription, ruleConfiguration: ruleConfiguration)
Expand Down

0 comments on commit e70af82

Please sign in to comment.