Call Hierarchy: Add support of local declarations
This commit is contained in:
@@ -1029,4 +1029,16 @@ public class JetPsiUtil {
|
|||||||
|
|
||||||
return header != null ? header.getQualifiedName() : null;
|
return header != null ? header.getQualifiedName() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JetElement getLocalizingCodeBlock(@NotNull JetNamedDeclaration declaration) {
|
||||||
|
//noinspection unchecked
|
||||||
|
JetDeclaration container =
|
||||||
|
PsiTreeUtil.getParentOfType(declaration, JetNamedFunction.class, JetPropertyAccessor.class, JetClassInitializer.class);
|
||||||
|
|
||||||
|
if (container == null) return null;
|
||||||
|
|
||||||
|
return (container instanceof JetClassInitializer)
|
||||||
|
? ((JetClassInitializer) container).getBody()
|
||||||
|
: ((JetDeclarationWithBody) container).getBodyExpression();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ public class HierarchyUtils {
|
|||||||
return input instanceof PsiMethod ||
|
return input instanceof PsiMethod ||
|
||||||
input instanceof PsiClass ||
|
input instanceof PsiClass ||
|
||||||
input instanceof JetFile ||
|
input instanceof JetFile ||
|
||||||
(input instanceof JetNamedFunction && !((JetNamedFunction) input).isLocal()) ||
|
input instanceof JetNamedFunction ||
|
||||||
input instanceof JetClassOrObject ||
|
input instanceof JetClassOrObject ||
|
||||||
(input instanceof JetProperty && !((JetProperty) input).isLocal());
|
input instanceof JetProperty;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.plugin.hierarchy.calls;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiMethod;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
|
|
||||||
|
public abstract class CalleeReferenceVisitorBase extends JetTreeVisitorVoid {
|
||||||
|
private final BindingContext bindingContext;
|
||||||
|
private final boolean deepTraversal;
|
||||||
|
|
||||||
|
protected CalleeReferenceVisitorBase(BindingContext bindingContext, boolean deepTraversal) {
|
||||||
|
this.bindingContext = bindingContext;
|
||||||
|
this.deepTraversal = deepTraversal;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void processDeclaration(JetReferenceExpression reference, PsiElement declaration);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJetElement(JetElement element) {
|
||||||
|
if (deepTraversal || !(element instanceof JetClassOrObject || element instanceof JetNamedFunction)) {
|
||||||
|
super.visitJetElement(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSimpleNameExpression(JetSimpleNameExpression expression) {
|
||||||
|
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
|
||||||
|
if (descriptor == null) return;
|
||||||
|
|
||||||
|
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
||||||
|
if (declaration == null) return;
|
||||||
|
|
||||||
|
if (isProperty(descriptor, declaration) || isCallable(descriptor, declaration, expression)) {
|
||||||
|
processDeclaration(expression, declaration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept callees of JetCallElement which refer to Kotlin function, Kotlin class or Java method
|
||||||
|
private static boolean isCallable(DeclarationDescriptor descriptor, PsiElement declaration, JetSimpleNameExpression reference) {
|
||||||
|
JetCallElement callElement = PsiTreeUtil.getParentOfType(reference, JetCallElement.class);
|
||||||
|
if (callElement == null || !PsiTreeUtil.isAncestor(callElement.getCalleeExpression(), reference, false)) return false;
|
||||||
|
|
||||||
|
return descriptor instanceof FunctionDescriptor
|
||||||
|
&& (declaration instanceof JetClassOrObject
|
||||||
|
|| declaration instanceof JetNamedFunction
|
||||||
|
|| declaration instanceof PsiMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept only properties (not local variables or references to Java fields)
|
||||||
|
private static boolean isProperty(DeclarationDescriptor descriptor, PsiElement declaration) {
|
||||||
|
return descriptor instanceof PropertyDescriptor && declaration instanceof JetProperty;
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-2
@@ -12,8 +12,10 @@ import com.intellij.openapi.util.Comparing;
|
|||||||
import com.intellij.openapi.util.Iconable;
|
import com.intellij.openapi.util.Iconable;
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.pom.Navigatable;
|
import com.intellij.pom.Navigatable;
|
||||||
import com.intellij.psi.PsiClass;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.presentation.java.ClassPresentationUtil;
|
||||||
|
import com.intellij.psi.util.PsiFormatUtil;
|
||||||
|
import com.intellij.psi.util.PsiFormatUtilBase;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import com.intellij.ui.LayeredIcon;
|
import com.intellij.ui.LayeredIcon;
|
||||||
import com.intellij.util.Function;
|
import com.intellij.util.Function;
|
||||||
|
|||||||
@@ -8,14 +8,48 @@ import com.intellij.psi.PsiClass;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiMethod;
|
import com.intellij.psi.PsiMethod;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.util.containers.HashMap;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.asJava.LightClassUtil;
|
import org.jetbrains.jet.asJava.LightClassUtil;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure {
|
public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure {
|
||||||
public KotlinCallTreeStructure(@NotNull Project project, HierarchyNodeDescriptor baseDescriptor) {
|
protected final String scopeType;
|
||||||
super(project, baseDescriptor);
|
protected final JetElement localizingCodeBlock;
|
||||||
|
protected final PsiMethod basePsiMethod;
|
||||||
|
protected final PsiClass basePsiClass;
|
||||||
|
|
||||||
|
public KotlinCallTreeStructure(@NotNull Project project, PsiElement element, String scopeType) {
|
||||||
|
super(project, createNodeDescriptor(project, element, null));
|
||||||
|
|
||||||
|
this.scopeType = scopeType;
|
||||||
|
|
||||||
|
localizingCodeBlock = element instanceof JetNamedDeclaration
|
||||||
|
? JetPsiUtil.getLocalizingCodeBlock((JetNamedDeclaration) element)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (localizingCodeBlock == null) {
|
||||||
|
basePsiMethod = getPsiMethod(element);
|
||||||
|
assert basePsiMethod != null;
|
||||||
|
|
||||||
|
basePsiClass = basePsiMethod.getContainingClass();
|
||||||
|
assert basePsiClass != null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
basePsiMethod = null;
|
||||||
|
basePsiClass = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HierarchyNodeDescriptor createNodeDescriptor(Project project, PsiElement element, HierarchyNodeDescriptor parent) {
|
||||||
|
boolean root = (parent == null);
|
||||||
|
return element instanceof JetElement
|
||||||
|
? new KotlinCallHierarchyNodeDescriptor(project, parent, element, root, false)
|
||||||
|
: new CallHierarchyNodeDescriptor(project, parent, element, root, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static PsiElement getTargetElement(HierarchyNodeDescriptor descriptor) {
|
protected static PsiElement getTargetElement(HierarchyNodeDescriptor descriptor) {
|
||||||
@@ -24,17 +58,6 @@ public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure {
|
|||||||
: ((KotlinCallHierarchyNodeDescriptor)descriptor).getTargetElement();
|
: ((KotlinCallHierarchyNodeDescriptor)descriptor).getTargetElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected PsiMethod getBasePsiMethod() {
|
|
||||||
return getPsiMethod(((KotlinCallHierarchyNodeDescriptor) getBaseDescriptor()).getTargetElement());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected PsiClass getBasePsiClass() {
|
|
||||||
PsiMethod method = getBasePsiMethod();
|
|
||||||
return method != null ? method.getContainingClass() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PsiMethod getClosestContainingClassConstructor(PsiElement element) {
|
private static PsiMethod getClosestContainingClassConstructor(PsiElement element) {
|
||||||
while (element != null) {
|
while (element != null) {
|
||||||
JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(element, JetClassOrObject.class, false);
|
JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(element, JetClassOrObject.class, false);
|
||||||
@@ -53,7 +76,9 @@ public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected static PsiMethod getPsiMethod(PsiElement element) {
|
protected final PsiMethod getPsiMethod(PsiElement element) {
|
||||||
|
assert localizingCodeBlock == null : "Can't build light method for local declaration";
|
||||||
|
|
||||||
if (element instanceof PsiMethod) {
|
if (element instanceof PsiMethod) {
|
||||||
return (PsiMethod) element;
|
return (PsiMethod) element;
|
||||||
}
|
}
|
||||||
@@ -77,12 +102,6 @@ public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure {
|
|||||||
return method != null ? method : getClosestContainingClassConstructor(element);
|
return method != null ? method : getClosestContainingClassConstructor(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected static PsiClass getPsiClass(PsiElement element) {
|
|
||||||
PsiMethod method = getPsiMethod(element);
|
|
||||||
return method != null ? method.getContainingClass() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static CallHierarchyNodeDescriptor getJavaNodeDescriptor(HierarchyNodeDescriptor originalDescriptor) {
|
protected static CallHierarchyNodeDescriptor getJavaNodeDescriptor(HierarchyNodeDescriptor originalDescriptor) {
|
||||||
if (originalDescriptor instanceof CallHierarchyNodeDescriptor) return (CallHierarchyNodeDescriptor) originalDescriptor;
|
if (originalDescriptor instanceof CallHierarchyNodeDescriptor) return (CallHierarchyNodeDescriptor) originalDescriptor;
|
||||||
|
|
||||||
@@ -90,6 +109,36 @@ public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure {
|
|||||||
return ((KotlinCallHierarchyNodeDescriptor) originalDescriptor).getJavaDelegate();
|
return ((KotlinCallHierarchyNodeDescriptor) originalDescriptor).getJavaDelegate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final Object[] collectNodeDescriptors(HierarchyNodeDescriptor descriptor, List<? extends PsiElement> calleeElements) {
|
||||||
|
HashMap<PsiElement, HierarchyNodeDescriptor> declarationToDescriptorMap = new HashMap<PsiElement, HierarchyNodeDescriptor>();
|
||||||
|
for (PsiElement callee : calleeElements) {
|
||||||
|
if (basePsiClass != null && !isInScope(basePsiClass, callee, scopeType)) continue;
|
||||||
|
|
||||||
|
addNodeDescriptorForElement(callee, declarationToDescriptorMap, descriptor);
|
||||||
|
}
|
||||||
|
return declarationToDescriptorMap.values().toArray(new Object[declarationToDescriptorMap.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void addNodeDescriptorForElement(
|
||||||
|
PsiElement element,
|
||||||
|
Map<PsiElement, HierarchyNodeDescriptor> declarationToDescriptorMap,
|
||||||
|
HierarchyNodeDescriptor descriptor
|
||||||
|
) {
|
||||||
|
HierarchyNodeDescriptor d = declarationToDescriptorMap.get(element);
|
||||||
|
if (d == null) {
|
||||||
|
d = createNodeDescriptor(myProject, element, descriptor);
|
||||||
|
declarationToDescriptorMap.put(element, d);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (d instanceof CallHierarchyNodeDescriptor) {
|
||||||
|
((CallHierarchyNodeDescriptor) d).incrementUsageCount();
|
||||||
|
}
|
||||||
|
else if (d instanceof KotlinCallHierarchyNodeDescriptor) {
|
||||||
|
((KotlinCallHierarchyNodeDescriptor) d).incrementUsageCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAlwaysShowPlus() {
|
public boolean isAlwaysShowPlus() {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+13
-114
@@ -24,13 +24,9 @@ import com.intellij.psi.PsiClass;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiMethod;
|
import com.intellij.psi.PsiMethod;
|
||||||
import com.intellij.util.ArrayUtil;
|
import com.intellij.util.ArrayUtil;
|
||||||
import com.intellij.util.containers.HashMap;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod;
|
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod;
|
||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||||
|
|
||||||
@@ -38,87 +34,21 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class KotlinCalleeMethodsTreeStructure extends KotlinCallTreeStructure {
|
public class KotlinCalleeMethodsTreeStructure extends KotlinCallTreeStructure {
|
||||||
private final String scopeType;
|
private final CalleeMethodsTreeStructure javaTreeStructure;
|
||||||
private final CalleeMethodsTreeStructure javaTreeStucture;
|
|
||||||
|
|
||||||
public KotlinCalleeMethodsTreeStructure(@NotNull Project project, @NotNull PsiElement element, String scopeType) {
|
public KotlinCalleeMethodsTreeStructure(@NotNull Project project, @NotNull PsiElement element, String scopeType) {
|
||||||
super(project, new KotlinCallHierarchyNodeDescriptor(project, null, element, true, false));
|
super(project, element, scopeType);
|
||||||
this.scopeType = scopeType;
|
this.javaTreeStructure = basePsiMethod != null ? new CalleeMethodsTreeStructure(project, basePsiMethod, scopeType) : null;
|
||||||
|
|
||||||
PsiMethod psiMethod = getPsiMethod(element);
|
|
||||||
assert psiMethod != null;
|
|
||||||
|
|
||||||
this.javaTreeStucture = new CalleeMethodsTreeStructure(project, psiMethod, scopeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class VisitorBase extends JetTreeVisitorVoid {
|
|
||||||
final BindingContext bindingContext;
|
|
||||||
final ArrayList<PsiElement> result;
|
|
||||||
|
|
||||||
private VisitorBase(BindingContext bindingContext, ArrayList<PsiElement> result) {
|
|
||||||
this.bindingContext = bindingContext;
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitJetElement(JetElement element) {
|
|
||||||
if (!(element instanceof JetClassOrObject || element instanceof JetNamedFunction)) {
|
|
||||||
super.visitJetElement(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitCallExpression(JetCallExpression expression) {
|
|
||||||
super.visitCallExpression(expression);
|
|
||||||
processCallElement(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSimpleNameExpression(JetSimpleNameExpression expression) {
|
|
||||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
|
|
||||||
if (descriptor instanceof PropertyDescriptor) {
|
|
||||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
|
||||||
if (declaration instanceof JetProperty) {
|
|
||||||
result.add(declaration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDelegationSpecifier(JetDelegationSpecifier specifier) {
|
|
||||||
if (specifier instanceof JetCallElement) {
|
|
||||||
processCallElement((JetCallElement) specifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processCallElement(JetCallElement element) {
|
|
||||||
JetExpression callee = element.getCalleeExpression();
|
|
||||||
|
|
||||||
JetReferenceExpression referenceExpression = null;
|
|
||||||
if (callee instanceof JetReferenceExpression) {
|
|
||||||
referenceExpression = (JetReferenceExpression) callee;
|
|
||||||
}
|
|
||||||
else if (callee instanceof JetConstructorCalleeExpression) {
|
|
||||||
referenceExpression = ((JetConstructorCalleeExpression) callee).getConstructorReferenceExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (referenceExpression != null) {
|
|
||||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression);
|
|
||||||
if (descriptor == null) return;
|
|
||||||
|
|
||||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
|
||||||
if (declaration instanceof JetClassOrObject
|
|
||||||
|| (declaration instanceof JetNamedFunction && !((JetNamedFunction) declaration).isLocal())
|
|
||||||
|| declaration instanceof PsiMethod ) {
|
|
||||||
result.add(declaration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<? extends PsiElement> getCalleeElements(@NotNull JetElement rootElement, BindingContext bindingContext) {
|
private static List<? extends PsiElement> getCalleeElements(@NotNull JetElement rootElement, BindingContext bindingContext) {
|
||||||
ArrayList<PsiElement> result = new ArrayList<PsiElement>();
|
final ArrayList<PsiElement> result = new ArrayList<PsiElement>();
|
||||||
JetVisitorVoid visitor = new VisitorBase(bindingContext, result);
|
JetVisitorVoid visitor = new CalleeReferenceVisitorBase(bindingContext, false) {
|
||||||
|
@Override
|
||||||
|
protected void processDeclaration(JetReferenceExpression reference, PsiElement declaration) {
|
||||||
|
result.add(declaration);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (rootElement instanceof JetNamedFunction) {
|
if (rootElement instanceof JetNamedFunction) {
|
||||||
JetExpression body = ((JetNamedFunction) rootElement).getBodyExpression();
|
JetExpression body = ((JetNamedFunction) rootElement).getBodyExpression();
|
||||||
@@ -157,33 +87,6 @@ public class KotlinCalleeMethodsTreeStructure extends KotlinCallTreeStructure {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copied from Java
|
|
||||||
private Object[] collectNodeDescriptors(
|
|
||||||
HierarchyNodeDescriptor descriptor,
|
|
||||||
List<? extends PsiElement> calleeElements,
|
|
||||||
PsiElement baseElement
|
|
||||||
) {
|
|
||||||
HashMap<PsiElement, KotlinCallHierarchyNodeDescriptor> declarationToDescriptorMap =
|
|
||||||
new HashMap<PsiElement, KotlinCallHierarchyNodeDescriptor>();
|
|
||||||
|
|
||||||
ArrayList<KotlinCallHierarchyNodeDescriptor> result = new ArrayList<KotlinCallHierarchyNodeDescriptor>();
|
|
||||||
|
|
||||||
for (PsiElement callee : calleeElements) {
|
|
||||||
if (!isInScope(baseElement, callee, scopeType)) continue;
|
|
||||||
|
|
||||||
KotlinCallHierarchyNodeDescriptor d = declarationToDescriptorMap.get(callee);
|
|
||||||
if (d == null) {
|
|
||||||
d = new KotlinCallHierarchyNodeDescriptor(myProject, descriptor, callee, false, false);
|
|
||||||
declarationToDescriptorMap.put(callee, d);
|
|
||||||
result.add(d);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
d.incrementUsageCount();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ArrayUtil.toObjectArray(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object[] buildChildren(HierarchyNodeDescriptor descriptor) {
|
protected Object[] buildChildren(HierarchyNodeDescriptor descriptor) {
|
||||||
PsiElement targetElement = getTargetElement(descriptor);
|
PsiElement targetElement = getTargetElement(descriptor);
|
||||||
@@ -209,24 +112,20 @@ public class KotlinCalleeMethodsTreeStructure extends KotlinCallTreeStructure {
|
|||||||
return buildChildrenByKotlinTarget(descriptor, (JetElement) targetElement);
|
return buildChildrenByKotlinTarget(descriptor, (JetElement) targetElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (javaTreeStucture != null) {
|
if (javaTreeStructure != null) {
|
||||||
CallHierarchyNodeDescriptor javaDescriptor = descriptor instanceof CallHierarchyNodeDescriptor
|
CallHierarchyNodeDescriptor javaDescriptor = descriptor instanceof CallHierarchyNodeDescriptor
|
||||||
? (CallHierarchyNodeDescriptor) descriptor
|
? (CallHierarchyNodeDescriptor) descriptor
|
||||||
: ((KotlinCallHierarchyNodeDescriptor)descriptor).getJavaDelegate();
|
: ((KotlinCallHierarchyNodeDescriptor)descriptor).getJavaDelegate();
|
||||||
return javaTreeStucture.getChildElements(javaDescriptor);
|
return javaTreeStructure.getChildElements(javaDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object[] buildChildrenByKotlinTarget(HierarchyNodeDescriptor descriptor, JetElement targetElement) {
|
private Object[] buildChildrenByKotlinTarget(HierarchyNodeDescriptor descriptor, JetElement targetElement) {
|
||||||
PsiClass baseClass = getBasePsiClass();
|
|
||||||
if (baseClass == null) return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
|
||||||
|
|
||||||
BindingContext bindingContext =
|
BindingContext bindingContext =
|
||||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) targetElement.getContainingFile()).getBindingContext();
|
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) targetElement.getContainingFile()).getBindingContext();
|
||||||
List<? extends PsiElement> calleeDescriptors = getCalleeElements((JetElement) targetElement, bindingContext);
|
List<? extends PsiElement> calleeDescriptors = getCalleeElements((JetElement) targetElement, bindingContext);
|
||||||
|
return collectNodeDescriptors(descriptor, calleeDescriptors);
|
||||||
return collectNodeDescriptors(descriptor, calleeDescriptors, baseClass);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-13
@@ -34,38 +34,61 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.asJava.LightClassUtil;
|
import org.jetbrains.jet.asJava.LightClassUtil;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.plugin.findUsages.FindUsagesUtils;
|
import org.jetbrains.jet.plugin.findUsages.FindUsagesUtils;
|
||||||
import org.jetbrains.jet.plugin.hierarchy.HierarchyUtils;
|
import org.jetbrains.jet.plugin.hierarchy.HierarchyUtils;
|
||||||
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||||
import org.jetbrains.jet.plugin.references.JetPsiReference;
|
import org.jetbrains.jet.plugin.references.JetPsiReference;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStructure {
|
public class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStructure {
|
||||||
private final String scopeType;
|
|
||||||
private final CallerMethodsTreeStructure javaTreeStructure;
|
private final CallerMethodsTreeStructure javaTreeStructure;
|
||||||
|
|
||||||
public KotlinCallerMethodsTreeStructure(@NotNull Project project, @NotNull PsiElement element, String scopeType) {
|
public KotlinCallerMethodsTreeStructure(@NotNull Project project, @NotNull PsiElement element, String scopeType) {
|
||||||
super(project, new KotlinCallHierarchyNodeDescriptor(project, null, element, true, false));
|
super(project, element, scopeType);
|
||||||
this.scopeType = scopeType;
|
this.javaTreeStructure = basePsiMethod != null ? new CallerMethodsTreeStructure(project, basePsiMethod, scopeType) : null;
|
||||||
|
|
||||||
PsiMethod psiMethod = getPsiMethod(element);
|
|
||||||
assert psiMethod != null;
|
|
||||||
|
|
||||||
this.javaTreeStructure = new CallerMethodsTreeStructure(project, psiMethod, scopeType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object[] buildChildren(HierarchyNodeDescriptor descriptor) {
|
protected Object[] buildChildren(HierarchyNodeDescriptor descriptor) {
|
||||||
PsiElement targetElement = getTargetElement(descriptor);
|
PsiElement targetElement = getTargetElement(descriptor);
|
||||||
|
|
||||||
PsiClass baseClass = getBasePsiClass();
|
if (localizingCodeBlock != null) {
|
||||||
if (baseClass == null) return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
return buildLocalizedChildren(targetElement, (KotlinCallHierarchyNodeDescriptor) descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
return processCallers(targetElement, descriptor, baseClass);
|
return processCallers(targetElement, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object[] processCallers(PsiElement element, HierarchyNodeDescriptor descriptor, PsiClass baseClass) {
|
private Object[] buildLocalizedChildren(final PsiElement element, KotlinCallHierarchyNodeDescriptor descriptor) {
|
||||||
SearchScope searchScope = getSearchScope(scopeType, baseClass);
|
BindingContext bindingContext =
|
||||||
|
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
||||||
|
|
||||||
|
final ArrayList<PsiElement> result = new ArrayList<PsiElement>();
|
||||||
|
localizingCodeBlock.accept(new CalleeReferenceVisitorBase(bindingContext, true) {
|
||||||
|
@Override
|
||||||
|
protected void processDeclaration(JetReferenceExpression reference, PsiElement declaration) {
|
||||||
|
if (!declaration.equals(element)) return;
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
PsiElement container =
|
||||||
|
PsiTreeUtil.getParentOfType(reference, JetNamedFunction.class, JetPropertyAccessor.class, JetClassOrObject.class);
|
||||||
|
if (container instanceof JetPropertyAccessor) {
|
||||||
|
container = PsiTreeUtil.getParentOfType(container, JetProperty.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container != null) {
|
||||||
|
result.add(container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return collectNodeDescriptors(descriptor, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object[] processCallers(PsiElement element, HierarchyNodeDescriptor descriptor) {
|
||||||
|
SearchScope searchScope = getSearchScope(scopeType, basePsiClass);
|
||||||
Map<PsiElement, KotlinCallHierarchyNodeDescriptor> methodToDescriptorMap =
|
Map<PsiElement, KotlinCallHierarchyNodeDescriptor> methodToDescriptorMap =
|
||||||
new HashMap<PsiElement, KotlinCallHierarchyNodeDescriptor>();
|
new HashMap<PsiElement, KotlinCallHierarchyNodeDescriptor>();
|
||||||
|
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<node text="client.[anonymous] ()" base="true">
|
||||||
|
<node text="JA.JA()(2 usages) ()"/>
|
||||||
|
<node text="JA.foo(String) ()">
|
||||||
|
<node text="PrintStream.println(String) (java.io)"/>
|
||||||
|
</node>
|
||||||
|
<node text="KA(2 usages) ()"/>
|
||||||
|
<node text="KA.foo(String) ()"/>
|
||||||
|
<node text="KA.name ()"/>
|
||||||
|
<node text="packageFun(String)(2 usages) ()"/>
|
||||||
|
</node>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
class KA {
|
||||||
|
val name = "A"
|
||||||
|
fun foo(s: String): String = "A: $s"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun packageFun(s: String): String = s
|
||||||
|
|
||||||
|
val packageVal = ""
|
||||||
|
|
||||||
|
fun client() {
|
||||||
|
val obj = <caret>object {
|
||||||
|
val bar = run {
|
||||||
|
val localVal = packageFun("")
|
||||||
|
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
packageFun(localVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun localFun(s: String): String = packageFun(s)
|
||||||
|
|
||||||
|
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
localFun(packageVal)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class JA {
|
||||||
|
public String name = "A";
|
||||||
|
|
||||||
|
public JA() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String foo(String s) {
|
||||||
|
System.out.println(s);
|
||||||
|
return "A " + s;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
<node text="KClient" base="true">
|
<node text="KClient" base="true">
|
||||||
<node text="KClientBase"/>
|
<node text="KClientBase"/>
|
||||||
<node text="KA(4 usages)"/>
|
<node text="KA(4 usages)"/>
|
||||||
<node text="KA.name(2 usages)"/>
|
|
||||||
<node text="KA.foo(String)(2 usages)"/>
|
<node text="KA.foo(String)(2 usages)"/>
|
||||||
|
<node text="KA.name(2 usages)"/>
|
||||||
<node text="JA.JA()(4 usages)"/>
|
<node text="JA.JA()(4 usages)"/>
|
||||||
<node text="JA.foo(String)(2 usages)">
|
<node text="JA.foo(String)(2 usages)">
|
||||||
<node text="PrintStream.println(String) (java.io)"/>
|
<node text="PrintStream.println(String) (java.io)"/>
|
||||||
</node>
|
</node>
|
||||||
|
<node text="KClient.localFun(String)">
|
||||||
|
<node text="packageFun(String)"/>
|
||||||
|
</node>
|
||||||
<node text="packageVal"/>
|
<node text="packageVal"/>
|
||||||
<node text="packageFun(String)(2 usages)"/>
|
<node text="packageFun(String)(2 usages)"/>
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
+4
-1
@@ -1,7 +1,10 @@
|
|||||||
<node text="KClient.bar()" base="true">
|
<node text="KClient.bar()" base="true">
|
||||||
|
<node text="bar.localFun(String)(2 usages)">
|
||||||
|
<node text="packageFun(String)"/>
|
||||||
|
</node>
|
||||||
<node text="KA(4 usages)"/>
|
<node text="KA(4 usages)"/>
|
||||||
<node text="KA.name(2 usages)"/>
|
|
||||||
<node text="KA.foo(String)(2 usages)"/>
|
<node text="KA.foo(String)(2 usages)"/>
|
||||||
|
<node text="KA.name(2 usages)"/>
|
||||||
<node text="JA.JA()(4 usages)"/>
|
<node text="JA.JA()(4 usages)"/>
|
||||||
<node text="JA.foo(String)(2 usages)">
|
<node text="JA.foo(String)(2 usages)">
|
||||||
<node text="PrintStream.println(String) (java.io)"/>
|
<node text="PrintStream.println(String) (java.io)"/>
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<node text="client.T ()" base="true">
|
||||||
|
<node text="JA.JA()(2 usages) ()"/>
|
||||||
|
<node text="JA.foo(String) ()">
|
||||||
|
<node text="PrintStream.println(String) (java.io)"/>
|
||||||
|
</node>
|
||||||
|
<node text="KA(2 usages) ()"/>
|
||||||
|
<node text="KA.foo(String) ()"/>
|
||||||
|
<node text="KA.name ()"/>
|
||||||
|
<node text="packageFun(String)(2 usages) ()"/>
|
||||||
|
</node>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
class KA {
|
||||||
|
val name = "A"
|
||||||
|
fun foo(s: String): String = "A: $s"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun packageFun(s: String): String = s
|
||||||
|
|
||||||
|
val packageVal = ""
|
||||||
|
|
||||||
|
fun client() {
|
||||||
|
class <caret>T {
|
||||||
|
val bar = run {
|
||||||
|
val localVal = packageFun("")
|
||||||
|
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
packageFun(localVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun localFun(s: String): String = packageFun(s)
|
||||||
|
|
||||||
|
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
localFun(packageVal)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class JA {
|
||||||
|
public String name = "A";
|
||||||
|
|
||||||
|
public JA() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String foo(String s) {
|
||||||
|
System.out.println(s);
|
||||||
|
return "A " + s;
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
<node text="client.localFun(String) ()" base="true">
|
||||||
|
<node text="JA.JA()(2 usages) ()"/>
|
||||||
|
<node text="JA.foo(String) ()">
|
||||||
|
<node text="PrintStream.println(String) (java.io)"/>
|
||||||
|
</node>
|
||||||
|
<node text="KA(2 usages) ()"/>
|
||||||
|
<node text="KA.foo(String) ()"/>
|
||||||
|
<node text="KA.name ()"/>
|
||||||
|
<node text="localFun.bar() ()">
|
||||||
|
<node text="KA.name ()"/>
|
||||||
|
<node text="JA.foo(String) ()">
|
||||||
|
<node text="PrintStream.println(String) (java.io)"/>
|
||||||
|
</node>
|
||||||
|
<node text="KA(2 usages) ()"/>
|
||||||
|
<node text="JA.JA()(2 usages) ()"/>
|
||||||
|
<node text="KA.foo(String) ()"/>
|
||||||
|
</node>
|
||||||
|
<node text="packageFun(String)(2 usages) ()"/>
|
||||||
|
</node>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
class KA {
|
||||||
|
val name = "A"
|
||||||
|
fun foo(s: String): String = "A: $s"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun packageFun(s: String): String = s
|
||||||
|
|
||||||
|
val packageVal = ""
|
||||||
|
|
||||||
|
fun client() {
|
||||||
|
fun <caret>localFun(s: String): String {
|
||||||
|
val bar = run {
|
||||||
|
val localVal = packageFun("")
|
||||||
|
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
packageFun(localVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
}
|
||||||
|
|
||||||
|
bar()
|
||||||
|
}
|
||||||
|
|
||||||
|
KA().foo(KA().name)
|
||||||
|
JA().foo(JA().name)
|
||||||
|
localFun(packageVal)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class JA {
|
||||||
|
public String name = "A";
|
||||||
|
|
||||||
|
public JA() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String foo(String s) {
|
||||||
|
System.out.println(s);
|
||||||
|
return "A " + s;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
<node text="KClient" base="true">
|
<node text="KClient" base="true">
|
||||||
<node text="KClientBase"/>
|
<node text="KClientBase"/>
|
||||||
<node text="KA(4 usages)"/>
|
<node text="KA(4 usages)"/>
|
||||||
<node text="KA.name(2 usages)"/>
|
|
||||||
<node text="KA.foo(String)(2 usages)"/>
|
<node text="KA.foo(String)(2 usages)"/>
|
||||||
|
<node text="KA.name(2 usages)"/>
|
||||||
<node text="JA.JA()(4 usages)"/>
|
<node text="JA.JA()(4 usages)"/>
|
||||||
<node text="JA.foo(String)(2 usages)">
|
<node text="JA.foo(String)(2 usages)">
|
||||||
<node text="PrintStream.println(String) (java.io)"/>
|
<node text="PrintStream.println(String) (java.io)"/>
|
||||||
</node>
|
</node>
|
||||||
|
<node text="KClient.localFun(String)">
|
||||||
|
<node text="packageFun(String)"/>
|
||||||
|
</node>
|
||||||
<node text="packageVal"/>
|
<node text="packageVal"/>
|
||||||
<node text="packageFun(String)(2 usages)"/>
|
<node text="packageFun(String)(2 usages)"/>
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
+4
-1
@@ -1,7 +1,10 @@
|
|||||||
<node text="KClient.bar" base="true">
|
<node text="KClient.bar" base="true">
|
||||||
|
<node text="KClient.localFun(String)(2 usages)">
|
||||||
|
<node text="packageFun(String)"/>
|
||||||
|
</node>
|
||||||
<node text="KA(4 usages)"/>
|
<node text="KA(4 usages)"/>
|
||||||
<node text="KA.name(2 usages)"/>
|
|
||||||
<node text="KA.foo(String)(2 usages)"/>
|
<node text="KA.foo(String)(2 usages)"/>
|
||||||
|
<node text="KA.name(2 usages)"/>
|
||||||
<node text="JA.JA()(4 usages)"/>
|
<node text="JA.JA()(4 usages)"/>
|
||||||
<node text="JA.foo(String)(2 usages)">
|
<node text="JA.foo(String)(2 usages)">
|
||||||
<node text="PrintStream.println(String) (java.io)"/>
|
<node text="PrintStream.println(String) (java.io)"/>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<node text="KA" base="true">
|
<node text="KA" base="true">
|
||||||
<node text="JA"/>
|
|
||||||
<node text="JA.newKA()"/>
|
|
||||||
<node text="KClient"/>
|
|
||||||
<node text="KClient"/>
|
|
||||||
<node text="KClient.bar"/>
|
|
||||||
<node text="KClient.bar()(2 usages)"/>
|
|
||||||
<node text="KClientObj"/>
|
<node text="KClientObj"/>
|
||||||
<node text="main0.kt"/>
|
<node text="bar.localFun()"/>
|
||||||
<node text="packageFun(String)"/>
|
<node text="packageFun(String)"/>
|
||||||
|
<node text="KClient"/>
|
||||||
|
<node text="KClient.bar()"/>
|
||||||
|
<node text="main0.kt"/>
|
||||||
|
<node text="JA.newKA()"/>
|
||||||
|
<node text="JA"/>
|
||||||
|
<node text="KClient.bar"/>
|
||||||
|
<node text="KClient"/>
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
+8
-7
@@ -1,11 +1,12 @@
|
|||||||
<node text="KA.foo(String)" base="true">
|
<node text="KA.foo(String)" base="true">
|
||||||
<node text="JA"/>
|
|
||||||
<node text="JA.foo()"/>
|
|
||||||
<node text="KClient"/>
|
<node text="KClient"/>
|
||||||
<node text="KClient"/>
|
<node text="bar.localFun()"/>
|
||||||
<node text="KClient.bar"/>
|
|
||||||
<node text="KClient.bar()(2 usages)"/>
|
|
||||||
<node text="KClientObj"/>
|
|
||||||
<node text="main0.kt"/>
|
|
||||||
<node text="packageFun(String)"/>
|
<node text="packageFun(String)"/>
|
||||||
|
<node text="KClientObj"/>
|
||||||
|
<node text="KClient.bar"/>
|
||||||
|
<node text="main0.kt"/>
|
||||||
|
<node text="JA.foo()"/>
|
||||||
|
<node text="JA"/>
|
||||||
|
<node text="KClient"/>
|
||||||
|
<node text="KClient.bar()"/>
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<node text="client.KA ()" base="true">
|
||||||
|
<node text="bar.localFun() ()"/>
|
||||||
|
<node text="client.bar() ()"/>
|
||||||
|
<node text="client.KClientObj ()"/>
|
||||||
|
<node text="KClient.client() ()"/>
|
||||||
|
</node>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
class KClient {
|
||||||
|
fun client() {
|
||||||
|
class <caret>KA {
|
||||||
|
val name = "A"
|
||||||
|
fun foo(s: String): String = "A: $s"
|
||||||
|
}
|
||||||
|
|
||||||
|
val bar: String = KA().name
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
fun localFun() = KA()
|
||||||
|
|
||||||
|
KA()
|
||||||
|
}
|
||||||
|
|
||||||
|
object KClientObj {
|
||||||
|
val a = KA()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<node text="client.foo(String) ()" base="true">
|
||||||
|
<node text="client.bar() ()"/>
|
||||||
|
<node text="bar.localFun() ()"/>
|
||||||
|
<node text="client.KClientObj ()"/>
|
||||||
|
<node text="KClient.client() ()"/>
|
||||||
|
</node>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
class KClient {
|
||||||
|
fun client() {
|
||||||
|
fun <caret>foo(s: String): String = ""
|
||||||
|
|
||||||
|
val bar: String = foo("")
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
fun localFun() = foo("")
|
||||||
|
|
||||||
|
foo("")
|
||||||
|
}
|
||||||
|
|
||||||
|
object KClientObj {
|
||||||
|
val a = foo("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-6
@@ -1,11 +1,12 @@
|
|||||||
<node text="KA.name" base="true">
|
<node text="KA.name" base="true">
|
||||||
<node text="JA"/>
|
<node text="packageFun(String)(2 usages)"/>
|
||||||
<node text="JA.getName()"/>
|
<node text="KClient.bar()(2 usages)"/>
|
||||||
<node text="KClient(2 usages)"/>
|
|
||||||
<node text="KClient(2 usages)"/>
|
|
||||||
<node text="KClient.bar()(4 usages)"/>
|
|
||||||
<node text="KClient.bar(4 usages)"/>
|
<node text="KClient.bar(4 usages)"/>
|
||||||
|
<node text="bar.localFun()(2 usages)"/>
|
||||||
|
<node text="JA.getName()"/>
|
||||||
|
<node text="JA"/>
|
||||||
|
<node text="KClient(2 usages)"/>
|
||||||
|
<node text="KClient(2 usages)"/>
|
||||||
<node text="KClientObj(4 usages)"/>
|
<node text="KClientObj(4 usages)"/>
|
||||||
<node text="main0.kt(2 usages)"/>
|
<node text="main0.kt(2 usages)"/>
|
||||||
<node text="packageFun(String)(2 usages)"/>
|
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
@@ -217,6 +217,16 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest {
|
|||||||
doCallerHierarchyTest("idea/testData/hierarchy/calls/callers/kotlinFunction");
|
doCallerHierarchyTest("idea/testData/hierarchy/calls/callers/kotlinFunction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kotlinLocalClass")
|
||||||
|
public void testKotlinLocalClass() throws Exception {
|
||||||
|
doCallerHierarchyTest("idea/testData/hierarchy/calls/callers/kotlinLocalClass");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kotlinLocalFunction")
|
||||||
|
public void testKotlinLocalFunction() throws Exception {
|
||||||
|
doCallerHierarchyTest("idea/testData/hierarchy/calls/callers/kotlinLocalFunction");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kotlinNestedClass")
|
@TestMetadata("kotlinNestedClass")
|
||||||
public void testKotlinNestedClass() throws Exception {
|
public void testKotlinNestedClass() throws Exception {
|
||||||
doCallerHierarchyTest("idea/testData/hierarchy/calls/callers/kotlinNestedClass");
|
doCallerHierarchyTest("idea/testData/hierarchy/calls/callers/kotlinNestedClass");
|
||||||
@@ -250,6 +260,11 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest {
|
|||||||
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/javaMethod");
|
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/javaMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kotlinAnonymousObject")
|
||||||
|
public void testKotlinAnonymousObject() throws Exception {
|
||||||
|
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinAnonymousObject");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kotlinClass")
|
@TestMetadata("kotlinClass")
|
||||||
public void testKotlinClass() throws Exception {
|
public void testKotlinClass() throws Exception {
|
||||||
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinClass");
|
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinClass");
|
||||||
@@ -270,6 +285,16 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest {
|
|||||||
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinFunction");
|
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinFunction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kotlinLocalClass")
|
||||||
|
public void testKotlinLocalClass() throws Exception {
|
||||||
|
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinLocalClass");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kotlinLocalFunction")
|
||||||
|
public void testKotlinLocalFunction() throws Exception {
|
||||||
|
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinLocalFunction");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kotlinNestedClass")
|
@TestMetadata("kotlinNestedClass")
|
||||||
public void testKotlinNestedClass() throws Exception {
|
public void testKotlinNestedClass() throws Exception {
|
||||||
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinNestedClass");
|
doCalleeHierarchyTest("idea/testData/hierarchy/calls/callees/kotlinNestedClass");
|
||||||
|
|||||||
Reference in New Issue
Block a user