From 96f114c37c02fcfdfa0d4bc25b6e122d11afc485 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 14 Apr 2025 12:11:28 -0700 Subject: [PATCH] Prepare for an incompatible change to Log diagnostic handlers DeferredDiagnosticHandler changes from a static to inner class in https://github.com/openjdk/jdk/commit/4890b74c048a1472b87687294c316ecfb324e4ba, see also b/410556169 Follow-up to https://github.com/google/google-java-format/commit/6f46e8aa66914a23bcd55092fd826b15a08553ee PiperOrigin-RevId: 747516421 --- .../googlejavaformat/java/JavaInput.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 6cf7690c6..c59e74c6c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -42,6 +42,7 @@ import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler; import com.sun.tools.javac.util.Options; import java.io.IOException; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; @@ -365,7 +366,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept return text; } }); - DeferredDiagnosticHandler diagnostics = new DeferredDiagnosticHandler(log); + DeferredDiagnosticHandler diagnostics = deferredDiagnosticHandler(log); ImmutableList rawToks = JavacTokens.getTokens(text, context, stopTokens); Collection ds; try { @@ -482,6 +483,29 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept return ImmutableList.copyOf(toks); } + private static final Constructor + DEFERRED_DIAGNOSTIC_HANDLER_CONSTRUCTOR = getDeferredDiagnosticHandlerConstructor(); + + // Depending on the JDK version, we might have a static class whose constructor has an explicit + // Log parameter, or an inner class whose constructor has an *implicit* Log parameter. They are + // different at the source level, but look the same to reflection. + + private static Constructor getDeferredDiagnosticHandlerConstructor() { + try { + return DeferredDiagnosticHandler.class.getConstructor(Log.class); + } catch (NoSuchMethodException e) { + throw new LinkageError(e.getMessage(), e); + } + } + + private static DeferredDiagnosticHandler deferredDiagnosticHandler(Log log) { + try { + return DEFERRED_DIAGNOSTIC_HANDLER_CONSTRUCTOR.newInstance(log); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + private static final Method GET_DIAGNOSTICS = getGetDiagnostics(); private static @Nullable Method getGetDiagnostics() {