rewrite-static-analysis
rewrite-static-analysis copied to clipboard
`UseDiamondOperator` drops type annotations thus it breaks code
What version of OpenRewrite are you using?
org.openrewrite.rewrite.gradle.plugin:6.4.3
How are you running OpenRewrite?
./gradlew rewriteRun, see https://github.com/pgjdbc/pgjdbc/pull/2979
What is the smallest, simplest way to reproduce the problem?
private static final AtomicReferenceFieldUpdater<QueryExecutorCloseAction, @Nullable PGStream> PG_STREAM_UPDATER =
AtomicReferenceFieldUpdater.<QueryExecutorCloseAction, @Nullable PGStream>newUpdater(
QueryExecutorCloseAction.class, PGStream.class, "pgStream");
What did you expect to see?
The code should be left intact.
What did you see instead?
Explicit type annotations disappeared from newUpdater, so the compilation breaks.
private static final AtomicReferenceFieldUpdater<QueryExecutorCloseAction, @Nullable PGStream> PG_STREAM_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(
QueryExecutorCloseAction.class, PGStream.class, "pgStream");
What is the full stack trace of any errors you encountered?
Error: Execution failed for task ':postgresql:compileJava'.
> Compilation failed; see the compiler error output for details.
Error: [Task :postgresql:compileJava] [assignment] incompatible types in assignment.
AtomicReferenceFieldUpdater.newUpdater(
^
found : @Initialized @NonNull AtomicReferenceFieldUpdater<@Initialized @NonNull QueryExecutorCloseAction, @Initialized @NonNull PGStream>
See https://github.com/pgjdbc/pgjdbc/actions/runs/6795291805/job/18473128566?pr=2979#step:4:814
Are you interested in contributing a fix to OpenRewrite?
I think UseDiamondOperator should keep explicit types when they have type annotations.
This fix has also been deployed to https://app.moderne.io/: https://app.moderne.io/results/1GYDVrVbq
I tried latest.integration and it does not resolve the case for me:
private static final AtomicReferenceFieldUpdater<PgStatement, @Nullable TimerTask> CANCEL_TIMER_UPDATER =
AtomicReferenceFieldUpdater.<PgStatement, @Nullable TimerTask>newUpdater(
PgStatement.class, TimerTask.class, "cancelTimerTask");
still converts to
private static final AtomicReferenceFieldUpdater<PgStatement, @Nullable TimerTask> CANCEL_TIMER_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(
PgStatement.class, TimerTask.class, "cancelTimerTask");
For the reference, I used the following workaround:
@SuppressWarnings("RedundantCast")
// Cast is needed for checkerframework to accept the code
private static final AtomicReferenceFieldUpdater<PgStatement, @Nullable TimerTask> CANCEL_TIMER_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(
PgStatement.class, (Class<@Nullable TimerTask>) TimerTask.class, "cancelTimerTask");
@vlsi The following test case passes:
@Test
void doNotChangeAnnotatedTypeParameters() {
rewriteRun(
spec -> spec
.allSources(s -> s.markers(javaVersion(9)))
.parser(JavaParser.fromJavaVersion().classpath("annotations-24.1.0")),
//language=java
java(
"""
import org.jetbrains.annotations.NotNull;
import java.util.Map;
class Test {
private static final Map<String, @NotNull String> MAP = Map.<String, @NotNull String>of();
}
"""
)
);
}
So I wonder if the problem could be that you are using the latest release and this fix hasn't made it into a release yet?
Note: The same test with java.lang.@NotNull String rather than just @NotNull String also passes.
Would be great if you could try to confirm what version of the rewrite-static-analysis artifact was used here and / or if the current snapshot version would fix your issue. We can then look into publishing a new release.
I am sure I use -bom:latest.integration
I will try to reproduce in a setup using a build tool as the driver.
The code is here: https://github.com/pgjdbc/pgjdbc/pull/2979
./gradlew rewriteRun
If that matters, I use javac 17 and target 8