diff --git a/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindUsagesHandlerFactory.java b/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindUsagesHandlerFactory.java index 276075ebf9e..4c358f5993b 100644 --- a/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindUsagesHandlerFactory.java +++ b/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindUsagesHandlerFactory.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.findUsages.handlers.KotlinFindClassUsagesHandler import org.jetbrains.jet.plugin.findUsages.handlers.KotlinFindFunctionUsagesHandler; import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil; -import java.util.Collection; +import java.util.List; public class KotlinFindUsagesHandlerFactory extends FindUsagesHandlerFactory { private final KotlinMethodFindUsagesOptions findMethodOptions; @@ -61,13 +61,14 @@ public class KotlinFindUsagesHandlerFactory extends FindUsagesHandlerFactory { } if (element instanceof JetNamedFunction) { if (!forHighlightUsages) { - Collection methods = + List methods = JetRefactoringUtil.checkSuperMethods((JetDeclaration) element, null, "super.methods.action.key.find.usages"); if (methods == null || methods.isEmpty()) return FindUsagesHandler.NULL_HANDLER; if (methods.size() > 1) { return new KotlinFindFunctionUsagesHandler((JetNamedFunction) element, methods, this); } + return new KotlinFindFunctionUsagesHandler((JetNamedFunction) methods.get(0), this); } return new KotlinFindFunctionUsagesHandler((JetNamedFunction) element, this); diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java index 652068d68a7..b089e8bfc9b 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java @@ -25,6 +25,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.search.searches.DeepestSuperMethodsSearch; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.psi.util.PsiFormatUtilBase; import com.intellij.ui.components.JBList; @@ -32,6 +33,7 @@ import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.asJava.LightClassUtil; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -112,43 +114,81 @@ public class JetRefactoringUtil { return markAsJava ? "[Java] " + description : description; } + private static PsiElement toJetDeclarationOrMethod(PsiMethod method) { + return (method instanceof JetClsMethod) ? ((JetClsMethod) method).getOrigin() : method; + } + + @NotNull + private static List getFunctionSuperDeclarations(@NotNull JetNamedFunction function) { + PsiMethod lightMethod = LightClassUtil.getLightClassMethod(function); + if (lightMethod == null) return Collections.emptyList(); + + return ContainerUtil.map( + DeepestSuperMethodsSearch.search(lightMethod).findAll(), + new Function() { + @Override + public PsiElement fun(PsiMethod method) { + return toJetDeclarationOrMethod(method); + } + } + ); + } + + @NotNull + private static List getPropertySuperDeclarations(@NotNull JetProperty property) { + LightClassUtil.PropertyAccessorsPsiMethods lightMethods = LightClassUtil.getLightClassPropertyMethods(property); + + Collection foundMethods = new HashSet(); + if (lightMethods.getGetter() != null) { + foundMethods.addAll(DeepestSuperMethodsSearch.search(lightMethods.getGetter()).findAll()); + } + if (lightMethods.getSetter() != null) { + foundMethods.addAll(DeepestSuperMethodsSearch.search(lightMethods.getSetter()).findAll()); + } + + Set declarations = new HashSet(); + for (PsiMethod method : foundMethods) { + declarations.add(toJetDeclarationOrMethod(method)); + } + + return new ArrayList(declarations); + } + + @NotNull + private static List getSuperDeclarations(@NotNull JetDeclaration declaration) { + if (declaration instanceof JetNamedFunction) return getFunctionSuperDeclarations((JetNamedFunction) declaration); + if (declaration instanceof JetProperty) return getPropertySuperDeclarations((JetProperty) declaration); + return Collections.emptyList(); + } + @Nullable - public static Collection checkSuperMethods( + public static List checkSuperMethods( @NotNull JetDeclaration declaration, @Nullable Collection ignore, @NotNull String actionStringKey ) { - final BindingContext bindingContext = + BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) declaration.getContainingFile()).getBindingContext(); DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration); if (!(declarationDescriptor instanceof CallableMemberDescriptor)) return null; CallableMemberDescriptor callableDescriptor = (CallableMemberDescriptor) declarationDescriptor; - Set overridenDescriptors = callableDescriptor.getOverriddenDescriptors(); - Collection superMethods = ContainerUtil.map( - overridenDescriptors, - new Function() { - @Override - public PsiElement fun(CallableMemberDescriptor descriptor) { - return BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); - } - } - ); + List superDeclarations = getSuperDeclarations(declaration); if (ignore != null) { - superMethods.removeAll(ignore); + superDeclarations.removeAll(ignore); } - if (superMethods.isEmpty()) return Collections.singletonList(declaration); + if (superDeclarations.isEmpty()) return Collections.singletonList(declaration); - java.util.List superClasses = getClassDescriptions(bindingContext, superMethods); - return askUserForMethodsToSearch(declaration, callableDescriptor, superMethods, superClasses, actionStringKey); + java.util.List superClasses = getClassDescriptions(bindingContext, superDeclarations); + return askUserForMethodsToSearch(declaration, callableDescriptor, superDeclarations, superClasses, actionStringKey); } @NotNull - private static Collection askUserForMethodsToSearch( + private static List askUserForMethodsToSearch( @NotNull JetDeclaration declaration, @NotNull CallableMemberDescriptor callableDescriptor, - @NotNull Collection superMethods, + @NotNull List superMethods, @NotNull List superClasses, @NotNull String actionStringKey ) {