mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
fe5baca7cd
New APIs were introduced in SourceKitten to allow for a more typesafe distinction between integers meaning NSString-based distances and byte-based distances. * https://github.com/jpsim/SourceKitten/pull/639 * https://github.com/jpsim/SourceKitten/pull/642 This PR migrates SwiftLint's use of those APIs.
65 lines
2.3 KiB
Swift
65 lines
2.3 KiB
Swift
import SourceKittenFramework
|
|
|
|
extension ColonRule {
|
|
internal func dictionaryColonViolationRanges(in file: SwiftLintFile,
|
|
dictionary: SourceKittenDictionary) -> [ByteRange] {
|
|
guard configuration.applyToDictionaries else {
|
|
return []
|
|
}
|
|
|
|
let ranges: [ByteRange] = dictionary.traverseDepthFirst { subDict in
|
|
guard let kind = subDict.expressionKind else { return nil }
|
|
return dictionaryColonViolationRanges(in: file, kind: kind, dictionary: subDict)
|
|
}
|
|
|
|
return ranges.unique
|
|
}
|
|
|
|
internal func dictionaryColonViolationRanges(in file: SwiftLintFile, kind: SwiftExpressionKind,
|
|
dictionary: SourceKittenDictionary) -> [ByteRange] {
|
|
guard kind == .dictionary,
|
|
let ranges = dictionaryColonRanges(dictionary: dictionary) else {
|
|
return []
|
|
}
|
|
|
|
let contents = file.stringView
|
|
return ranges.filter {
|
|
guard let colon = contents.substringWithByteRange($0) else {
|
|
return false
|
|
}
|
|
|
|
if configuration.flexibleRightSpacing {
|
|
let isCorrect = colon.hasPrefix(": ") || colon.hasPrefix(":\n")
|
|
return !isCorrect
|
|
}
|
|
|
|
return colon != ": " && !colon.hasPrefix(":\n")
|
|
}
|
|
}
|
|
|
|
private func dictionaryColonRanges(dictionary: SourceKittenDictionary) -> [ByteRange]? {
|
|
let elements = dictionary.elements
|
|
guard elements.count % 2 == 0 else {
|
|
return nil
|
|
}
|
|
|
|
let expectedKind = "source.lang.swift.structure.elem.expr"
|
|
let ranges: [ByteRange] = elements.compactMap { subDict in
|
|
guard subDict.kind == expectedKind else {
|
|
return nil
|
|
}
|
|
|
|
return subDict.byteRange
|
|
}
|
|
|
|
let even = ranges.enumerated().compactMap { $0 % 2 == 0 ? $1 : nil }
|
|
let odd = ranges.enumerated().compactMap { $0 % 2 != 0 ? $1 : nil }
|
|
|
|
return zip(even, odd).map { evenRange, oddRange -> ByteRange in
|
|
let location = evenRange.upperBound
|
|
let length = oddRange.location - location
|
|
return ByteRange(location: location, length: length)
|
|
}
|
|
}
|
|
}
|