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 @@ -70,6 +70,7 @@ public J.Block visitBlock(J.Block originalBlock, ExecutionContext ctx) {
return block.withStatements(ListUtils.map(block.getStatements(), (index, statement) -> {
if (statement == originalSwitch.getAndSet(null)) {
doAfterVisit(new InlineVariable().getVisitor());
doAfterVisit(new SwitchExpressionYieldToArrow().getVisitor());
// We've already converted the switch/assignments to an assignment with a switch expression.
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright 2025 the original author or authors.
* <p>
* Licensed under the Moderne Source Available License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://docs.moderne.io/licensing/moderne-source-available-license
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.java.migrate.lang;

import lombok.EqualsAndHashCode;
import lombok.Value;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.search.UsesJavaVersion;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JContainer;
import org.openrewrite.java.tree.Space;
import org.openrewrite.java.tree.Statement;
import org.openrewrite.staticanalysis.groovy.GroovyFileChecker;
import org.openrewrite.staticanalysis.kotlin.KotlinFileChecker;

import static java.util.Objects.requireNonNull;

@Value
@EqualsAndHashCode(callSuper = false)
public class SwitchExpressionYieldToArrow extends Recipe {
@Override
public String getDisplayName() {
return "Convert switch expression yield to arrow";
}

@Override
public String getDescription() {
return "Convert switch expressions with colon cases and yield statements to arrow syntax.";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
TreeVisitor<?, ExecutionContext> preconditions = Preconditions.and(
new UsesJavaVersion<>(14),
Preconditions.not(new KotlinFileChecker<>()),
Preconditions.not(new GroovyFileChecker<>())
);
return Preconditions.check(preconditions, new JavaIsoVisitor<ExecutionContext>() {
@Override
public J.SwitchExpression visitSwitchExpression(J.SwitchExpression switchExpression, ExecutionContext ctx) {
J.SwitchExpression se = super.visitSwitchExpression(switchExpression, ctx);

// Check if this is a complex case (more than just a yield)
if (anythingOtherThanYield(se)) {
return se;
}

return se.withCases(se.getCases().withStatements(ListUtils.map(se.getCases().getStatements(), statement -> {
J.Case caseStatement = (J.Case) requireNonNull(statement);
J.Yield yieldStatement = (J.Yield) caseStatement.getStatements().get(0);

// Add space after the last case label to create space before arrow
JContainer<J> caseLabels = caseStatement.getPadding().getCaseLabels();
JContainer<J> updatedLabels = caseLabels.getPadding().withElements(
ListUtils.mapLast(caseLabels.getPadding().getElements(),
elem -> elem.withAfter(Space.SINGLE_SPACE))
);

return caseStatement
.withStatements(null)
.withBody(yieldStatement.getValue().withPrefix(Space.SINGLE_SPACE))
.withType(J.Case.Type.Rule)
.getPadding()
.withCaseLabels(updatedLabels);
})));
}

// For now, we only convert switch expressions that consist solely of yield statements
private boolean anythingOtherThanYield(J.SwitchExpression se) {
for (Statement statement : se.getCases().getStatements()) {
if (!(statement instanceof J.Case)) {
return true;
}

J.Case caseStatement = (J.Case) statement;
if (caseStatement.getType() != J.Case.Type.Statement ||
caseStatement.getStatements().size() != 1 ||
!(caseStatement.getStatements().get(0) instanceof J.Yield)) {
return true;
}
}
return false;
}
});
}
}
105 changes: 67 additions & 38 deletions src/main/resources/META-INF/rewrite/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1025,31 +1025,34 @@ recipeName: org.openrewrite.java.migrate.UpgradePluginsForJava11
examples:
- description: ''
sources:
- before: project
language: mavenProject
- before: |
<project>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<properties>
<wro4j.version>1.8.0</wro4j.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-maven-plugin</artifactId>
<version>${wro4j.version}</version>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3.1</version>
</plugin>
</plugins>
</build>
</project>
after: |
path: pom.xml
language: xml
- description: ''
sources:
- before: |
<project>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<properties>
<wro4j.version>1.10.1</wro4j.version>
<wro4j.version>1.8.0</wro4j.version>
</properties>
<build>
<plugins>
Expand All @@ -1061,23 +1064,20 @@ examples:
</plugins>
</build>
</project>
path: pom.xml
language: xml
- description: ''
sources:
- before: project
language: mavenProject
- before: |
after: |
<project>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<properties>
<wro4j.version>1.10.1</wro4j.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3.1</version>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-maven-plugin</artifactId>
<version>${wro4j.version}</version>
</plugin>
</plugins>
</build>
Expand Down Expand Up @@ -3338,25 +3338,6 @@ examples:
type: specs.openrewrite.org/v1beta/example
recipeName: org.openrewrite.java.migrate.guava.NoGuava
examples:
- description: ''
sources:
- before: |
import com.google.common.base.MoreObjects;

class A {
Object foo(Object obj) {
return MoreObjects.firstNonNull(obj, "default");
}
}
after: |
import java.util.Objects;

class A {
Object foo(Object obj) {
return Objects.requireNonNullElse(obj, "default");
}
}
language: java
- description: ''
sources:
- before: |
Expand Down Expand Up @@ -3403,6 +3384,25 @@ examples:
}
}
language: java
- description: ''
sources:
- before: |
import com.google.common.base.MoreObjects;

class A {
Object foo(Object obj) {
return MoreObjects.firstNonNull(obj, "default");
}
}
after: |
import java.util.Objects;

class A {
Object foo(Object obj) {
return Objects.requireNonNullElse(obj, "default");
}
}
language: java
---
type: specs.openrewrite.org/v1beta/example
recipeName: org.openrewrite.java.migrate.guava.NoGuavaAtomicsNewReference
Expand Down Expand Up @@ -6235,7 +6235,7 @@ examples:
language: java
---
type: specs.openrewrite.org/v1beta/example
recipeName: org.openrewrite.java.migrate.lang.SwitchCaseAssigningToSwitchExpression
recipeName: org.openrewrite.java.migrate.lang.SwitchCaseAssignmentsToSwitchExpression
examples:
- description: ''
sources:
Expand Down Expand Up @@ -6314,6 +6314,35 @@ examples:
language: java
---
type: specs.openrewrite.org/v1beta/example
recipeName: org.openrewrite.java.migrate.lang.SwitchExpressionYieldToArrow
examples:
- description: ''
sources:
- before: |
class Test {
String format(String str) {
String formatted = switch (str) {
case "foo": yield "Foo";
case "bar": yield "Bar";
case null, default: yield "unknown";
};
return formatted;
}
}
after: |
class Test {
String format(String str) {
String formatted = switch (str) {
case "foo" -> "Foo";
case "bar" -> "Bar";
case null, default -> "unknown";
};
return formatted;
}
}
language: java
---
type: specs.openrewrite.org/v1beta/example
recipeName: org.openrewrite.java.migrate.lang.ThreadStopUnsupported
examples:
- description: ''
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/META-INF/rewrite/java-version-17.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ recipeList:
newVersion: 1.17.x
- org.openrewrite.java.migrate.AddLombokMapstructBinding
- org.openrewrite.java.migrate.lang.SwitchCaseAssignmentsToSwitchExpression
- org.openrewrite.java.migrate.lang.SwitchExpressionYieldToArrow

---
type: specs.openrewrite.org/v1beta/recipe
Expand Down
Loading