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

Find and remove unused @Suppress() annotations #1530

Open
sanyavertolet opened this issue Sep 29, 2022 · 1 comment
Open

Find and remove unused @Suppress() annotations #1530

sanyavertolet opened this issue Sep 29, 2022 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@sanyavertolet
Copy link
Member

sanyavertolet commented Sep 29, 2022

It might be a good idea to implement feature of detecting rule suppresses that could be removed e.g. this code:

@Suppress("TYPE_ALIAS") // <-- unused
fun foo() {
    println("diktak")
}

would show warning as far as @Suppress("TYPE_ALIAS")` is unnecessary.

Moreover, fix feature might be also good.

@sanyavertolet sanyavertolet added the enhancement New feature or request label Sep 29, 2022
@0x6675636b796f75676974687562 0x6675636b796f75676974687562 changed the title Diktat useless rule suppress checker Find and remove unused @Suppress() annotations Mar 14, 2023
@0x6675636b796f75676974687562
Copy link
Member

0x6675636b796f75676974687562 commented Mar 16, 2023

Analysis

We decide whether a warning should be issued (or whether the parent AST node doesn't have any @Suppress() annotation) from Warnings.warn() and Warnings.fix().

Approach A

In order to decide whether a particular @Suppress("XYZ") annotation (for the XYZ rule) on an AST node (or any of its parent nodes) is used or not, we must process all AST nodes in the given file and collect the following statistics:

  1. whether any of the nodes has triggered a warning from the XYZ check
  2. whether any of the node hierarchies are annotated with @Suppress("XYZ").

The simplest case (no warnings at all, at least one matching @Suppress annotation) is indeed easy to implement.
Yet, this needs to be done either at KtLint level or higher (DiktatMain level), as currently we're only in control of our rules (DiktatRule), and rules just don't have enough information.

Yet, there're more complex cases like empty intersection

FILE
|
+- dirty code
|
+- @Suppress("XYZ")-annotated node

or even

FILE
|
+- @Suppress("XYZ")-annotated node
  |
  +- @Suppress("XYZ")-annotated node
    |
    +- dirty code

(in the above case only the smallest-scope annotation should be preserved).

Approach B

If there're N Diktat checks suppressed in a given file, we could run Diktat at minimum 2 times (all suppressions on, all suppressions off), and at most O(N2) times, excluding suppressions one by one and checking whether there's any change in the number of warnings reported.

Related

@nulls, @petertrr, what do you think?

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

No branches or pull requests

2 participants