Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift type checking using is #5561

Merged

Conversation

ikelax
Copy link
Contributor

@ikelax ikelax commented May 5, 2024

Addresses #5295.

This new rule triggers on code like

if a as? Dog != nil { 
   doSomeThing()
}

which can be replaced by

if a is Dog  { 
   doSomeThing()
}

or

if let a = a as? Dog  { 
   a.run()
}

However, so far there is not a Rewriter for fixing this automatically. If I am not mistaken, a as? Dog != nil can always be replaced by a is Dog.

@SwiftLintBot
Copy link

SwiftLintBot commented May 5, 2024

26 Warnings
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift:2447:81: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift:459:41: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift:470:41: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Browser/TabDisplayManager.swift:459:46: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Browser/TabDisplayManager.swift:702:29: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Home/HomepageContextMenuHelper.swift:271:24: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Home/HomepageViewController.swift:325:36: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Home/TopSites/DataManagement/TopSitesDataAdaptor.swift:183:19: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Library/HistoryPanel/HistoryPanel.swift:548:17: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Settings/SettingsTableViewController.swift:1012:20: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/TabContentsScripts/LoginsHelper.swift:326:35: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/TabContentsScripts/LoginsHelper.swift:327:37: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Widgets/SiteTableViewController.swift:112:41: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Firefox: /firefox-ios/Client/Frontend/Widgets/SiteTableViewController.swift:54:17: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Kickstarter: /Library/TestHelpers/MockStripeIntentService.swift:18:41: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Kickstarter: /Library/TestHelpers/MockStripeIntentService.swift:39:41: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/MatchError.swift:62:24: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Realm: /RealmSwift/Impl/SchemaDiscovery.swift:159:27: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Realm: /RealmSwift/Realm.swift:1375:30: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Sourcery: /SourceryTests/Stub/Performance-Code/Kiosk/App/AppViewController.swift:79:36: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Swift: /stdlib/public/core/BridgeObjectiveC.swift:819:25: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Wire: /wire-ios-request-strategy/Tests/Sources/Payloads/Processing/ConversationEventPayloadProcessorTests.swift:1387:76: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in Wire: /wire-ios/Wire-iOS/Sources/UserInterface/Components/Views/MarkdownTextView+Recognizers.swift:41:61: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in WordPress: /WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift:764:52: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in WordPress: /WordPress/Classes/ViewRelated/Notifications/Tools/NotificationMediaDownloader.swift:98:88: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
⚠️ This PR introduced a violation in WordPress: /WordPress/Classes/ViewRelated/Reader/ReaderCardsStreamViewController.swift:256:18: warning: Prefer Type Checking Violation: Prefer a is X to a as? X != nil (prefer_type_checking)
17 Messages
📖 Linting Aerial with this PR took 0.84s vs 0.83s on main (1% slower)
📖 Linting Alamofire with this PR took 1.15s vs 1.16s on main (0% faster)
📖 Linting Brave with this PR took 6.98s vs 6.92s on main (0% slower)
📖 Linting DuckDuckGo with this PR took 4.31s vs 4.22s on main (2% slower)
📖 Linting Firefox with this PR took 9.98s vs 10.05s on main (0% faster)
📖 Linting Kickstarter with this PR took 9.2s vs 9.14s on main (0% slower)
📖 Linting Moya with this PR took 0.49s vs 0.49s on main (0% slower)
📖 Linting NetNewsWire with this PR took 2.38s vs 2.35s on main (1% slower)
📖 Linting Nimble with this PR took 0.7s vs 0.69s on main (1% slower)
📖 Linting PocketCasts with this PR took 8.0s vs 7.92s on main (1% slower)
📖 Linting Quick with this PR took 0.4s vs 0.4s on main (0% slower)
📖 Linting Realm with this PR took 4.4s vs 4.38s on main (0% slower)
📖 Linting Sourcery with this PR took 2.19s vs 2.16s on main (1% slower)
📖 Linting Swift with this PR took 4.14s vs 4.11s on main (0% slower)
📖 Linting VLC with this PR took 1.15s vs 1.12s on main (2% slower)
📖 Linting Wire with this PR took 16.69s vs 16.33s on main (2% slower)
📖 Linting WordPress with this PR took 10.82s vs 10.48s on main (3% slower)

Generated by 🚫 Danger

@ikelax
Copy link
Contributor Author

ikelax commented May 29, 2024

I added a Rewriter for fixing this automatically. Also, I checked the findings of SwiftLintBot. As far as I can tell, there is not anything that speaks against this rule.

@mildm8nnered
Copy link
Collaborator

So I wrote #5649 the other day because I had not spotted this PR. I've left mine open as a draft - please feel free to steal anything you like from it - I overrode visitPost(_ node: UnresolvedAsExprSyntax), and then look at the siblings of the parent ExprListSyntax to look for != nil, which might be a bit more efficient that looking at every ExprListSyntax (although I have not measured that).

I think the solutions are quite similar, but mine seem to pick up 26 OSS violations, versus 10 for this branch. When I looked at a couple, they did not seem to be false alarms. For example

https://github.com/wireapp/wire-ios/blob/ff4e0b2b87c7f78d638e3dc1791d587eaab8b6ed/wire-ios/Wire-iOS/Sources/UserInterface/Components/Views/MarkdownTextView+Recognizers.swift#L41:61

and

https://github.com/kickstarter/ios-oss/blob/eb2e07004a6ffb7be3764dfa6f23d518c0b38290/Library/TestHelpers/MockStripeIntentService.swift#L17:41

@ikelax
Copy link
Contributor Author

ikelax commented Jul 3, 2024

Thank you. I prefer your idea so far. As soon as I am free again, I will work on it.

@ikelax
Copy link
Contributor Author

ikelax commented Aug 20, 2024

@mildm8nnered I stole a lot from #5649. What do you think about the current solution? Do you mind if I also mention you in the changelog?

@mildm8nnered
Copy link
Collaborator

@mildm8nnered I stole a lot from #5649. What do you think about the current solution? Do you mind if I also mention you in the changelog?

Hi @ikelax - absolutely fine to credit me, but make sure you put yourself first!

I'm on vacation right now, but back home at the end of this week, so I'll be able to review it then, but hopefully @SimplyDanny will take a look too, as he is the most stringent code reviewer.

@SimplyDanny SimplyDanny linked an issue Aug 20, 2024 that may be closed by this pull request
Copy link
Collaborator

@SimplyDanny SimplyDanny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very well done! With a folded tree, this looks much simpler indeed.

With that, my stringent review is done and I'll hand over to @mildm8nnered to discover what I've missed. 😉

Comment on lines +83 to +85
self.leftOperand.is(AsExprSyntax.self)
&& self.operator.as(BinaryOperatorExprSyntax.self)?.operator.tokenKind == .binaryOperator("!=")
&& self.rightOperand.is(NilLiteralExprSyntax.self)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.leftOperand.is(AsExprSyntax.self)
&& self.operator.as(BinaryOperatorExprSyntax.self)?.operator.tokenKind == .binaryOperator("!=")
&& self.rightOperand.is(NilLiteralExprSyntax.self)
leftOperand.is(AsExprSyntax.self)
&& operator.as(BinaryOperatorExprSyntax.self)?.operator.tokenKind == .binaryOperator("!=")
&& rightOperand.is(NilLiteralExprSyntax.self)

Copy link
Collaborator

@mildm8nnered mildm8nnered left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@mildm8nnered mildm8nnered merged commit 9f4cb92 into realm:main Aug 23, 2024
13 checks passed
@mildm8nnered
Copy link
Collaborator

Congratulations on your first rule @ikelax !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Swift type checking using is
4 participants