From e847d166f5df5f8a55d267c88e0c4b15266d021e Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 4 Mar 2016 16:32:44 +0100 Subject: [PATCH] inline super: don't search for inheritors (may be only this should be replaced: IDEA-152522); dialog layout simplified (IDEA-152474) --- .../InlineSuperClassRefactoringDialog.java | 31 ++------------- .../InlineSuperClassRefactoringHandler.java | 22 +++-------- .../InlineSuperClassRefactoringProcessor.java | 39 ++++++++++++++++--- .../refactoring/InlineSuperClassTest.java | 6 +-- 4 files changed, 45 insertions(+), 53 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringDialog.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringDialog.java index 80c0178ab362..6809c9779a81 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringDialog.java @@ -21,16 +21,11 @@ package com.intellij.refactoring.inlineSuperClass; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiClass; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.inline.InlineOptionsDialog; import com.intellij.refactoring.ui.DocCommentPanel; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.util.Function; -import com.intellij.util.ui.JBDimension; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,15 +35,13 @@ import java.awt.*; public class InlineSuperClassRefactoringDialog extends InlineOptionsDialog { private final PsiClass mySuperClass; private final PsiClass myCurrentInheritor; - private final PsiClass[] myTargetClasses; private final DocCommentPanel myDocPanel; - protected InlineSuperClassRefactoringDialog(@NotNull Project project, PsiClass superClass, PsiClass currentInheritor, final PsiClass... targetClasses) { + protected InlineSuperClassRefactoringDialog(@NotNull Project project, PsiClass superClass, PsiClass currentInheritor) { super(project, false, superClass); mySuperClass = superClass; myCurrentInheritor = currentInheritor; myInvokedOnReference = currentInheritor != null; - myTargetClasses = targetClasses; myDocPanel = new DocCommentPanel("JavaDoc for inlined members"); myDocPanel.setPolicy(JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC); init(); @@ -60,7 +53,7 @@ public class InlineSuperClassRefactoringDialog extends InlineOptionsDialog { if(myRbInlineThisOnly.isEnabled() && myRbInlineAll.isEnabled()) { settings.INLINE_SUPER_CLASS_THIS = isInlineThisOnly(); } - invokeRefactoring(new InlineSuperClassRefactoringProcessor(getProject(), isInlineThisOnly() ? myCurrentInheritor : null, mySuperClass, myDocPanel.getPolicy(), myTargetClasses)); + invokeRefactoring(new InlineSuperClassRefactoringProcessor(getProject(), isInlineThisOnly() ? myCurrentInheritor : null, mySuperClass, myDocPanel.getPolicy())); } @Override @@ -76,31 +69,15 @@ public class InlineSuperClassRefactoringDialog extends InlineOptionsDialog { @NotNull protected JComponent createCenterPanel() { - final JLabel label = new JLabel("Super class \'" + - mySuperClass.getQualifiedName() + - "\' inheritors: " + - (myTargetClasses.length > 1 ? "
   \'" : "\'") + - StringUtil.join(myTargetClasses, new Function() { - public String fun(final PsiClass psiClass) { - return psiClass.getQualifiedName(); - } - }, "\',
   \'") + - "\'"); - label.setVerticalAlignment(SwingConstants.TOP); final JPanel panel = new JPanel(new GridBagLayout()); final GridBagConstraints gc = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0); panel.add(myDocPanel, gc); - JScrollPane pane = ScrollPaneFactory.createScrollPane(label); - pane.setBorder(IdeBorderFactory.createEmptyBorder(5, 5, 5, 5)); - pane.setMinimumSize(JBDimension.create(new Dimension(-1, 100))); + panel.add(super.createCenterPanel(), gc); gc.weighty = 1; gc.fill = GridBagConstraints.BOTH; - panel.add(pane, gc); - gc.weighty = 0; - gc.fill = GridBagConstraints.HORIZONTAL; - panel.add(super.createCenterPanel(), gc); + panel.add(Box.createVerticalGlue(), gc); return panel; } diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringHandler.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringHandler.java index a42cd4c72c55..cd89b1aab2b8 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringHandler.java @@ -24,9 +24,11 @@ import com.intellij.codeInsight.TargetElementUtil; import com.intellij.lang.StdLanguages; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceList; import com.intellij.psi.search.searches.DirectClassInheritorsSearch; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.inline.JavaInlineActionHandler; import com.intellij.refactoring.util.CommonRefactoringUtil; @@ -49,23 +51,11 @@ public class InlineSuperClassRefactoringHandler extends JavaInlineActionHandler public void inlineElement(final Project project, final Editor editor, final PsiElement element) { PsiClass superClass = (PsiClass) element; - Collection inheritors = DirectClassInheritorsSearch.search((PsiClass)element).findAll(); if (!superClass.getManager().isInProject(superClass)) { CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline non-project class", REFACTORING_NAME, null); return; } - for (PsiClass inheritor : inheritors) { - if (PsiTreeUtil.isAncestor(superClass, inheritor, false)) { - CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline into the inner class. Move \'" + inheritor.getName() + "\' to upper level", REFACTORING_NAME, null); - return; - } - if (inheritor instanceof PsiAnonymousClass) { - CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline into anonymous class.", REFACTORING_NAME, null); - return; - } - } - PsiClass chosen = null; PsiReference reference = editor != null ? TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()) : null; if (reference != null) { @@ -76,13 +66,13 @@ public class InlineSuperClassRefactoringHandler extends JavaInlineActionHandler final PsiElement parent = referenceElement.getParent(); if (parent instanceof PsiReferenceList) { final PsiElement gParent = parent.getParent(); - if (gParent instanceof PsiClass && inheritors.contains(gParent)) { + if (gParent instanceof PsiClass) { chosen = (PsiClass)gParent; } } } } } - new InlineSuperClassRefactoringDialog(project, superClass, chosen, inheritors.toArray(new PsiClass[inheritors.size()])).show(); + new InlineSuperClassRefactoringDialog(project, superClass, chosen).show(); } } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java index 8b4ceef2605b..5945ca3d5169 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java @@ -24,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; +import com.intellij.psi.search.searches.DirectClassInheritorsSearch; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; @@ -51,6 +52,7 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -60,15 +62,14 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori private final PsiClass myCurrentInheritor; private final PsiClass mySuperClass; private final int myPolicy; - private final PsiClass[] myTargetClasses; + private PsiClass[] myTargetClasses; private final MemberInfo[] myMemberInfos; - public InlineSuperClassRefactoringProcessor(Project project, PsiClass currentInheritor, PsiClass superClass, int policy, final PsiClass... targetClasses) { + public InlineSuperClassRefactoringProcessor(Project project, PsiClass currentInheritor, PsiClass superClass, int policy) { super(project); myCurrentInheritor = currentInheritor; mySuperClass = superClass; myPolicy = policy; - myTargetClasses = currentInheritor != null ? new PsiClass[] {currentInheritor} : targetClasses; MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySuperClass, new MemberInfo.Filter() { public boolean includeMember(PsiMember element) { return !(element instanceof PsiClass) || PsiTreeUtil.isAncestor(mySuperClass, element, true); @@ -92,6 +93,14 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori final PsiElementFactory elementFactory = facade.getElementFactory(); final PsiResolveHelper resolveHelper = facade.getResolveHelper(); + if (myCurrentInheritor != null) { + myTargetClasses = new PsiClass[] {myCurrentInheritor}; + } + else { + Collection inheritors = DirectClassInheritorsSearch.search(mySuperClass).findAll(); + myTargetClasses = inheritors.toArray(new PsiClass[inheritors.size()]); + } + ReferencesSearch.search(mySuperClass).forEach(new Processor() { public boolean process(final PsiReference reference) { final PsiElement element = reference.getElement(); @@ -157,6 +166,10 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori } }); for (PsiClass targetClass : myTargetClasses) { + if (skipTargetClass(targetClass)) { + continue; + } + for (MemberInfo memberInfo : myMemberInfos) { final PsiMember member = memberInfo.getMember(); for (PsiReference reference : ReferencesSearch.search(member, member.getUseScope(), true)) { @@ -220,11 +233,19 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori final MultiMap conflicts = new MultiMap(); final PushDownConflicts pushDownConflicts = new PushDownConflicts(mySuperClass, myMemberInfos, conflicts); for (PsiClass targetClass : myTargetClasses) { - for (MemberInfo info : myMemberInfos) { - final PsiMember member = info.getMember(); - pushDownConflicts.checkMemberPlacementInTargetClassConflict(targetClass, member); + if (targetClass instanceof PsiAnonymousClass) { + conflicts.putValue(targetClass, "Cannot inline into anonymous class."); } + else if (PsiTreeUtil.isAncestor(mySuperClass, targetClass, false)) { + conflicts.putValue(targetClass, "Cannot inline into the inner class. Move \'" + targetClass.getName() + "\' to upper level"); + } + else { + for (MemberInfo info : myMemberInfos) { + final PsiMember member = info.getMember(); + pushDownConflicts.checkMemberPlacementInTargetClassConflict(targetClass, member); + } //todo check accessibility conflicts + } } if (myCurrentInheritor != null) { ReferencesSearch.search(myCurrentInheritor).forEach(new Processor() { @@ -249,6 +270,11 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori return showConflicts(conflicts, refUsages.get()); } + private boolean skipTargetClass(PsiClass targetClass) { + return targetClass instanceof PsiAnonymousClass || + PsiTreeUtil.isAncestor(mySuperClass, targetClass, false); + } + @Nullable private static PsiType getPlaceExpectedType(PsiElement parent) { PsiType type = PsiTypesUtil.getExpectedTypeByParent((PsiExpression)parent); @@ -346,6 +372,7 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori final PsiResolveHelper resolveHelper = facade.getResolveHelper(); final Map replacementMap = new HashMap(); for (final PsiClass targetClass : myTargetClasses) { + if (skipTargetClass(targetClass)) continue; final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY); final PsiClassType targetClassType = elementFactory.createType(targetClass, superClassSubstitutor); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java index 074f1b1e7110..59b8ca4a981d 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java @@ -87,7 +87,7 @@ public class InlineSuperClassTest extends MultiFileTestCase { PsiClass superClass = myJavaFacade.findClass("Super", scope); if (superClass == null) superClass = myJavaFacade.findClass("p1.Super", scope); assertNotNull("Class Super not found", superClass); - new InlineSuperClassRefactoringProcessor(myProject, inlineOne ? aClass : null, superClass, DocCommentPolicy.ASIS, aClass).run(); + new InlineSuperClassRefactoringProcessor(myProject, inlineOne ? aClass : null, superClass, DocCommentPolicy.ASIS).run(); }); } catch (BaseRefactoringProcessor.ConflictsInTestsException e) { @@ -109,9 +109,7 @@ public class InlineSuperClassTest extends MultiFileTestCase { PsiClass superClass = myJavaFacade.findClass("Super", scope); if (superClass == null) superClass = myJavaFacade.findClass("p1.Super", scope); assertNotNull("Class Super not found", superClass); - PsiClass target1 = myJavaFacade.findClass("Test", scope); - PsiClass target2 = myJavaFacade.findClass("Test1", scope); - new InlineSuperClassRefactoringProcessor(myProject, null, superClass, DocCommentPolicy.ASIS, target1, target2).run(); + new InlineSuperClassRefactoringProcessor(myProject, null, superClass, DocCommentPolicy.ASIS).run(); }); } }