diff --git a/rewrite-java-test/src/test/java/org/openrewrite/java/ChangeTypeTest.java b/rewrite-java-test/src/test/java/org/openrewrite/java/ChangeTypeTest.java index 8462e5820e7..8ab8ca75b9d 100644 --- a/rewrite-java-test/src/test/java/org/openrewrite/java/ChangeTypeTest.java +++ b/rewrite-java-test/src/test/java/org/openrewrite/java/ChangeTypeTest.java @@ -1427,6 +1427,55 @@ public class Target { ); } + @Test + void doNotRenameFileWhenPathAlreadyHasNewTypeName() { + rewriteRun( + spec -> spec.recipe(new ChangeType("a.A", "a.ANew", false)), + java( + """ + package a; + public class A { + } + """, + """ + package a; + public class ANew { + } + """, + spec -> spec.path("a/ANew.java").afterRecipe(cu -> { + assertThat(PathUtils.separatorsToUnix(cu.getSourcePath().toString())).isEqualTo("a/ANew.java"); + assertThat(TypeUtils.isOfClassType(cu.getClasses().getFirst().getType(), "a.ANew")).isTrue(); + }) + ) + ); + } + + @Test + void doNotCorruptPathWhenDirectoryMatchesOldFqn() { + String pathWithOriginalDir = "src/main/java/com/example/Original/Original.java"; + rewriteRun( + spec -> spec.recipe(new ChangeType("com.example.Original", "com.example.NewName", false)), + java( + """ + package com.example; + public class Original { + } + """, + """ + package com.example; + public class NewName { + } + """, + spec -> spec.path(pathWithOriginalDir).afterRecipe(cu -> { + String path = PathUtils.separatorsToUnix(cu.getSourcePath().toString()); + assertThat(path).isEqualTo(pathWithOriginalDir); + assertThat(path).doesNotContain("NewName/Original.java"); + assertThat(TypeUtils.isOfClassType(cu.getClasses().getFirst().getType(), "com.example.NewName")).isTrue(); + }) + ) + ); + } + @Issue("https://github.com/openrewrite/rewrite/issues/1904") @Test void updateImportPrefixWithEmptyPackage() { diff --git a/rewrite-java/src/main/java/org/openrewrite/java/ChangeType.java b/rewrite-java/src/main/java/org/openrewrite/java/ChangeType.java index 4d4887e4faf..3937b19e3fc 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/ChangeType.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/ChangeType.java @@ -647,11 +647,15 @@ public J visit(@Nullable Tree tree, ExecutionContext ctx) { } String oldPath = cu.getSourcePath().toString().replace('\\', '/'); - // The old FQN must exist in the path. String oldFqn = fqnToPath(originalType.getFullyQualifiedName()); String newFqn = fqnToPath(targetType.getFullyQualifiedName()); - - Path newPath = Paths.get(oldPath.replaceFirst(oldFqn, newFqn)); + int lastDot = oldPath.lastIndexOf('.'); + String extension = lastDot >= 0 ? oldPath.substring(lastDot) : ""; + String newPathStr = oldPath; + if (!extension.isEmpty() && oldPath.endsWith(oldFqn + extension)) { + newPathStr = oldPath.substring(0, oldPath.length() - (oldFqn + extension).length()) + newFqn + extension; + } + Path newPath = Paths.get(newPathStr); if (updatePath(cu, oldPath, newPath.toString())) { cu = cu.withSourcePath(newPath); }