Compare commits
6 Commits
main
...
feature/ne
Author | SHA1 | Date |
---|---|---|
![]() |
d5ac1b2be1 | |
![]() |
25d89926ac | |
![]() |
8b307ba960 | |
![]() |
03e1c32230 | |
![]() |
92b27e02ec | |
![]() |
0dcc37ecca |
|
@ -9,7 +9,7 @@
|
|||
url = https://github.com/Carthage/Commandant.git
|
||||
[submodule "Carthage/Checkouts/SourceKitten"]
|
||||
path = Carthage/Checkouts/SourceKitten
|
||||
url = https://github.com/jpsim/SourceKitten.git
|
||||
url = https://github.com/PaulTaykalo/SourceKitten.git
|
||||
[submodule "Carthage/Checkouts/SwiftyTextTable"]
|
||||
path = Carthage/Checkouts/SwiftyTextTable
|
||||
url = https://github.com/scottrhoyt/SwiftyTextTable.git
|
||||
|
|
2
Cartfile
2
Cartfile
|
@ -1,2 +1,2 @@
|
|||
github "jpsim/SourceKitten" ~> 0.27.0
|
||||
github "PaulTaykalo/SourceKitten" "f5287da"
|
||||
github "scottrhoyt/SwiftyTextTable" ~> 0.9.0
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
github "Carthage/Commandant" "0.17.0"
|
||||
github "PaulTaykalo/SourceKitten" "f5287da0c67e41a24ec5c9f3a001a88d66cf3168"
|
||||
github "drmohundro/SWXMLHash" "5.0.1"
|
||||
github "jpsim/SourceKitten" "0.27.0"
|
||||
github "jpsim/Yams" "2.0.0"
|
||||
github "jspahrsummers/xcconfigs" "0.12"
|
||||
github "scottrhoyt/SwiftyTextTable" "0.9.0"
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 356551fc513eb12ed779bb369f79cf86a3a01599
|
||||
Subproject commit f5287da0c67e41a24ec5c9f3a001a88d66cf3168
|
|
@ -48,11 +48,11 @@
|
|||
},
|
||||
{
|
||||
"package": "SourceKitten",
|
||||
"repositoryURL": "https://github.com/jpsim/SourceKitten.git",
|
||||
"repositoryURL": "https://github.com/PaulTaykalo/SourceKitten.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "356551fc513eb12ed779bb369f79cf86a3a01599",
|
||||
"version": "0.27.0"
|
||||
"branch": "f5287da",
|
||||
"revision": "f5287da0c67e41a24ec5c9f3a001a88d66cf3168",
|
||||
"version": null
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ let package = Package(
|
|||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/Carthage/Commandant.git", .upToNextMinor(from: "0.17.0")),
|
||||
.package(url: "https://github.com/jpsim/SourceKitten.git", from: "0.27.0"),
|
||||
.package(url: "https://github.com/PaulTaykalo/SourceKitten.git", .revision("f5287da")),
|
||||
.package(url: "https://github.com/jpsim/Yams.git", from: "2.0.0"),
|
||||
.package(url: "https://github.com/scottrhoyt/SwiftyTextTable.git", from: "0.9.0"),
|
||||
] + (addCryptoSwift ? [.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMinor(from: "1.0.0"))] : []),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Foundation
|
||||
import SourceKittenFramework
|
||||
|
||||
private var regexCache = [RegexCacheKey: NSRegularExpression]()
|
||||
private let regexCacheLock = NSLock()
|
||||
|
@ -33,3 +34,21 @@ extension NSRegularExpression {
|
|||
return result
|
||||
}
|
||||
}
|
||||
|
||||
extension NSRegularExpression {
|
||||
internal func matches(in stringView: StringView,
|
||||
options: NSRegularExpression.MatchingOptions = []) -> [NSTextCheckingResult] {
|
||||
return matches(in: stringView.string, options: options, range: stringView.range)
|
||||
}
|
||||
|
||||
internal func matches(in stringView: StringView,
|
||||
options: NSRegularExpression.MatchingOptions = [],
|
||||
range: NSRange) -> [NSTextCheckingResult] {
|
||||
return matches(in: stringView.string, options: options, range: range)
|
||||
}
|
||||
|
||||
internal func matches(in file: SwiftLintFile,
|
||||
options: NSRegularExpression.MatchingOptions = []) -> [NSTextCheckingResult] {
|
||||
return matches(in: file.stringView.string, options: options, range: file.stringView.range)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,11 +58,16 @@ extension SwiftLintFile {
|
|||
if sourcekitdFailed {
|
||||
return []
|
||||
}
|
||||
let contents = self.contents.bridge()
|
||||
let range = range ?? NSRange(location: 0, length: contents.length)
|
||||
let contents = stringView
|
||||
let range = range ?? stringView.range
|
||||
let pattern = "swiftlint:(enable|disable)(:previous|:this|:next)?\\ [^\\n]+"
|
||||
return match(pattern: pattern, with: [.comment], range: range).compactMap { range in
|
||||
return Command(string: contents, range: range)
|
||||
return match(pattern: pattern, with: [.comment], range: range).compactMap { range -> Command? in
|
||||
let actionString = contents.substring(with: range)
|
||||
guard let lineAndCharacter = stringView.lineAndCharacter(forCharacterOffset: NSMaxRange(range))
|
||||
else { return nil }
|
||||
return Command(actionString: actionString,
|
||||
line: lineAndCharacter.line,
|
||||
character: lineAndCharacter.character)
|
||||
}.flatMap { command in
|
||||
return command.expand()
|
||||
}
|
||||
|
@ -96,10 +101,10 @@ extension SwiftLintFile {
|
|||
|
||||
internal func matchesAndTokens(matching pattern: String,
|
||||
range: NSRange? = nil) -> [(NSTextCheckingResult, [SwiftLintSyntaxToken])] {
|
||||
let contents = self.contents.bridge()
|
||||
let range = range ?? NSRange(location: 0, length: contents.length)
|
||||
let contents = stringView
|
||||
let range = range ?? stringView.range
|
||||
let syntax = syntaxMap
|
||||
return regex(pattern).matches(in: self.contents, options: [], range: range).map { match in
|
||||
return regex(pattern).matches(in: contents, options: [], range: range).map { match in
|
||||
let matchByteRange = contents.NSRangeToByteRange(start: match.range.location,
|
||||
length: match.range.length) ?? match.range
|
||||
let tokensInRange = syntax.tokens(inByteRange: matchByteRange)
|
||||
|
@ -217,8 +222,8 @@ extension SwiftLintFile {
|
|||
if matches.isEmpty {
|
||||
return []
|
||||
}
|
||||
let range = range ?? NSRange(location: 0, length: contents.bridge().length)
|
||||
let exclusionRanges = regex(excludingPattern).matches(in: contents, options: [],
|
||||
let range = range ?? stringView.range
|
||||
let exclusionRanges = regex(excludingPattern).matches(in: stringView, options: [],
|
||||
range: range).map(exclusionMapping)
|
||||
return matches.filter { !$0.intersects(exclusionRanges) }
|
||||
}
|
||||
|
@ -233,6 +238,7 @@ extension SwiftLintFile {
|
|||
_ = fileHandle.seekToEndOfFile()
|
||||
fileHandle.write(stringData)
|
||||
fileHandle.closeFile()
|
||||
|
||||
file.contents += string
|
||||
}
|
||||
|
||||
|
@ -327,7 +333,6 @@ extension SwiftLintFile {
|
|||
}
|
||||
|
||||
internal func contents(for token: SwiftLintSyntaxToken) -> String? {
|
||||
return contents.bridge().substringWithByteRange(start: token.offset,
|
||||
length: token.length)
|
||||
return stringView.substringWithByteRange(start: token.offset, length: token.length)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Foundation
|
||||
import SourceKittenFramework
|
||||
|
||||
#if os(Linux)
|
||||
private extension Scanner {
|
||||
|
@ -72,8 +73,8 @@ public struct Command: Equatable {
|
|||
self.trailingComment = trailingComment
|
||||
}
|
||||
|
||||
public init?(string: NSString, range: NSRange) {
|
||||
let scanner = Scanner(string: string.substring(with: range))
|
||||
public init?(actionString: String, line: Int, character: Int) {
|
||||
let scanner = Scanner(string: actionString)
|
||||
_ = scanner.scanString(string: "swiftlint:")
|
||||
// (enable|disable)(:previous|:this|:next)
|
||||
guard let actionAndModifierString = scanner.scanUpToString(" ") else {
|
||||
|
@ -81,14 +82,13 @@ public struct Command: Equatable {
|
|||
}
|
||||
let actionAndModifierScanner = Scanner(string: actionAndModifierString)
|
||||
guard let actionString = actionAndModifierScanner.scanUpToString(":"),
|
||||
let action = Action(rawValue: actionString),
|
||||
let lineAndCharacter = string.lineAndCharacter(forCharacterOffset: NSMaxRange(range))
|
||||
let action = Action(rawValue: actionString)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
self.action = action
|
||||
line = lineAndCharacter.line
|
||||
character = lineAndCharacter.character
|
||||
self.line = line
|
||||
self.character = character
|
||||
|
||||
let rawRuleTexts = scanner.scanUpToString(Command.commentDelimiter) ?? ""
|
||||
if scanner.isAtEnd {
|
||||
|
|
|
@ -25,7 +25,7 @@ public struct Location: CustomStringConvertible, Comparable, Codable {
|
|||
|
||||
public init(file: SwiftLintFile, byteOffset offset: Int) {
|
||||
self.file = file.path
|
||||
if let lineAndCharacter = file.contents.bridge().lineAndCharacter(forByteOffset: offset) {
|
||||
if let lineAndCharacter = file.stringView.lineAndCharacter(forByteOffset: offset) {
|
||||
line = lineAndCharacter.line
|
||||
character = lineAndCharacter.character
|
||||
} else {
|
||||
|
@ -36,7 +36,7 @@ public struct Location: CustomStringConvertible, Comparable, Codable {
|
|||
|
||||
public init(file: SwiftLintFile, characterOffset offset: Int) {
|
||||
self.file = file.path
|
||||
if let lineAndCharacter = file.contents.bridge().lineAndCharacter(forCharacterOffset: offset) {
|
||||
if let lineAndCharacter = file.stringView.lineAndCharacter(forCharacterOffset: offset) {
|
||||
line = lineAndCharacter.line
|
||||
character = lineAndCharacter.character
|
||||
} else {
|
||||
|
|
|
@ -41,6 +41,10 @@ public final class SwiftLintFile {
|
|||
return file.contents
|
||||
}
|
||||
|
||||
public var stringView: StringView {
|
||||
return file.stringView
|
||||
}
|
||||
|
||||
public var lines: [Line] {
|
||||
return file.lines
|
||||
}
|
||||
|
|
|
@ -34,15 +34,13 @@ extension CallPairRule {
|
|||
reason: String? = nil,
|
||||
predicate: (SourceKittenDictionary) -> Bool = { _ in true }) -> [StyleViolation] {
|
||||
let firstRanges = file.match(pattern: pattern, with: patternSyntaxKinds)
|
||||
let contents = file.contents.bridge()
|
||||
let stringView = file.stringView
|
||||
let dictionary = file.structureDictionary
|
||||
|
||||
let violatingLocations: [Int] = firstRanges.compactMap { range in
|
||||
guard let bodyByteRange = contents.NSRangeToByteRange(start: range.location,
|
||||
length: range.length),
|
||||
guard let bodyByteRange = stringView.NSRangeToByteRange(start: range.location, length: range.length),
|
||||
case let firstLocation = range.location + range.length - 1,
|
||||
let firstByteRange = contents.NSRangeToByteRange(start: firstLocation,
|
||||
length: 1) else {
|
||||
let firstByteRange = stringView.NSRangeToByteRange(start: firstLocation, length: 1) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ public struct ConvenienceTypeRule: ASTRule, OptInRule, ConfigurationProviderRule
|
|||
return dictionary.swiftAttributes.contains { dict -> Bool in
|
||||
guard dict.attribute.flatMap(SwiftDeclarationAttributeKind.init(rawValue:)) == .available,
|
||||
let offset = dict.offset, let length = dict.length,
|
||||
let contents = file.contents.bridge().substringWithByteRange(start: offset, length: length) else {
|
||||
let contents = file.stringView.substringWithByteRange(start: offset, length: length) else {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@ public struct DiscouragedOptionalCollectionRule: ASTRule, OptInRule, Configurati
|
|||
let offset = dictionary.offset,
|
||||
case let start = nameOffset + nameLength,
|
||||
case let end = dictionary.bodyOffset ?? offset + length,
|
||||
case let contents = file.contents.bridge(),
|
||||
let range = contents.byteRangeToNSRange(start: start, length: end - start),
|
||||
case let contents = file.stringView,
|
||||
let range = file.stringView.byteRangeToNSRange(start: start, length: end - start),
|
||||
let match = file.match(pattern: "->\\s*(.*?)\\{", excludingSyntaxKinds: excludingKinds, range: range).first
|
||||
else { return [] }
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ public struct DuplicateImportsRule: ConfigurationProviderRule, AutomaticTestable
|
|||
)
|
||||
|
||||
private func rangesInConditionalCompilation(file: SwiftLintFile) -> [NSRange] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
let ranges = file.syntaxMap.tokens
|
||||
.filter { $0.kind == .buildconfigKeyword }
|
||||
|
@ -39,7 +39,7 @@ public struct DuplicateImportsRule: ConfigurationProviderRule, AutomaticTestable
|
|||
}
|
||||
|
||||
public func validate(file: SwiftLintFile) -> [StyleViolation] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
let ignoredRanges = self.rangesInConditionalCompilation(file: file)
|
||||
|
||||
|
@ -55,7 +55,7 @@ public struct DuplicateImportsRule: ConfigurationProviderRule, AutomaticTestable
|
|||
return !importRange.intersects(ignoredRanges)
|
||||
}
|
||||
|
||||
let lines = contents.lines()
|
||||
let lines = file.lines
|
||||
|
||||
let importLines: [Line] = importRanges.compactMap { range in
|
||||
guard let line = contents.lineAndCharacter(forByteOffset: range.location)?.line
|
||||
|
|
|
@ -54,7 +54,7 @@ public struct ExplicitACLRule: OptInRule, ConfigurationProviderRule, AutomaticTe
|
|||
)
|
||||
|
||||
private func findAllExplicitInternalTokens(in file: SwiftLintFile) -> [NSRange] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return file.match(pattern: "internal", with: [.attributeBuiltin]).compactMap {
|
||||
contents.NSRangeToByteRange(start: $0.location, length: $0.length)
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public struct ExplicitInitRule: SubstitutionCorrectableASTRule, ConfigurationPro
|
|||
let name = dictionary.name, isExpected(name),
|
||||
let nameOffset = dictionary.nameOffset,
|
||||
let nameLength = dictionary.nameLength,
|
||||
let range = file.contents.bridge()
|
||||
let range = file.stringView
|
||||
.byteRangeToNSRange(start: nameOffset + nameLength - length, length: length)
|
||||
else { return [] }
|
||||
return [range]
|
||||
|
|
|
@ -56,7 +56,7 @@ public struct ExplicitTopLevelACLRule: OptInRule, ConfigurationProviderRule, Aut
|
|||
}
|
||||
|
||||
// find all "internal" tokens
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
let allInternalRanges = file.match(pattern: "internal", with: [.attributeBuiltin]).compactMap {
|
||||
contents.NSRangeToByteRange(start: $0.location, length: $0.length)
|
||||
}
|
||||
|
|
|
@ -108,13 +108,13 @@ private extension SourceKittenDictionary {
|
|||
guard
|
||||
let nameOffset = nameOffset,
|
||||
let nameLength = nameLength,
|
||||
case let contents = file.contents.bridge(),
|
||||
let afterNameRange = contents.byteRangeToNSRange(start: nameOffset + nameLength, length: 0)
|
||||
let afterNameRange = file.stringView.byteRangeToNSRange(start: nameOffset + nameLength, length: 0)
|
||||
else {
|
||||
return false
|
||||
}
|
||||
|
||||
let contentAfterName = contents.substring(from: afterNameRange.location)
|
||||
let contents = file.stringView
|
||||
let contentAfterName = contents.nsString.substring(from: afterNameRange.location)
|
||||
let initCallRegex =
|
||||
regex("^\\s*=\\s*(?:try[!?]?\\s+)?\\[?\\p{Lu}[^\\(\\s<]*(?:<[^\\>]*>)?(?::\\s*[^\\(\\n]+)?\\]?\\(")
|
||||
|
||||
|
@ -125,13 +125,13 @@ private extension SourceKittenDictionary {
|
|||
guard
|
||||
let nameOffset = nameOffset,
|
||||
let nameLength = nameLength,
|
||||
case let contents = file.contents.bridge(),
|
||||
let afterNameRange = contents.byteRangeToNSRange(start: nameOffset + nameLength, length: 0)
|
||||
let afterNameRange = file.stringView.byteRangeToNSRange(start: nameOffset + nameLength, length: 0)
|
||||
else {
|
||||
return false
|
||||
}
|
||||
|
||||
let contentAfterName = contents.substring(from: afterNameRange.location)
|
||||
let contents = file.stringView
|
||||
let contentAfterName = contents.nsString.substring(from: afterNameRange.location)
|
||||
let typeAssignment = regex("^\\s*=\\s*(?:\\p{Lu}[^\\(\\s<]*(?:<[^\\>]*>)?\\.)*self")
|
||||
|
||||
return typeAssignment.firstMatch(in: contentAfterName, options: [], range: contentAfterName.fullNSRange) != nil
|
||||
|
@ -170,7 +170,7 @@ private extension SwiftLintFile {
|
|||
var captureGroupByteRanges: [NSRange] {
|
||||
return match(pattern: "\\{\\s*\\[(\\s*\\w+\\s+\\w+,*)+\\]",
|
||||
excludingSyntaxKinds: SyntaxKind.commentKinds)
|
||||
.compactMap { contents.bridge().NSRangeToByteRange(start: $0.location, length: $0.length) }
|
||||
.compactMap { stringView.NSRangeToByteRange(start: $0.location, length: $0.length) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ public struct ExtensionAccessModifierRule: ASTRule, ConfigurationProviderRule, O
|
|||
declarationOffsets: [Int],
|
||||
dictionary: SourceKittenDictionary) -> [StyleViolation] {
|
||||
guard let offset = dictionary.offset, let length = dictionary.length,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let range = contents.byteRangeToNSRange(start: offset, length: length) else {
|
||||
return []
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public struct FatalErrorMessageRule: ASTRule, ConfigurationProviderRule, OptInRu
|
|||
return true
|
||||
}
|
||||
|
||||
let body = file.contents.bridge().substringWithByteRange(start: bodyOffset, length: bodyLength)
|
||||
let body = file.stringView.substringWithByteRange(start: bodyOffset, length: bodyLength)
|
||||
return body == "\"\""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ public struct ForWhereRule: ASTRule, ConfigurationProviderRule, AutomaticTestabl
|
|||
|
||||
private func isComplexCondition(dictionary: SourceKittenDictionary, file: SwiftLintFile) -> Bool {
|
||||
let kind = "source.lang.swift.structure.elem.condition_expr"
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return dictionary.elements.contains { element in
|
||||
guard element.kind == kind,
|
||||
let offset = element.offset,
|
||||
|
|
|
@ -80,44 +80,41 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule, Automat
|
|||
private static let excludingSyntaxKindsForSecondCapture = SyntaxKind.commentAndStringKinds
|
||||
|
||||
private func violationRanges(in file: SwiftLintFile) -> [NSRange] {
|
||||
let contents = file.contents
|
||||
let nsstring = contents.bridge()
|
||||
let range = NSRange(location: 0, length: nsstring.length)
|
||||
let syntaxMap = file.syntaxMap
|
||||
|
||||
let varDeclarationRanges = ForceUnwrappingRule.varDeclarationRegularExpression
|
||||
.matches(in: contents, options: [], range: range)
|
||||
.matches(in: file)
|
||||
.compactMap { match -> NSRange? in
|
||||
return match.range
|
||||
}
|
||||
|
||||
let functionDeclarationRanges = regex(ForceUnwrappingRule.functionReturnPattern)
|
||||
.matches(in: contents, options: [], range: range)
|
||||
.matches(in: file)
|
||||
.compactMap { match -> NSRange? in
|
||||
return match.range
|
||||
}
|
||||
|
||||
return ForceUnwrappingRule.regularExpression
|
||||
.matches(in: contents, options: [], range: range)
|
||||
.matches(in: file)
|
||||
.compactMap { match -> NSRange? in
|
||||
if match.range.intersects(varDeclarationRanges) || match.range.intersects(functionDeclarationRanges) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return violationRange(match: match, nsstring: nsstring, syntaxMap: syntaxMap, file: file)
|
||||
return violationRange(match: match, syntaxMap: syntaxMap, file: file)
|
||||
}
|
||||
}
|
||||
|
||||
private func violationRange(match: NSTextCheckingResult, nsstring: NSString, syntaxMap: SwiftLintSyntaxMap,
|
||||
private func violationRange(match: NSTextCheckingResult, syntaxMap: SwiftLintSyntaxMap,
|
||||
file: SwiftLintFile) -> NSRange? {
|
||||
if match.numberOfRanges < 3 { return nil }
|
||||
|
||||
let firstRange = match.range(at: 1)
|
||||
let secondRange = match.range(at: 2)
|
||||
|
||||
guard let matchByteFirstRange = nsstring
|
||||
guard let matchByteFirstRange = file.stringView
|
||||
.NSRangeToByteRange(start: firstRange.location, length: firstRange.length),
|
||||
let matchByteSecondRange = nsstring
|
||||
let matchByteSecondRange = file.stringView
|
||||
.NSRangeToByteRange(start: secondRange.location, length: secondRange.length)
|
||||
else { return nil }
|
||||
|
||||
|
@ -139,14 +136,14 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule, Automat
|
|||
// check if firstCapturedString is either ")" or "]"
|
||||
// and '!' is not within comment or string
|
||||
// and matchByteFirstRange is not a type annotation
|
||||
let firstCapturedString = nsstring.substring(with: firstRange)
|
||||
let firstCapturedString = file.stringView.substring(with: firstRange)
|
||||
if [")", "]"].contains(firstCapturedString) {
|
||||
// check second capture '!'
|
||||
let kindsInSecondRange = syntaxMap.kinds(inByteRange: matchByteSecondRange)
|
||||
let forceUnwrapNotInCommentOrString = !kindsInSecondRange
|
||||
.contains(where: ForceUnwrappingRule.excludingSyntaxKindsForSecondCapture.contains)
|
||||
if forceUnwrapNotInCommentOrString &&
|
||||
!isTypeAnnotation(in: file, contents: nsstring, byteRange: matchByteFirstRange) {
|
||||
!isTypeAnnotation(in: file, byteRange: matchByteFirstRange) {
|
||||
return violationRange
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +166,7 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule, Automat
|
|||
}
|
||||
|
||||
// check deepest kind matching range in structure is a typeAnnotation
|
||||
private func isTypeAnnotation(in file: SwiftLintFile, contents: NSString, byteRange: NSRange) -> Bool {
|
||||
private func isTypeAnnotation(in file: SwiftLintFile, byteRange: NSRange) -> Bool {
|
||||
let kinds = file.structureDictionary.kinds(forByteOffset: byteRange.location)
|
||||
guard let lastItem = kinds.last,
|
||||
let lastKind = SwiftDeclarationKind(rawValue: lastItem.kind),
|
||||
|
@ -180,7 +177,7 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule, Automat
|
|||
// range is in some "source.lang.swift.decl.var.*"
|
||||
let byteOffset = lastItem.byteRange.location
|
||||
let byteLength = byteRange.location - byteOffset
|
||||
if let varDeclarationString = contents.substringWithByteRange(start: byteOffset, length: byteLength),
|
||||
if let varDeclarationString = file.stringView.substringWithByteRange(start: byteOffset, length: byteLength),
|
||||
varDeclarationString.contains("=") {
|
||||
// if declarations contains "=", range is not type annotation
|
||||
return false
|
||||
|
|
|
@ -97,7 +97,7 @@ public struct FunctionDefaultParameterAtEndRule: ASTRule, ConfigurationProviderR
|
|||
}
|
||||
|
||||
private func isDefaultParameter(file: SwiftLintFile, dictionary: SourceKittenDictionary) -> Bool {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let offset = dictionary.offset, let length = dictionary.length,
|
||||
let range = contents.byteRangeToNSRange(start: offset, length: length) else {
|
||||
return false
|
||||
|
|
|
@ -130,7 +130,7 @@ extension GenericTypeNameRule {
|
|||
return []
|
||||
}
|
||||
|
||||
let genericConstraint = file.contents.bridge().substring(with: match)
|
||||
let genericConstraint = file.stringView.substring(with: match)
|
||||
return extractTypes(fromGenericConstraint: genericConstraint, offset: match.location, file: file)
|
||||
}.flatMap { validate(name: $0.0, file: file, offset: $0.1) }
|
||||
}
|
||||
|
@ -141,10 +141,10 @@ extension GenericTypeNameRule {
|
|||
let nameOffset = dictionary.nameOffset,
|
||||
let nameLength = dictionary.nameLength,
|
||||
let bodyOffset = dictionary.bodyOffset,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
case let start = nameOffset + nameLength,
|
||||
case let length = bodyOffset - start,
|
||||
let range = contents.byteRangeToNSRange(start: start, length: length),
|
||||
let range = file.stringView.byteRangeToNSRange(start: start, length: length),
|
||||
let match = type(of: self).genericTypeRegex.firstMatch(in: file.contents, options: [],
|
||||
range: range)?.range(at: 1) else {
|
||||
return []
|
||||
|
@ -159,7 +159,7 @@ extension GenericTypeNameRule {
|
|||
guard SwiftDeclarationKind.functionKinds.contains(kind),
|
||||
let offset = dictionary.nameOffset,
|
||||
let length = dictionary.nameLength,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let range = contents.byteRangeToNSRange(start: offset, length: length),
|
||||
let match = type(of: self).genericTypeRegex.firstMatch(in: file.contents,
|
||||
options: [], range: range)?.range(at: 1),
|
||||
|
@ -174,7 +174,7 @@ extension GenericTypeNameRule {
|
|||
private func minParameterOffset(parameters: [SourceKittenDictionary], file: SwiftLintFile) -> Int {
|
||||
let offsets = parameters.compactMap { param -> Int? in
|
||||
return param.offset.flatMap {
|
||||
file.contents.bridge().byteRangeToNSRange(start: $0, length: 0)?.location
|
||||
file.stringView.byteRangeToNSRange(start: $0, length: 0)?.location
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ extension GenericTypeNameRule {
|
|||
}
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return namesAndRanges.compactMap { name, range -> (String, Int)? in
|
||||
guard let byteRange = contents.NSRangeToByteRange(start: range.location + offset,
|
||||
length: range.length),
|
||||
|
|
|
@ -79,12 +79,12 @@ public struct JoinedDefaultParameterRule: SubstitutionCorrectableASTRule, Config
|
|||
// is this single argument the default parameter?
|
||||
let bodyOffset = argument.bodyOffset,
|
||||
let bodyLength = argument.bodyLength,
|
||||
let body = file.contents.bridge().substringWithByteRange(start: bodyOffset, length: bodyLength),
|
||||
let body = file.stringView.substringWithByteRange(start: bodyOffset, length: bodyLength),
|
||||
body == "\"\""
|
||||
else { return [] }
|
||||
|
||||
guard
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: offset, length: length)
|
||||
let range = file.stringView.byteRangeToNSRange(start: offset, length: length)
|
||||
else { return [] }
|
||||
|
||||
return [range]
|
||||
|
|
|
@ -182,7 +182,7 @@ public struct LegacyConstructorRule: ASTRule, CorrectableRule, ConfigurationProv
|
|||
|
||||
for dictionary in violatingDictionaries.reversed() {
|
||||
guard let offset = dictionary.offset, let length = dictionary.length,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: offset, length: length),
|
||||
let range = file.stringView.byteRangeToNSRange(start: offset, length: length),
|
||||
let name = dictionary.name,
|
||||
let correctedName = type(of: self).constructorsToCorrectedNames[name],
|
||||
file.ruleEnabled(violatingRanges: [range], for: self) == [range],
|
||||
|
@ -211,7 +211,7 @@ public struct LegacyConstructorRule: ASTRule, CorrectableRule, ConfigurationProv
|
|||
}
|
||||
|
||||
private func argumentsContents(file: SwiftLintFile, arguments: [SourceKittenDictionary]) -> [String] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return arguments.compactMap { argument -> String? in
|
||||
guard argument.name == nil,
|
||||
let offset = argument.offset,
|
||||
|
|
|
@ -120,7 +120,7 @@ public struct NimbleOperatorRule: ConfigurationProviderRule, OptInRule, Correcta
|
|||
excludingKinds.isDisjoint(with: kinds) && kinds.first == .identifier
|
||||
}.map { $0.0 }
|
||||
.filter { range in
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let byteRange = contents.NSRangeToByteRange(start: range.location, length: range.length) else {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ public struct NoFallthroughOnlyRule: ASTRule, ConfigurationProviderRule, Automat
|
|||
guard kind == .case,
|
||||
let length = dictionary.length,
|
||||
let offset = dictionary.offset,
|
||||
case let nsstring = file.contents.bridge(),
|
||||
let range = nsstring.byteRangeToNSRange(start: offset, length: length),
|
||||
let colonLocation = findCaseColon(text: nsstring, range: range)
|
||||
case let contents = file.stringView,
|
||||
let range = contents.byteRangeToNSRange(start: offset, length: length),
|
||||
let colonLocation = findCaseColon(text: file.stringView.nsString, range: range)
|
||||
else {
|
||||
return []
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public struct NoFallthroughOnlyRule: ASTRule, ConfigurationProviderRule, Automat
|
|||
}
|
||||
|
||||
let nsRange = nonCommentCaseBody[0].0
|
||||
if nsstring.substring(with: nsRange) == "fallthrough" && nonCommentCaseBody[0].1 == [.keyword] &&
|
||||
if contents.substring(with: nsRange) == "fallthrough" && nonCommentCaseBody[0].1 == [.keyword] &&
|
||||
!isNextTokenUnknownAttribute(afterOffset: offset + length, file: file) {
|
||||
return [StyleViolation(ruleDescription: type(of: self).description,
|
||||
severity: configuration.severity,
|
||||
|
|
|
@ -45,7 +45,7 @@ public struct NoGroupingExtensionRule: OptInRule, ConfigurationProviderRule, Aut
|
|||
}
|
||||
|
||||
private func hasWhereClause(dictionary: SourceKittenDictionary, file: SwiftLintFile) -> Bool {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
guard let nameOffset = dictionary.nameOffset,
|
||||
let nameLength = dictionary.nameLength,
|
||||
|
|
|
@ -40,7 +40,7 @@ public struct PatternMatchingKeywordsRule: ASTRule, ConfigurationProviderRule, O
|
|||
return []
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return dictionary.elements.flatMap { subDictionary -> [StyleViolation] in
|
||||
guard subDictionary.kind == "source.lang.swift.structure.elem.pattern",
|
||||
let offset = subDictionary.offset,
|
||||
|
|
|
@ -65,7 +65,7 @@ public struct PrivateOverFilePrivateRule: ConfigurationProviderRule, Substitutio
|
|||
|
||||
public func violationRanges(in file: SwiftLintFile) -> [NSRange] {
|
||||
let syntaxTokens = file.syntaxMap.tokens
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
let dict = file.structureDictionary
|
||||
return dict.substructure.compactMap { dictionary -> NSRange? in
|
||||
|
|
|
@ -43,7 +43,7 @@ public struct RedundantObjcAttributeRule: SubstitutionCorrectableRule, Configura
|
|||
.first(where: { $0.attribute == SwiftDeclarationAttributeKind.objc.rawValue })
|
||||
guard let objcOffset = objcAttribute?.offset,
|
||||
let objcLength = objcAttribute?.length,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: objcOffset, length: objcLength),
|
||||
let range = file.stringView.byteRangeToNSRange(start: objcOffset, length: objcLength),
|
||||
!dictionary.isObjcAndIBDesignableDeclaredExtension else {
|
||||
return []
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ public struct RedundantOptionalInitializationRule: SubstitutionCorrectableASTRul
|
|||
return nil
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
if let bodyOffset = dictionary.bodyOffset {
|
||||
return contents.byteRangeToNSRange(start: offset, length: bodyOffset - offset)
|
||||
} else {
|
||||
|
@ -149,7 +149,7 @@ extension SourceKittenDictionary {
|
|||
|
||||
private func isVariable(file: SwiftLintFile) -> Bool {
|
||||
guard let start = offset, let length = length,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let range = contents.byteRangeToNSRange(start: start, length: length),
|
||||
!file.match(pattern: "\\Avar\\b", with: [.keyword], range: range).isEmpty else {
|
||||
return false
|
||||
|
|
|
@ -132,7 +132,7 @@ public struct RedundantStringEnumValueRule: ASTRule, ConfigurationProviderRule,
|
|||
}
|
||||
|
||||
// the string would be quoted if offset and length were used directly
|
||||
let enumCaseName = file.contents.bridge()
|
||||
let enumCaseName = file.stringView
|
||||
.substringWithByteRange(start: offset + 1, length: length - 2) ?? ""
|
||||
guard enumCaseName == name else {
|
||||
return nil
|
||||
|
|
|
@ -81,7 +81,7 @@ public struct RedundantTypeAnnotationRule: OptInRule, SubstitutionCorrectableRul
|
|||
}
|
||||
|
||||
private func isFalsePositive(in file: SwiftLintFile, range: NSRange) -> Bool {
|
||||
let substring = file.contents.bridge().substring(with: range)
|
||||
let substring = file.stringView.substring(with: range)
|
||||
|
||||
let components = substring.components(separatedBy: "=")
|
||||
let charactersToTrimFromRhs = CharacterSet(charactersIn: ".(").union(.whitespaces)
|
||||
|
@ -98,7 +98,7 @@ public struct RedundantTypeAnnotationRule: OptInRule, SubstitutionCorrectableRul
|
|||
}
|
||||
|
||||
private func isIBInspectable(range: NSRange, file: SwiftLintFile) -> Bool {
|
||||
guard let byteRange = file.contents.bridge().NSRangeToByteRange(start: range.location, length: range.length),
|
||||
guard let byteRange = file.stringView.NSRangeToByteRange(start: range.location, length: range.length),
|
||||
let dict = file.structureDictionary.structures(forByteOffset: byteRange.location).last,
|
||||
let kind = dict.declarationKind,
|
||||
SwiftDeclarationKind.variableKinds.contains(kind) else {
|
||||
|
|
|
@ -80,7 +80,7 @@ public struct RedundantVoidReturnRule: ConfigurationProviderRule, SubstitutionCo
|
|||
let offset = dictionary.offset,
|
||||
case let start = nameOffset + nameLength,
|
||||
case let end = dictionary.bodyOffset ?? offset + length,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let range = contents.byteRangeToNSRange(start: start, length: end - start),
|
||||
file.match(pattern: "->", excludingSyntaxKinds: excludingKinds, range: range).count == 1,
|
||||
let match = file.match(pattern: pattern, excludingSyntaxKinds: excludingKinds, range: range).first else {
|
||||
|
|
|
@ -68,7 +68,7 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
|
|||
)
|
||||
|
||||
public func validate(file: SwiftLintFile) -> [StyleViolation] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return violationResults(in: file).map {
|
||||
let typeString = contents.substring(with: $0.range(at: 1))
|
||||
return StyleViolation(ruleDescription: type(of: self).description,
|
||||
|
@ -83,7 +83,7 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
|
|||
}
|
||||
|
||||
public func substitution(for violationRange: NSRange, in file: SwiftLintFile) -> (NSRange, String) {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
let declaration = contents.substring(with: violationRange)
|
||||
let originalRange = NSRange(location: 0, length: declaration.count)
|
||||
var substitutionResult = declaration
|
||||
|
@ -126,10 +126,8 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
|
|||
|
||||
private func violationResults(in file: SwiftLintFile) -> [NSTextCheckingResult] {
|
||||
let excludingKinds = SyntaxKind.commentAndStringKinds
|
||||
let contents = file.contents.bridge()
|
||||
let range = NSRange(location: 0, length: contents.length)
|
||||
|
||||
return regex(pattern).matches(in: file.contents, options: [], range: range).compactMap { result in
|
||||
let contents = file.stringView
|
||||
return regex(pattern).matches(in: contents).compactMap { result in
|
||||
let range = result.range
|
||||
guard let byteRange = contents.NSRangeToByteRange(start: range.location, length: range.length) else {
|
||||
return nil
|
||||
|
@ -146,11 +144,11 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
|
|||
}
|
||||
|
||||
private func isValidViolation(range: NSRange, file: SwiftLintFile) -> Bool {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
// avoid triggering when referring to an associatedtype
|
||||
let start = range.location + range.length
|
||||
let restOfFileRange = NSRange(location: start, length: contents.length - start)
|
||||
let restOfFileRange = NSRange(location: start, length: contents.nsString.length - start)
|
||||
if regex("\\s*\\.").firstMatch(in: file.contents, options: [],
|
||||
range: restOfFileRange)?.range.location == start {
|
||||
guard let byteOffset = contents.NSRangeToByteRange(start: range.location,
|
||||
|
|
|
@ -47,7 +47,7 @@ public struct ToggleBoolRule: SubstitutionCorrectableRule, ConfigurationProvider
|
|||
}
|
||||
|
||||
public func substitution(for violationRange: NSRange, in file: SwiftLintFile) -> (NSRange, String) {
|
||||
let violationString = file.contents.bridge().substring(with: violationRange)
|
||||
let violationString = file.stringView.substring(with: violationRange)
|
||||
let identifier = violationString.components(separatedBy: .whitespaces).first { !$0.isEmpty }
|
||||
return (violationRange, identifier! + ".toggle()")
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public struct UnavailableFunctionRule: ASTRule, ConfigurationProviderRule, OptIn
|
|||
guard let offset = dictionary.offset, containsFatalError,
|
||||
!isFunctionUnavailable(file: file, dictionary: dictionary),
|
||||
let bodyOffset = dictionary.bodyOffset, let bodyLength = dictionary.bodyLength,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: bodyOffset, length: bodyLength),
|
||||
let range = file.stringView.byteRangeToNSRange(start: bodyOffset, length: bodyLength),
|
||||
file.match(pattern: "\\breturn\\b", with: [.keyword], range: range).isEmpty else {
|
||||
return []
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ public struct UnavailableFunctionRule: ASTRule, ConfigurationProviderRule, OptIn
|
|||
return dictionary.swiftAttributes.contains { dict -> Bool in
|
||||
guard dict.attribute.flatMap(SwiftDeclarationAttributeKind.init(rawValue:)) == .available,
|
||||
let offset = dict.offset, let length = dict.length,
|
||||
let contents = file.contents.bridge().substringWithByteRange(start: offset, length: length) else {
|
||||
let contents = file.stringView.substringWithByteRange(start: offset, length: length) else {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ public struct UnneededBreakInSwitchRule: ConfigurationProviderRule, AutomaticTes
|
|||
|
||||
public func validate(file: SwiftLintFile) -> [StyleViolation] {
|
||||
return file.match(pattern: "break", with: [.keyword]).compactMap { range in
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let byteRange = contents.NSRangeToByteRange(start: range.location, length: range.length),
|
||||
let innerStructure = file.structureDictionary.structures(forByteOffset: byteRange.location).last,
|
||||
innerStructure.statementKind == .case,
|
||||
|
|
|
@ -60,7 +60,7 @@ public struct XCTFailMessageRule: ASTRule, ConfigurationProviderRule, AutomaticT
|
|||
|
||||
guard bodyLength > 0 else { return true }
|
||||
|
||||
let body = file.contents.bridge().substringWithByteRange(start: bodyOffset, length: bodyLength)
|
||||
let body = file.stringView.substringWithByteRange(start: bodyOffset, length: bodyLength)
|
||||
return body == "\"\""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public struct XCTSpecificMatcherRule: ASTRule, OptInRule, ConfigurationProviderR
|
|||
guard
|
||||
let argOffset = argument.offset,
|
||||
let argLength = argument.length,
|
||||
let body = file.contents.bridge().substringWithByteRange(start: argOffset, length: argLength)
|
||||
let body = file.stringView.substringWithByteRange(start: argOffset, length: argLength)
|
||||
else { return nil }
|
||||
|
||||
return body
|
||||
|
|
|
@ -63,13 +63,13 @@ public struct AnyObjectProtocolRule: SubstitutionCorrectableASTRule, OptInRule,
|
|||
guard
|
||||
let offset = subDict.offset,
|
||||
let length = subDict.length,
|
||||
let content = file.contents.bridge().substringWithByteRange(start: offset, length: length),
|
||||
let content = file.stringView.substringWithByteRange(start: offset, length: length),
|
||||
content == "class"
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return file.contents.bridge().byteRangeToNSRange(start: offset, length: length)
|
||||
return file.stringView.byteRangeToNSRange(start: offset, length: length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public struct ArrayInitRule: ASTRule, ConfigurationProviderRule, OptInRule, Auto
|
|||
file: SwiftLintFile) -> Bool {
|
||||
let length = firstToken.offset - nameEndPosition
|
||||
guard length > 0,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let byteRange = contents.byteRangeToNSRange(start: nameEndPosition, length: length) else {
|
||||
return false
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ public struct ArrayInitRule: ASTRule, ConfigurationProviderRule, OptInRule, Auto
|
|||
}
|
||||
|
||||
private func containsContent(inByteRange byteRange: NSRange, file: SwiftLintFile) -> Bool {
|
||||
let nsstring = file.contents.bridge()
|
||||
let nsstring = file.stringView
|
||||
let remainingTokens = file.syntaxMap.tokens(inByteRange: byteRange)
|
||||
let ranges = NSMutableIndexSet(indexesIn: byteRange)
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public struct ClassDelegateProtocolRule: ASTRule, ConfigurationProviderRule, Aut
|
|||
let nameOffset = dictionary.nameOffset,
|
||||
let nameLength = dictionary.nameLength,
|
||||
let bodyOffset = dictionary.bodyOffset,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
case let start = nameOffset + nameLength,
|
||||
let range = contents.byteRangeToNSRange(start: start, length: bodyOffset - start),
|
||||
!isClassProtocol(file: file, range: range) else {
|
||||
|
|
|
@ -54,7 +54,7 @@ public struct CompilerProtocolInitRule: ASTRule, ConfigurationProviderRule {
|
|||
compilerProtocol.match(arguments: arguments),
|
||||
let offset = dictionary.offset,
|
||||
let length = dictionary.length,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: offset, length: length) else {
|
||||
let range = file.stringView.byteRangeToNSRange(start: offset, length: length) else {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,8 @@ public struct DeploymentTargetRule: ConfigurationProviderRule {
|
|||
return file.rangesAndTokens(matching: pattern).flatMap { range, tokens -> [StyleViolation] in
|
||||
guard let availabilityToken = tokens.first,
|
||||
availabilityToken.kind == .keyword,
|
||||
let tokenRange = file.contents.bridge().byteRangeToNSRange(start: availabilityToken.offset,
|
||||
length: availabilityToken.length) else {
|
||||
let tokenRange = file.stringView.byteRangeToNSRange(start: availabilityToken.offset,
|
||||
length: availabilityToken.length) else {
|
||||
return []
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public struct DeploymentTargetRule: ConfigurationProviderRule {
|
|||
return []
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return attributes.flatMap { dictionary -> [StyleViolation] in
|
||||
guard let offset = dictionary.offset, let length = dictionary.length,
|
||||
let range = contents.byteRangeToNSRange(start: offset, length: length) else {
|
||||
|
|
|
@ -57,7 +57,7 @@ public struct DiscardedNotificationCenterObserverRule: ASTRule, ConfigurationPro
|
|||
argumentsNames == ["forName", "object", "queue"] ||
|
||||
argumentsNames == ["forName", "object", "queue", "using"],
|
||||
let offset = dictionary.offset,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: 0, length: offset) else {
|
||||
let range = file.stringView.byteRangeToNSRange(start: 0, length: offset) else {
|
||||
return []
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ public struct DynamicInlineRule: ASTRule, ConfigurationProviderRule, AutomaticTe
|
|||
attributes.contains(.dynamic),
|
||||
attributes.contains(.inline),
|
||||
let funcByteOffset = dictionary.offset,
|
||||
let funcOffset = file.contents.bridge()
|
||||
let funcOffset = file.stringView
|
||||
.byteRangeToNSRange(start: funcByteOffset, length: 0)?.location,
|
||||
case let inlinePattern = regex("@inline"),
|
||||
case let range = NSRange(location: 0, length: funcOffset),
|
||||
|
|
|
@ -79,7 +79,7 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom
|
|||
}
|
||||
|
||||
private func violationRangeFrom(match: NSTextCheckingResult, in file: SwiftLintFile) -> NSRange? {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
let operatorRange = match.range(at: 1)
|
||||
guard let operatorByteRange = contents.NSRangeToByteRange(operatorRange) else {
|
||||
return nil
|
||||
|
@ -131,8 +131,8 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom
|
|||
}
|
||||
}
|
||||
|
||||
let violationRange = file.contents.byteRangeToNSRange(start: leftmostToken.offset,
|
||||
length: leftmostToken.length)
|
||||
let violationRange = file.stringView.byteRangeToNSRange(start: leftmostToken.offset,
|
||||
length: leftmostToken.length)
|
||||
return violationRange
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom
|
|||
while currentIndex > 0 {
|
||||
let prevToken = tokens[currentIndex - 1]
|
||||
|
||||
guard file.contents.isDotOrOptionalChainingBetweenTokens(prevToken, leftMostToken) else { break }
|
||||
guard file.stringView.isDotOrOptionalChainingBetweenTokens(prevToken, leftMostToken) else { break }
|
||||
|
||||
leftTokens.insert(prevToken, at: 0)
|
||||
currentIndex -= 1
|
||||
|
@ -161,7 +161,7 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom
|
|||
while currentIndex < tokens.count - 1 {
|
||||
let nextToken = tokens[currentIndex + 1]
|
||||
|
||||
guard file.contents.isDotOrOptionalChainingBetweenTokens(rightMostToken, nextToken) else { break }
|
||||
guard file.stringView.isDotOrOptionalChainingBetweenTokens(rightMostToken, nextToken) else { break }
|
||||
|
||||
rightTokens.append(nextToken)
|
||||
currentIndex += 1
|
||||
|
@ -173,11 +173,7 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom
|
|||
}
|
||||
}
|
||||
|
||||
private extension NSString {
|
||||
func NSRangeToByteRange(_ range: NSRange) -> NSRange? {
|
||||
return NSRangeToByteRange(start: range.location, length: range.length)
|
||||
}
|
||||
|
||||
private extension StringView {
|
||||
func subStringWithSyntaxToken(_ syntaxToken: SwiftLintSyntaxToken) -> String? {
|
||||
return substringWithByteRange(start: syntaxToken.offset, length: syntaxToken.length)
|
||||
}
|
||||
|
@ -195,7 +191,7 @@ private extension NSString {
|
|||
func isWhiteSpaceBetweenTokens(_ startToken: SwiftLintSyntaxToken,
|
||||
_ endToken: SwiftLintSyntaxToken) -> Bool {
|
||||
guard let betweenTokens = subStringBetweenTokens(startToken, endToken) else { return false }
|
||||
let range = NSRange(location: 0, length: betweenTokens.utf16.count)
|
||||
let range = betweenTokens.fullNSRange
|
||||
return !regex(#"^[\s\(,]*$"#).matches(in: betweenTokens, options: [], range: range).isEmpty
|
||||
}
|
||||
|
||||
|
@ -203,7 +199,7 @@ private extension NSString {
|
|||
_ endToken: SwiftLintSyntaxToken) -> Bool {
|
||||
guard let betweenTokens = subStringBetweenTokens(startToken, endToken) else { return false }
|
||||
|
||||
let range = NSRange(location: 0, length: betweenTokens.utf16.count)
|
||||
let range = betweenTokens.fullNSRange
|
||||
return !regex("^\\s*\(regexString)\\s*$").matches(in: betweenTokens, options: [], range: range).isEmpty
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public struct InertDeferRule: ConfigurationProviderRule, AutomaticTestableRule {
|
|||
let defers = file.match(pattern: "defer\\s*\\{", with: [.keyword])
|
||||
|
||||
return defers.compactMap { range -> StyleViolation? in
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let byteRange = contents.NSRangeToByteRange(start: range.location, length: range.length),
|
||||
case let kinds = file.structureDictionary.kinds(forByteOffset: byteRange.upperBound),
|
||||
let brace = kinds.enumerated().lazy.reversed().first(where: isBrace),
|
||||
|
|
|
@ -183,14 +183,13 @@ public struct MarkRule: CorrectableRule, ConfigurationProviderRule {
|
|||
}
|
||||
|
||||
private func violationRanges(in file: SwiftLintFile, matching pattern: String) -> [NSRange] {
|
||||
let nsstring = file.contents.bridge()
|
||||
return file.rangesAndTokens(matching: pattern).filter { _, syntaxTokens in
|
||||
guard let syntaxKind = syntaxTokens.first?.kind else {
|
||||
return false
|
||||
}
|
||||
return !syntaxTokens.isEmpty && SyntaxKind.commentKinds.contains(syntaxKind)
|
||||
}.compactMap { range, syntaxTokens in
|
||||
let identifierRange = nsstring
|
||||
let identifierRange = file.stringView
|
||||
.byteRangeToNSRange(start: syntaxTokens[0].offset, length: 0)
|
||||
return identifierRange.map { NSUnionRange($0, range) }
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ public struct PrivateUnitTestRule: ASTRule, ConfigurationProviderRule, CacheDesc
|
|||
guard let regex = configuration.regex, let superclass = dictionary.superclass else {
|
||||
return false
|
||||
}
|
||||
let range = NSRange(location: 0, length: superclass.bridge().length)
|
||||
let range = superclass.fullNSRange
|
||||
return !regex.matches(in: superclass, options: [], range: range).isEmpty
|
||||
}
|
||||
|
||||
|
|
|
@ -38,16 +38,16 @@ public struct TodoRule: ConfigurationProviderRule {
|
|||
var reason = type(of: self).description.description
|
||||
let offset = NSMaxRange(range)
|
||||
|
||||
guard let (lineNumber, _) = file.contents.bridge().lineAndCharacter(forCharacterOffset: offset) else {
|
||||
guard let (lineNumber, _) = file.stringView.lineAndCharacter(forCharacterOffset: offset) else {
|
||||
return reason
|
||||
}
|
||||
|
||||
let line = file.lines[lineNumber - 1]
|
||||
// customizing the reason message to be specific to fixme or todo
|
||||
let violationSubstring = file.contents.bridge().substring(with: range)
|
||||
let violationSubstring = file.stringView.substring(with: range)
|
||||
|
||||
let range = NSRange(location: offset, length: NSMaxRange(line.range) - offset)
|
||||
var message = file.contents.bridge().substring(with: range)
|
||||
var message = file.stringView.substring(with: range)
|
||||
let kind = violationSubstring.hasPrefix("FIXME") ? "FIXMEs" : "TODOs"
|
||||
|
||||
// trim whitespace
|
||||
|
|
|
@ -30,7 +30,7 @@ public struct UnownedVariableCaptureRule: ASTRule, OptInRule, ConfigurationProvi
|
|||
public func validate(file: SwiftLintFile, kind: SwiftExpressionKind,
|
||||
dictionary: SourceKittenDictionary) -> [StyleViolation] {
|
||||
guard kind == .closure, let bodyOffset = dictionary.bodyOffset, let bodyLength = dictionary.bodyLength,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let closureRange = contents.byteRangeToNSRange(start: bodyOffset, length: bodyLength),
|
||||
let inTokenRange = file.match(pattern: "\\bin\\b", with: [.keyword], range: closureRange).first,
|
||||
let inTokenByteRange = contents.NSRangeToByteRange(start: inTokenRange.location,
|
||||
|
|
|
@ -76,7 +76,7 @@ public struct UnusedCaptureListRule: ASTRule, ConfigurationProviderRule, Automat
|
|||
|
||||
public func validate(file: SwiftLintFile, kind: SwiftExpressionKind,
|
||||
dictionary: SourceKittenDictionary) -> [StyleViolation] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard kind == .closure,
|
||||
let offset = dictionary.offset,
|
||||
let length = dictionary.length,
|
||||
|
|
|
@ -134,7 +134,7 @@ public struct UnusedClosureParameterRule: SubstitutionCorrectableASTRule, Config
|
|||
let rangeStart = nameOffset + nameLength
|
||||
let rangeLength = (offset + length) - (nameOffset + nameLength)
|
||||
let parameters = dictionary.enclosedVarParameters
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
return parameters.compactMap { param -> (NSRange, String)? in
|
||||
guard let paramOffset = param.offset,
|
||||
|
@ -180,8 +180,7 @@ public struct UnusedClosureParameterRule: SubstitutionCorrectableASTRule, Config
|
|||
|
||||
private func isClosure(dictionary: SourceKittenDictionary) -> Bool {
|
||||
return dictionary.name.flatMap { name -> Bool in
|
||||
let length = name.bridge().length
|
||||
let range = NSRange(location: 0, length: length)
|
||||
let range = name.fullNSRange
|
||||
return regex("\\A[\\s\\(]*?\\{").firstMatch(in: name, options: [], range: range) != nil
|
||||
} ?? false
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ public struct UnusedControlFlowLabelRule: SubstitutionCorrectableASTRule, Config
|
|||
|
||||
public func substitution(for violationRange: NSRange, in file: SwiftLintFile) -> (NSRange, String) {
|
||||
var rangeToRemove = violationRange
|
||||
let contentsNSString = file.contents.bridge()
|
||||
let contentsNSString = file.stringView
|
||||
if let byteRange = contentsNSString.NSRangeToByteRange(start: violationRange.location,
|
||||
length: violationRange.length),
|
||||
let nextToken = file.syntaxMap.tokens.first(where: { $0.offset > byteRange.location }),
|
||||
|
@ -120,7 +120,7 @@ public struct UnusedControlFlowLabelRule: SubstitutionCorrectableASTRule, Config
|
|||
let firstToken = tokens.first,
|
||||
firstToken.kind == .identifier,
|
||||
let tokenContent = file.contents(for: firstToken),
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let range = contents.byteRangeToNSRange(start: offset, length: length) else {
|
||||
return []
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ public struct UnusedSetterValueRule: ConfigurationProviderRule, AutomaticTestabl
|
|||
guard let dict = declarations(forByteOffset: setToken.offset,
|
||||
structureDictionary: file.structureDictionary).last,
|
||||
let bodyOffset = dict.bodyOffset, let bodyLength = dict.bodyLength,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let propertyRange = contents.byteRangeToNSRange(start: bodyOffset, length: bodyLength),
|
||||
let getToken = findGetToken(in: propertyRange, file: file, propertyStructure: dict) else {
|
||||
return nil
|
||||
|
|
|
@ -69,7 +69,7 @@ public struct YodaConditionRule: ASTRule, OptInRule, ConfigurationProviderRule,
|
|||
}
|
||||
|
||||
let matches = file.lines.filter({ $0.byteRange.contains(offset) }).reduce(into: []) { matches, line in
|
||||
let range = NSRange(location: 0, length: line.content.bridge().length)
|
||||
let range = line.content.fullNSRange
|
||||
let lineMatches = YodaConditionRule.regularExpression.matches(in: line.content, options: [], range: range)
|
||||
matches.append(contentsOf: lineMatches)
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ public struct YodaConditionRule: ASTRule, OptInRule, ConfigurationProviderRule,
|
|||
}
|
||||
|
||||
private func startOffset(of offset: Int, with length: Int, in file: SwiftLintFile) -> Int {
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: offset, length: length)
|
||||
let range = file.stringView.byteRangeToNSRange(start: offset, length: length)
|
||||
return range?.location ?? offset
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ public struct ClosureBodyLengthRule: OptInRule, ASTRule, ConfigurationProviderRu
|
|||
let offset = dictionary.offset,
|
||||
let bodyOffset = dictionary.bodyOffset,
|
||||
let bodyLength = dictionary.bodyLength,
|
||||
let startLine = file.contents.bridge().lineAndCharacter(forByteOffset: bodyOffset)?.line,
|
||||
let endLine = file.contents.bridge().lineAndCharacter(forByteOffset: bodyOffset + bodyLength)?.line
|
||||
let startLine = file.stringView.lineAndCharacter(forByteOffset: bodyOffset)?.line,
|
||||
let endLine = file.stringView.lineAndCharacter(forByteOffset: bodyOffset + bodyLength)?.line
|
||||
else {
|
||||
return []
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public struct CyclomaticComplexityRule: ASTRule, ConfigurationProviderRule {
|
|||
let bodyOffset = dictionary.bodyOffset ?? 0
|
||||
let bodyLength = dictionary.bodyLength ?? 0
|
||||
|
||||
let contents = file.contents.bridge().substringWithByteRange(start: bodyOffset, length: bodyLength) ?? ""
|
||||
let contents = file.stringView.substringWithByteRange(start: bodyOffset, length: bodyLength) ?? ""
|
||||
|
||||
let fallthroughCount = contents.components(separatedBy: "fallthrough").count - 1
|
||||
return complexity - fallthroughCount
|
||||
|
|
|
@ -18,7 +18,7 @@ public struct FunctionBodyLengthRule: ASTRule, ConfigurationProviderRule {
|
|||
let offset = dictionary.offset,
|
||||
let bodyOffset = dictionary.bodyOffset,
|
||||
let bodyLength = dictionary.bodyLength,
|
||||
case let contentsNSString = file.contents.bridge(),
|
||||
case let contentsNSString = file.stringView,
|
||||
let startLine = contentsNSString.lineAndCharacter(forByteOffset: bodyOffset)?.line,
|
||||
let endLine = contentsNSString.lineAndCharacter(forByteOffset: bodyOffset + bodyLength)?.line
|
||||
else {
|
||||
|
|
|
@ -99,13 +99,13 @@ public struct FunctionParameterCountRule: ASTRule, ConfigurationProviderRule {
|
|||
}
|
||||
|
||||
private func defaultFunctionParameterCount(file: SwiftLintFile, byteOffset: Int, byteLength: Int) -> Int {
|
||||
let substring = file.contents.bridge().substringWithByteRange(start: byteOffset, length: byteLength)!
|
||||
let substring = file.stringView.substringWithByteRange(start: byteOffset, length: byteLength)!
|
||||
let equals = substring.filter { $0 == "=" }
|
||||
return equals.count
|
||||
}
|
||||
|
||||
private func functionIsInitializer(file: SwiftLintFile, byteOffset: Int, byteLength: Int) -> Bool {
|
||||
guard let name = file.contents.bridge()
|
||||
guard let name = file.stringView
|
||||
.substringWithByteRange(start: byteOffset, length: byteLength),
|
||||
name.hasPrefix("init"),
|
||||
let funcName = name.components(separatedBy: CharacterSet(charactersIn: "<(")).first else {
|
||||
|
|
|
@ -87,7 +87,7 @@ public struct LargeTupleRule: ASTRule, ConfigurationProviderRule, AutomaticTesta
|
|||
|
||||
private func violationOffsetsForFunctions(in file: SwiftLintFile, dictionary: SourceKittenDictionary,
|
||||
kind: SwiftDeclarationKind) -> [(offset: Int, size: Int)] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard SwiftDeclarationKind.functionKinds.contains(kind),
|
||||
let returnRange = returnRangeForFunction(dictionary: dictionary),
|
||||
let returnSubstring = contents.substringWithByteRange(start: returnRange.location,
|
||||
|
@ -110,7 +110,7 @@ public struct LargeTupleRule: ASTRule, ConfigurationProviderRule, AutomaticTesta
|
|||
for (range, kind) in ranges {
|
||||
let substring = text.substring(with: range)
|
||||
if kind != .generic,
|
||||
let byteRange = text.NSRangeToByteRange(start: range.location, length: range.length),
|
||||
let byteRange = StringView(text).NSRangeToByteRange(start: range.location, length: range.length),
|
||||
!containsReturnArrow(in: text.bridge(), range: range) {
|
||||
let size = substring.components(separatedBy: ",").count
|
||||
let offset = byteRange.location + initialOffset
|
||||
|
|
|
@ -136,7 +136,7 @@ private class Lazy<Result> {
|
|||
|
||||
private extension String {
|
||||
var strippingURLs: String {
|
||||
let range = NSRange(location: 0, length: bridge().length)
|
||||
let range = fullNSRange
|
||||
// Workaround for Linux until NSDataDetector is available
|
||||
#if os(Linux)
|
||||
// Regex pattern from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||
|
|
|
@ -39,8 +39,8 @@ public struct TypeBodyLengthRule: ASTRule, ConfigurationProviderRule, AutomaticT
|
|||
if let offset = dictionary.offset,
|
||||
let bodyOffset = dictionary.bodyOffset,
|
||||
let bodyLength = dictionary.bodyLength {
|
||||
let startLine = file.contents.bridge().lineAndCharacter(forByteOffset: bodyOffset)
|
||||
let endLine = file.contents.bridge()
|
||||
let startLine = file.stringView.lineAndCharacter(forByteOffset: bodyOffset)
|
||||
let endLine = file.stringView
|
||||
.lineAndCharacter(forByteOffset: bodyOffset + bodyLength)
|
||||
|
||||
if let startLine = startLine?.line, let endLine = endLine?.line {
|
||||
|
|
|
@ -103,7 +103,7 @@ public struct ReduceIntoRule: ASTRule, ConfigurationProviderRule, OptInRule, Aut
|
|||
kind == .call,
|
||||
let nameOffset = dictionary.nameOffset,
|
||||
let nameLength = dictionary.nameLength,
|
||||
let nameRange = file.contents.byteRangeToNSRange(start: nameOffset, length: nameLength),
|
||||
let nameRange = file.stringView.byteRangeToNSRange(start: nameOffset, length: nameLength),
|
||||
let match = reduceExpression.firstMatch(in: file.contents, options: [], range: nameRange),
|
||||
dictionary.enclosedArguments.count == 2,
|
||||
// would otherwise equal "into"
|
||||
|
@ -131,7 +131,7 @@ public struct ReduceIntoRule: ASTRule, ConfigurationProviderRule, OptInRule, Aut
|
|||
}
|
||||
}
|
||||
|
||||
let contents = file.contents
|
||||
let contents = file.stringView
|
||||
guard let offset = argument.offset,
|
||||
let length = argument.length,
|
||||
let range = contents.byteRangeToNSRange(start: offset, length: length)
|
||||
|
@ -145,7 +145,7 @@ public struct ReduceIntoRule: ASTRule, ConfigurationProviderRule, OptInRule, Aut
|
|||
}
|
||||
|
||||
// check for Array or Dictionary init
|
||||
let initMatch = initExpression.firstMatch(in: contents, options: [], range: range)
|
||||
let initMatch = initExpression.firstMatch(in: contents.string, options: [], range: range)
|
||||
return initMatch != nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public struct AttributesRule: ASTRule, OptInRule, ConfigurationProviderRule {
|
|||
return nil
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
let match = contents.substring(with: range)
|
||||
let idx = match.lastIndex(of: "import") ?? 0
|
||||
let location = idx + range.location
|
||||
|
@ -76,7 +76,7 @@ public struct AttributesRule: ASTRule, OptInRule, ConfigurationProviderRule {
|
|||
|
||||
guard !attributes.isEmpty,
|
||||
let offset = dictionary.offset,
|
||||
let (line, _) = file.contents.bridge().lineAndCharacter(forByteOffset: offset) else {
|
||||
let (line, _) = file.stringView.lineAndCharacter(forByteOffset: offset) else {
|
||||
return []
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ public struct AttributesRule: ASTRule, OptInRule, ConfigurationProviderRule {
|
|||
var currentLine = lineNumber - 1
|
||||
var allTokens = [(String, Bool)]()
|
||||
var foundEmptyLine = false
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
while currentLine >= 0 {
|
||||
defer {
|
||||
|
@ -247,11 +247,11 @@ public struct AttributesRule: ASTRule, OptInRule, ConfigurationProviderRule {
|
|||
let restOfLineLength = line.byteRange.location + line.byteRange.length - restOfLineOffset
|
||||
|
||||
let regex = AttributesRule.regularExpression
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
// check if after the token is a `(` with only spaces allowed between the token and `(`
|
||||
guard let restOfLine = contents.substringWithByteRange(start: restOfLineOffset, length: restOfLineLength),
|
||||
case let range = NSRange(location: 0, length: restOfLine.bridge().length),
|
||||
case let range = restOfLine.fullNSRange,
|
||||
regex.firstMatch(in: restOfLine, options: [], range: range) != nil else {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ extension ClosureEndIndentationRule {
|
|||
guard
|
||||
let offset = dictionary.offset,
|
||||
let length = dictionary.length,
|
||||
let text = file.contents.bridge().substringWithByteRange(start: offset, length: length)
|
||||
let text = file.stringView.substringWithByteRange(start: offset, length: length)
|
||||
else {
|
||||
return false
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ extension ClosureEndIndentationRule {
|
|||
|
||||
private func validateCall(in file: SwiftLintFile,
|
||||
dictionary: SourceKittenDictionary) -> Violation? {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let offset = dictionary.offset,
|
||||
let length = dictionary.length,
|
||||
let bodyLength = dictionary.bodyLength,
|
||||
|
@ -208,7 +208,7 @@ extension ClosureEndIndentationRule {
|
|||
|
||||
private func validateClosureArgument(in file: SwiftLintFile,
|
||||
dictionary: SourceKittenDictionary) -> Violation? {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let offset = dictionary.offset,
|
||||
let length = dictionary.length,
|
||||
let bodyLength = dictionary.bodyLength,
|
||||
|
@ -254,7 +254,7 @@ extension ClosureEndIndentationRule {
|
|||
}
|
||||
|
||||
let newLineRegex = regex("\n(\\s*\\}?\\.)")
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let range = contents.byteRangeToNSRange(start: nameOffset, length: nameLength),
|
||||
let match = newLineRegex.matches(in: file.contents, options: [],
|
||||
range: range).last?.range(at: 1),
|
||||
|
@ -268,7 +268,7 @@ extension ClosureEndIndentationRule {
|
|||
|
||||
private func isSingleLineClosure(dictionary: SourceKittenDictionary,
|
||||
endPosition: Int, file: SwiftLintFile) -> Bool {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
guard let start = dictionary.bodyOffset,
|
||||
let (startLine, _) = contents.lineAndCharacter(forByteOffset: start),
|
||||
|
@ -281,7 +281,7 @@ extension ClosureEndIndentationRule {
|
|||
|
||||
private func containsSingleLineClosure(dictionary: SourceKittenDictionary,
|
||||
endPosition: Int, file: SwiftLintFile) -> Bool {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
guard let closure = trailingClosure(dictionary: dictionary, file: file),
|
||||
let start = closure.bodyOffset,
|
||||
|
@ -311,7 +311,7 @@ extension ClosureEndIndentationRule {
|
|||
return arguments.filter { argument in
|
||||
guard let offset = argument.bodyOffset,
|
||||
let length = argument.bodyLength,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: offset, length: length),
|
||||
let range = file.stringView.byteRangeToNSRange(start: offset, length: length),
|
||||
let match = regex("\\s*\\{").firstMatch(in: file.contents, options: [], range: range)?.range,
|
||||
match.location == range.location else {
|
||||
return false
|
||||
|
@ -330,7 +330,7 @@ extension ClosureEndIndentationRule {
|
|||
let firstArgumentOffset = firstArgument.offset,
|
||||
case let offset = nameOffset + nameLength,
|
||||
case let length = firstArgumentOffset - offset,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: offset, length: length),
|
||||
let range = file.stringView.byteRangeToNSRange(start: offset, length: length),
|
||||
let match = regex("\\(\\s*\\n\\s*").firstMatch(in: file.contents, options: [], range: range)?.range,
|
||||
match.location == range.location else {
|
||||
return false
|
||||
|
|
|
@ -68,7 +68,7 @@ public struct ClosureParameterPositionRule: ASTRule, ConfigurationProviderRule,
|
|||
}
|
||||
|
||||
let rangeLength = paramOffset - rangeStart
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
guard let range = contents.byteRangeToNSRange(start: rangeStart, length: rangeLength),
|
||||
let match = regex.matches(in: file.contents, options: [], range: range).last?.range,
|
||||
|
|
|
@ -90,7 +90,7 @@ public struct ClosureSpacingRule: CorrectableRule, ConfigurationProviderRule, Op
|
|||
return kindsToExclude.contains(tokenKind)
|
||||
}
|
||||
let tokenRanges = tokens.compactMap {
|
||||
file.contents.bridge().byteRangeToNSRange(start: $0.offset, length: $0.length)
|
||||
file.stringView.byteRangeToNSRange(start: $0.offset, length: $0.length)
|
||||
}
|
||||
linesWithBraces.append(braces.filter({ !$0.intersects(tokenRanges) }))
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public struct CollectionAlignmentRule: ASTRule, ConfigurationProviderRule, OptIn
|
|||
|
||||
private func colonLocation(with file: SwiftLintFile, keyOffset: Int, keyLength: Int,
|
||||
valueOffset: Int) -> Location? {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
let matchStart = keyOffset + keyLength
|
||||
let matchLength = valueOffset - matchStart
|
||||
let range = contents.byteRangeToNSRange(start: matchStart, length: matchLength)
|
||||
|
|
|
@ -23,7 +23,7 @@ extension ColonRule {
|
|||
return []
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return ranges.filter {
|
||||
guard let colon = contents.substringWithByteRange(start: $0.location, length: $0.length) else {
|
||||
return false
|
||||
|
|
|
@ -17,7 +17,7 @@ extension ColonRule {
|
|||
return []
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return ranges.filter {
|
||||
guard let colon = contents.substringWithByteRange(start: $0.location, length: $0.length) else {
|
||||
return false
|
||||
|
|
|
@ -23,7 +23,7 @@ internal extension ColonRule {
|
|||
}
|
||||
|
||||
func typeColonViolationRanges(in file: SwiftLintFile, matching pattern: String) -> [NSRange] {
|
||||
let nsstring = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return file.matchesAndTokens(matching: pattern).filter { match, syntaxTokens in
|
||||
if match.range(at: 2).length > 0 && syntaxTokens.count > 2 { // captured a generic definition
|
||||
let tokens = [syntaxTokens.first, syntaxTokens.last].compactMap { $0 }
|
||||
|
@ -32,7 +32,7 @@ internal extension ColonRule {
|
|||
|
||||
return isValidMatch(syntaxTokens: syntaxTokens, file: file)
|
||||
}.compactMap { match, syntaxTokens in
|
||||
let identifierRange = nsstring
|
||||
let identifierRange = contents
|
||||
.byteRangeToNSRange(start: syntaxTokens[0].offset, length: 0)
|
||||
return identifierRange.map { NSUnionRange($0, match.range) }
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public struct ColonRule: CorrectableRule, ConfigurationProviderRule {
|
|||
(range: $0, kind: ColonKind.type)
|
||||
}
|
||||
let dictionary = file.structureDictionary
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
let dictViolations: [RangeWithKind] = dictionaryColonViolationRanges(in: file,
|
||||
dictionary: dictionary).compactMap {
|
||||
guard let range = contents.byteRangeToNSRange(start: $0.location, length: $0.length) else {
|
||||
|
|
|
@ -73,9 +73,8 @@ public struct CommaRule: SubstitutionCorrectableRule, ConfigurationProviderRule,
|
|||
private static let excludingSyntaxKindsForSecondCapture = SyntaxKind.commentKinds.union([.objectLiteral])
|
||||
|
||||
public func violationRanges(in file: SwiftLintFile) -> [NSRange] {
|
||||
let contents = file.contents
|
||||
let nsstring = contents.bridge()
|
||||
let range = NSRange(location: 0, length: nsstring.length)
|
||||
let contents = file.stringView
|
||||
let range = contents.range
|
||||
let syntaxMap = file.syntaxMap
|
||||
return CommaRule.regularExpression
|
||||
.matches(in: contents, options: [], range: range)
|
||||
|
@ -89,7 +88,7 @@ public struct CommaRule: SubstitutionCorrectableRule, ConfigurationProviderRule,
|
|||
|
||||
// check first captured range
|
||||
let firstRange = match.range(at: indexStartRange)
|
||||
guard let matchByteFirstRange = nsstring
|
||||
guard let matchByteFirstRange = contents
|
||||
.NSRangeToByteRange(start: firstRange.location, length: firstRange.length)
|
||||
else { return nil }
|
||||
|
||||
|
@ -102,13 +101,13 @@ public struct CommaRule: SubstitutionCorrectableRule, ConfigurationProviderRule,
|
|||
|
||||
// If the first range does not start with comma, it already violates this rule
|
||||
// no matter what is contained in the second range.
|
||||
if !nsstring.substring(with: firstRange).hasPrefix(", ") {
|
||||
if !contents.substring(with: firstRange).hasPrefix(", ") {
|
||||
return firstRange
|
||||
}
|
||||
|
||||
// check second captured range
|
||||
let secondRange = match.range(at: indexStartRange + 1)
|
||||
guard let matchByteSecondRange = nsstring
|
||||
guard let matchByteSecondRange = contents
|
||||
.NSRangeToByteRange(start: secondRange.location, length: secondRange.length)
|
||||
else { return nil }
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ public struct ControlStatementRule: ConfigurationProviderRule, AutomaticTestable
|
|||
}
|
||||
.map { $0.0 }
|
||||
.filter { match -> Bool in
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let byteOffset = contents.NSRangeToByteRange(start: match.location, length: 1)?.location,
|
||||
let outerKind = file.structureDictionary.structures(forByteOffset: byteOffset).last else {
|
||||
return true
|
||||
|
@ -115,7 +115,7 @@ public struct ControlStatementRule: ConfigurationProviderRule, AutomaticTestable
|
|||
}
|
||||
|
||||
public func substitution(for violationRange: NSRange, in file: SwiftLintFile) -> (NSRange, String) {
|
||||
var violationString = file.contents.bridge().substring(with: violationRange)
|
||||
var violationString = file.stringView.substring(with: violationRange)
|
||||
if violationString.contains("(") && violationString.contains(")") {
|
||||
if let openingIndex = violationString.firstIndex(of: "(") {
|
||||
let replacement = violationString[violationString.index(before: openingIndex)] == " " ? "" : " "
|
||||
|
|
|
@ -68,7 +68,7 @@ public struct CustomRules: Rule, ConfigurationProviderRule, CacheDescriptionProv
|
|||
}
|
||||
|
||||
if let path = file.path {
|
||||
let pathRange = NSRange(location: 0, length: path.bridge().length)
|
||||
let pathRange = path.fullNSRange
|
||||
configurations = configurations.filter { config in
|
||||
let included: Bool
|
||||
if let includedRegex = config.included {
|
||||
|
|
|
@ -73,7 +73,7 @@ public struct EmptyEnumArgumentsRule: SubstitutionCorrectableASTRule, Configurat
|
|||
return []
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
let callsRanges = dictionary.substructure.compactMap { dict -> NSRange? in
|
||||
guard dict.expressionKind == .call,
|
||||
|
|
|
@ -84,7 +84,7 @@ public struct EmptyParenthesesWithTrailingClosureRule: SubstitutionCorrectableAS
|
|||
let rangeLength = (offset + length) - (nameOffset + nameLength)
|
||||
let regex = EmptyParenthesesWithTrailingClosureRule.emptyParenthesesRegex
|
||||
|
||||
guard let range = file.contents.bridge().byteRangeToNSRange(start: rangeStart, length: rangeLength),
|
||||
guard let range = file.stringView.byteRangeToNSRange(start: rangeStart, length: rangeLength),
|
||||
let match = regex.firstMatch(in: file.contents, options: [], range: range)?.range,
|
||||
match.location == range.location else {
|
||||
return []
|
||||
|
|
|
@ -137,7 +137,7 @@ public struct ExplicitSelfRule: CorrectableRule, ConfigurationProviderRule, Anal
|
|||
return []
|
||||
}
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
return cursorsMissingExplicitSelf.compactMap { cursorInfo in
|
||||
guard let byteOffset = cursorInfo["swiftlint.offset"] as? Int64 else {
|
||||
|
@ -159,7 +159,7 @@ private extension SwiftLintFile {
|
|||
func allCursorInfo(compilerArguments: [String], atByteOffsets byteOffsets: [Int]) throws
|
||||
-> [[String: SourceKitRepresentable]] {
|
||||
return try byteOffsets.compactMap { offset in
|
||||
if contents.bridge().substringWithByteRange(start: offset - 1, length: 1)! == "." { return nil }
|
||||
if stringView.substringWithByteRange(start: offset - 1, length: 1)! == "." { return nil }
|
||||
var cursorInfo = try Request.cursorInfo(file: self.path!, offset: Int64(offset),
|
||||
arguments: compilerArguments).sendIfNotDisabled()
|
||||
cursorInfo["swiftlint.offset"] = Int64(offset)
|
||||
|
@ -168,10 +168,10 @@ private extension SwiftLintFile {
|
|||
}
|
||||
}
|
||||
|
||||
private extension NSString {
|
||||
private extension StringView {
|
||||
func byteOffset(forLine line: Int, column: Int) -> Int {
|
||||
var byteOffset = 0
|
||||
for line in lines()[..<(line - 1)] {
|
||||
for line in lines[..<(line - 1)] {
|
||||
byteOffset += line.byteRange.length
|
||||
}
|
||||
return byteOffset + column - 1
|
||||
|
@ -197,6 +197,6 @@ private extension NSString {
|
|||
private func binaryOffsets(file: SwiftLintFile, compilerArguments: [String]) throws -> [Int] {
|
||||
let absoluteFile = file.path!.bridge().absolutePathRepresentation()
|
||||
let index = try Request.index(file: absoluteFile, arguments: compilerArguments).sendIfNotDisabled()
|
||||
let binaryOffsets = file.contents.bridge().recursiveByteOffsets(index)
|
||||
let binaryOffsets = file.stringView.recursiveByteOffsets(index)
|
||||
return binaryOffsets.sorted()
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public struct FileHeaderRule: ConfigurationProviderRule, OptInRule {
|
|||
if let firstToken = firstToken, let lastToken = lastToken {
|
||||
let start = firstToken.offset
|
||||
let length = lastToken.offset + lastToken.length - firstToken.offset
|
||||
guard let range = file.contents.bridge().byteRangeToNSRange(start: start, length: length) else {
|
||||
guard let range = file.stringView.byteRangeToNSRange(start: start, length: length) else {
|
||||
return []
|
||||
}
|
||||
|
||||
|
@ -98,9 +98,9 @@ public struct FileHeaderRule: ConfigurationProviderRule, OptInRule {
|
|||
}
|
||||
|
||||
private func isSwiftLintCommand(token: SwiftLintSyntaxToken, file: SwiftLintFile) -> Bool {
|
||||
guard let range = file.contents.bridge().byteRangeToNSRange(start: token.offset,
|
||||
length: token.length) else {
|
||||
return false
|
||||
guard let range = file.stringView.byteRangeToNSRange(start: token.offset,
|
||||
length: token.length) else {
|
||||
return false
|
||||
}
|
||||
|
||||
return !file.commands(in: range).isEmpty
|
||||
|
|
|
@ -61,7 +61,7 @@ public struct ImplicitReturnRule: ConfigurationProviderRule, SubstitutionCorrect
|
|||
|
||||
public func violationRanges(in file: SwiftLintFile) -> [NSRange] {
|
||||
let pattern = "(?:\\bin|\\{)\\s+(return\\s+)"
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
|
||||
return file.matchesAndSyntaxKinds(matching: pattern).compactMap { result, kinds in
|
||||
let range = result.range
|
||||
|
|
|
@ -193,7 +193,7 @@ extension LiteralExpressionEndIdentationRule {
|
|||
|
||||
let elements = dictionary.elements.filter { $0.kind == "source.lang.swift.structure.elem.expr" }
|
||||
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard !elements.isEmpty,
|
||||
let offset = dictionary.offset,
|
||||
let length = dictionary.length,
|
||||
|
|
|
@ -66,7 +66,7 @@ public struct ModifierOrderRule: ASTRule, OptInRule, ConfigurationProviderRule,
|
|||
kind: SwiftDeclarationKind,
|
||||
dictionary: SourceKittenDictionary) -> [Correction] {
|
||||
guard let offset = dictionary.offset else { return [] }
|
||||
let originalContents = file.contents.bridge()
|
||||
let originalContents = file.stringView
|
||||
let violatingRanges = violatingModifiers(dictionary: dictionary)
|
||||
.compactMap { preferred, declared -> (NSRange, NSRange)? in
|
||||
guard
|
||||
|
@ -87,9 +87,10 @@ public struct ModifierOrderRule: ASTRule, OptInRule, ConfigurationProviderRule,
|
|||
if violatingRanges.isEmpty {
|
||||
corrections = []
|
||||
} else {
|
||||
var correctedContents = originalContents
|
||||
var correctedContents = originalContents.nsString
|
||||
|
||||
violatingRanges.reversed().forEach { preferredModifierRange, declaredModifierRange in
|
||||
violatingRanges.reversed().forEach { arg in
|
||||
let (preferredModifierRange, declaredModifierRange) = arg
|
||||
correctedContents = correctedContents.replacingCharacters(
|
||||
in: declaredModifierRange,
|
||||
with: originalContents.substring(with: preferredModifierRange)
|
||||
|
|
|
@ -82,7 +82,7 @@ public struct MultilineArgumentsBracketsRule: ASTRule, OptInRule, ConfigurationP
|
|||
kind == .call,
|
||||
let bodyOffset = dictionary.bodyOffset,
|
||||
let bodyLength = dictionary.bodyLength,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: bodyOffset, length: bodyLength)
|
||||
let range = file.stringView.byteRangeToNSRange(start: bodyOffset, length: bodyLength)
|
||||
else {
|
||||
return []
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public struct MultilineArgumentsRule: ASTRule, OptInRule, ConfigurationProviderR
|
|||
private func findViolations(in arguments: [Argument],
|
||||
dictionary: SourceKittenDictionary,
|
||||
file: SwiftLintFile) -> [Argument] {
|
||||
guard case let contents = file.contents.bridge(),
|
||||
guard case let contents = file.stringView,
|
||||
let nameOffset = dictionary.nameOffset,
|
||||
let (nameLine, _) = contents.lineAndCharacter(forByteOffset: nameOffset) else {
|
||||
return []
|
||||
|
@ -114,7 +114,7 @@ public struct MultilineArgumentsRule: ASTRule, OptInRule, ConfigurationProviderR
|
|||
guard let offset = dictionary.offset,
|
||||
let length = dictionary.length,
|
||||
case let start = min(offset, offset + length - 1),
|
||||
let text = file.contents.bridge().substringWithByteRange(start: start, length: length) else {
|
||||
let text = file.stringView.substringWithByteRange(start: start, length: length) else {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ public struct MultilineArgumentsRule: ASTRule, OptInRule, ConfigurationProviderR
|
|||
|
||||
private func isClosure(in file: SwiftLintFile) -> (Argument) -> Bool {
|
||||
return { argument in
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
let closureMatcher = regex("^\\s*\\{")
|
||||
guard let range = contents.byteRangeToNSRange(start: argument.bodyOffset,
|
||||
length: argument.bodyLength),
|
||||
|
@ -147,7 +147,7 @@ private struct Argument {
|
|||
|
||||
init?(dictionary: SourceKittenDictionary, file: SwiftLintFile, index: Int) {
|
||||
guard let offset = dictionary.offset,
|
||||
let (line, _) = file.contents.bridge().lineAndCharacter(forByteOffset: offset),
|
||||
let (line, _) = file.stringView.lineAndCharacter(forByteOffset: offset),
|
||||
let bodyOffset = dictionary.bodyOffset,
|
||||
let bodyLength = dictionary.bodyLength else {
|
||||
return nil
|
||||
|
|
|
@ -112,7 +112,7 @@ public struct MultilineFunctionChainsRule: ASTRule, OptInRule, ConfigurationProv
|
|||
let calls = ranges.compactMap { range -> (dotLine: Int, dotOffset: Int, range: NSRange)? in
|
||||
guard
|
||||
let offset = callDotOffset(file: file, callRange: range),
|
||||
let line = file.contents.bridge().lineAndCharacter(forCharacterOffset: offset)?.line else {
|
||||
let line = file.stringView.lineAndCharacter(forCharacterOffset: offset)?.line else {
|
||||
return nil
|
||||
}
|
||||
return (dotLine: line, dotOffset: offset, range: range)
|
||||
|
@ -136,7 +136,7 @@ public struct MultilineFunctionChainsRule: ASTRule, OptInRule, ConfigurationProv
|
|||
|
||||
private func callDotOffset(file: SwiftLintFile, callRange: NSRange) -> Int? {
|
||||
guard
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: callRange.location, length: callRange.length),
|
||||
let range = file.stringView.byteRangeToNSRange(start: callRange.location, length: callRange.length),
|
||||
case let regex = type(of: self).whitespaceDotRegex,
|
||||
let match = regex.matches(in: file.contents, options: [], range: range).last?.range else {
|
||||
return nil
|
||||
|
@ -148,7 +148,7 @@ public struct MultilineFunctionChainsRule: ASTRule, OptInRule, ConfigurationProv
|
|||
|
||||
private func callHasLeadingNewline(file: SwiftLintFile, callRange: NSRange) -> Bool {
|
||||
guard
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: callRange.location, length: callRange.length),
|
||||
let range = file.stringView.byteRangeToNSRange(start: callRange.location, length: callRange.length),
|
||||
case let regex = type(of: self).newlineWhitespaceDotRegex,
|
||||
regex.firstMatch(in: file.contents, options: [], range: range) != nil else {
|
||||
return false
|
||||
|
@ -162,7 +162,7 @@ public struct MultilineFunctionChainsRule: ASTRule, OptInRule, ConfigurationProv
|
|||
parentCallName: String? = nil) -> [NSRange] {
|
||||
guard
|
||||
kind == .call,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let offset = dictionary.nameOffset,
|
||||
let length = dictionary.nameLength,
|
||||
let name = contents.substringWithByteRange(start: offset, length: length) else {
|
||||
|
@ -190,7 +190,7 @@ public struct MultilineFunctionChainsRule: ASTRule, OptInRule, ConfigurationProv
|
|||
parentName: String,
|
||||
parentNameOffset: Int) -> NSRange? {
|
||||
guard
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let nameOffset = call.nameOffset,
|
||||
parentNameOffset == nameOffset,
|
||||
let nameLength = call.nameLength,
|
||||
|
|
|
@ -104,7 +104,7 @@ public struct MultilineLiteralBracketsRule: ASTRule, OptInRule, ConfigurationPro
|
|||
[.array, .dictionary].contains(kind),
|
||||
let bodyOffset = dictionary.bodyOffset,
|
||||
let bodyLength = dictionary.bodyLength,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: bodyOffset, length: bodyLength)
|
||||
let range = file.stringView.byteRangeToNSRange(start: bodyOffset, length: bodyLength)
|
||||
else {
|
||||
return []
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ public struct MultilineParametersBracketsRule: OptInRule, ConfigurationProviderR
|
|||
guard
|
||||
let nameOffset = substructure.nameOffset,
|
||||
let nameLength = substructure.nameLength,
|
||||
let functionName = file.contents.bridge().substringWithByteRange(start: nameOffset, length: nameLength)
|
||||
let functionName = file.stringView.substringWithByteRange(start: nameOffset, length: nameLength)
|
||||
else {
|
||||
return []
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ public struct MultilineParametersBracketsRule: OptInRule, ConfigurationProviderR
|
|||
guard
|
||||
let firstParamByteOffset = parameters.first?.offset,
|
||||
let firstParamByteLength = parameters.first?.length,
|
||||
let firstParamRange = file.contents.bridge().byteRangeToNSRange(
|
||||
let firstParamRange = file.stringView.byteRangeToNSRange(
|
||||
start: firstParamByteOffset,
|
||||
length: firstParamByteLength
|
||||
)
|
||||
|
@ -140,7 +140,7 @@ public struct MultilineParametersBracketsRule: OptInRule, ConfigurationProviderR
|
|||
return nil
|
||||
}
|
||||
|
||||
let prefix = file.contents.bridge().substring(to: firstParamRange.lowerBound)
|
||||
let prefix = file.stringView.nsString.substring(to: firstParamRange.lowerBound)
|
||||
let invalidRegex = regex("\\([ \\t]*\\z")
|
||||
|
||||
guard let invalidMatch = invalidRegex.firstMatch(in: prefix, options: [], range: prefix.fullNSRange) else {
|
||||
|
@ -159,7 +159,7 @@ public struct MultilineParametersBracketsRule: OptInRule, ConfigurationProviderR
|
|||
guard
|
||||
let lastParamByteOffset = parameters.last?.offset,
|
||||
let lastParamByteLength = parameters.last?.length,
|
||||
let lastParamRange = file.contents.bridge().byteRangeToNSRange(
|
||||
let lastParamRange = file.stringView.byteRangeToNSRange(
|
||||
start: lastParamByteOffset,
|
||||
length: lastParamByteLength
|
||||
)
|
||||
|
@ -167,7 +167,7 @@ public struct MultilineParametersBracketsRule: OptInRule, ConfigurationProviderR
|
|||
return nil
|
||||
}
|
||||
|
||||
let suffix = file.contents.bridge().substring(from: lastParamRange.upperBound)
|
||||
let suffix = file.stringView.nsString.substring(from: lastParamRange.upperBound)
|
||||
let invalidRegex = regex("\\A[ \\t]*\\)")
|
||||
|
||||
guard let invalidMatch = invalidRegex.firstMatch(in: suffix, options: [], range: suffix.fullNSRange) else {
|
||||
|
|
|
@ -44,7 +44,7 @@ public struct MultilineParametersRule: ASTRule, OptInRule, ConfigurationProvider
|
|||
|
||||
for range in parameterRanges {
|
||||
guard
|
||||
let (line, _) = file.contents.bridge().lineAndCharacter(forByteOffset: range.offset),
|
||||
let (line, _) = file.stringView.lineAndCharacter(forByteOffset: range.offset),
|
||||
offset..<(offset + length) ~= range.offset,
|
||||
isRange(range, withinRanges: parameterRanges)
|
||||
else {
|
||||
|
|
|
@ -69,7 +69,7 @@ private extension Array where Element == SourceKittenDictionary {
|
|||
return filter { argument in
|
||||
guard let offset = argument.bodyOffset,
|
||||
let length = argument.bodyLength,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: offset, length: length),
|
||||
let range = file.stringView.byteRangeToNSRange(start: offset, length: length),
|
||||
let match = regex("^\\s*\\{").firstMatch(in: file.contents, options: [], range: range)?.range,
|
||||
match.location == range.location else {
|
||||
return false
|
||||
|
|
|
@ -68,7 +68,7 @@ public struct NoSpaceInMethodCallRule: SubstitutionCorrectableASTRule, Configura
|
|||
nameLength > 0,
|
||||
case let nameEndPosition = nameOffset + nameLength,
|
||||
bodyOffset != nameEndPosition + 1,
|
||||
case let contents = file.contents.bridge(),
|
||||
case let contents = file.stringView,
|
||||
let range = contents.byteRangeToNSRange(start: nameEndPosition,
|
||||
length: bodyOffset - nameEndPosition - 1) else {
|
||||
return []
|
||||
|
|
|
@ -60,9 +60,9 @@ public struct NumberSeparatorRule: OptInRule, CorrectableRule, ConfigurationProv
|
|||
guard let integerSubstring = components.first,
|
||||
case let (valid, expected) = isValid(number: integerSubstring, isFraction: false),
|
||||
!valid || !validFraction,
|
||||
let range = file.contents.bridge().byteRangeToNSRange(start: token.offset,
|
||||
length: token.length) else {
|
||||
return nil
|
||||
let range = file.stringView.byteRangeToNSRange(start: token.offset,
|
||||
length: token.length) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
var corrected = ""
|
||||
|
|
|
@ -139,7 +139,7 @@ public struct OperatorUsageWhitespaceRule: OptInRule, CorrectableRule, Configura
|
|||
}
|
||||
|
||||
private func kinds(in range: NSRange, file: SwiftLintFile) -> [SyntaxKind] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
guard let byteRange = contents.NSRangeToByteRange(start: range.location, length: range.length) else {
|
||||
return []
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ public struct OperatorUsageWhitespaceRule: OptInRule, CorrectableRule, Configura
|
|||
}
|
||||
|
||||
private func operatorInRange(file: SwiftLintFile, range: NSRange) -> String {
|
||||
return file.contents.bridge().substring(with: range).trimmingCharacters(in: .whitespaces)
|
||||
return file.stringView.substring(with: range).trimmingCharacters(in: .whitespaces)
|
||||
}
|
||||
|
||||
public func correct(file: SwiftLintFile) -> [Correction] {
|
||||
|
|
|
@ -42,7 +42,7 @@ public struct RedundantDiscardableLetRule: SubstitutionCorrectableRule, Configur
|
|||
}
|
||||
|
||||
public func violationRanges(in file: SwiftLintFile) -> [NSRange] {
|
||||
let contents = file.contents.bridge()
|
||||
let contents = file.stringView
|
||||
return file.match(pattern: "let\\s+_\\b", with: [.keyword, .keyword]).filter { range in
|
||||
guard let byteRange = contents.NSRangeToByteRange(start: range.location, length: range.length) else {
|
||||
return false
|
||||
|
@ -51,7 +51,7 @@ public struct RedundantDiscardableLetRule: SubstitutionCorrectableRule, Configur
|
|||
return !isInBooleanCondition(byteOffset: byteRange.location,
|
||||
dictionary: file.structureDictionary)
|
||||
&& !hasExplicitType(utf16Range: range.location ..< range.location + range.length,
|
||||
fileContents: contents)
|
||||
fileContents: contents.nsString)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,10 +65,8 @@ public struct ShorthandOperatorRule: ConfigurationProviderRule, AutomaticTestabl
|
|||
}()
|
||||
|
||||
public func validate(file: SwiftLintFile) -> [StyleViolation] {
|
||||
let contents = file.contents.bridge()
|
||||
let range = NSRange(location: 0, length: contents.length)
|
||||
|
||||
let matches = ShorthandOperatorRule.violationRegex.matches(in: file.contents, options: [], range: range)
|
||||
let contents = file.stringView
|
||||
let matches = ShorthandOperatorRule.violationRegex.matches(in: file)
|
||||
|
||||
return matches.compactMap { match -> StyleViolation? in
|
||||
// byteRanges will have the ranges of captured groups
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue