Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8348611

Eliminate DeferredLintHandler and emit all lint warnings in the warn phase

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P5 P5
    • None
    • 25
    • tools
    • jdk-25+7-43-g907350e9e8e

    • generic
    • generic

      In javac, lint warnings are generated by many parts of the compiler. Some of these parts execute before attribution and therefore require the services of the DeferredLintHandler so that @SuppressWarnings is handled properly. But there are some issues with this design and it could be cleaned up.

      Quoting Maurizio (from https://github.com/openjdk/jdk/pull/23281)

      <quote>
      * The class seems to be serving too many masters -- the "immediate" mode seems to be a sign of that
      * Using this class correctly is rather finicky, and depends on which part of javac you are on. For instance, Flow doesn't use it, because it is after Attr... in other words, reporting of lint warnings is not centralized - and each component does what it needs to get the job done -- understandable, but leads to messy code (this also leads to Check::setLint)
      * The synergy between Lint and DeferredLintHandler goes quite deep. For instance, flush has to be called in a place where Lint has been augmented with the contents of the relevant SuppressWarnings. All these dependencies make it quite hard to verify that the code does what it needs to do.

      My general feeling here is that we'd be better off with a separate compilation step that runs after all the various front-end steps (e.g. after Flow). E.g. up to Flow, we keep accumulating lint warnings grouped by declaration. Then, in a single pass we take care of updating Lint with the correct @SuppressWarning found in a given declaration, and flush all the pending lint warnings for all that declaration. This would also mean that Attr and Check would be hypothetically be freed from Lint duties.
      </quote>

      The following refactoring was proposed along those lines:

      * Move the deferral logic of DeferredLintManager into Lint; the DeferredLintManager singleton goes away.
      * Lint has a single flush() method which is invoked once per source file during the compiler warn() step (added by JDK-8344148)
          * First, lexical deferrals are remapped to innermost containing JCTree
          * Next, all warnings are emitted (in lexical order) by scanning the JCCompilationUnit and flushing each declaration
      * Lint warnings are created via Lint.logIfEnabled() (or similar) at any time during compilation
          * If you can locate the warning with a JCTree, you supply that
          * Otherwise, you locate the warning with an integer pos source file offset
          * In either case, an assertion verifies that flush() has not yet been invoked
      * No more need for "immediate mode"

      Etc.

            acobbs Archie Cobbs
            acobbs Archie Cobbs
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: