diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/ReplaceConstructorWithFactoryAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/ReplaceConstructorWithFactoryAction.java index d399273bccc0..7f7b5f0b013d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/ReplaceConstructorWithFactoryAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/ReplaceConstructorWithFactoryAction.java @@ -52,7 +52,8 @@ public class ReplaceConstructorWithFactoryAction implements ModCommandAction { if (constructorOrClass == null) return ModCommands.nop(); List targets = StreamEx.iterate(constructorOrClass, Objects::nonNull, PsiMember::getContainingClass) - .select(PsiClass.class).toList(); + .select(PsiClass.class).filter(cls -> cls.hasModifierProperty(PsiModifier.STATIC) || cls.getContainingClass() == null) + .toList(); SmartPsiElementPointer constructorOrClassPtr = SmartPointerManager.createPointer(constructorOrClass); List options = ContainerUtil.map(targets, target -> ModCommands.psiUpdateStep( @@ -91,7 +92,7 @@ public class ReplaceConstructorWithFactoryAction implements ModCommandAction { PsiClass wrContainingClass = updater.getWritable( constructorOrClass instanceof PsiClass cls ? cls : Objects.requireNonNull(constructorOrClass.getContainingClass())); PsiReferenceExpression classReferenceExpression = factory.createReferenceExpression(targetClass); - String factoryName = suggestName(wrContainingClass); + String factoryName = suggestName(targetClass, Objects.requireNonNull(wrContainingClass.getName())); PsiReferenceExpression qualifiedMethodReference = (PsiReferenceExpression)factory.createExpressionFromText("A." + factoryName, null); PsiMethod constructor = ObjectUtils.tryCast(constructorOrClass, PsiMethod.class); @@ -128,11 +129,10 @@ public class ReplaceConstructorWithFactoryAction implements ModCommandAction { } } - private static String suggestName(PsiClass psiClass) { + private static String suggestName(@NotNull PsiClass psiClass, @NotNull String baseName) { int i = 0; - String className = psiClass.getName(); String[] baseNames = - {"create" + className, "new" + className, "get" + className, "createInstance", "getInstance", "newInstance", "create"}; + {"create" + baseName, "new" + baseName, "get" + baseName, "createInstance", "getInstance", "newInstance", "create"}; while (true) { for (String name : baseNames) { String finalName = name + (i == 0 ? "" : i); diff --git a/java/java-tests/testData/refactoring/replaceConstructorWithFactory/afterNestedClass.java b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/afterNestedClass.java new file mode 100644 index 000000000000..0d837d21d5a9 --- /dev/null +++ b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/afterNestedClass.java @@ -0,0 +1,20 @@ +class OuterClass { + static InnerClass createInnerClass(int _i) { + return newInnerClass(_i); + } + + static InnerClass newInnerClass(int _i) { + return new InnerClass(_i); + } + + static class InnerClass { + int i; + private InnerClass(int _i) { + i = _i; + } + } + InnerClass myInner = newInnerClass(27); + static int method() { + InnerClass inner = newInnerClass(15); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/replaceConstructorWithFactory/afterNestedClass2.java b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/afterNestedClass2.java new file mode 100644 index 000000000000..e1106b9156c9 --- /dev/null +++ b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/afterNestedClass2.java @@ -0,0 +1,16 @@ +class OuterClass { + static class InnerClass { + int i; + private InnerClass(int _i) { + i = _i; + } + + static InnerClass createInnerClass(int _i) { + return new InnerClass(_i); + } + } + InnerClass myInner = InnerClass.createInnerClass(27); + static int method() { + InnerClass inner = InnerClass.createInnerClass(15); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeNestedClass.java b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeNestedClass.java new file mode 100644 index 000000000000..9d424ddfc084 --- /dev/null +++ b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeNestedClass.java @@ -0,0 +1,16 @@ +class OuterClass { + static InnerClass createInnerClass(int _i) { + return new InnerClass(_i); + } + + static class InnerClass { + int i; + InnerClass(int _i) { + i = _i; + } + } + InnerClass myInner = new InnerClass(27); + static int method() { + InnerClass inner = new InnerClass(15); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeNestedClass2.java b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeNestedClass2.java new file mode 100644 index 000000000000..9fddc7896fb5 --- /dev/null +++ b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeNestedClass2.java @@ -0,0 +1,12 @@ +class OuterClass { + static class InnerClass { + int i; + InnerClass(int _i) { + i = _i; + } + } + InnerClass myInner = new InnerClass(27); + static int method() { + InnerClass inner = new InnerClass(15); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ReplaceConstructorWithFactoryTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/ReplaceConstructorWithFactoryTest.java index ad64f673cab9..c9bae44b45fe 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/ReplaceConstructorWithFactoryTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ReplaceConstructorWithFactoryTest.java @@ -28,7 +28,11 @@ public class ReplaceConstructorWithFactoryTest extends LightRefactoringTestCase public void testDefaultConstructor() { runTest("03", null); } public void testDefaultConstructorWithTypeParams() { runTest("TypeParams", null); } - public void testInnerClass() { runTest("04", "OuterClass"); } + public void testInnerClass() { runTest("04", null); } + + public void testNestedClass() { runTest("NestedClass", "OuterClass"); } + + public void testNestedClass2() { runTest("NestedClass2", "InnerClass"); } public void testSubclassVisibility() { runTest("05", null); }