rogerkeays / unchecked

Say goodbye to checked exceptions forever.

Home Page:https://patreon.com/Jamaica440

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

javac warns that catch blocks are unreachable

rogerkeays opened this issue · comments

Test code

        try {
            assert new String(STARS, "UTF-8").equals("***");
        } catch (UnsupportedEncodingException e) {} // okay, never thrown

compiler output

Test.java:18: warning: unreachable catch clause
        } catch (UnsupportedEncodingException e) {} // okay, never thrown
          ^
  thrown types  have already been caught

other tests show that catch blocks are executed correctly:

        for (int i = 0; i < 1; i++) {
            try { throw new Exception(); } catch (Exception e) { if (1 == 1) break; }
            assert false;
        }
  • this warning only appears for checked exceptions
  • in github JDK, the source is Flow.FlowAnalyzer.checkCaughtType() (line 1693)
  • this doesn't exist in older compilers, it is just Flow.checkCaughtType()
  • we can override Flow.analyzeTree(), which creates the FlowAnalyzer, but the implementation differs too much between versions
  • we can override Log.warning(), but the signature has changed between javac versions

Log.warning() is stable since java 9, so we can override Log.warning:

// suppress invalid warnings
@Override
public void warning(DiagnosticPosition pos, Warning warningKey) {
    if (!warningKey.key().startsWith("compiler.warn.unreachable.catch")) {
        super.warning(pos, warningKey);
    }
}

and update the context in the plugin init:

Object log = instance(reload(UncheckedLog.class, context), context);
inject(JavaCompiler.class, "log", log, context);
inject(Flow.class, "chk", chk, context);
inject(Flow.class, "log", log, context);