Disable/re-enable rules from within source code comments. Fixes #4.

This commit is contained in:
JP Simard
2015-08-29 17:09:28 -07:00
parent 524bee7931
commit c699d3d2fa
3 changed files with 62 additions and 2 deletions
+5
View File
@@ -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.
+43 -1
View File
@@ -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
+14 -1
View File
@@ -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] {