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 @@ -35,6 +35,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.openrewrite.java.migrate.lang.NullCheck.Matcher.nullCheck;
import static org.openrewrite.java.tree.J.Block.createEmptyBlock;
Expand Down Expand Up @@ -75,7 +76,9 @@ public J.Case visitCase(J.Case case_, ExecutionContext ctx) {
if (case_.getBody() instanceof J.Block &&
((J.Block) case_.getBody()).getStatements().isEmpty() &&
!((J.Block) case_.getBody()).getEnd().isEmpty()) {
return case_.withBody(((J.Block) case_.getBody()).withEnd(Space.EMPTY));
return case_.withBody(((J.Block) case_.getBody())
.withPrefix(Space.SINGLE_SPACE)
.withEnd(Space.EMPTY));
}
return case_.withBody(case_.getBody().withPrefix(Space.SINGLE_SPACE));
}
Expand All @@ -100,6 +103,11 @@ private static class SwitchCandidate {
private SwitchCandidate(J.If if_, Cursor cursor) {
this.if_ = if_;
this.cursor = cursor;
Cursor parent = cursor.getParent(2);
if (parent == null || parent.getValue() instanceof J.If.Else) {
potentialCandidate = false;
return;
}
J.If ifPart = if_;
while (potentialCandidate && ifPart != null) {
if (ifPart.getIfCondition().getTree() instanceof J.Binary) {
Expand Down Expand Up @@ -157,6 +165,11 @@ private boolean validatePotentialCandidate() {
if (patternMatchers.keySet().stream().anyMatch(instanceOf -> instanceOf.getPattern() == null)) {
return false;
}
// The blocks cannot do a return as that would lead to all blocks having to do a return,
// the block/expression difference in return for switch statements / expressions being different...
if (returns(nullCheckedStatement) || patternMatchers.values().stream().anyMatch(this::returns) || returns(else_)) {
return false;
}
// Do no harm -> If we do not know how to replace(yet), do not replace
if (patternMatchers.keySet().stream().anyMatch(instanceOf -> {
J clazz = instanceOf.getClazz();
Expand All @@ -173,6 +186,16 @@ private boolean validatePotentialCandidate() {
(hasLastElseBlock ? 1 : 0);
}

private boolean returns(@Nullable Statement statement) {
return statement != null && new JavaIsoVisitor<AtomicBoolean>() {
@Override
public J.Return visitReturn(J.Return return_, AtomicBoolean atomicBoolean) {
atomicBoolean.set(true);
return return_;
}
}.reduce(statement, new AtomicBoolean(false)).get();
}

public J.@Nullable Switch buildSwitchTemplate() {
Optional<Expression> switchOn = switchOn();
if (!this.potentialCandidate || !switchOn.isPresent()) {
Expand All @@ -183,36 +206,20 @@ private boolean validatePotentialCandidate() {
StringBuilder switchBody = new StringBuilder("switch (#{any()}) {\n");
int i = 1;
if (nullCheckedParameter != null) {
Statement statement = getStatement(Objects.requireNonNull(nullCheckedStatement));
if (statement instanceof J.Block) {
switchBody.append("case null -> #{}\n");
} else {
switchBody.append("case null -> #{any()};\n");
}
arguments[i++] = statement;
switchBody.append("case null -> #{any()};\n");
arguments[i++] = getStatement(Objects.requireNonNull(nullCheckedStatement));
}
for (Map.Entry<J.InstanceOf, Statement> entry : patternMatchers.entrySet()) {
J.InstanceOf instanceOf = entry.getKey();
Statement statement = getStatement(entry.getValue());
if (statement instanceof J.Block) {
switchBody.append("case #{}#{} -> #{}\n");
} else {
switchBody.append("case #{}#{} -> #{any()};\n");
}
switchBody.append("case #{}#{} -> #{any()};\n");
arguments[i++] = getClassName(instanceOf);
arguments[i++] = getPattern(instanceOf);
arguments[i++] = statement;
arguments[i++] = getStatement(entry.getValue());
}
switchBody.append("default -> #{any()};\n");
if (else_ != null) {
Statement statement = getStatement(else_);
if (statement instanceof J.Block) {
switchBody.append("default -> #{}\n");
} else {
switchBody.append("default -> #{any()};\n");
}
arguments[i] = statement;
arguments[i] = getStatement(else_);
} else {
switchBody.append("default -> #{}\n");
arguments[i] = createEmptyBlock();
}
switchBody.append("}\n");
Expand Down Expand Up @@ -243,11 +250,13 @@ private String getPattern(J.InstanceOf statement) {
}

private Statement getStatement(Statement statement) {
Statement toAdd = statement;
if (statement instanceof J.Block && ((J.Block) statement).getStatements().size() == 1) {
toAdd = ((J.Block) statement).getStatements().get(0);
Statement firstStatement = ((J.Block) statement).getStatements().get(0);
if (firstStatement instanceof Expression || firstStatement instanceof J.Throw) {
return firstStatement;
}
}
return toAdd;
return statement;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ private boolean hasNullCase(J.Switch switch_) {

private J.Case createNullCase(J.Switch aSwitch, Statement whenNull) {
if (whenNull instanceof J.Block && ((J.Block) whenNull).getStatements().size() == 1) {
whenNull = ((J.Block) whenNull).getStatements().get(0);
Statement firstStatement = ((J.Block) whenNull).getStatements().get(0);
if (firstStatement instanceof Expression || firstStatement instanceof J.Throw) {
whenNull = firstStatement;
}
}
String semicolon = whenNull instanceof J.Block ? "" : ";";
J.Switch switchWithNullCase = JavaTemplate.apply(
Expand Down
Loading