Skip to content

SwitchCaseReturnsToSwitchExpression doesn't handle spurious return when all values covered #828

@protocol7

Description

@protocol7

What version of OpenRewrite are you using?

  • org.openrewrite:rewrite-core:8.60.0
  • org.openrewrite.recipe:rewrite-migrate-java:3.15.0

What is the smallest, simplest way to reproduce the problem?

In cases where the switch statement covers all values, but there is also a trailing return, SwitchCaseReturnsToSwitchExpression will generate invalid code.

  @Test
  void switchWithReturn() {
    rewriteRun(
            spec -> spec.recipe(new SwitchCaseReturnsToSwitchExpression()),
        java(
            """
            package com.helloworld;

            public class Foo {
              public enum MyEnum {
                E1
              }
            
              public String foo(final MyEnum e) {
                switch (e) {
                  case E1 -> return "foo";
                }
                return "baz";
              }
            }
            """, """
            package com.helloworld;
            
            public class Foo {
              public enum MyEnum {
                E1
              }
          
              public String foo(final MyEnum e) {
                return switch (e) {
                  case E1 -> "foo";
                };
              }
            }
            """, s -> s.markers(new JavaVersion(randomId(), "", "", "21", "21"))));
  }
org.opentest4j.AssertionFailedError: [Unexpected result in "com/helloworld/Foo.java":
diff --git a/com/helloworld/Foo.java b/com/helloworld/Foo.java
index be04e86..0fec2ec 100644
--- a/com/helloworld/Foo.java
+++ b/com/helloworld/Foo.java
@@ -9,5 +9,6 @@
     return switch (e) {
       case E1 -> "foo";
     };
+    return "baz";
   }
 }
\ No newline at end of file
]
expected:
  "package com.helloworld;

  public class Foo {
    public enum MyEnum {
      E1
    }

    public String foo(final MyEnum e) {
      return switch (e) {
        case E1 -> "foo";
      };
    }
  }"
 but was:
  "package com.helloworld;

  public class Foo {
    public enum MyEnum {
      E1
    }

    public String foo(final MyEnum e) {
      return switch (e) {
        case E1 -> "foo";
      };
      return "baz";
    }
  }"
	at org.openrewrite.test.RewriteTest.assertContentEquals(RewriteTest.java:627)
	at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:517)
	at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:132)

This is obviously a bit of an edge case, but we have stumbled on a few examples in our code base. In the test above I went with removing the unneeded return statement, which I believe should be safe since it is not reachable.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions