Skip to content

Commit

Permalink
Fix false-positive identical operands rule
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulTaykalo committed Nov 10, 2019
1 parent 944bea4 commit 3a36b69
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 8 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

#### Bug Fixes

* None.
* Fix for false-positive identical operands rule.
[PaulTaykalo](https://github.com/PaulTaykalo)
[#2953](https://github.com/realm/SwiftLint/issues/2953)

## 0.37.0: Double Load

Expand Down
104 changes: 104 additions & 0 deletions Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -9647,6 +9647,14 @@ guard Set(identifiers).count != identifiers.count else { return }
expect("foo") == "foo"
```

```swift
type(of: model).cachePrefix == cachePrefix
```

```swift
histogram[156].0 == 0x003B8D96 && histogram[156].1 == 1
```

</details>
<details>
<summary>Triggering Examples</summary>
Expand Down Expand Up @@ -9675,6 +9683,18 @@ expect("foo") == "foo"
↓a?.b == a?.b
```

```swift
if (↓elem == elem) {}
```

```swift
XCTAssertTrue(↓s3 == s3)
```

```swift
if let tab = tabManager.selectedTab, ↓tab.webView == tab.webView
```

```swift
↓1 != 1
```
Expand All @@ -9699,6 +9719,18 @@ expect("foo") == "foo"
↓a?.b != a?.b
```

```swift
if (↓elem != elem) {}
```

```swift
XCTAssertTrue(↓s3 != s3)
```

```swift
if let tab = tabManager.selectedTab, ↓tab.webView != tab.webView
```

```swift
↓1 === 1
```
Expand All @@ -9723,6 +9755,18 @@ expect("foo") == "foo"
↓a?.b === a?.b
```

```swift
if (↓elem === elem) {}
```

```swift
XCTAssertTrue(↓s3 === s3)
```

```swift
if let tab = tabManager.selectedTab, ↓tab.webView === tab.webView
```

```swift
↓1 !== 1
```
Expand All @@ -9747,6 +9791,18 @@ expect("foo") == "foo"
↓a?.b !== a?.b
```

```swift
if (↓elem !== elem) {}
```

```swift
XCTAssertTrue(↓s3 !== s3)
```

```swift
if let tab = tabManager.selectedTab, ↓tab.webView !== tab.webView
```

```swift
↓1 > 1
```
Expand All @@ -9771,6 +9827,18 @@ expect("foo") == "foo"
↓a?.b > a?.b
```

```swift
if (↓elem > elem) {}
```

```swift
XCTAssertTrue(↓s3 > s3)
```

```swift
if let tab = tabManager.selectedTab, ↓tab.webView > tab.webView
```

```swift
↓1 >= 1
```
Expand All @@ -9795,6 +9863,18 @@ expect("foo") == "foo"
↓a?.b >= a?.b
```

```swift
if (↓elem >= elem) {}
```

```swift
XCTAssertTrue(↓s3 >= s3)
```

```swift
if let tab = tabManager.selectedTab, ↓tab.webView >= tab.webView
```

```swift
↓1 < 1
```
Expand All @@ -9819,6 +9899,18 @@ expect("foo") == "foo"
↓a?.b < a?.b
```

```swift
if (↓elem < elem) {}
```

```swift
XCTAssertTrue(↓s3 < s3)
```

```swift
if let tab = tabManager.selectedTab, ↓tab.webView < tab.webView
```

```swift
↓1 <= 1
```
Expand All @@ -9843,6 +9935,18 @@ expect("foo") == "foo"
↓a?.b <= a?.b
```

```swift
if (↓elem <= elem) {}
```

```swift
XCTAssertTrue(↓s3 <= s3)
```

```swift
if let tab = tabManager.selectedTab, ↓tab.webView <= tab.webView
```

</details>


Expand Down
21 changes: 14 additions & 7 deletions Source/SwiftLintFramework/Rules/Lint/IdenticalOperandsRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom
"func evaluate(_ mode: CommandMode) -> Result<AutoCorrectOptions, CommandantError<CommandantError<()>>>",
"let array = Array<Array<Int>>()",
"guard Set(identifiers).count != identifiers.count else { return }",
"expect(\"foo\") == \"foo\""
#"expect("foo") == "foo""#,
"type(of: model).cachePrefix == cachePrefix",
"histogram[156].0 == 0x003B8D96 && histogram[156].1 == 1"
],
triggeringExamples: operators.flatMap { operation in
[
Expand All @@ -47,7 +49,10 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom
"↓foo.aProperty \(operation) foo.aProperty",
"↓self.aProperty \(operation) self.aProperty",
"↓$0 \(operation) $0",
"↓a?.b \(operation) a?.b"
"↓a?.b \(operation) a?.b",
"if (↓elem \(operation) elem) {}",
"XCTAssertTrue(↓s3 \(operation) s3)",
"if let tab = tabManager.selectedTab, ↓tab.webView \(operation) tab.webView"
]
}
)
Expand Down Expand Up @@ -118,10 +123,10 @@ public struct IdenticalOperandsRule: ConfigurationProviderRule, OptInRule, Autom
return nil
}

// last check is to check if we have ?? to the left of the leftmost token
if leftOperand.index != 0 {
let previousToken = tokens[leftOperand.index - 1]
guard !contents.isNilCoalecingOperatorBetweenTokens(previousToken, leftmostToken) else {

guard contents.isWhiteSpaceBetweenTokens(previousToken, leftmostToken) else {
return nil
}
}
Expand Down Expand Up @@ -183,11 +188,13 @@ private extension NSString {
}

func isDotOrOptionalChainingBetweenTokens(_ startToken: SyntaxToken, _ endToken: SyntaxToken) -> Bool {
return isRegexBetweenTokens(startToken, "[\\?!]?\\.", endToken)
return isRegexBetweenTokens(startToken, #"[\?!]?\."#, endToken)
}

func isNilCoalecingOperatorBetweenTokens(_ startToken: SyntaxToken, _ endToken: SyntaxToken) -> Bool {
return isRegexBetweenTokens(startToken, "\\?\\?", endToken)
func isWhiteSpaceBetweenTokens(_ startToken: SyntaxToken, _ endToken: SyntaxToken) -> Bool {
guard let betweenTokens = subStringBetweenTokens(startToken, endToken) else { return false }
let range = NSRange(location: 0, length: betweenTokens.utf16.count)
return !regex(#"^[\s\(,]*$"#).matches(in: betweenTokens, options: [], range: range).isEmpty
}

func isRegexBetweenTokens(_ startToken: SyntaxToken, _ regexString: String, _ endToken: SyntaxToken) -> Bool {
Expand Down

0 comments on commit 3a36b69

Please sign in to comment.