openrewrite / rewrite-migrate-java

OpenRewrite recipes for migrating to newer versions of Java.
Apache License 2.0
111 stars 75 forks source link

AbstractNoGuavaImmutableOf#isParentTypeDownCast throws IndexOutOfBoundsException #520

Closed mbruggmann closed 1 month ago

mbruggmann commented 4 months ago

What version of OpenRewrite are you using?

rewrite-migrate-java 2.20.0

What is the smallest, simplest way to reproduce the problem?

This testcase throws an IndexOutOfBoundsException:

  @Test
  void noGuavaImmutableOfException() {
    rewriteRun(
        spec -> spec.recipe(new NoGuavaJava21()),
        java(
            """
            package com.helloworld;

            import com.google.common.collect.ImmutableMap;
            import com.google.common.collect.ImmutableSet;

            import java.util.Map;
            import java.util.Set;

            public class Main {

             public Map<String, Set<String>> getMap() {
               return ImmutableMap.of("key", ImmutableSet.of("value1", "value2"));
             }

            }""",
            """
            package com.helloworld;

            import java.util.Map;
            import java.util.Set;

            public class Main {

             public Map<String, Set<String>> getMap() {
               return Map.of("key", Set.of("value1", "value2"));
             }

            }""",
            src -> src.markers(javaVersion(21))));
  }

I stumbled across this while trying to reproduce an issue where our rewrites would leave an unexpected marker in the output, something along the lines of:

Map.of("key", /*~~(Index: 1)~~>*/ ImmutableSet.of("value1", "value2"));

My assumption is that those are related?

What is the full stack trace of any errors you encountered?

java.lang.AssertionError: 
    at org.openrewrite.test.RewriteTest.lambda$defaultExecutionContext$15(RewriteTest.java:632)
    at org.openrewrite.scheduling.RecipeRunCycle.handleError(RecipeRunCycle.java:242)
    at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$6(RecipeRunCycle.java:184)
    at org.openrewrite.scheduling.RecipeStack.reduce(RecipeStack.java:57)
    at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$7(RecipeRunCycle.java:134)
    at org.openrewrite.internal.InMemoryLargeSourceSet.lambda$edit$0(InMemoryLargeSourceSet.java:66)
    at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
    at org.openrewrite.internal.InMemoryLargeSourceSet.edit(InMemoryLargeSourceSet.java:65)
    at org.openrewrite.scheduling.RecipeRunCycle.editSources(RecipeRunCycle.java:133)
    at org.openrewrite.RecipeScheduler.runRecipeCycles(RecipeScheduler.java:86)
    at org.openrewrite.RecipeScheduler.scheduleRun(RecipeScheduler.java:41)
    at org.openrewrite.Recipe.run(Recipe.java:376)
    at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:374)
    at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:132)
    at com.spotify.[...] <-- our testclass
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.openrewrite.internal.RecipeRunException: java.lang.IndexOutOfBoundsException: Index: 1
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:287)
    at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:317)
    at org.openrewrite.java.JavaVisitor.visitRightPadded(JavaVisitor.java:1365)
    at org.openrewrite.java.JavaVisitor.lambda$visitContainer$37(JavaVisitor.java:1415)
    at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
    at org.openrewrite.java.JavaVisitor.visitContainer(JavaVisitor.java:1415)
    at org.openrewrite.java.JavaVisitor.visitMethodInvocation(JavaVisitor.java:918)
    at org.openrewrite.java.migrate.guava.AbstractNoGuavaImmutableOf$1.visitMethodInvocation(AbstractNoGuavaImmutableOf.java:115)
    at org.openrewrite.java.migrate.guava.AbstractNoGuavaImmutableOf$1.visitMethodInvocation(AbstractNoGuavaImmutableOf.java:68)
    at org.openrewrite.java.tree.J$MethodInvocation.acceptJava(J.java:3912)
    at org.openrewrite.java.tree.J.accept(J.java:59)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
    at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:317)
    at org.openrewrite.java.JavaVisitor.visitReturn(JavaVisitor.java:1098)
    at org.openrewrite.java.tree.J$Return.acceptJava(J.java:4977)
    at org.openrewrite.java.tree.J.accept(J.java:59)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
    at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:317)
    at org.openrewrite.java.JavaVisitor.visitRightPadded(JavaVisitor.java:1365)
    at org.openrewrite.java.JavaVisitor.lambda$visitBlock$4(JavaVisitor.java:397)
    at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
    at org.openrewrite.java.JavaVisitor.visitBlock(JavaVisitor.java:396)
    at org.openrewrite.java.tree.J$Block.acceptJava(J.java:838)
    at org.openrewrite.java.tree.J.accept(J.java:59)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
    at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:317)
    at org.openrewrite.java.JavaVisitor.visitMethodDeclaration(JavaVisitor.java:879)
    at org.openrewrite.java.tree.J$MethodDeclaration.acceptJava(J.java:3658)
    at org.openrewrite.java.tree.J.accept(J.java:59)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
    at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:317)
    at org.openrewrite.java.JavaVisitor.visitRightPadded(JavaVisitor.java:1365)
    at org.openrewrite.java.JavaVisitor.lambda$visitBlock$4(JavaVisitor.java:397)
    at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
    at org.openrewrite.java.JavaVisitor.visitBlock(JavaVisitor.java:396)
    at org.openrewrite.java.tree.J$Block.acceptJava(J.java:838)
    at org.openrewrite.java.tree.J.accept(J.java:59)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
    at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:317)
    at org.openrewrite.java.JavaVisitor.visitClassDeclaration(JavaVisitor.java:484)
    at org.openrewrite.java.tree.J$ClassDeclaration.acceptJava(J.java:1280)
    at org.openrewrite.java.tree.J.accept(J.java:59)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
    at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:317)
    at org.openrewrite.java.JavaVisitor.lambda$visitCompilationUnit$10(JavaVisitor.java:497)
    at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
    at org.openrewrite.java.JavaVisitor.visitCompilationUnit(JavaVisitor.java:497)
    at org.openrewrite.java.tree.J$CompilationUnit.acceptJava(J.java:1551)
    at org.openrewrite.java.tree.J.accept(J.java:59)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:147)
    at org.openrewrite.Preconditions$Check.visit(Preconditions.java:175)
    at org.openrewrite.Preconditions$Check.visit(Preconditions.java:145)
    at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$5(RecipeRunCycle.java:164)
    at io.micrometer.core.instrument.AbstractTimer.recordCallable(AbstractTimer.java:175)
    at org.openrewrite.table.RecipeRunStats.recordEdit(RecipeRunStats.java:67)
    at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$6(RecipeRunCycle.java:161)
    ... 15 more
Caused by: java.lang.IndexOutOfBoundsException: Index: 1
    at java.base/java.util.Collections$EmptyList.get(Collections.java:4807)
    at org.openrewrite.java.migrate.guava.AbstractNoGuavaImmutableOf$1.isParentTypeDownCast(AbstractNoGuavaImmutableOf.java:149)
    at org.openrewrite.java.migrate.guava.AbstractNoGuavaImmutableOf$1.visitMethodInvocation(AbstractNoGuavaImmutableOf.java:71)
    at org.openrewrite.java.migrate.guava.AbstractNoGuavaImmutableOf$1.visitMethodInvocation(AbstractNoGuavaImmutableOf.java:68)
    at org.openrewrite.java.tree.J$MethodInvocation.acceptJava(J.java:3912)
    at org.openrewrite.java.tree.J.accept(J.java:59)
    at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
    ... 71 more

Are you interested in contributing a fix to OpenRewrite?

Short on time at the moment, possibly later.