Find Usages: Show class-specific dialog for all Kotlin classes (including bultins)

#KT-7048 Fixed
This commit is contained in:
Alexey Sedunov
2015-05-12 14:32:33 +03:00
parent 02006126f5
commit 3e620dbbbb
2 changed files with 73 additions and 17 deletions
@@ -21,15 +21,24 @@ import com.intellij.find.findUsages.FindClassUsagesDialog;
import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.find.findUsages.JavaClassFindUsagesOptions;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiModifier;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.StateRestoringCheckBox;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.asJava.KotlinLightClassForExplicitDeclaration;
import org.jetbrains.kotlin.asJava.AsJavaPackage;
import org.jetbrains.kotlin.asJava.LightClassUtil;
import org.jetbrains.kotlin.idea.JetBundle;
import org.jetbrains.kotlin.idea.findUsages.KotlinClassFindUsagesOptions;
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil;
import org.jetbrains.kotlin.psi.JetClass;
import org.jetbrains.kotlin.psi.JetClassOrObject;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
import javax.swing.*;
@@ -39,7 +48,7 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
private StateRestoringCheckBox derivedTraits;
public KotlinFindClassUsagesDialog(
PsiClass klass,
JetClassOrObject classOrObject,
Project project,
FindUsagesOptions findUsagesOptions,
boolean toShowInNewTab,
@@ -47,7 +56,47 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
boolean isSingleFile,
FindUsagesHandler handler
) {
super(klass, project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, handler);
super(getRepresentingPsiClass(classOrObject), project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, handler);
}
private static final Key<JetClassOrObject> ORIGINAL_CLASS = Key.create("ORIGINAL_CLASS");
@NotNull
private static PsiClass getRepresentingPsiClass(@NotNull JetClassOrObject classOrObject) {
PsiClass lightClass = LightClassUtil.getPsiClass(classOrObject);
if (lightClass != null) return lightClass;
// TODO: Remove this code when light classes are generated for builtins
PsiElementFactory factory = PsiElementFactory.SERVICE.getInstance(classOrObject.getProject());
String name = classOrObject.getName();
if (name == null || name.isEmpty()) {
name = "Anonymous";
}
PsiClass javaClass;
if (classOrObject instanceof JetClass) {
JetClass klass = (JetClass) classOrObject;
javaClass = !klass.isInterface()
? factory.createClass(name)
: klass.isAnnotation()
? factory.createAnnotationType(name)
: factory.createInterface(name);
}
else {
javaClass = factory.createClass(name);
}
//noinspection ConstantConditions
javaClass.getModifierList().setModifierProperty(
PsiModifier.FINAL,
!(classOrObject instanceof JetClass && PsiUtilPackage.isInheritable((JetClass) classOrObject))
);
javaClass.putUserData(ORIGINAL_CLASS, classOrObject);
return javaClass;
}
@Override
@@ -98,9 +147,14 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
@Override
public void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent) {
PsiClass klass = (PsiClass) getPsiElement();
if (klass instanceof KotlinLightClassForExplicitDeclaration) {
coloredComponent.append(JetRefactoringUtil.formatClass(((KotlinLightClassForExplicitDeclaration) klass).getOrigin()));
PsiElement klass = AsJavaPackage.getUnwrapped(getPsiElement());
//noinspection ConstantConditions
JetClassOrObject originalClass = klass instanceof JetClassOrObject
? (JetClassOrObject) klass
: klass.getUserData(ORIGINAL_CLASS);
if (originalClass != null) {
coloredComponent.append(JetRefactoringUtil.formatClass(originalClass));
}
}
@@ -19,8 +19,6 @@ package org.jetbrains.kotlin.idea.findUsages.handlers
import com.intellij.find.findUsages.AbstractFindUsagesDialog
import com.intellij.find.findUsages.FindUsagesOptions
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.search.PsiElementProcessor
import com.intellij.psi.search.PsiElementProcessorAdapter
import com.intellij.usageView.UsageInfo
@@ -40,12 +38,14 @@ import org.jetbrains.kotlin.idea.util.application.runReadAction
import java.util.Collections
import com.intellij.find.findUsages.JavaFindUsagesHandler
import com.intellij.find.findUsages.JavaFindUsagesHandlerFactory
import com.intellij.psi.PsiMethod
import com.intellij.psi.*
import com.intellij.psi.search.searches.MethodReferencesSearch
import com.intellij.util.CommonProcessors
import org.jetbrains.kotlin.asJava.KotlinLightMethod
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstructorUsages
import org.jetbrains.kotlin.psi.JetClass
import org.jetbrains.kotlin.psi.psiUtil.isInheritable
public class KotlinFindClassUsagesHandler(
jetClass: JetClassOrObject,
@@ -54,20 +54,22 @@ public class KotlinFindClassUsagesHandler(
public override fun getFindUsagesDialog(
isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean
): AbstractFindUsagesDialog {
val lightClass = LightClassUtil.getPsiClass(getElement())
if (lightClass != null) {
return KotlinFindClassUsagesDialog(lightClass, getProject(), getFactory().findClassOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, this)
}
return super.getFindUsagesDialog(isSingleFile, toShowInNewTab, mustOpenInNewTab)
return KotlinFindClassUsagesDialog(getElement(),
getProject(),
getFactory().findClassOptions,
toShowInNewTab,
mustOpenInNewTab,
isSingleFile,
this)
}
protected override fun searchReferences(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Boolean {
val kotlinOptions = options as KotlinClassFindUsagesOptions
fun processInheritors(): Boolean {
val request = HierarchySearchRequest(element, options.searchScope!!, options.isCheckDeepInheritance)
val request = HierarchySearchRequest(element, options.searchScope, options.isCheckDeepInheritance)
return request.searchInheritors().forEach(
PsiElementProcessorAdapter<PsiClass>(
PsiElementProcessorAdapter(
object : PsiElementProcessor<PsiClass> {
public override fun execute(element: PsiClass): Boolean {
val traitOrInterface = element.isInterface()