diff --git a/source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java b/source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java index 9d7178ede9ae..13df1343cc0c 100644 --- a/source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java +++ b/source/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java @@ -369,6 +369,7 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor { } private void findClassUsages(final PsiClass psiClass, ArrayList usages) { + final boolean justPrivates = containsOnlyPrivates(psiClass); PsiManager manager = psiClass.getManager(); GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); final PsiReference[] references = manager.getSearchHelper().findReferences(psiClass, projectScope, false); @@ -379,6 +380,19 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor { if (!isInside(element, myElements)) { PsiElement parent = element.getParent(); + if (parent instanceof PsiReferenceList) { + final PsiElement pparent = parent.getParent(); + if (pparent instanceof PsiClass) { + final PsiClass inheritor = ((PsiClass)pparent); + //If psiClass contains only private members, then it is safe to remove it and change inheritor's extends/implements accordingly + if (justPrivates) { + if (parent.equals(inheritor.getExtendsList()) || parent.equals(inheritor.getImplementsList())) { + usages.add(new SafeDeleteExtendsClassUsageInfo((PsiJavaCodeReferenceElement)element, psiClass, inheritor)); + continue; + } + } + } + } usages.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(parent, psiClass, parent instanceof PsiImportStatement)); } } @@ -386,6 +400,25 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor { addNonCodeUsages(psiClass, usages, myInsideDeletedElements); } + private boolean containsOnlyPrivates(final PsiClass aClass) { + final PsiField[] fields = aClass.getFields(); + for (int i = 0; i < fields.length; i++) { + if (!fields[i].hasModifierProperty(PsiModifier.PRIVATE)) return false; + } + + final PsiMethod[] methods = aClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + if (!methods[i].hasModifierProperty(PsiModifier.PRIVATE)) return false; + } + + final PsiClass[] inners = aClass.getInnerClasses(); + for (int i = 0; i < inners.length; i++) { + if (!inners[i].hasModifierProperty(PsiModifier.PRIVATE)) return false; + } + + return true; + } + private void findMethodUsages(PsiMethod psiMethod, ArrayList usages) { PsiManager manager = psiMethod.getManager(); final PsiSearchHelper searchHelper = manager.getSearchHelper(); diff --git a/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java b/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java new file mode 100644 index 000000000000..196023ccacb1 --- /dev/null +++ b/source/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java @@ -0,0 +1,65 @@ +package com.intellij.refactoring.safeDelete.usageInfo; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiReferenceList; +import com.intellij.util.IncorrectOperationException; + +/** + * @author ven + */ +public class SafeDeleteExtendsClassUsageInfo extends SafeDeleteReferenceUsageInfo { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteExtendsClassUsageInfo"); + private final PsiClass myExtendingClass; + + public SafeDeleteExtendsClassUsageInfo(final PsiJavaCodeReferenceElement reference, PsiClass refClass, PsiClass extendingClass) { + super(reference, refClass, true); + myExtendingClass = extendingClass; + } + + public PsiClass getReferencedElement() { + return (PsiClass)super.getReferencedElement(); + } + + public void deleteElement() throws IncorrectOperationException { + final PsiElement parent = getElement().getParent(); + LOG.assertTrue(parent instanceof PsiReferenceList); + final PsiClass refClass = getReferencedElement(); + final PsiReferenceList extendsList = refClass.getExtendsList(); + if (extendsList != null) { + final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements(); + final PsiReferenceList listToAddExtends = refClass.isInterface() == myExtendingClass.isInterface() ? myExtendingClass.getExtendsList() : + myExtendingClass.getImplementsList(); + for (int i = 0; i < referenceElements.length; i++) { + listToAddExtends.add(referenceElements[i]); + } + } + + final PsiReferenceList implementsList = refClass.getImplementsList(); + if (implementsList != null) { + final PsiJavaCodeReferenceElement[] referenceElements = implementsList.getReferenceElements(); + for (int i = 0; i < referenceElements.length; i++) { + myExtendingClass.getImplementsList().add(referenceElements[i]); + } + } + + getElement().delete(); + } + + public boolean isSafeDelete() { + final PsiClass refClass = getReferencedElement(); + if (refClass.getExtendsListTypes().length > 0) { + final PsiReferenceList listToAddExtends = refClass.isInterface() == myExtendingClass.isInterface() ? myExtendingClass.getExtendsList() : + myExtendingClass.getImplementsList(); + if (listToAddExtends == null) return false; + } + + if (refClass.getImplementsListTypes().length > 0) { + if (myExtendingClass.getImplementsList() == null) return false; + } + + return true; + } +}