Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IndexOutOfBoundsException on matcher.parameter(0) when matching str.getBytes(UTF_8).length #49

Closed
timtebeek opened this issue Dec 17, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@timtebeek
Copy link
Contributor

timtebeek commented Dec 17, 2023

What version of OpenRewrite are you using?

  • rewrite-templating v1.3.11

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

The following Refaster rule

class Utf8EncodedLength {
  @BeforeTemplate
  int before(String str) {
    return str.getBytes(UTF_8).length;
  }

  @AfterTemplate
  int after(String str) {
    return Utf8.encodedLength(str);
  }
}

Generates a Rewrite recipe

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
    JavaVisitor<ExecutionContext> javaVisitor = new AbstractRefasterJavaVisitor() {
        final JavaTemplate before = Semantics.expression(this, "before", (String str) -> str.getBytes(UTF_8).length).build();
        final JavaTemplate after = Semantics.expression(this, "after", (String str) -> com.google.common.base.Utf8.encodedLength(str)).build();

        @Override
        public J visitFieldAccess(J.FieldAccess elem, ExecutionContext ctx) {
            JavaTemplate.Matcher matcher;
            if ((matcher = before.matcher(getCursor())).find()) {
                maybeRemoveImport("java.nio.charset.StandardCharsets.UTF_8");
                return embed(
                        after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)), // FIXME IndexOutOfBoundsException
                        getCursor(),
                        ctx,
                        SHORTEN_NAMES
                );
            }
            return super.visitFieldAccess(elem, ctx);
        }
...

Which uses template

public static JavaTemplate.Builder getTemplate() {
    return JavaTemplate
            .builder("#{str:any(java.lang.String)}.getBytes(UTF_8).length")
            .staticImports("java.nio.charset.StandardCharsets.UTF_8");
}

Which produces an IndexOutOfBoundsException when run against the reference input/output test:
https://github.com/timtebeek/error-prone-support/blob/e0c795d248e5a7c434b9a95c08e6e060af942136/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/StringRulesTestInput.java#L19

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

java.lang.AssertionError: Failed to parse sources or run recipe

	at org.openrewrite.test.RewriteTest.lambda$defaultExecutionContext$10(RewriteTest.java:591)
	at org.openrewrite.RecipeScheduler$RecipeRunCycle.handleError(RecipeScheduler.java:308)
	at org.openrewrite.RecipeScheduler$RecipeRunCycle.lambda$editSources$4(RecipeScheduler.java:250)
	at org.openrewrite.RecipeScheduler$RecipeRunCycle.lambda$mapForRecipeRecursively$5(RecipeScheduler.java:334)
	at org.openrewrite.internal.InMemoryLargeSourceSet.lambda$edit$0(InMemoryLargeSourceSet.java:62)
	at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
	at org.openrewrite.internal.InMemoryLargeSourceSet.edit(InMemoryLargeSourceSet.java:61)
	at org.openrewrite.RecipeScheduler$RecipeRunCycle.mapForRecipeRecursively(RecipeScheduler.java:327)
	at org.openrewrite.RecipeScheduler$RecipeRunCycle.editSources(RecipeScheduler.java:200)
	at org.openrewrite.RecipeScheduler.scheduleRun(RecipeScheduler.java:76)
	at org.openrewrite.Recipe.run(Recipe.java:281)
	at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:346)
	at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:132)
	at tech.picnic.errorprone.refasterrules.StringRulesRecipesTest.reuseStringRulesTestInputOutput(StringRulesRecipesTest.java:43)
	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 0 out of bounds for length 0
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:329)
	at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:361)
	at org.openrewrite.java.JavaVisitor.visitReturn(JavaVisitor.java:1067)
	at org.openrewrite.java.tree.J$Return.acceptJava(J.java:4830)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:361)
	at org.openrewrite.java.JavaVisitor.visitRightPadded(JavaVisitor.java:1340)
	at org.openrewrite.java.JavaVisitor.lambda$visitBlock$4(JavaVisitor.java:386)
	at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
	at org.openrewrite.java.JavaVisitor.visitBlock(JavaVisitor.java:385)
	at org.openrewrite.java.tree.J$Block.acceptJava(J.java:767)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:361)
	at org.openrewrite.java.JavaVisitor.visitMethodDeclaration(JavaVisitor.java:868)
	at org.openrewrite.java.tree.J$MethodDeclaration.acceptJava(J.java:3594)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:361)
	at org.openrewrite.java.JavaVisitor.visitRightPadded(JavaVisitor.java:1340)
	at org.openrewrite.java.JavaVisitor.lambda$visitBlock$4(JavaVisitor.java:386)
	at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
	at org.openrewrite.java.JavaVisitor.visitBlock(JavaVisitor.java:385)
	at org.openrewrite.java.tree.J$Block.acceptJava(J.java:767)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:361)
	at org.openrewrite.java.JavaVisitor.visitClassDeclaration(JavaVisitor.java:473)
	at org.openrewrite.java.tree.J$ClassDeclaration.acceptJava(J.java:1219)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	at org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:361)
	at org.openrewrite.java.JavaVisitor.lambda$visitCompilationUnit$10(JavaVisitor.java:486)
	at org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
	at org.openrewrite.java.JavaVisitor.visitCompilationUnit(JavaVisitor.java:486)
	at org.openrewrite.java.tree.J$CompilationUnit.acceptJava(J.java:1517)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:184)
	at org.openrewrite.Preconditions$1.visit(Preconditions.java:51)
	at org.openrewrite.Preconditions$1.visit(Preconditions.java:31)
	at org.openrewrite.RecipeScheduler$RecipeRunCycle.lambda$editSources$3(RecipeScheduler.java:230)
	at io.micrometer.core.instrument.AbstractTimer.recordCallable(AbstractTimer.java:147)
	at org.openrewrite.table.RecipeRunStats.recordEdit(RecipeRunStats.java:68)
	at org.openrewrite.RecipeScheduler$RecipeRunCycle.lambda$editSources$4(RecipeScheduler.java:227)
	... 14 more
Caused by: java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
	at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
	at java.base/java.util.Objects.checkIndex(Objects.java:385)
	at java.base/java.util.ArrayList.get(ArrayList.java:427)
	at org.openrewrite.java.JavaTemplate$Matcher.parameter(JavaTemplate.java:103)
	at tech.picnic.errorprone.refasterrules.StringRulesRecipes$Utf8EncodedLengthRecipe$1.visitFieldAccess(StringRulesRecipes.java:172)
	at tech.picnic.errorprone.refasterrules.StringRulesRecipes$Utf8EncodedLengthRecipe$1.visitFieldAccess(StringRulesRecipes.java:162)
	at org.openrewrite.java.tree.J$FieldAccess.acceptJava(J.java:1906)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	... 59 more
@timtebeek
Copy link
Contributor Author

Current implementation is sufficiently different that we'll close this report and can open a new one if it's seen again.

@github-project-automation github-project-automation bot moved this from Backlog to Done in OpenRewrite Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Done
Development

No branches or pull requests

1 participant