mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
Disable/re-enable rules from within source code comments. Fixes #4.
This commit is contained in:
@@ -18,6 +18,11 @@
|
||||
names to start with an underscore.
|
||||
[JP Simard](https://github.com/jpsim)
|
||||
|
||||
* Disable and re-enable rules from within source code comments using
|
||||
`// swiftlint:disable:$IDENTIFIER` and `// swiftlint:enable:$IDENTIFIER`.
|
||||
[JP Simard](https://github.com/jpsim)
|
||||
[#4](https://github.com/realm/SwiftLint/issues/4)
|
||||
|
||||
##### Bug Fixes
|
||||
|
||||
* None.
|
||||
|
||||
@@ -9,9 +9,51 @@
|
||||
import SourceKittenFramework
|
||||
import SwiftXPC
|
||||
|
||||
typealias Line = (index: Int, content: String)
|
||||
public typealias Line = (index: Int, content: String)
|
||||
|
||||
public typealias Region = (startLine: Int, endLine: Int, disabledRules: [String])
|
||||
|
||||
public enum CommandAction: String {
|
||||
case Enable = "enable"
|
||||
case Disable = "disable"
|
||||
}
|
||||
|
||||
public typealias Command = (CommandAction, String, Int)
|
||||
|
||||
extension File {
|
||||
public func regions() -> [Region] {
|
||||
let nsStringContents = contents as NSString
|
||||
let commands = matchPattern("swiftlint:(enable|disable):force_cast")
|
||||
.flatMap { range, syntaxKinds -> Command? in
|
||||
let scanner = NSScanner(string: nsStringContents.substringWithRange(range))
|
||||
scanner.scanString("swiftlint:", intoString: nil)
|
||||
var actionString: NSString? = nil
|
||||
scanner.scanUpToString(":", intoString: &actionString)
|
||||
let start = range.location
|
||||
if let actionString = actionString as String?,
|
||||
action = CommandAction(rawValue: actionString),
|
||||
lineRange = nsStringContents.lineRangeWithByteRange(start: start, length: 0) {
|
||||
scanner.scanString(":", intoString: nil)
|
||||
let ruleStart = scanner.string.startIndex.advancedBy(scanner.scanLocation)
|
||||
let rule = scanner.string.substringFromIndex(ruleStart)
|
||||
return (action, rule, lineRange.start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
let totalNumberOfLines = contents.lines().count
|
||||
var regions: [Region] = [(1, commands.first?.2 ?? totalNumberOfLines, [])]
|
||||
var disabledRules = Set<String>()
|
||||
let commandPairs = zip(commands, Array(commands.dropFirst().map({Optional($0)})) + [nil])
|
||||
for (command, nextCommand) in commandPairs {
|
||||
switch command.0 {
|
||||
case .Disable: disabledRules.insert(command.1)
|
||||
case .Enable: disabledRules.remove(command.1)
|
||||
}
|
||||
regions.append((command.2, nextCommand?.2 ?? totalNumberOfLines, Array(disabledRules)))
|
||||
}
|
||||
return regions
|
||||
}
|
||||
|
||||
public func matchPattern(pattern: String,
|
||||
withSyntaxKinds syntaxKinds: [SyntaxKind]) -> [NSRange] {
|
||||
return matchPattern(pattern).filter { _, kindsInRange in
|
||||
|
||||
@@ -16,7 +16,20 @@ public struct Linter {
|
||||
private let rules: [Rule]
|
||||
|
||||
public var styleViolations: [StyleViolation] {
|
||||
return rules.flatMap { $0.validateFile(self.file) }
|
||||
let regions = file.regions()
|
||||
return rules.flatMap { rule in
|
||||
return rule.validateFile(self.file).filter { styleViolation in
|
||||
guard let line = styleViolation.location.line else {
|
||||
return true
|
||||
}
|
||||
guard let violationRegion = regions.filter({
|
||||
$0.startLine < line && $0.endLine > line
|
||||
}).first else {
|
||||
return true
|
||||
}
|
||||
return !violationRegion.disabledRules.contains(rule.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var ruleExamples: [RuleExample] {
|
||||
|
||||
Reference in New Issue
Block a user