Show call sites of overriden members in "Caller Hierarchy"
#KT-4395 Fixed
This commit is contained in:
+37
-11
@@ -29,9 +29,10 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.FilteringProcessor;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.asJava.LightClassUtil;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
@@ -40,8 +41,7 @@ import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.plugin.references.JetPsiReference;
|
||||
import org.jetbrains.jet.plugin.search.usagesSearch.UsagesSearchPackage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStructure {
|
||||
private static class WithLocalRoot extends KotlinCallerMethodsTreeStructure {
|
||||
@@ -110,17 +110,18 @@ public abstract class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStr
|
||||
Object[] javaCallers = null;
|
||||
if (element instanceof PsiMethod) {
|
||||
javaCallers = javaTreeStructure.getChildElements(getJavaNodeDescriptor(descriptor));
|
||||
processPsiMethodCallers((PsiMethod) element, descriptor, methodToDescriptorMap, searchScope, true);
|
||||
processPsiMethodCallers(
|
||||
Collections.singleton((PsiMethod) element), descriptor, methodToDescriptorMap, searchScope, true
|
||||
);
|
||||
}
|
||||
if (element instanceof JetNamedFunction) {
|
||||
PsiMethod lightMethod = LightClassUtil.getLightClassMethod((JetNamedFunction) element);
|
||||
processPsiMethodCallers(lightMethod, descriptor, methodToDescriptorMap, searchScope, false);
|
||||
processPsiMethodCallers(Collections.singleton(lightMethod), descriptor, methodToDescriptorMap, searchScope, false);
|
||||
}
|
||||
if (element instanceof JetProperty) {
|
||||
LightClassUtil.PropertyAccessorsPsiMethods propertyMethods =
|
||||
LightClassUtil.getLightClassPropertyMethods((JetProperty) element);
|
||||
processPsiMethodCallers(propertyMethods.getGetter(), descriptor, methodToDescriptorMap, searchScope, false);
|
||||
processPsiMethodCallers(propertyMethods.getSetter(), descriptor, methodToDescriptorMap, searchScope, false);
|
||||
processPsiMethodCallers(propertyMethods, descriptor, methodToDescriptorMap, searchScope, false);
|
||||
}
|
||||
if (element instanceof JetClassOrObject) {
|
||||
processJetClassOrObjectCallers((JetClassOrObject) element, descriptor, methodToDescriptorMap, searchScope);
|
||||
@@ -131,15 +132,40 @@ public abstract class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStr
|
||||
}
|
||||
|
||||
private void processPsiMethodCallers(
|
||||
@Nullable PsiMethod lightMethod,
|
||||
Iterable<PsiMethod> lightMethods,
|
||||
HierarchyNodeDescriptor descriptor,
|
||||
Map<PsiElement, HierarchyNodeDescriptor> methodToDescriptorMap,
|
||||
SearchScope searchScope,
|
||||
boolean kotlinOnly
|
||||
) {
|
||||
if (lightMethod == null) return;
|
||||
MethodReferencesSearch.search(lightMethod, searchScope, true)
|
||||
.forEach(defaultQueryProcessor(descriptor, methodToDescriptorMap, kotlinOnly));
|
||||
Set<PsiMethod> methodsToFind = new HashSet<PsiMethod>();
|
||||
for (PsiMethod lightMethod : lightMethods) {
|
||||
if (lightMethod == null) continue;
|
||||
|
||||
PsiMethod[] superMethods = lightMethod.findDeepestSuperMethods();
|
||||
methodsToFind.add(lightMethod);
|
||||
ContainerUtil.addAll(methodsToFind, superMethods);
|
||||
}
|
||||
|
||||
if (methodsToFind.isEmpty()) return;
|
||||
|
||||
Set<PsiReference> references = ContainerUtil.newTroveSet(
|
||||
new TObjectHashingStrategy<PsiReference>() {
|
||||
@Override
|
||||
public int computeHashCode(PsiReference object) {
|
||||
return object.getElement().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(PsiReference o1, PsiReference o2) {
|
||||
return o1.getElement().equals(o2.getElement());
|
||||
}
|
||||
}
|
||||
);
|
||||
for (PsiMethod superMethod: methodsToFind) {
|
||||
ContainerUtil.addAll(references, MethodReferencesSearch.search(superMethod, searchScope, true));
|
||||
}
|
||||
ContainerUtil.process(references, defaultQueryProcessor(descriptor, methodToDescriptorMap, kotlinOnly));
|
||||
}
|
||||
|
||||
private void processJetClassOrObjectCallers(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<node text="KA.foo(String) ()" base="true">
|
||||
<node text="KClient.bar() ()"/>
|
||||
<node text="KClient.getBar() ()"/>
|
||||
<node text="KClient(2 usages) ()"/>
|
||||
<node text="JA.foo() ()"/>
|
||||
<node text="JA ()"/>
|
||||
<node text="JA(2 usages) ()"/>
|
||||
<node text="JA.foo()(2 usages) ()"/>
|
||||
<node text="KClient(4 usages) ()"/>
|
||||
<node text="KClient.bar()(2 usages) ()"/>
|
||||
<node text="KClient.getBar()(2 usages) ()"/>
|
||||
</node>
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
class KA {
|
||||
public final String name = "A"
|
||||
class KBase {
|
||||
public String foo(String s) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
class KA extends KBase {
|
||||
public final String name = "A";
|
||||
|
||||
@Override
|
||||
public final String <caret>foo(String s) {
|
||||
return "A " + s;
|
||||
}
|
||||
@@ -8,16 +15,17 @@ class KA {
|
||||
|
||||
class KClient {
|
||||
{
|
||||
new KBase().foo("");
|
||||
new KA().foo("");
|
||||
}
|
||||
|
||||
public static final String a = new KA().foo("");
|
||||
public static final String a = new KBase().foo("") + new KA().foo("");
|
||||
|
||||
public final String getBar() {
|
||||
return new KA().foo("");
|
||||
return new KBase().foo("") + new KA().foo("");
|
||||
}
|
||||
|
||||
public final String bar() {
|
||||
return new KA().foo("");
|
||||
return new KBase().foo("") + new KA().foo("");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
open class JA() {
|
||||
public var name: String = KA().foo("")
|
||||
public var name: String = KBase().foo("") + KA().foo("")
|
||||
|
||||
public open fun foo(): String {
|
||||
return KA().foo("")
|
||||
return KBase().foo("") + KA().foo("")
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -1,12 +1,12 @@
|
||||
<node text="KA.foo(String) ()" base="true">
|
||||
<node text="KClientObj ()"/>
|
||||
<node text="JA.foo() ()"/>
|
||||
<node text="packageFun(String) ()"/>
|
||||
<node text="KClient ()"/>
|
||||
<node text="KClient ()"/>
|
||||
<node text="bar.localFun() ()"/>
|
||||
<node text="KClient.bar() ()"/>
|
||||
<node text="KClient.bar ()"/>
|
||||
<node text="main0.kt ()"/>
|
||||
<node text="JA ()"/>
|
||||
<node text="JA(2 usages) ()"/>
|
||||
<node text="JA.foo()(2 usages) ()"/>
|
||||
<node text="KClient(2 usages) ()"/>
|
||||
<node text="KClient(2 usages) ()"/>
|
||||
<node text="KClient.bar()(2 usages) ()"/>
|
||||
<node text="KClient.bar(2 usages) ()"/>
|
||||
<node text="KClientObj(2 usages) ()"/>
|
||||
<node text="bar.localFun()(2 usages) ()"/>
|
||||
<node text="main0.kt(2 usages) ()"/>
|
||||
<node text="packageFun(String)(2 usages) ()"/>
|
||||
</node>
|
||||
|
||||
@@ -1,31 +1,37 @@
|
||||
class KA {
|
||||
val name = "A"
|
||||
fun <caret>foo(s: String): String = "A: $s"
|
||||
open class KBase {
|
||||
open fun foo(s: String): String = s
|
||||
}
|
||||
|
||||
fun packageFun(s: String): String = KA().foo(s)
|
||||
class KA: KBase() {
|
||||
val name = "A"
|
||||
override fun <caret>foo(s: String): String = "A: $s"
|
||||
}
|
||||
|
||||
val packageVal = KA().foo("")
|
||||
fun packageFun(s: String): String = KBase().foo("") + KA().foo(s)
|
||||
|
||||
val packageVal = KBase().foo("") + KA().foo("")
|
||||
|
||||
class KClient {
|
||||
{
|
||||
KA().foo("")
|
||||
KBase().foo("")
|
||||
}
|
||||
|
||||
class object {
|
||||
val a = KA().foo("")
|
||||
val a = KBase().foo("") + KA().foo("")
|
||||
}
|
||||
|
||||
val bar: String
|
||||
get() = KA().foo("")
|
||||
get() = KBase().foo("") + KA().foo("")
|
||||
|
||||
fun bar() {
|
||||
fun localFun() = KA().foo("")
|
||||
fun localFun() = KBase().foo("") + KA().foo("")
|
||||
|
||||
KA().foo("")
|
||||
KBase().foo("")
|
||||
}
|
||||
}
|
||||
|
||||
object KClientObj {
|
||||
val a = KA().foo("")
|
||||
val a = KBase().foo("") + KA().foo("")
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
class JA {
|
||||
public String name = new KA().foo("");
|
||||
public String name = new KBase().foo("") + new KA().foo("");
|
||||
|
||||
public String foo() {
|
||||
return new KA().foo("");
|
||||
return new KBase().foo("") + new KA().foo("");
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
<node text="KA.name ()" base="true">
|
||||
<node text="JA(2 usages) ()"/>
|
||||
<node text="JA.getName()(2 usages) ()"/>
|
||||
<node text="KClient(2 usages) ()"/>
|
||||
<node text="main0.kt(2 usages) ()"/>
|
||||
<node text="KClient(2 usages) ()"/>
|
||||
<node text="packageFun(String)(2 usages) ()"/>
|
||||
<node text="KClient.bar()(2 usages) ()"/>
|
||||
<node text="KClient.bar(4 usages) ()"/>
|
||||
<node text="KClientObj(4 usages) ()"/>
|
||||
<node text="bar.localFun()(2 usages) ()"/>
|
||||
<node text="KClient.bar(4 usages) ()"/>
|
||||
<node text="JA.getName() ()"/>
|
||||
<node text="KClient.bar()(2 usages) ()"/>
|
||||
<node text="JA ()"/>
|
||||
<node text="main0.kt(2 usages) ()"/>
|
||||
<node text="packageFun(String)(2 usages) ()"/>
|
||||
</node>
|
||||
|
||||
@@ -1,35 +1,44 @@
|
||||
class KA {
|
||||
var <caret>name = "A"
|
||||
open class KBase {
|
||||
open var name = ""
|
||||
}
|
||||
|
||||
class KA: KBase() {
|
||||
override var <caret>name = "A"
|
||||
fun foo(s: String): String = "A: $s"
|
||||
}
|
||||
|
||||
fun packageFun(s: String): String = KA().name
|
||||
fun packageFun(s: String): String = KBase().name + KA().name
|
||||
|
||||
val packageVal = KA().name
|
||||
val packageVal = KBase().name + KA().name
|
||||
|
||||
class KClient {
|
||||
{
|
||||
KBase().name = ""
|
||||
KA().name = ""
|
||||
}
|
||||
|
||||
class object {
|
||||
val a = KA().name
|
||||
val a = KBase().name + KA().name
|
||||
}
|
||||
|
||||
val bar: String
|
||||
get() = KA().name
|
||||
set(value: String) {KA().name = value}
|
||||
var bar: String
|
||||
get() = KBase().name + KA().name
|
||||
set(value: String) {
|
||||
KBase().name = value
|
||||
KA().name = value
|
||||
}
|
||||
|
||||
fun bar() {
|
||||
fun localFun() = KA().name
|
||||
fun localFun() = KBase().name + KA().name
|
||||
|
||||
val s = KA().name
|
||||
val s = KBase().name + KA().name
|
||||
}
|
||||
}
|
||||
|
||||
object KClientObj {
|
||||
val a = KA().name
|
||||
val a = KBase().name + KA().name
|
||||
{
|
||||
KBase().name = ""
|
||||
KA().name = ""
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
class JA {
|
||||
public String name = new KA().getName();
|
||||
public String name = new KBase().getName() + new KA().getName();
|
||||
|
||||
public String getName() {
|
||||
return new KA().getName();
|
||||
return new KBase().getName() + new KA().getName();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user