realm / SwiftLint

A tool to enforce Swift style and conventions.
https://realm.github.io/SwiftLint
MIT License
18.46k stars 2.2k forks source link

Have a custom rule where if we have a call to a method, we should expect another one #5529

Open ipodishima opened 2 months ago

ipodishima commented 2 months ago

New Issue Checklist

New rule request

Hi there

I might be missing something, but basically, I have places in the code where I have a call to subscribeToNotifications() And I need a way to assert that unsubscribeFromNotifications is called when subscribeToNotifications is. This is to prevent developers from misusing our internal APIs.

I can't find a way using custom rules to do so... And I'm not sure the swiftlint yaml syntax could be adapted for it?

Thanks

Triggering example

    func viewWillAppear() {
        super.viewWillAppear()
        subscribeToNotifications()
    }

    func viewDidDisappear() {
        super.viewDidDisappear()
    }

Non triggering example

    func viewWillAppear() {
        super.viewWillAppear()
        subscribeToNotifications()
    }

    func viewDidDisappear() {
        super.viewDidDisappear()
        unsubscribeFromNotifications()
    }
SimplyDanny commented 2 months ago

I admittedly can't make heads or tails of your examples. addScrubberFeatureTip isn't called at all and so isn't observeTip. viewWillDisappear calls or doesn't call cancelTipObservations. Where is the connection to observeTip?

But generally multiline matches work. So finding cases where observeTip is not immediately followed by cancelTipObservations should be possible. For more complex cases, custom rules might not be sufficient.

ipodishima commented 2 months ago

Hi

I changed the description of my issue to remove personal context from our app and make it more generic.

SimplyDanny commented 2 months ago

I changed the description of my issue to remove personal context from our app and make it more generic.

That makes it much clearer.

So I think that your use case is impossible to achieve with a custom rule, at least not in its full generality. But there are so called Swift Custom Rules (as opposed to the default Regex Custom Rules) which would allow you to implement this check based on SwiftSyntax.

However, this requires you to build SwiftLint yourself with Bazel.