diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingMethodsDialog.java b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingDialog.java similarity index 96% rename from idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingMethodsDialog.java rename to idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingDialog.java index 9321d0fa5ab..41d28e9051c 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingMethodsDialog.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingDialog.java @@ -57,7 +57,7 @@ import java.util.List; * Revision: 14aa2e2 * (replace PsiMethod formatting) */ -class KotlinOverridingMethodsDialog extends DialogWrapper { +class KotlinOverridingDialog extends DialogWrapper { private final List myOverridingMethods; private final String[] myMethodText; private final boolean[] myChecked; @@ -66,7 +66,7 @@ class KotlinOverridingMethodsDialog extends DialogWrapper { private JBTable myTable; private final UsagePreviewPanel myUsagePreviewPanel; - public KotlinOverridingMethodsDialog(Project project, List overridingMethods) { + public KotlinOverridingDialog(Project project, List overridingMethods) { super(project, true); myOverridingMethods = overridingMethods; myChecked = new boolean[myOverridingMethods.size()]; @@ -102,13 +102,14 @@ class KotlinOverridingMethodsDialog extends DialogWrapper { } } - assert element instanceof PsiMethod; + assert element instanceof PsiMethod + : "Method accepts only kotlin functions/properties and java methods, but '" + element.getText() + "' was found"; return KotlinSafeDeleteProcessor.formatPsiMethod((PsiMethod) element, true, false); } @Override protected String getDimensionServiceKey() { - return "#org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinOverridingMethodsDialog"; + return "#org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinOverridingDialog"; } public ArrayList getSelected() { diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java index 32e296c1c7e..fc58fd5293f 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java @@ -29,7 +29,6 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.*; import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor; import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo; -import com.intellij.refactoring.safeDelete.SafeDeleteProcessor; import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverridingMethodUsageInfo; import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo; import com.intellij.usageView.UsageInfo; @@ -64,10 +63,24 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { return canDeleteElement(element); } - protected static NonCodeUsageSearchInfo getDefaultNonCodeUsageSearchInfo( - @NotNull PsiElement element, @NotNull PsiElement[] allElementsToDelete + protected static NonCodeUsageSearchInfo getSearchInfo( + @NotNull PsiElement element, @NotNull final Collection ignoredElements ) { - return new NonCodeUsageSearchInfo(SafeDeleteProcessor.getDefaultInsideDeletedCondition(allElementsToDelete), element); + + return new NonCodeUsageSearchInfo( + new Condition() { + @Override + public boolean value(PsiElement usage) { + if (usage instanceof JetFile) return false; + return isInside(usage, ignoredElements); + } + }, + element + ); + } + + protected static NonCodeUsageSearchInfo getSearchInfo(@NotNull PsiElement element, @NotNull PsiElement[] ignoredElements) { + return getSearchInfo(element, Arrays.asList(ignoredElements)); } @Nullable @@ -90,11 +103,11 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { JetProperty property = (JetProperty) element; if (property.isLocal()) { - return findLocalPropertyUsages(property, allElementsToDelete, result); + return findLocalVariableUsages(property, allElementsToDelete, result); } - return findNonLocalPropertyUsages(property, allElementsToDelete, result); + return findPropertyUsages(property, allElementsToDelete, result); } - return getDefaultNonCodeUsageSearchInfo(element, allElementsToDelete); + return getSearchInfo(element, allElementsToDelete); } private static PsiElement getObjectDeclarationOrFail(PsiElement element) { @@ -148,7 +161,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { } }); - return getDefaultNonCodeUsageSearchInfo(referencedElement, allElementsToDelete); + return getSearchInfo(referencedElement, allElementsToDelete); } protected NonCodeUsageSearchInfo findPsiMethodUsages( @@ -178,58 +191,54 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { return list; } + private static void processDeclarationUsages( + JetDeclaration declaration, + PsiElement[] allElementsToDelete, + List result, + Collection references, + List overridingDeclarations + ) { + for (PsiReference reference : references) { + PsiElement element = reference.getElement(); + if (!isInside(element, allElementsToDelete) && !isInside(element, overridingDeclarations)) { + JetImportDirective importDirective = PsiTreeUtil.getParentOfType(element, JetImportDirective.class, false); + if (importDirective != null) { + result.add(new SafeDeleteImportDirectiveUsageInfo(importDirective, declaration)); + } + else { + result.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, declaration, false)); + } + } + } + } + protected static NonCodeUsageSearchInfo findFunctionUsages( JetNamedFunction function, - final PsiElement[] allElementsToDelete, + PsiElement[] allElementsToDelete, List result ) { PsiMethod lightMethod = LightClassUtil.getLightClassMethod(function); if (lightMethod == null) { - return getDefaultNonCodeUsageSearchInfo(function, allElementsToDelete); + return getSearchInfo(function, allElementsToDelete); } Collection references = ReferencesSearch.search(function).findAll(); List overridingMethods = difference(OverridingMethodsSearch.search(lightMethod, true).findAll(), allElementsToDelete); - for (PsiReference reference : references) { - PsiElement element = reference.getElement(); - if (!isInside(element, allElementsToDelete) && !isInside(element, overridingMethods)) { - JetImportDirective importDirective = PsiTreeUtil.getParentOfType(element, JetImportDirective.class, false); - if (importDirective != null) { - result.add(new SafeDeleteImportDirectiveUsageInfo(importDirective, function)); - } - else { - result.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, function, false)); - } - } - } + processDeclarationUsages(function, allElementsToDelete, result, references, overridingMethods); - HashMap> methodToReferences = new HashMap>(); - for (PsiMethod overridingMethod : overridingMethods) { - Collection overridingReferences = - ReferencesSearch.search( - overridingMethod instanceof JetClsMethod ? ((JetClsMethod) overridingMethod).getOrigin() : overridingMethod - ).findAll(); - methodToReferences.put(overridingMethod, overridingReferences); - } - final Set safeOverriding = + Map> methodToReferences = getOverridingUsagesMap(overridingMethods); + Set safeOverriding = filterSafeOverridingMethods(lightMethod, references, overridingMethods, methodToReferences, result, allElementsToDelete); - return new NonCodeUsageSearchInfo( - new Condition() { - @Override - public boolean value(PsiElement usage) { - if (usage instanceof JetFile) return false; - return isInside(usage, allElementsToDelete) || isInside(usage, safeOverriding); - } - }, - function - ); + List ignoredElements = new ArrayList(safeOverriding); + ContainerUtil.addAll(ignoredElements, allElementsToDelete); + return getSearchInfo(function, ignoredElements); } - protected static NonCodeUsageSearchInfo findNonLocalPropertyUsages( + protected static NonCodeUsageSearchInfo findPropertyUsages( JetProperty property, - final PsiElement[] allElementsToDelete, + PsiElement[] allElementsToDelete, List result ) { LightClassUtil.PropertyAccessorsPsiMethods propertyMethods = LightClassUtil.getLightClassPropertyMethods(property); @@ -248,20 +257,22 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { overridingMethods.addAll(setterOverriding); overridingMethods = difference(overridingMethods, allElementsToDelete); - for (PsiReference reference : references) { - PsiElement element = reference.getElement(); - if (!isInside(element, allElementsToDelete) && !isInside(element, overridingMethods)) { - JetImportDirective importDirective = PsiTreeUtil.getParentOfType(element, JetImportDirective.class, false); - if (importDirective != null) { - result.add(new SafeDeleteImportDirectiveUsageInfo(importDirective, property)); - } - else { - result.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, property, false)); - } - } - } + processDeclarationUsages(property, allElementsToDelete, result, references, overridingMethods); - HashMap> methodToReferences = new HashMap>(); + Map> methodToReferences = getOverridingUsagesMap(overridingMethods); + Set safeGetterOverriding = + filterSafeOverridingMethods(getter, references, getterOverriding, methodToReferences, result, allElementsToDelete); + Set safeSetterOverriding = + filterSafeOverridingMethods(setter, references, setterOverriding, methodToReferences, result, allElementsToDelete); + + List ignoredElements = new ArrayList(safeGetterOverriding); + ignoredElements.addAll(safeSetterOverriding); + ContainerUtil.addAll(ignoredElements, allElementsToDelete); + return getSearchInfo(property, ignoredElements); + } + + private static Map> getOverridingUsagesMap(List overridingMethods) { + Map> methodToReferences = new HashMap>(); for (PsiMethod overridingMethod : overridingMethods) { Collection overridingReferences = ReferencesSearch.search( @@ -269,26 +280,10 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { ).findAll(); methodToReferences.put(overridingMethod, overridingReferences); } - final Set safeGetterOverriding = - filterSafeOverridingMethods(getter, references, getterOverriding, methodToReferences, result, allElementsToDelete); - final Set safeSetterOverriding = - filterSafeOverridingMethods(setter, references, setterOverriding, methodToReferences, result, allElementsToDelete); - - return new NonCodeUsageSearchInfo( - new Condition() { - @Override - public boolean value(PsiElement usage) { - if (usage instanceof JetFile) return false; - return isInside(usage, allElementsToDelete) - || isInside(usage, safeGetterOverriding) - || isInside(usage, safeSetterOverriding) ; - } - }, - property - ); + return methodToReferences; } - protected static NonCodeUsageSearchInfo findLocalPropertyUsages( + protected static NonCodeUsageSearchInfo findLocalVariableUsages( final JetProperty property, final PsiElement[] allElementsToDelete, final List result @@ -304,7 +299,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { } }); - return getDefaultNonCodeUsageSearchInfo(property, allElementsToDelete); + return getSearchInfo(property, allElementsToDelete); } /* @@ -314,7 +309,8 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { */ private static Set filterSafeOverridingMethods( PsiMethod originalMethod, Collection originalReferences, - Collection overridingMethods, HashMap> methodToReferences, + Collection overridingMethods, + Map> methodToReferences, List usages, PsiElement[] allElementsToDelete ) { @@ -366,7 +362,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { @SuppressWarnings("MethodOverridesPrivateMethodOfSuperclass") private static boolean isMultipleInterfacesImplementation(PsiMethod method, PsiMethod originalMethod, PsiElement[] ignore) { PsiMethod[] methods = method.findSuperMethods(); - for (PsiMethod superMethod: methods) { + for (PsiMethod superMethod : methods) { PsiElement relevantElement = superMethod instanceof JetClsMethod ? ((JetClsMethod) superMethod).getOrigin() : superMethod; relevantElement = JetPsiUtil.ascendIfPropertyAccessor(relevantElement); if (ArrayUtilRt.find(ignore, relevantElement) < 0 && !MethodSignatureUtil.isSuperMethod(originalMethod, superMethod)) { @@ -495,7 +491,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { result.addAll(overridingMethodUsages); } else { - KotlinOverridingMethodsDialog dialog = new KotlinOverridingMethodsDialog(project, overridingMethodUsages); + KotlinOverridingDialog dialog = new KotlinOverridingDialog(project, overridingMethodUsages); dialog.show(); if (!dialog.isOK()) return null; result.addAll(dialog.getSelected()); @@ -562,15 +558,16 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { private static boolean checkPsiMethodEquality(PsiMethod method1, PsiMethod method2) { if (method1 instanceof JetClsMethod && method2 instanceof JetClsMethod) { - return ((JetClsMethod) method1).getOrigin() == ((JetClsMethod) method2).getOrigin(); + return ((JetClsMethod) method1).getOrigin().equals(((JetClsMethod) method2).getOrigin()); } - return method1 == method2; + return method1.equals(method2); } private static void cleanUpOverrides(PsiMethod method) { Collection superMethods = Arrays.asList(method.findSuperMethods(true)); Collection overridingMethods = OverridingMethodsSearch.search(method, true).findAll(); - overrideLoop: for (PsiMethod overridingMethod : overridingMethods) { + overrideLoop: + for (PsiMethod overridingMethod : overridingMethods) { PsiElement overridingElement = overridingMethod instanceof JetClsMethod ? ((JetClsMethod) overridingMethod).getOrigin() : overridingMethod; @@ -578,7 +575,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { Collection currentSuperMethods = new ArrayList(); ContainerUtil.addAll(currentSuperMethods, overridingMethod.findSuperMethods(true)); currentSuperMethods.addAll(superMethods); - for (PsiMethod superMethod: currentSuperMethods) { + for (PsiMethod superMethod : currentSuperMethods) { if (!checkPsiMethodEquality(superMethod, method)) continue overrideLoop; } diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinReferencesSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinReferencesSearcher.java index dcd74e77463..b9c5c3ca203 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinReferencesSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinReferencesSearcher.java @@ -47,8 +47,6 @@ public class KotlinReferencesSearcher extends QueryExecutorBase consumer) { PsiElement element = queryParameters.getElementToSearch();