Files
SwiftLint/Source/SwiftLintFramework/Rules/FileprivateRule.swift
T
2017-07-03 01:09:42 +02:00

54 lines
2.2 KiB
Swift

//
// FileprivateRule.swift
// SwiftLint
//
// Created by Jose Cheyo Jimenez on 05/02/17.
// Copyright © 2017 Realm. All rights reserved.
//
import Foundation
import SourceKittenFramework
public struct FileprivateRule: Rule, ConfigurationProviderRule {
public var configuration = FileprivateConfiguration(strict: false)
public init() {}
public static let description = FileprivateConfiguration.fileprivateLimited
public func validate(file: File) -> [StyleViolation] {
if !configuration.strict {
let toplevel = file.structure.dictionary.substructure.flatMap({ $0.offset })
let syntaxTokens = file.syntaxMap.tokens
let violationOffsets = toplevel.flatMap { (offSet) -> Int? in
let parts = syntaxTokens.partitioned { offSet <= $0.offset }
guard let lastKind = parts.first.last,
lastKind.type == SyntaxKind.attributeBuiltin.rawValue,
// Cut the amount of name-look-ups by first checking the char count
lastKind.length == "fileprivate".bridge().length,
// Get the actual name of the attibute
let aclName = file.contents.bridge()
.substringWithByteRange(start:lastKind.offset, length: lastKind.length),
// fileprivate(set) is not possible at toplevel
aclName == "fileprivate"
else { return nil }
return offSet
}
return violationOffsets.map({ StyleViolation(
ruleDescription: FileprivateConfiguration.fileprivateLimited,
location: Location(file: file, byteOffset: $0))
})
} else { // Mark all fileprivate occurences as a violation
let fileprivates = file.match(pattern: "fileprivate", with: [.attributeBuiltin]).flatMap({
file.contents.bridge().NSRangeToByteRange(start: $0.location, length: $0.length)
}).map({ $0.location })
return fileprivates.map({ StyleViolation(
ruleDescription: FileprivateConfiguration.fileprivateDisallowed,
location: Location(file: file, byteOffset: $0))
})
}
}
}