mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
extract super class: check for conflicts under progress; skip check for superclass inheritors mismatch - as no actual members would go there
This commit is contained in:
+10
-3
@@ -29,6 +29,7 @@ import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.*;
|
||||
@@ -124,7 +125,7 @@ public class ExtractSuperclassHandler implements RefactoringActionHandler, Extra
|
||||
|
||||
}
|
||||
|
||||
public boolean checkConflicts(ExtractSuperclassDialog dialog) {
|
||||
public boolean checkConflicts(final ExtractSuperclassDialog dialog) {
|
||||
final MemberInfo[] infos = ArrayUtil.toObjectArray(dialog.getSelectedMemberInfos(), MemberInfo.class);
|
||||
final PsiDirectory targetDirectory = dialog.getTargetDirectory();
|
||||
final PsiPackage targetPackage;
|
||||
@@ -134,8 +135,14 @@ public class ExtractSuperclassHandler implements RefactoringActionHandler, Extra
|
||||
else {
|
||||
targetPackage = null;
|
||||
}
|
||||
final MultiMap<PsiElement,String> conflicts =
|
||||
PullUpConflictsUtil.checkConflicts(infos, mySubclass, mySubclass.getSuperClass(), targetPackage, targetDirectory, dialog.getContainmentVerifier());
|
||||
final MultiMap<PsiElement,String> conflicts = new MultiMap<PsiElement, String>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
public void run() {
|
||||
final PsiClass superClass = mySubclass.getExtendsListTypes().length > 0 ? mySubclass.getSuperClass() : null;
|
||||
conflicts.putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory, dialog.getContainmentVerifier(), false));
|
||||
}
|
||||
}, "Detecting possible conflicts...", true, myProject)) return false;
|
||||
|
||||
if (!conflicts.isEmpty()) {
|
||||
ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts);
|
||||
conflictsDialog.show();
|
||||
|
||||
@@ -60,6 +60,16 @@ public class PullUpConflictsUtil {
|
||||
PsiPackage targetPackage,
|
||||
PsiDirectory targetDirectory,
|
||||
final InterfaceContainmentVerifier interfaceContainmentVerifier) {
|
||||
return checkConflicts(infos, subclass, superClass, targetPackage, targetDirectory, interfaceContainmentVerifier, true);
|
||||
}
|
||||
|
||||
public static MultiMap<PsiElement, String> checkConflicts(final MemberInfo[] infos,
|
||||
PsiClass subclass,
|
||||
@Nullable PsiClass superClass,
|
||||
PsiPackage targetPackage,
|
||||
PsiDirectory targetDirectory,
|
||||
final InterfaceContainmentVerifier interfaceContainmentVerifier,
|
||||
boolean movedMembers2Super) {
|
||||
final Set<PsiMember> movedMembers = new HashSet<PsiMember>();
|
||||
final Set<PsiMethod> abstractMethods = new HashSet<PsiMethod>();
|
||||
final boolean isInterfaceTarget;
|
||||
@@ -98,7 +108,7 @@ public class PullUpConflictsUtil {
|
||||
}
|
||||
}
|
||||
RefactoringConflictsUtil.analyzeAccessibilityConflicts(movedMembers, superClass, conflicts, null, targetRepresentativeElement, abstrMethods);
|
||||
if (superClass != null) {
|
||||
if (superClass != null && movedMembers2Super) {
|
||||
checkSuperclassMembers(superClass, infos, conflicts);
|
||||
if (isInterfaceTarget) {
|
||||
checkInterfaceTarget(infos, conflicts);
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class Test {
|
||||
void x() {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
public class TestSubclass extends Test {
|
||||
|
||||
private void foo(){}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public class Test {
|
||||
void x() {
|
||||
foo();
|
||||
}
|
||||
|
||||
private void foo(){}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Test extends ArrayList {
|
||||
void x() {
|
||||
removeRange(0, 0);
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
public class TestSubclass extends Test {
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import java.util.*;
|
||||
public class Test extends ArrayList {
|
||||
void x() {
|
||||
removeRange(0, 0);
|
||||
}
|
||||
}
|
||||
@@ -9,20 +9,24 @@ import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.refactoring.extractSuperclass.ExtractSuperClassProcessor;
|
||||
import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil;
|
||||
import com.intellij.refactoring.memberPullUp.PullUpHelper;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -37,6 +41,18 @@ public class ExtractSuperClassTest extends CodeInsightTestCase {
|
||||
doTest("Test", "TestSubclass", new RefactoringTestUtil.MemberDescriptor("x", PsiField.class));
|
||||
}
|
||||
|
||||
public void testConflictUsingPrivateMethod() throws Exception {
|
||||
doTest("Test", "TestSubclass",
|
||||
new String[] {"Method <b><code>Test.foo()</code></b> is private and will not be accessible from method <b><code>x()</code></b>.",
|
||||
"Method <b><code>x()</code></b> uses method <b><code>Test.foo()</code></b>, which is not moved to the superclass"},
|
||||
new RefactoringTestUtil.MemberDescriptor("x", PsiMethod.class));
|
||||
}
|
||||
|
||||
public void testNoConflictUsingProtectedMethodFromSuper() throws Exception {
|
||||
doTest("Test", "TestSubclass",
|
||||
new RefactoringTestUtil.MemberDescriptor("x", PsiMethod.class));
|
||||
}
|
||||
|
||||
public void testParameterNameEqualsFieldName() throws Exception { // IDEADEV-10629
|
||||
doTest("Test", "TestSubclass", new RefactoringTestUtil.MemberDescriptor("a", PsiField.class));
|
||||
}
|
||||
@@ -79,18 +95,54 @@ public class ExtractSuperClassTest extends CodeInsightTestCase {
|
||||
|
||||
private void doTest(@NonNls final String className, @NonNls final String newClassName,
|
||||
RefactoringTestUtil.MemberDescriptor... membersToFind) throws Exception {
|
||||
doTest(className, newClassName, null, membersToFind);
|
||||
}
|
||||
|
||||
private void doTest(@NonNls final String className, @NonNls final String newClassName,
|
||||
String[] conflicts,
|
||||
RefactoringTestUtil.MemberDescriptor... membersToFind) throws Exception {
|
||||
String rootBefore = getRoot() + "/before";
|
||||
PsiTestUtil.removeAllRoots(myModule, JavaSdkImpl.getMockJdk14());
|
||||
final VirtualFile rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, rootBefore, myFilesToDelete);
|
||||
PsiClass psiClass = myJavaFacade.findClass(className, ProjectScope.getAllScope(myProject));
|
||||
assertNotNull(psiClass);
|
||||
final MemberInfo[] members = RefactoringTestUtil.findMembers(psiClass, membersToFind);
|
||||
final PsiDirectory targetDirectory = psiClass.getContainingFile().getContainingDirectory();
|
||||
ExtractSuperClassProcessor processor = new ExtractSuperClassProcessor(myProject,
|
||||
psiClass.getContainingFile().getContainingDirectory(),
|
||||
targetDirectory,
|
||||
newClassName,
|
||||
psiClass, members,
|
||||
false,
|
||||
new DocCommentPolicy(DocCommentPolicy.ASIS));
|
||||
new DocCommentPolicy<PsiComment>(DocCommentPolicy.ASIS));
|
||||
final PsiPackage targetPackage;
|
||||
if (targetDirectory != null) {
|
||||
targetPackage = JavaDirectoryService.getInstance().getPackage(targetDirectory);
|
||||
}
|
||||
else {
|
||||
targetPackage = null;
|
||||
}
|
||||
final PsiClass superClass = psiClass.getExtendsListTypes().length > 0 ? psiClass.getSuperClass() : null;
|
||||
final MultiMap<PsiElement, String> conflictsMap =
|
||||
PullUpConflictsUtil.checkConflicts(members, psiClass, superClass, targetPackage, targetDirectory, new InterfaceContainmentVerifier() {
|
||||
public boolean checkedInterfacesContain(PsiMethod psiMethod) {
|
||||
return PullUpHelper.checkedInterfacesContain(Arrays.asList(members), psiMethod);
|
||||
}
|
||||
}, false);
|
||||
if (conflicts != null) {
|
||||
if (conflictsMap.isEmpty()) {
|
||||
fail("Conflicts were not detected");
|
||||
}
|
||||
final HashSet<String> expectedConflicts = new HashSet<String>(Arrays.asList(conflicts));
|
||||
final HashSet<String> actualConflicts = new HashSet<String>(conflictsMap.values());
|
||||
assertEquals(expectedConflicts.size(), actualConflicts.size());
|
||||
for (String actualConflict : actualConflicts) {
|
||||
if (!expectedConflicts.contains(actualConflict)) {
|
||||
fail("Unexpected conflict: " + actualConflict);
|
||||
}
|
||||
}
|
||||
} else if (!conflictsMap.isEmpty()) {
|
||||
fail("Unexpected conflicts!!!");
|
||||
}
|
||||
processor.run();
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
|
||||
Reference in New Issue
Block a user