From 20421355f2a5aeedeecda50aa367d2dfe93c5bf6 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Sun, 6 Oct 2024 13:55:17 +0200 Subject: [PATCH 1/2] Use reflection to invoke getCommentTree to support Java 21 & 23 Fixes https://github.com/openrewrite/rewrite/issues/4540 --- .../java/isolated/ReloadableJava21ParserVisitor.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java b/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java index 2c59e8f8924..7ab8b5b26e2 100644 --- a/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java +++ b/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java @@ -44,6 +44,7 @@ import javax.lang.model.element.Modifier; import javax.lang.model.element.Name; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.nio.charset.Charset; import java.nio.file.Path; import java.util.*; @@ -1664,7 +1665,10 @@ private J2 convert(Tree t) { try { String prefix = source.substring(cursor, max(((JCTree) t).getStartPosition(), cursor)); cursor += prefix.length(); - @SuppressWarnings("unchecked") J2 j = (J2) scan(t, formatWithCommentTree(prefix, (JCTree) t, docCommentTable.getCommentTree((JCTree) t))); + // Java 21 and 23 have a different return type from getCommentTree; with reflection we can support both + Method getCommentTreeMethod = DocCommentTable.class.getMethod("getCommentTree", JCTree.class); + DocCommentTree commentTree = (DocCommentTree) getCommentTreeMethod.invoke(docCommentTable, (JCTree) t); + @SuppressWarnings("unchecked") J2 j = (J2) scan(t, formatWithCommentTree(prefix, (JCTree) t, commentTree)); return j; } catch (Throwable ex) { // this SHOULD never happen, but is here simply as a diagnostic measure in the event of unexpected exceptions From 5eb6d3f8e051ddd383a3220e8c2660078b2a1f67 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Sun, 6 Oct 2024 14:06:05 +0200 Subject: [PATCH 2/2] Catch new exceptions from Method invoke --- .../ReloadableJava21ParserVisitor.java | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java b/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java index 7ab8b5b26e2..016248562e1 100644 --- a/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java +++ b/rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21ParserVisitor.java @@ -44,6 +44,7 @@ import javax.lang.model.element.Modifier; import javax.lang.model.element.Name; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.charset.Charset; import java.nio.file.Path; @@ -1670,30 +1671,37 @@ private J2 convert(Tree t) { DocCommentTree commentTree = (DocCommentTree) getCommentTreeMethod.invoke(docCommentTable, (JCTree) t); @SuppressWarnings("unchecked") J2 j = (J2) scan(t, formatWithCommentTree(prefix, (JCTree) t, commentTree)); return j; + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + reportJavaParsingException(ex); + throw new IllegalStateException("Failed to invoke getCommentTree method", ex); } catch (Throwable ex) { - // this SHOULD never happen, but is here simply as a diagnostic measure in the event of unexpected exceptions - StringBuilder message = new StringBuilder("Failed to convert for the following cursor stack:"); - message.append("--- BEGIN PATH ---\n"); - - List paths = stream(getCurrentPath().spliterator(), false).toList(); - for (int i = paths.size(); i-- > 0; ) { - JCTree tree = (JCTree) paths.get(i); - if (tree instanceof JCCompilationUnit) { - message.append("JCCompilationUnit(sourceFile = ").append(((JCCompilationUnit) tree).sourcefile.getName()).append(")\n"); - } else if (tree instanceof JCClassDecl) { - message.append("JCClassDecl(name = ").append(((JCClassDecl) tree).name).append(", line = ").append(lineNumber(tree)).append(")\n"); - } else if (tree instanceof JCVariableDecl) { - message.append("JCVariableDecl(name = ").append(((JCVariableDecl) tree).name).append(", line = ").append(lineNumber(tree)).append(")\n"); - } else { - message.append(tree.getClass().getSimpleName()).append("(line = ").append(lineNumber(tree)).append(")\n"); - } - } + reportJavaParsingException(ex); + throw ex; + } + } - message.append("--- END PATH ---\n"); + private void reportJavaParsingException(Throwable ex) { + // this SHOULD never happen, but is here simply as a diagnostic measure in the event of unexpected exceptions + StringBuilder message = new StringBuilder("Failed to convert for the following cursor stack:"); + message.append("--- BEGIN PATH ---\n"); - ctx.getOnError().accept(new JavaParsingException(message.toString(), ex)); - throw ex; + List paths = stream(getCurrentPath().spliterator(), false).toList(); + for (int i = paths.size(); i-- > 0; ) { + JCTree tree = (JCTree) paths.get(i); + if (tree instanceof JCCompilationUnit) { + message.append("JCCompilationUnit(sourceFile = ").append(((JCCompilationUnit) tree).sourcefile.getName()).append(")\n"); + } else if (tree instanceof JCClassDecl) { + message.append("JCClassDecl(name = ").append(((JCClassDecl) tree).name).append(", line = ").append(lineNumber(tree)).append(")\n"); + } else if (tree instanceof JCVariableDecl) { + message.append("JCVariableDecl(name = ").append(((JCVariableDecl) tree).name).append(", line = ").append(lineNumber(tree)).append(")\n"); + } else { + message.append(tree.getClass().getSimpleName()).append("(line = ").append(lineNumber(tree)).append(")\n"); + } } + + message.append("--- END PATH ---\n"); + + ctx.getOnError().accept(new JavaParsingException(message.toString(), ex)); } private JRightPadded convert(Tree t, Function suffix) {