From 889408d6876d6854b9b18d022937297c5e6ecc71 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Tue, 31 Mar 2026 13:58:14 +0200 Subject: [PATCH] Inline JavaTemplate fields at call sites Replace stored JavaTemplate fields with inline builder chains across 8 recipes, eliminating unnecessary visitor state. --- .../BigDecimalRoundingConstantsToEnums.java | 32 ++++++------- .../staticanalysis/EmptyBlockVisitor.java | 7 +-- .../ExplicitCharsetOnStringGetBytes.java | 12 ++--- .../staticanalysis/MinimumSwitchCases.java | 46 +++++-------------- .../staticanalysis/SimplifyBooleanReturn.java | 13 +++--- .../SimplifyConsecutiveAssignments.java | 12 ++--- .../SortedSetStreamToLinkedHashSet.java | 9 ++-- .../staticanalysis/WhileInsteadOfFor.java | 7 ++- 8 files changed, 54 insertions(+), 84 deletions(-) diff --git a/src/main/java/org/openrewrite/staticanalysis/BigDecimalRoundingConstantsToEnums.java b/src/main/java/org/openrewrite/staticanalysis/BigDecimalRoundingConstantsToEnums.java index 33bc45f67..8dc71e921 100644 --- a/src/main/java/org/openrewrite/staticanalysis/BigDecimalRoundingConstantsToEnums.java +++ b/src/main/java/org/openrewrite/staticanalysis/BigDecimalRoundingConstantsToEnums.java @@ -50,20 +50,6 @@ public class BigDecimalRoundingConstantsToEnums extends Recipe { @Override public TreeVisitor getVisitor() { return Preconditions.check(new UsesType<>("java.math.BigDecimal", false), new JavaIsoVisitor() { - private final JavaTemplate twoArgDivide = JavaTemplate.builder("#{any(java.math.BigDecimal)}, #{}") - .contextSensitive() - .imports("java.math.RoundingMode") - .build(); - - private final JavaTemplate twoArgScale = JavaTemplate.builder("#{any(int)}, #{}") - .contextSensitive() - .imports("java.math.RoundingMode") - .build(); - - private final JavaTemplate threeArg = JavaTemplate.builder("#{any(java.math.BigDecimal)}, #{any(int)}, #{}") - .contextSensitive() - .imports("java.math.RoundingMode").build(); - @Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { J.MethodInvocation m = super.visitMethodInvocation(method, ctx); @@ -73,14 +59,22 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu if (roundingModeEnum == null) { return m; } - m = twoArgDivide.apply(updateCursor(m), m.getCoordinates().replaceArguments(), m.getArguments().get(0), roundingModeEnum); + m = JavaTemplate.builder("#{any(java.math.BigDecimal)}, #{}") + .contextSensitive() + .imports("java.math.RoundingMode") + .build() + .apply(updateCursor(m), m.getCoordinates().replaceArguments(), m.getArguments().get(0), roundingModeEnum); maybeAddImport("java.math.RoundingMode"); } else if (BIG_DECIMAL_SET_SCALE.matches(m) && isConvertibleBigDecimalConstant(m.getArguments().get(1))) { String roundingModeEnum = getTemplateText(m.getArguments().get(1)); if (roundingModeEnum == null) { return m; } - m = twoArgScale.apply(updateCursor(m), m.getCoordinates().replaceArguments(), m.getArguments().get(0), roundingModeEnum); + m = JavaTemplate.builder("#{any(int)}, #{}") + .contextSensitive() + .imports("java.math.RoundingMode") + .build() + .apply(updateCursor(m), m.getCoordinates().replaceArguments(), m.getArguments().get(0), roundingModeEnum); maybeAddImport("java.math.RoundingMode"); } else if (BIG_DECIMAL_DIVIDE_WITH_SCALE.matches(m) && isConvertibleBigDecimalConstant(m.getArguments().get(2))) { @@ -88,7 +82,11 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu if (roundingModeEnum == null) { return m; } - m = threeArg.apply(updateCursor(m), m.getCoordinates().replaceArguments(), m.getArguments().get(0), m.getArguments().get(1), roundingModeEnum); + m = JavaTemplate.builder("#{any(java.math.BigDecimal)}, #{any(int)}, #{}") + .contextSensitive() + .imports("java.math.RoundingMode") + .build() + .apply(updateCursor(m), m.getCoordinates().replaceArguments(), m.getArguments().get(0), m.getArguments().get(1), roundingModeEnum); maybeAddImport("java.math.RoundingMode"); } return m; diff --git a/src/main/java/org/openrewrite/staticanalysis/EmptyBlockVisitor.java b/src/main/java/org/openrewrite/staticanalysis/EmptyBlockVisitor.java index ec26b79de..52bcdc541 100644 --- a/src/main/java/org/openrewrite/staticanalysis/EmptyBlockVisitor.java +++ b/src/main/java/org/openrewrite/staticanalysis/EmptyBlockVisitor.java @@ -47,7 +47,6 @@ @AllArgsConstructor public class EmptyBlockVisitor

extends JavaIsoVisitor

{ private EmptyBlockStyle emptyBlockStyle; - private final JavaTemplate continueStatement = JavaTemplate.builder("continue;").build(); @Override public @Nullable J visit(@Nullable Tree tree, P p) { @@ -64,7 +63,8 @@ public J.WhileLoop visitWhileLoop(J.WhileLoop whileLoop, P p) { if (Boolean.TRUE.equals(emptyBlockStyle.getLiteralWhile()) && isEmptyBlock(w.getBody())) { J.Block body = (J.Block) w.getBody(); - w = continueStatement.apply(updateCursor(w), body.getCoordinates().lastStatement()); + w = JavaTemplate.builder("continue;").build() + .apply(updateCursor(w), body.getCoordinates().lastStatement()); } return w; @@ -76,7 +76,8 @@ public J.DoWhileLoop visitDoWhileLoop(J.DoWhileLoop doWhileLoop, P p) { if (Boolean.TRUE.equals(emptyBlockStyle.getLiteralWhile()) && isEmptyBlock(w.getBody())) { J.Block body = (J.Block) w.getBody(); - w = continueStatement.apply(updateCursor(w), body.getCoordinates().lastStatement()); + w = JavaTemplate.builder("continue;").build() + .apply(updateCursor(w), body.getCoordinates().lastStatement()); } return w; diff --git a/src/main/java/org/openrewrite/staticanalysis/ExplicitCharsetOnStringGetBytes.java b/src/main/java/org/openrewrite/staticanalysis/ExplicitCharsetOnStringGetBytes.java index 3236e55c2..1775ee8b7 100644 --- a/src/main/java/org/openrewrite/staticanalysis/ExplicitCharsetOnStringGetBytes.java +++ b/src/main/java/org/openrewrite/staticanalysis/ExplicitCharsetOnStringGetBytes.java @@ -51,18 +51,16 @@ public class ExplicitCharsetOnStringGetBytes extends Recipe { @Override public TreeVisitor getVisitor() { return Preconditions.check(new UsesMethod<>(GET_BYTES), new JavaIsoVisitor() { - final JavaTemplate WITH_ENCODING = JavaTemplate - .builder("getBytes(StandardCharsets.#{})") - .contextSensitive() - .imports("java.nio.charset.StandardCharsets") - .build(); - @Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { J.MethodInvocation m = super.visitMethodInvocation(method, ctx); if (GET_BYTES.matches(method)) { maybeAddImport("java.nio.charset.StandardCharsets"); - m = WITH_ENCODING.apply(updateCursor(m), m.getCoordinates().replaceMethod(), encoding == null ? "UTF_8" : encoding); + m = JavaTemplate.builder("getBytes(StandardCharsets.#{})") + .contextSensitive() + .imports("java.nio.charset.StandardCharsets") + .build() + .apply(updateCursor(m), m.getCoordinates().replaceMethod(), encoding == null ? "UTF_8" : encoding); } return m; } diff --git a/src/main/java/org/openrewrite/staticanalysis/MinimumSwitchCases.java b/src/main/java/org/openrewrite/staticanalysis/MinimumSwitchCases.java index 229f6d2c7..f9d2257fd 100644 --- a/src/main/java/org/openrewrite/staticanalysis/MinimumSwitchCases.java +++ b/src/main/java/org/openrewrite/staticanalysis/MinimumSwitchCases.java @@ -55,34 +55,6 @@ public class MinimumSwitchCases extends Recipe { @Override public TreeVisitor getVisitor() { return Preconditions.check(Preconditions.not(new CSharpFileChecker<>()), new JavaVisitor() { - final JavaTemplate ifElseIfPrimitive = JavaTemplate.builder("" + - "if(#{any()} == #{any()}) {\n" + - "} else if(#{any()} == #{any()}) {\n" + - "}").build(); - - final JavaTemplate ifElseIfString = JavaTemplate.builder("" + - "if(#{any(java.lang.String)}.equals(#{any(java.lang.String)})) {\n" + - "} else if(#{any(java.lang.String)}.equals(#{any(java.lang.String)})) {\n" + - "}").build(); - - final JavaTemplate ifElsePrimitive = JavaTemplate.builder("" + - "if(#{any()} == #{any()}) {\n" + - "} else {\n" + - "}").build(); - - final JavaTemplate ifElseString = JavaTemplate.builder("" + - "if(#{any(java.lang.String)}.equals(#{any(java.lang.String)})) {\n" + - "} else {\n" + - "}").build(); - - final JavaTemplate ifPrimitive = JavaTemplate.builder("" + - "if(#{any()} == #{any()}) {\n" + - "}").build(); - - final JavaTemplate ifString = JavaTemplate.builder("" + - "if(#{any(java.lang.String)}.equals(#{any(java.lang.String)})) {\n" + - "}").build(); - @Override public J visitBlock(J.Block block, ExecutionContext ctx) { // Handle the edge case of the extra-pointless switch statement which contains _only_ the default case @@ -147,11 +119,14 @@ public J visitSwitch(J.Switch switch_, ExecutionContext ctx) { if (isDefault(cases[0])) { return switch_.withMarkers(switch_.getMarkers().add(new DefaultOnly())); } - generatedIf = ifString.apply(getCursor(), switch_.getCoordinates().replace(), cases[0].getPattern(), tree); + generatedIf = JavaTemplate.builder("if(#{any(java.lang.String)}.equals(#{any(java.lang.String)})) {\n}").build() + .apply(getCursor(), switch_.getCoordinates().replace(), cases[0].getPattern(), tree); } else if (isDefault(cases[1])) { - generatedIf = ifElseString.apply(getCursor(), switch_.getCoordinates().replace(), cases[0].getPattern(), tree); + generatedIf = JavaTemplate.builder("if(#{any(java.lang.String)}.equals(#{any(java.lang.String)})) {\n} else {\n}").build() + .apply(getCursor(), switch_.getCoordinates().replace(), cases[0].getPattern(), tree); } else { - generatedIf = ifElseIfString.apply(getCursor(), switch_.getCoordinates().replace(), cases[0].getPattern(), tree, cases[1].getPattern(), tree); + generatedIf = JavaTemplate.builder("if(#{any(java.lang.String)}.equals(#{any(java.lang.String)})) {\n} else if(#{any(java.lang.String)}.equals(#{any(java.lang.String)})) {\n}").build() + .apply(getCursor(), switch_.getCoordinates().replace(), cases[0].getPattern(), tree, cases[1].getPattern(), tree); } } else if (switchesOnEnum(switch_)) { if (cases[1] == null && isDefault(cases[0])) { @@ -179,11 +154,14 @@ public J visitSwitch(J.Switch switch_, ExecutionContext ctx) { if (isDefault(cases[0])) { return switch_.withMarkers(switch_.getMarkers().add(new DefaultOnly())); } - generatedIf = ifPrimitive.apply(getCursor(), switch_.getCoordinates().replace(), tree, cases[0].getPattern()); + generatedIf = JavaTemplate.builder("if(#{any()} == #{any()}) {\n}").build() + .apply(getCursor(), switch_.getCoordinates().replace(), tree, cases[0].getPattern()); } else if (isDefault(cases[1])) { - generatedIf = ifElsePrimitive.apply(getCursor(), switch_.getCoordinates().replace(), tree, cases[0].getPattern()); + generatedIf = JavaTemplate.builder("if(#{any()} == #{any()}) {\n} else {\n}").build() + .apply(getCursor(), switch_.getCoordinates().replace(), tree, cases[0].getPattern()); } else { - generatedIf = ifElseIfPrimitive.apply(getCursor(), switch_.getCoordinates().replace(), tree, cases[0].getPattern(), tree, cases[1].getPattern()); + generatedIf = JavaTemplate.builder("if(#{any()} == #{any()}) {\n} else if(#{any()} == #{any()}) {\n}").build() + .apply(getCursor(), switch_.getCoordinates().replace(), tree, cases[0].getPattern(), tree, cases[1].getPattern()); } } diff --git a/src/main/java/org/openrewrite/staticanalysis/SimplifyBooleanReturn.java b/src/main/java/org/openrewrite/staticanalysis/SimplifyBooleanReturn.java index b1da9fbdb..fc683ad1b 100644 --- a/src/main/java/org/openrewrite/staticanalysis/SimplifyBooleanReturn.java +++ b/src/main/java/org/openrewrite/staticanalysis/SimplifyBooleanReturn.java @@ -54,11 +54,6 @@ public class SimplifyBooleanReturn extends Recipe { @Override public TreeVisitor getVisitor() { return new JavaVisitor() { - private final JavaTemplate notIfConditionReturn = JavaTemplate.builder("return !(#{any(boolean)});") - .build(); - private final JavaTemplate plainReturn = JavaTemplate.builder("return #{any(boolean)};") - .build(); - @Override public J visitIf(J.If iff, ExecutionContext ctx) { J.If i = visitAndCast(iff, ctx, super::visitIf); @@ -119,10 +114,14 @@ public J visitIf(J.If iff, ExecutionContext ctx) { if (ifCondition instanceof J.Unary) { J.Unary u = (J.Unary) ifCondition; if (u.getOperator() == J.Unary.Type.Not) { - return plainReturn.apply(updateCursor(i), i.getCoordinates().replace(), u.getExpression()); + return JavaTemplate.builder("return #{any(boolean)};") + .build() + .apply(updateCursor(i), i.getCoordinates().replace(), u.getExpression()); } } - return notIfConditionReturn.apply(updateCursor(i), i.getCoordinates().replace(), ifCondition); + return JavaTemplate.builder("return !(#{any(boolean)});") + .build() + .apply(updateCursor(i), i.getCoordinates().replace(), ifCondition); } } } diff --git a/src/main/java/org/openrewrite/staticanalysis/SimplifyConsecutiveAssignments.java b/src/main/java/org/openrewrite/staticanalysis/SimplifyConsecutiveAssignments.java index d2381e380..8ccbf6dcf 100644 --- a/src/main/java/org/openrewrite/staticanalysis/SimplifyConsecutiveAssignments.java +++ b/src/main/java/org/openrewrite/staticanalysis/SimplifyConsecutiveAssignments.java @@ -41,11 +41,6 @@ public class SimplifyConsecutiveAssignments extends Recipe { @Override public TreeVisitor getVisitor() { return new JavaIsoVisitor() { - // TODO if we had a `replace()` coordinate on every `Expression`, we wouldn't need the left side of this - final JavaTemplate combinedAssignment = JavaTemplate - .builder("o = (#{any()} #{} #{any()});") - .build(); - @Override public J.Block visitBlock(J.Block block, ExecutionContext ctx) { J.Block b = super.visitBlock(block, ctx); @@ -180,12 +175,15 @@ private Statement combine(Cursor cursor, String op, Expression right) { Statement s = cursor.getValue(); if (s instanceof J.Assignment) { J.Assignment assign = (J.Assignment) s; - J.Assignment after = combinedAssignment.apply(cursor, s.getCoordinates().replace(), assign.getAssignment(), op, right); + // TODO if we had a `replace()` coordinate on every `Expression`, we wouldn't need the left side of this + J.Assignment after = JavaTemplate.builder("o = (#{any()} #{} #{any()});").build() + .apply(cursor, s.getCoordinates().replace(), assign.getAssignment(), op, right); return assign.withAssignment(after.getAssignment()); } if (s instanceof J.VariableDeclarations) { J.VariableDeclarations variables = (J.VariableDeclarations) s; - J.Assignment after = combinedAssignment.apply(cursor, s.getCoordinates().replace(), variables.getVariables().get(0).getInitializer(), op, right); + J.Assignment after = JavaTemplate.builder("o = (#{any()} #{} #{any()});").build() + .apply(cursor, s.getCoordinates().replace(), variables.getVariables().get(0).getInitializer(), op, right); return variables.withVariables(ListUtils.map(variables.getVariables(), (i, namedVar) -> i == 0 ? namedVar.withInitializer(after.getAssignment()) : namedVar)); } diff --git a/src/main/java/org/openrewrite/staticanalysis/SortedSetStreamToLinkedHashSet.java b/src/main/java/org/openrewrite/staticanalysis/SortedSetStreamToLinkedHashSet.java index f2479cf73..387d69c48 100644 --- a/src/main/java/org/openrewrite/staticanalysis/SortedSetStreamToLinkedHashSet.java +++ b/src/main/java/org/openrewrite/staticanalysis/SortedSetStreamToLinkedHashSet.java @@ -42,10 +42,6 @@ public class SortedSetStreamToLinkedHashSet extends Recipe { @Override public TreeVisitor getVisitor() { return Preconditions.check(new UsesMethod<>(COLLECTORS_TO_SET_METHOD_MATCHER), new JavaIsoVisitor() { - private final JavaTemplate template = JavaTemplate.builder("Collectors.toCollection(LinkedHashSet::new)") - .imports("java.util.stream.Collectors", "java.util.LinkedHashSet") - .build(); - @Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { J.MethodInvocation mi = super.visitMethodInvocation(method, ctx); @@ -55,7 +51,10 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu maybeRemoveImport("java.util.stream.Collectors.toSet"); maybeAddImport("java.util.LinkedHashSet"); maybeAddImport("java.util.stream.Collectors"); - return template.apply(updateCursor(mi), mi.getCoordinates().replaceArguments()); + return JavaTemplate.builder("Collectors.toCollection(LinkedHashSet::new)") + .imports("java.util.stream.Collectors", "java.util.LinkedHashSet") + .build() + .apply(updateCursor(mi), mi.getCoordinates().replaceArguments()); } return mi; } diff --git a/src/main/java/org/openrewrite/staticanalysis/WhileInsteadOfFor.java b/src/main/java/org/openrewrite/staticanalysis/WhileInsteadOfFor.java index 99542a447..fb5c60e68 100644 --- a/src/main/java/org/openrewrite/staticanalysis/WhileInsteadOfFor.java +++ b/src/main/java/org/openrewrite/staticanalysis/WhileInsteadOfFor.java @@ -41,16 +41,15 @@ public class WhileInsteadOfFor extends Recipe { @Override public TreeVisitor getVisitor() { return new JavaVisitor() { - final JavaTemplate whileLoop = JavaTemplate.builder("while(#{any(boolean)}) {}") - .build(); - @Override public J visitForLoop(J.ForLoop forLoop, ExecutionContext ctx) { if (forLoop.getControl().getInit().get(0) instanceof J.Empty && forLoop.getControl().getUpdate().get(0) instanceof J.Empty && !(forLoop.getControl().getCondition() instanceof J.Empty) ) { - J.WhileLoop w = whileLoop.apply(getCursor(), forLoop.getCoordinates().replace(), forLoop.getControl().getCondition()); + J.WhileLoop w = JavaTemplate.builder("while(#{any(boolean)}) {}") + .build() + .apply(getCursor(), forLoop.getCoordinates().replace(), forLoop.getControl().getCondition()); return w.withBody(forLoop.getBody()); } return super.visitForLoop(forLoop, ctx);