Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,6 @@ public class BigDecimalRoundingConstantsToEnums extends Recipe {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesType<>("java.math.BigDecimal", false), new JavaIsoVisitor<ExecutionContext>() {
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);
Expand All @@ -73,22 +59,34 @@ 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))) {
String roundingModeEnum = getTemplateText(m.getArguments().get(2));
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
@AllArgsConstructor
public class EmptyBlockVisitor<P> extends JavaIsoVisitor<P> {
private EmptyBlockStyle emptyBlockStyle;
private final JavaTemplate continueStatement = JavaTemplate.builder("continue;").build();

@Override
public @Nullable J visit(@Nullable Tree tree, P p) {
Expand All @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,16 @@ public class ExplicitCharsetOnStringGetBytes extends Recipe {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesMethod<>(GET_BYTES), new JavaIsoVisitor<ExecutionContext>() {
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,34 +55,6 @@ public class MinimumSwitchCases extends Recipe {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(Preconditions.not(new CSharpFileChecker<>()), new JavaVisitor<ExecutionContext>() {
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
Expand Down Expand Up @@ -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])) {
Expand Down Expand Up @@ -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());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ public class SimplifyBooleanReturn extends Recipe {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaVisitor<ExecutionContext>() {
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);
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ public class SimplifyConsecutiveAssignments extends Recipe {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaIsoVisitor<ExecutionContext>() {
// 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);
Expand Down Expand Up @@ -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));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ public class SortedSetStreamToLinkedHashSet extends Recipe {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesMethod<>(COLLECTORS_TO_SET_METHOD_MATCHER), new JavaIsoVisitor<ExecutionContext>() {
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);
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,15 @@ public class WhileInsteadOfFor extends Recipe {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaVisitor<ExecutionContext>() {
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);
Expand Down
Loading