mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
inline super: don't search for inheritors (may be only this should be replaced: IDEA-152522); dialog layout simplified (IDEA-152474)
This commit is contained in:
+4
-27
@@ -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("<html>Super class \'" +
|
||||
mySuperClass.getQualifiedName() +
|
||||
"\' inheritors: " +
|
||||
(myTargetClasses.length > 1 ? " <br> \'" : "\'") +
|
||||
StringUtil.join(myTargetClasses, new Function<PsiClass, String>() {
|
||||
public String fun(final PsiClass psiClass) {
|
||||
return psiClass.getQualifiedName();
|
||||
}
|
||||
}, "\',<br> \'") +
|
||||
"\'</html>");
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+6
-16
@@ -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<PsiClass> 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();
|
||||
}
|
||||
}
|
||||
+33
-6
@@ -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<PsiMember>() {
|
||||
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<PsiClass> inheritors = DirectClassInheritorsSearch.search(mySuperClass).findAll();
|
||||
myTargetClasses = inheritors.toArray(new PsiClass[inheritors.size()]);
|
||||
}
|
||||
|
||||
ReferencesSearch.search(mySuperClass).forEach(new Processor<PsiReference>() {
|
||||
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<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
|
||||
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<PsiReference>() {
|
||||
@@ -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<UsageInfo, PsiElement> replacementMap = new HashMap<UsageInfo, PsiElement>();
|
||||
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);
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user