pull up: add conflicts on pulling up abstract method (IDEA-189200)

This commit is contained in:
Anna.Kozlova
2018-04-24 14:51:22 +02:00
parent 810aa503b1
commit a7da5544e8
3 changed files with 31 additions and 7 deletions

View File

@@ -99,7 +99,8 @@ public class PullUpConflictsUtil {
}
}
if (newAbstractMethodInSuper(infos)) {
List<PsiMethod> newAbstractMethods = newAbstractMethodInSuper(infos);
if (!newAbstractMethods.isEmpty()) {
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(superClass, CommonClassNames.JAVA_LANG_FUNCTIONAL_INTERFACE);
if (annotation != null) {
conflicts.putValue(annotation, RefactoringBundle.message("functional.interface.broken"));
@@ -108,6 +109,17 @@ public class PullUpConflictsUtil {
if (functionalExpression != null) {
conflicts.putValue(functionalExpression, RefactoringBundle.message("functional.interface.broken"));
}
ClassInheritorsSearch.search(superClass).forEach(sClass -> {
if (!sClass.isInheritor(subclass, true) && !sClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
for (PsiMethod aMethod : newAbstractMethods) {
if (MethodSignatureUtil.findMethodBySignature(sClass, aMethod, true) == null) {
conflicts.putValue(sClass, "Concrete '" + RefactoringUIUtil.getDescription(sClass, true) + "' would inherit a new abstract method");
return false;
}
}
}
return true;
});
}
}
}
@@ -187,14 +199,17 @@ public class PullUpConflictsUtil {
return conflicts;
}
private static boolean newAbstractMethodInSuper(MemberInfoBase<? extends PsiMember>[] infos) {
boolean toAbstract = false;
private static List<PsiMethod> newAbstractMethodInSuper(MemberInfoBase<? extends PsiMember>[] infos) {
List<PsiMethod> result = new ArrayList<>();
for (MemberInfoBase<? extends PsiMember> info : infos) {
if (info.isToAbstract()) {
toAbstract = true;
PsiMember member = info.getMember();
if (member instanceof PsiMethod) {
if (info.isToAbstract() || member.hasModifierProperty(PsiModifier.ABSTRACT)) {
result.add((PsiMethod)member);
}
}
}
return toAbstract;
return result;
}
private static void checkInterfaceTarget(MemberInfoBase<? extends PsiMember>[] infos, MultiMap<PsiElement, String> conflictsList) {

View File

@@ -0,0 +1,5 @@
abstract class A {}
abstract class B extends A {
public abstract void f<caret>oo();
}
class C extends A {}

View File

@@ -159,7 +159,11 @@ public class PullUpTest extends LightRefactoringTestCase {
public void testTypeParamsConflictingNames() {
doTest(false, new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class, true));
}
}
public void testConflictOnNewAbstractMethod() {
doTest(false, "Concrete 'class <b><code>C</code></b>' would inherit a new abstract method", new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class));
}
public void testEscalateVisibility() {
doTest(false, new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class));