Compare commits

...

6 Commits

Author SHA1 Message Date
Paul Taykalo d5ac1b2be1 Update Carthage 2019-11-17 23:09:39 +02:00
Paul Taykalo 25d89926ac Change Lines Container to StringView 2019-11-17 22:01:50 +02:00
Paul Taykalo 8b307ba960 Make tests great again 2019-11-17 21:22:57 +02:00
Paul Taykalo 03e1c32230 Use lazy linesContainer 2019-11-17 21:22:57 +02:00
Paul Taykalo 92b27e02ec LinesContainer for the win 2019-11-17 21:22:57 +02:00
Paul Taykalo 0dcc37ecca 39 errors left 2019-11-17 21:22:57 +02:00
113 changed files with 321 additions and 286 deletions

2
.gitmodules vendored
View File

@ -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

View File

@ -1,2 +1,2 @@
github "jpsim/SourceKitten" ~> 0.27.0
github "PaulTaykalo/SourceKitten" "f5287da"
github "scottrhoyt/SwiftyTextTable" ~> 0.9.0

View File

@ -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

View File

@ -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
}
},
{

View File

@ -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"))] : []),

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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 [] }

View File

@ -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

View File

@ -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)
}

View File

@ -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]

View File

@ -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)
}

View File

@ -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) }
}
}

View File

@ -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 []
}

View File

@ -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 == "\"\""
}
}

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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),

View File

@ -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]

View File

@ -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,

View File

@ -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
}

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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 []
}

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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,

View File

@ -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()")
}

View File

@ -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
}

View File

@ -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,

View File

@ -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 == "\"\""
}
}

View File

@ -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

View File

@ -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)
}
}
}

View File

@ -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)

View File

@ -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 {

View File

@ -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
}

View File

@ -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 {

View File

@ -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 []
}

View File

@ -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),

View File

@ -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
}
}

View File

@ -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),

View File

@ -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) }
}

View File

@ -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
}

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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
}

View File

@ -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 []
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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 []
}

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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

View File

@ -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,

View File

@ -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) }))
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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) }
}

View File

@ -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 {

View File

@ -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 }

View File

@ -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)] == " " ? "" : " "

View File

@ -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 {

View File

@ -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,

View File

@ -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 []

View File

@ -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()
}

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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 []
}

View File

@ -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

View File

@ -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,

View File

@ -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 []
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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 []

View File

@ -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 = ""

View File

@ -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] {

View File

@ -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)
}
}

View File

@ -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