Fix force_unwrapping false positives for local variables

Fixes: #1710
This commit is contained in:
Otávio Lima
2017-07-13 00:29:45 +03:00
committed by JP Simard
parent de08c7a447
commit fb7ffbab99
2 changed files with 27 additions and 3 deletions
+4 -1
View File
@@ -17,7 +17,10 @@
##### Bug Fixes
* None.
* Fix false positive on `force_unwrapping` rule when declaring
local variable with implicity unwrapped type.
[Otávio Lima](https://github.com/otaviolima)
[#1710](https://github.com/realm/SwiftLint/issues/1710)
## 0.21.0: Vintage Washboard
@@ -35,7 +35,8 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule {
"print(\"\\(xVar)!\")",
"var test = (!bar)",
"var a: [Int]!",
"private var myProperty: (Void -> Void)!"
"private var myProperty: (Void -> Void)!",
"func foo(_ options: [AnyHashable: Any]!) {"
],
triggeringExamples: [
"let url = NSURL(string: query)↓!",
@@ -48,7 +49,11 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule {
"let a = dict[\"abc\"]↓!.contains(\"B\")",
"dict[\"abc\"]↓!.bar(\"B\")",
"if dict[\"a\"]↓!!!! {",
"var foo: [Bool]! = dict[\"abc\"]↓!"
"var foo: [Bool]! = dict[\"abc\"]↓!",
"context(\"abc\") {" +
"var foo: [Bool]! = dict[\"abc\"]↓!" +
"}",
"open var computed: String { return foo.bar↓! }"
]
)
@@ -63,8 +68,13 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule {
// capture previous of "!"
// http://userguide.icu-project.org/strings/regexp
private static let pattern = "([^\\s\\p{Ps}])(!+)"
// Match any variable declaration
// Has a small bug in @IBOutlet due suffix "let"
// But that does not compromise the filtering for var declarations
private static let varDeclarionPattern = "[[:blank:]]?(?:let|var)[[:blank:]]+[^=\\v{]*!"
private static let regularExpression = regex(pattern, options: [.dotMatchesLineSeparators])
private static let varDeclarationRegularExpression = regex(varDeclarionPattern, options: [])
private static let excludingSyntaxKindsForFirstCapture = SyntaxKind.commentKeywordStringAndTypeidentifierKinds()
private static let excludingSyntaxKindsForSecondCapture = SyntaxKind.commentAndStringKinds()
@@ -73,9 +83,20 @@ public struct ForceUnwrappingRule: OptInRule, ConfigurationProviderRule {
let nsstring = contents.bridge()
let range = NSRange(location: 0, length: nsstring.length)
let syntaxMap = file.syntaxMap
let varDeclarationRanges = ForceUnwrappingRule.varDeclarationRegularExpression
.matches(in: contents, options: [], range: range)
.flatMap { match -> NSRange? in
return match.range
}
return ForceUnwrappingRule.regularExpression
.matches(in: contents, options: [], range: range)
.flatMap { match -> NSRange? in
if match.range.intersects(varDeclarationRanges) {
return nil
}
return violationRange(match: match, nsstring: nsstring, syntaxMap: syntaxMap, file: file)
}
}