SwiftLint/Source/SwiftLintFramework/Extensions/String+SwiftLint.swift

93 lines
2.9 KiB
Swift

import Foundation
import SourceKittenFramework
extension String {
internal func hasTrailingWhitespace() -> Bool {
if isEmpty {
return false
}
if let unicodescalar = unicodeScalars.last {
return CharacterSet.whitespaces.contains(unicodescalar)
}
return false
}
internal func isUppercase() -> Bool {
return self == uppercased()
}
internal func isLowercase() -> Bool {
return self == lowercased()
}
internal func nameStrippingLeadingUnderscoreIfPrivate(_ dict: SourceKittenDictionary) -> String {
if let acl = dict.accessibility,
acl.isPrivate && first == "_" {
return String(self[index(after: startIndex)...])
}
return self
}
private subscript (range: Range<Int>) -> String {
let nsrange = NSRange(location: range.lowerBound,
length: range.upperBound - range.lowerBound)
if let indexRange = nsrangeToIndexRange(nsrange) {
return String(self[indexRange])
}
queuedFatalError("invalid range")
}
internal func substring(from: Int, length: Int? = nil) -> String {
if let length = length {
return self[from..<from + length]
}
return String(self[index(startIndex, offsetBy: from, limitedBy: endIndex)!...])
}
internal func lastIndex(of search: String) -> Int? {
if let range = range(of: search, options: [.literal, .backwards]) {
return distance(from: startIndex, to: range.lowerBound)
}
return nil
}
internal func nsrangeToIndexRange(_ nsrange: NSRange) -> Range<Index>? {
guard nsrange.location != NSNotFound else {
return nil
}
let from16 = utf16.index(utf16.startIndex, offsetBy: nsrange.location,
limitedBy: utf16.endIndex) ?? utf16.endIndex
let to16 = utf16.index(from16, offsetBy: nsrange.length,
limitedBy: utf16.endIndex) ?? utf16.endIndex
guard let fromIndex = Index(from16, within: self),
let toIndex = Index(to16, within: self) else {
return nil
}
return fromIndex..<toIndex
}
internal var fullNSRange: NSRange {
return NSRange(location: 0, length: utf16.count)
}
/// Returns a new string, converting the path to a canonical absolute path.
public func absolutePathStandardized() -> String {
return bridge().absolutePathRepresentation().bridge().standardizingPath
}
internal var isFile: Bool {
if self.isEmpty {
return false
}
var isDirectoryObjC: ObjCBool = false
if FileManager.default.fileExists(atPath: self, isDirectory: &isDirectoryObjC) {
return !isDirectoryObjC.boolValue
}
return false
}
}