mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
be341f90b9
`fatalError` prints the full path of the file, which leaks filesystem information from the machine that built the binary. Now that we release via CocoaPods, this is more critical.
104 lines
3.1 KiB
Swift
104 lines
3.1 KiB
Swift
//
|
|
// String+SwiftLint.swift
|
|
// SwiftLint
|
|
//
|
|
// Created by JP Simard on 5/16/15.
|
|
// Copyright © 2015 Realm. All rights reserved.
|
|
//
|
|
|
|
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: [String: SourceKitRepresentable]) -> String {
|
|
if let aclString = dict.accessibility,
|
|
let acl = AccessControlLevel(identifier: aclString),
|
|
acl.isPrivate && characters.first == "_" {
|
|
#if swift(>=4.0)
|
|
return String(self[index(after: startIndex)...])
|
|
#else
|
|
return substring(from: index(after: startIndex))
|
|
#endif
|
|
}
|
|
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]
|
|
}
|
|
let index = characters.index(startIndex, offsetBy: from, limitedBy: endIndex)!
|
|
#if swift(>=4.0)
|
|
return String(self[index...])
|
|
#else
|
|
return substring(from: index)
|
|
#endif
|
|
}
|
|
|
|
internal func lastIndex(of search: String) -> Int? {
|
|
if let range = range(of: search, options: [.literal, .backwards]) {
|
|
return characters.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
|
|
if let from = Index(from16, within: self), let to = Index(to16, within: self) {
|
|
return from..<to
|
|
}
|
|
return nil
|
|
}
|
|
|
|
public func absolutePathStandardized() -> String {
|
|
return bridge().absolutePathRepresentation().bridge().standardizingPath
|
|
}
|
|
|
|
internal var isFile: Bool {
|
|
var isDirectoryObjC: ObjCBool = false
|
|
if FileManager.default.fileExists(atPath: self, isDirectory: &isDirectoryObjC) {
|
|
#if os(Linux)
|
|
return !isDirectoryObjC
|
|
#else
|
|
return !isDirectoryObjC.boolValue
|
|
#endif
|
|
}
|
|
return false
|
|
}
|
|
}
|