Skip to content

Commit 9f47c93

Browse files
cushongoogle-java-format Team
authored andcommitted
Prepare for end position API changes in https://bugs.openjdk.org/browse/JDK-8372948
PiperOrigin-RevId: 862139794
1 parent 62edae4 commit 9f47c93

File tree

1 file changed

+101
-9
lines changed
  • core/src/main/java/com/google/googlejavaformat/java

1 file changed

+101
-9
lines changed

core/src/main/java/com/google/googlejavaformat/java/Trees.java

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414

1515
package com.google.googlejavaformat.java;
1616

17-
import static com.google.googlejavaformat.java.Trees.getEndPosition;
18-
import static com.google.googlejavaformat.java.Trees.getStartPosition;
1917
import static java.nio.charset.StandardCharsets.UTF_8;
2018

19+
import com.google.common.base.Throwables;
2120
import com.google.common.collect.ImmutableList;
2221
import com.sun.source.tree.ClassTree;
2322
import com.sun.source.tree.CompilationUnitTree;
@@ -41,6 +40,10 @@
4140
import com.sun.tools.javac.util.Options;
4241
import java.io.IOError;
4342
import java.io.IOException;
43+
import java.lang.invoke.MethodHandle;
44+
import java.lang.invoke.MethodHandles;
45+
import java.lang.invoke.MethodType;
46+
import java.lang.invoke.VarHandle;
4447
import java.net.URI;
4548
import java.util.List;
4649
import javax.lang.model.element.Name;
@@ -49,6 +52,7 @@
4952
import javax.tools.JavaFileObject;
5053
import javax.tools.SimpleJavaFileObject;
5154
import javax.tools.StandardLocation;
55+
import org.jspecify.annotations.Nullable;
5256

5357
/** Utilities for working with {@link Tree}s. */
5458
class Trees {
@@ -69,7 +73,12 @@ static int getEndPosition(Tree expression, TreePath path) {
6973

7074
/** Returns the source end position of the node. */
7175
public static int getEndPosition(Tree tree, CompilationUnitTree unit) {
72-
return ((JCTree) tree).getEndPosition(((JCCompilationUnit) unit).endPositions);
76+
try {
77+
return (int) GET_END_POS_HANDLE.invokeExact((JCTree) tree, (JCCompilationUnit) unit);
78+
} catch (Throwable e) {
79+
Throwables.throwIfUnchecked(e);
80+
throw new AssertionError(e);
81+
}
7382
}
7483

7584
/** Returns the source text for the node. */
@@ -167,12 +176,20 @@ public String getCharContent(boolean ignoreEncodingErrors) {
167176
};
168177
Log.instance(context).useSource(source);
169178
ParserFactory parserFactory = ParserFactory.instance(context);
170-
JavacParser parser =
171-
parserFactory.newParser(
172-
javaInput,
173-
/* keepDocComments= */ true,
174-
/* keepEndPos= */ true,
175-
/* keepLineMap= */ true);
179+
JavacParser parser;
180+
try {
181+
parser =
182+
(JavacParser)
183+
NEW_PARSER_HANDLE.invokeExact(
184+
parserFactory,
185+
(CharSequence) javaInput,
186+
/* keepDocComments */ true,
187+
/* keepEndPos */ true,
188+
/* keepLineMap */ true);
189+
} catch (Throwable e) {
190+
Throwables.throwIfUnchecked(e);
191+
throw new AssertionError(e);
192+
}
176193
JCCompilationUnit unit = parser.parseCompilationUnit();
177194
unit.sourcefile = source;
178195
return unit;
@@ -186,4 +203,79 @@ private static boolean errorDiagnostic(Diagnostic<?> input) {
186203
// enclosing class
187204
return !input.getCode().equals("compiler.err.invalid.meth.decl.ret.type.req");
188205
}
206+
207+
private static final @Nullable Class<?> END_POS_TABLE_CLASS = getEndPosTableClass();
208+
209+
private static @Nullable Class<?> getEndPosTableClass() {
210+
try {
211+
return Class.forName("com.sun.tools.javac.tree.EndPosTable");
212+
} catch (ClassNotFoundException e) {
213+
// JDK versions after https://bugs.openjdk.org/browse/JDK-8372948
214+
return null;
215+
}
216+
}
217+
218+
private static final MethodHandle NEW_PARSER_HANDLE = getNewParserHandle();
219+
220+
private static MethodHandle getNewParserHandle() {
221+
MethodHandles.Lookup lookup = MethodHandles.lookup();
222+
if (END_POS_TABLE_CLASS == null) {
223+
try {
224+
// (parserFactory, input, keepDocComments, keepEndPos, keepLineMap) ->
225+
// parserFactory.newParser(input, keepDocComments, keepLineMap)
226+
return MethodHandles.dropArguments(
227+
lookup.findVirtual(
228+
ParserFactory.class,
229+
"newParser",
230+
MethodType.methodType(
231+
JavacParser.class, CharSequence.class, boolean.class, boolean.class)),
232+
2,
233+
boolean.class);
234+
} catch (ReflectiveOperationException e) {
235+
throw new LinkageError(e.getMessage(), e);
236+
}
237+
}
238+
try {
239+
// (parserFactory, input, keepDocComments, keepEndPos, keepLineMap) ->
240+
// parserFactory.newParser(input, keepDocComments, keepEndPos, keepLineMap)
241+
return lookup.findVirtual(
242+
ParserFactory.class,
243+
"newParser",
244+
MethodType.methodType(
245+
JavacParser.class, CharSequence.class, boolean.class, boolean.class, boolean.class));
246+
} catch (ReflectiveOperationException e) {
247+
throw new LinkageError(e.getMessage(), e);
248+
}
249+
}
250+
251+
private static final MethodHandle GET_END_POS_HANDLE = getEndPosMethodHandle();
252+
253+
private static MethodHandle getEndPosMethodHandle() {
254+
MethodHandles.Lookup lookup = MethodHandles.lookup();
255+
if (END_POS_TABLE_CLASS == null) {
256+
try {
257+
// (tree, unit) -> tree.getEndPosition()
258+
return MethodHandles.dropArguments(
259+
lookup.findVirtual(JCTree.class, "getEndPosition", MethodType.methodType(int.class)),
260+
1,
261+
JCCompilationUnit.class);
262+
} catch (ReflectiveOperationException e1) {
263+
throw new LinkageError(e1.getMessage(), e1);
264+
}
265+
}
266+
try {
267+
// (tree, unit) -> tree.getEndPosition(unit.endPositions)
268+
return MethodHandles.filterArguments(
269+
lookup.findVirtual(
270+
JCTree.class,
271+
"getEndPosition",
272+
MethodType.methodType(int.class, END_POS_TABLE_CLASS)),
273+
1,
274+
lookup
275+
.findVarHandle(JCCompilationUnit.class, "endPositions", END_POS_TABLE_CLASS)
276+
.toMethodHandle(VarHandle.AccessMode.GET));
277+
} catch (ReflectiveOperationException e) {
278+
throw new LinkageError(e.getMessage(), e);
279+
}
280+
}
189281
}

0 commit comments

Comments
 (0)