diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/commands/JavaCommandCompletionFactory.java b/java/java-impl/src/com/intellij/codeInsight/completion/commands/JavaCommandCompletionFactory.java index 34438eecde29..2aac49afe2d0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/commands/JavaCommandCompletionFactory.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/commands/JavaCommandCompletionFactory.java @@ -89,11 +89,12 @@ class JavaCommandCompletionFactory implements CommandCompletionFactory, DumbAwar if (open != null && curParent.getTextRange().getEndOffset() == element.getTextRange().getEndOffset()) { while (curParent.getTextRange().getEndOffset() == element.getTextRange().getEndOffset()) { int nextOffset = curParent.getTextRange().getStartOffset(); - if (results.add(nextOffset)) { + curParent = curParent.getParent(); + boolean stopParent = curParent == null || curParent instanceof PsiClass || curParent instanceof PsiFile; + if (results.add(nextOffset) && !stopParent) { queue.add(nextOffset); } - curParent = curParent.getParent(); - if (curParent == null) { + if (stopParent) { break; } } 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 3ba219f849ad..bc9ef13ea32d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/ReplaceConstructorWithFactoryAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/ReplaceConstructorWithFactoryAction.java @@ -38,7 +38,8 @@ public final class ReplaceConstructorWithFactoryAction implements ModCommandActi @Override public @Nullable Presentation getPresentation(@NotNull ActionContext context) { if (!BaseIntentionAction.canModify(context.file())) return null; - return getConstructorOrClass(context.findLeaf()) != null + PsiMember member = getConstructorOrClass(context.findLeaf()); + return member != null && !getTargets(member).isEmpty() ? Presentation.of(getFamilyName()).withIcon(NewUiValue.isEnabled() ? null : AllIcons.Actions.RefactoringBulb) : null; } @@ -48,12 +49,7 @@ public final class ReplaceConstructorWithFactoryAction implements ModCommandActi PsiElement element = context.findLeaf(); PsiMember constructorOrClass = getConstructorOrClass(element); if (constructorOrClass == null) return ModCommand.nop(); - - List targets = StreamEx.iterate(constructorOrClass, Objects::nonNull, PsiMember::getContainingClass) - .select(PsiClass.class) - .filter(cls -> !(cls instanceof PsiImplicitClass)) - .filter(cls -> cls.hasModifierProperty(PsiModifier.STATIC) || cls.getContainingClass() == null) - .toList(); + List targets = getTargets(constructorOrClass); SmartPsiElementPointer constructorOrClassPtr = SmartPointerManager.createPointer(constructorOrClass); List options = ContainerUtil.map(targets, target -> ModCommand.psiUpdateStep( @@ -66,6 +62,14 @@ public final class ReplaceConstructorWithFactoryAction implements ModCommandActi return ModCommand.chooseAction(JavaBundle.message("popup.title.choose.target.class"), options); } + private @NotNull List getTargets(PsiMember constructorOrClass) { + return StreamEx.iterate(constructorOrClass, Objects::nonNull, PsiMember::getContainingClass) + .select(PsiClass.class) + .filter(cls -> !(cls instanceof PsiImplicitClass)) + .filter(cls -> cls.hasModifierProperty(PsiModifier.STATIC) || cls.getContainingClass() == null) + .toList(); + } + private static void invoke(@NotNull PsiClass cls, @NotNull ModPsiUpdater updater, @NotNull SmartPsiElementPointer constructorOrClassPtr) { diff --git a/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeImplicitClassAfterName.java b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeImplicitClassAfterName.java new file mode 100644 index 000000000000..5634e54981d1 --- /dev/null +++ b/java/java-tests/testData/refactoring/replaceConstructorWithFactory/beforeImplicitClassAfterName.java @@ -0,0 +1,7 @@ +class nested { + +} +void main() { + + +} \ 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 7d3703ff38e6..f7856cfdba45 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/ReplaceConstructorWithFactoryTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ReplaceConstructorWithFactoryTest.java @@ -123,6 +123,10 @@ public class ReplaceConstructorWithFactoryTest extends LightRefactoringTestCase assertNotAvailable("RedCode"); } + public void testImplicitClassNotAvailable() { + assertNotAvailable("ImplicitClassAfterName"); + } + public void testRedCodeFromIDEA376351() { assertNotAvailable("RedCodeFromIDEA376351"); }