rewrite-static-analysis icon indicating copy to clipboard operation
rewrite-static-analysis copied to clipboard

`UseDiamondOperator` drops type annotations thus it breaks code

Open vlsi opened this issue 1 year ago • 9 comments

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.

vlsi avatar Nov 08 '23 08:11 vlsi

This fix has also been deployed to https://app.moderne.io/: https://app.moderne.io/results/1GYDVrVbq

knutwannheden avatar Nov 08 '23 09:11 knutwannheden

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");

vlsi avatar Jan 02 '24 10:01 vlsi

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 avatar Jan 03 '24 11:01 vlsi

@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?

knutwannheden avatar Jan 03 '24 16:01 knutwannheden

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.

knutwannheden avatar Jan 03 '24 16:01 knutwannheden

I am sure I use -bom:latest.integration

vlsi avatar Jan 03 '24 16:01 vlsi

I will try to reproduce in a setup using a build tool as the driver.

knutwannheden avatar Jan 03 '24 17:01 knutwannheden

The code is here: https://github.com/pgjdbc/pgjdbc/pull/2979

./gradlew rewriteRun

vlsi avatar Jan 03 '24 17:01 vlsi

If that matters, I use javac 17 and target 8

vlsi avatar Jan 03 '24 20:01 vlsi