IntelliJ IDEA 2016.3 EAP Makes Unused Code Detection More Flexible

Have you ever seen a project with no unused symbols? If so, you are really lucky! Jokes aside, finding unused code is difficult because of things like dependency injection, reflection, and countless frameworks. Luckily we have IntelliJ IDEA that provides instance editor highlighting and batch inspection that are a great aid in this task. Unfortunately, sometimes static information is not enough to detect that code is implicitly used by a framework or called through reflection, or your project is a library and all public methods are therefore implicitly used. To make the inspection more flexible and support all that cases, we’ve introduced the following settings.

Now, with IntelliJ IDEA 2016.3 EAP you can configure the IDE to treat your project as a library and report only private members:

screen-shot-2016-09-12-at-17-12-15

Please note that public method of a private inner class will be treated as private as well.

It was always possible to annotate a member as used, but sometimes it’s tedious to annotate every second method just to make the inspection happy. Now you can specify class or method pattern which should be treated as entry points, e.g. used by test harness or by reflection.

screen-shot-2016-09-12-at-17-11-47

The last but not the least, is that you can find code used from tests only. The code is strictly speaking reachable, but if your project is not a library, then you may consider removing it.

screen-shot-2016-09-12-at-15-42-21

Bottom line: unused declaration inspection now reports unused parameters and unused local variables, sharing the settings with the instant editor highlighting.

Feedback is very welcome.

Develop with Pleasure!

This entry was posted in EAP Releases, New Features and tagged , . Bookmark the permalink.

10 Responses to IntelliJ IDEA 2016.3 EAP Makes Unused Code Detection More Flexible

  1. Moshe says:

    This looks great, thanks.

    When will we get it?
    I can’t find it in the latest version of IntelliJ (2016.3 EAP, IU-163.4396.1).
    How can the dialog be opened?

    • Andrey Cheptsov says:

      Yes, it’s already there. If you’re asking about “Members to report” and “Entry points”, then it’s the Settings -> Editor -> Inspections -> Java -> Declaration redundancy -> Unused declaration.

  2. Oleksandr Kulychok says:

    For me it works in unexpected way with @Inject-ed fields with javax.inject.Inject
    If such field is unused, I’ve got ‘greyed’ field and warning “private field ‘xxx’ is assigned but never accessed” only when field is marked as ‘private’. When I set any other visibility level I lost the warning. Note: all settings in “Unused declaration” inspections are set to ‘public’.

    When I use com.google.inject.Inject (with proper configuration for ‘implicitly written fields’) – all works OK

    IDEA version – 2016.3.1 EAP

    • Anna Kozlova says:

      Fields annotated with javax.inject.Inject are treated as implicitly used. When such fields are private additional analysis is performed which detects that there are no explicit read usages and that’s why a warning. For non-private fields the check is not performed due to performance reasons – as . The field should be marked as unused if inspections are run in batch mode.

      Thanks,
      Anna

      • There is an issue with this approach. Dagger 2, or Toothpick, use annotation processing and need fields (or methods) to be package private. Generated code will then use the fields.

        But there should be a mechanism to detect that a package private, @Inject annotated field is only used by generated code (generate code follows regexp names), hence the field is unused. Of course, package private members being accessible to subclasses, these usages should also be taken into account.

        All applications using these DI frameworks, i.e., advanced Android apps are impacted by this missing feature. It’s quite costly as things are injected but are unused and it’s very hard to detect these issues.

        • Anna Kozlova says:

          Stephane,

          it’s impossible to support all cases just by configurations as they would be overcomplicated. In the described case, most probably a plugin should do the job better.

          Anna

  3. Paul Zagieboylo says:

    The setting for ignoring entry points called by test sources doesn’t seem to work at all for me. I set it to “unused” but it still reports methods as valid entry points, even though asking the inspection window where they’re used only finds calls in test sources, which I know IntelliJ knows are tests. Even if I set that to “unused” and also turn off JUnit and TestNG in the entry points checkboxes, the method is still considered an entry point. Am I doing something wrong? I’m using IDEA 2016.3.2.

    • Anna Kozlova says:

      The test methods should be still entry points (not marked as unused) but the code which is called only from test sources should be treated as unused. This feature works only for batch inspection and disabled in the editor.
      When you disable junit/testng checkboxes, test methods should be treated as unused. When in the editor they are not highlighted as unused, this could mean that the names of the methods are “common” to the project, so IDEA doesn’t check them for performance reasons. To check that, if you rename the test method to some very long name, would it be marked as unused?

      Anna

  4. kavnik says:

    How to enable unused declaration checking for @Inject-ed fields?
    Private field without @Inject is grayed, but on adding @Inject annotation it ceases to be gray.

  5. tieskedh says:

    Can you add this toKotlin as well?

Leave a Reply

Your email address will not be published. Required fields are marked *