`IndexOutOfBoundsException` on `matcher.parameter(0)` when matching `str.getBytes(UTF_8).length`
timtebeek opened this issue · 0 comments
timtebeek commented
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