`InstanceOf.getClazz() is null` in CheckStyle's Java 19+ `InputRecordPatternsPreview`
test: https://github.com/checkstyle/checkstyle/pull/16863
line 1:0 token recognition error at: '<u'
line 1:8 token recognition error at: '>'
[ERROR] The recipe produced an error. Please report this to the recipe author.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:01 min
[INFO] Finished at: 2025-04-14T18:06:43+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:6.6.1:run (default-cli) on project checkstyle: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:6.6.1:run failed: Error while visiting src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java19/InputRecordPatternsPreview.java: java.lang.NullPointerException: Cannot invoke "org.openrewrite.java.tree.J.getPrefix()" because the return value of "org.openrewrite.java.tree.J$InstanceOf.getClazz()" is null
[ERROR] org.openrewrite.staticanalysis.OperatorWrap$1.visitInstanceOf(OperatorWrap.java:183)
[ERROR] org.openrewrite.staticanalysis.OperatorWrap$1.visitInstanceOf(OperatorWrap.java:56)
[ERROR] org.openrewrite.java.tree.J$InstanceOf.acceptJava(J.java:2996)
[ERROR] org.openrewrite.java.tree.J.accept(J.java:58)
[ERROR] org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
[ERROR] org.openrewrite.staticanalysis.OperatorWrap$1.visit(OperatorWrap.java:70)
[ERROR] org.openrewrite.staticanalysis.OperatorWrap$1.visit(OperatorWrap.java:56)
[ERROR] org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:311)
[ERROR] org.openrewrite.java.JavaVisitor.visitRightPadded(JavaVisitor.java:1382)
[ERROR] org.openrewrite.java.JavaVisitor.visitControlParentheses(JavaVisitor.java:528)
[ERROR] org.openrewrite.java.JavaIsoVisitor.visitControlParentheses(JavaIsoVisitor.java:119)
[ERROR] org.openrewrite.java.JavaIsoVisitor.visitControlParentheses(JavaIsoVisitor.java:30)
[ERROR] org.openrewrite.java.tree.J$ControlParentheses.acceptJava(J.java:5002)
[ERROR] org.openrewrite.java.tree.J.accept(J.java:58)
[ERROR] org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
[ERROR] org.openrewrite.staticanalysis.OperatorWrap$1.visit(OperatorWrap.java:70)
[ERROR] ...
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException
Process finished with exit code 1
That's odd; that field is not nullable, so then it's a bit unclear how it ended up being null here.
https://github.com/openrewrite/rewrite-static-analysis/blob/ea97e582eb114c04bc7dc816d975770e5cec3189/src/main/java/org/openrewrite/staticanalysis/OperatorWrap.java#L179-L183
Those instanceof expressions are defined here.
https://github.com/checkstyle/checkstyle/blob/3e5c4a85daff57a4364199119416cc44b932c0c0/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java19/InputRecordPatternsPreview.java#L30-L89
Likely we have a parser issue here that's affecting the recipe. /cc @greg-at-moderne
I tried to reproduce the issue by running OperatorWrap against the file in question, but failed.
The best I could come up with so far is this test:
@Test
void recordVar() throws IOException {
rewriteRun(
java(
"""
class A {
record Box<T>(T t) {}
static boolean test2(Box<Object> bo) {
return bo instanceof Box<?>(var s);
}
}
"""
)
);
}
(inspired by https://github.com/checkstyle/checkstyle/blob/3e5c4a85daff57a4364199119416cc44b932c0c0/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java19/InputRecordPatternsPreview.java#L37)
The test fails with:
java.lang.AssertionError: Source file was parsed into an LST that contains non-whitespace characters in its whitespace. This is indicative of a bug in the parser.
[...]
return bo instanceof Box<?>(~~(non-whitespace)~~>var <~~s);
Great observation! This behavior likely stems from the parser interpreting imports in a fully-qualified manner, even when the class is used directly within the same package or via wildcard imports. One way to address this might be to enhance the import resolution logic to detect when an import is redundant or implicit (e.g., via same-package or static context).
I'd be happy to help investigate this or test adjustments in the import pruning logic if you'd like. Let me know how you'd prefer to approach it!
Also seen in PMD's Jep440_RecordPatterns.java#L8-L75
- https://github.com/openrewrite/rewrite-static-analysis/issues/631