push down: start with java processor

This commit is contained in:
Anna Kozlova
2016-02-23 20:20:03 +01:00
parent 358878ecf6
commit 5fb9e445ce
2 changed files with 45 additions and 43 deletions
@@ -15,7 +15,7 @@
*/
package com.intellij.refactoring.memberPushDown;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.InheritanceUtil;
@@ -70,9 +70,20 @@ public class PushDownConflicts {
child.accept(new UsedMovedMembersConflictsCollector(child));
}
}
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(myClass, CommonClassNames.JAVA_LANG_FUNCTIONAL_INTERFACE);
if (annotation != null && myMovedMembers.contains(LambdaUtil.getFunctionalInterfaceMethod(myClass))) {
myConflicts.putValue(annotation, RefactoringBundle.message("functional.interface.broken"));
}
}
public void checkTargetClassConflicts(final PsiClass targetClass, final boolean checkStatic, final PsiElement context) {
public void checkTargetClassConflicts(final PsiElement targetElement, final boolean checkStatic, final PsiElement context) {
if (targetElement instanceof PsiFunctionalExpression) {
myConflicts.putValue(targetElement, RefactoringBundle.message("functional.interface.broken"));
return;
}
final PsiClass targetClass = targetElement instanceof PsiClass ? (PsiClass)targetElement : null;
if (targetClass != null) {
for (final PsiMember movedMember : myMovedMembers) {
checkMemberPlacementInTargetClassConflict(targetClass, movedMember);
@@ -165,27 +165,9 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
pushDownConflicts.checkSourceClassConflicts();
if (usagesIn.length == 0) {
if (myClass.isEnum() || myClass.hasModifierProperty(PsiModifier.FINAL)) {
if (Messages.showOkCancelDialog((myClass.isEnum() ? "Enum " + myClass.getQualifiedName() + " doesn't have constants to inline to. " : "Final class " + myClass.getQualifiedName() + "does not have inheritors. ") +
"Pushing members down will result in them being deleted. " +
"Would you like to proceed?", JavaPushDownHandler.REFACTORING_NAME, Messages.getWarningIcon()) != Messages.OK) {
return false;
}
} else {
String noInheritors = myClass.isInterface() ?
RefactoringBundle.message("interface.0.does.not.have.inheritors", myClass.getQualifiedName()) :
RefactoringBundle.message("class.0.does.not.have.inheritors", myClass.getQualifiedName());
final String message = noInheritors + "\n" + RefactoringBundle.message("push.down.will.delete.members");
final int answer = Messages.showYesNoCancelDialog(message, JavaPushDownHandler.REFACTORING_NAME, Messages.getWarningIcon());
if (answer == Messages.YES) {
myCreateClassDlg = CreateSubclassAction.chooseSubclassToCreate(myClass);
if (myCreateClassDlg != null) {
pushDownConflicts.checkTargetClassConflicts(null, false, myCreateClassDlg.getTargetDirectory());
return showConflicts(pushDownConflicts.getConflicts(), usagesIn);
} else {
return false;
}
} else if (answer != Messages.NO) return false;
Boolean answered = preprocessNoInheritorsFound(usagesIn, pushDownConflicts);
if (answered != null) {
return answered;
}
}
Runnable runnable = new Runnable() {
@@ -195,10 +177,7 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
@Override
public void run() {
for (UsageInfo usage : usagesIn) {
final PsiElement element = usage.getElement();
if (element instanceof PsiClass) {
pushDownConflicts.checkTargetClassConflicts((PsiClass)element, usagesIn.length > 1, element);
}
pushDownConflicts.checkTargetClassConflicts(usage.getElement(), usagesIn.length > 1, usage.getElement());
}
}
});
@@ -209,19 +188,36 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
return false;
}
for (UsageInfo info : usagesIn) {
final PsiElement element = info.getElement();
if (element instanceof PsiFunctionalExpression) {
pushDownConflicts.getConflicts().putValue(element, RefactoringBundle.message("functional.interface.broken"));
}
}
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(myClass, CommonClassNames.JAVA_LANG_FUNCTIONAL_INTERFACE);
if (annotation != null && isMoved(LambdaUtil.getFunctionalInterfaceMethod(myClass))) {
pushDownConflicts.getConflicts().putValue(annotation, RefactoringBundle.message("functional.interface.broken"));
}
return showConflicts(pushDownConflicts.getConflicts(), usagesIn);
}
@Nullable
protected Boolean preprocessNoInheritorsFound(UsageInfo[] usagesIn, PushDownConflicts pushDownConflicts) {
if (myClass.isEnum() || myClass.hasModifierProperty(PsiModifier.FINAL)) {
if (Messages.showOkCancelDialog((myClass.isEnum() ? "Enum " + myClass.getQualifiedName() + " doesn't have constants to inline to. " : "Final class " + myClass.getQualifiedName() + "does not have inheritors. ") +
"Pushing members down will result in them being deleted. " +
"Would you like to proceed?", JavaPushDownHandler.REFACTORING_NAME, Messages.getWarningIcon()) != Messages.OK) {
return false;
}
} else {
String noInheritors = myClass.isInterface() ?
RefactoringBundle.message("interface.0.does.not.have.inheritors", myClass.getQualifiedName()) :
RefactoringBundle.message("class.0.does.not.have.inheritors", myClass.getQualifiedName());
final String message = noInheritors + "\n" + RefactoringBundle.message("push.down.will.delete.members");
final int answer = Messages.showYesNoCancelDialog(message, JavaPushDownHandler.REFACTORING_NAME, Messages.getWarningIcon());
if (answer == Messages.YES) {
myCreateClassDlg = CreateSubclassAction.chooseSubclassToCreate(myClass);
if (myCreateClassDlg != null) {
pushDownConflicts.checkTargetClassConflicts(null, false, myCreateClassDlg.getTargetDirectory());
return showConflicts(pushDownConflicts.getConflicts(), usagesIn);
} else {
return false;
}
} else if (answer != Messages.NO) return false;
}
return null;
}
@Override
protected void refreshElements(@NotNull PsiElement[] elements) {
if(elements.length == 1 && elements[0] instanceof PsiClass) {
@@ -524,12 +520,7 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
if (newMember != null) {
decodeRefs(newMember, targetClass);
//rebind imports first
Collections.sort(refsToRebind, new Comparator<PsiReference>() {
@Override
public int compare(PsiReference o1, PsiReference o2) {
return PsiUtil.BY_POSITION.compare(o1.getElement(), o2.getElement());
}
});
Collections.sort(refsToRebind, Comparator.comparing(PsiReference::getElement, PsiUtil.BY_POSITION));
for (PsiReference psiReference : refsToRebind) {
JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(psiReference.bindToElement(newMember));
}