diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index d1a16628f24..114ee6ea72a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -1030,7 +1030,7 @@ public class JetPsiUtil { return header != null ? header.getQualifiedName() : null; } - public static JetElement getLocalizingCodeBlock(@NotNull JetNamedDeclaration declaration) { + public static JetElement getEnclosingBlockForLocalDeclaration(@NotNull JetNamedDeclaration declaration) { //noinspection unchecked JetDeclaration container = PsiTreeUtil.getParentOfType(declaration, JetNamedFunction.class, JetPropertyAccessor.class, JetClassInitializer.class); @@ -1041,4 +1041,8 @@ public class JetPsiUtil { ? ((JetClassInitializer) container).getBody() : ((JetDeclarationWithBody) container).getBodyExpression(); } + + public static boolean isLocal(@NotNull JetNamedDeclaration declaration) { + return getEnclosingBlockForLocalDeclaration(declaration) != null; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallHierarchyBrowser.java b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallHierarchyBrowser.java index 72fa02f590e..d1c1c27bf49 100644 --- a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallHierarchyBrowser.java +++ b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallHierarchyBrowser.java @@ -31,7 +31,6 @@ import com.intellij.psi.PsiMethod; import com.intellij.ui.PopupHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetNamedDeclaration; -import org.jetbrains.jet.plugin.hierarchy.HierarchyUtils; import javax.swing.*; import java.util.Comparator; @@ -87,7 +86,7 @@ public class KotlinCallHierarchyBrowser extends CallHierarchyBrowserBase { @Override protected HierarchyTreeStructure createHierarchyTreeStructure(@NotNull String typeName, @NotNull PsiElement psiElement) { if (typeName.equals(CALLER_TYPE)) { - return new KotlinCallerMethodsTreeStructure(myProject, psiElement, getCurrentScopeType()); + return KotlinCallerMethodsTreeStructure.newInstance(myProject, psiElement, getCurrentScopeType()); } if (typeName.equals(CALLEE_TYPE)) { diff --git a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallTreeStructure.java b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallTreeStructure.java index aad264413e5..a29ef459688 100644 --- a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallTreeStructure.java +++ b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallTreeStructure.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.plugin.hierarchy.calls; +import com.google.common.base.Predicate; import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; import com.intellij.ide.hierarchy.HierarchyTreeStructure; import com.intellij.ide.hierarchy.call.CallHierarchyNodeDescriptor; @@ -7,7 +8,6 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,30 +19,16 @@ import java.util.Map; public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure { protected final String scopeType; - 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) + protected static JetElement getEnclosingBlockForLocalDeclaration(PsiElement element) { + return element instanceof JetNamedDeclaration + ? JetPsiUtil.getEnclosingBlockForLocalDeclaration((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) { @@ -58,15 +44,46 @@ public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure { : ((KotlinCallHierarchyNodeDescriptor)descriptor).getTargetElement(); } - private static PsiMethod getClosestContainingClassConstructor(PsiElement element) { - while (element != null) { - JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(element, JetClassOrObject.class, false); - if (classOrObject == null) return null; + private static final Predicate IS_NON_LOCAL_DECLARATION = new Predicate() { + @Override + public boolean apply(@javax.annotation.Nullable PsiElement input) { + return input instanceof PsiMethod + || ((input instanceof JetNamedFunction || input instanceof JetClassOrObject || input instanceof JetProperty) + && !JetPsiUtil.isLocal((JetNamedDeclaration) input)); + } + }; - element = classOrObject.getParent(); + @Nullable + protected static PsiMethod getRepresentativePsiMethod(PsiElement element) { + while (true) { + element = JetPsiUtil.getParentByTypeAndPredicate(element, PsiElement.class, IS_NON_LOCAL_DECLARATION, false); + if (element == null) return null; - PsiClass psiClass = LightClassUtil.getPsiClass(classOrObject); - if (psiClass == null) continue; + PsiMethod method = getRepresentativePsiMethodForNonLocalDeclaration(element); + if (method != null) return method; + + element = element.getParent(); + } + } + + private static PsiMethod getRepresentativePsiMethodForNonLocalDeclaration(PsiElement element) { + if (element instanceof PsiMethod) { + return (PsiMethod) element; + } + + if (element instanceof JetNamedFunction) { + return LightClassUtil.getLightClassMethod((JetNamedFunction) element); + } + + if (element instanceof JetProperty) { + LightClassUtil.PropertyAccessorsPsiMethods propertyMethods = + LightClassUtil.getLightClassPropertyMethods((JetProperty) element); + return (propertyMethods.getGetter() != null) ? propertyMethods.getGetter() : propertyMethods.getSetter(); + } + + if (element instanceof JetClassOrObject) { + PsiClass psiClass = LightClassUtil.getPsiClass((JetClassOrObject) element); + if (psiClass == null) return null; PsiMethod[] constructors = psiClass.getConstructors(); if (constructors.length > 0) return constructors[0]; @@ -75,33 +92,6 @@ public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure { return null; } - @Nullable - protected final PsiMethod getPsiMethod(PsiElement element) { - assert localizingCodeBlock == null : "Can't build light method for local declaration"; - - if (element instanceof PsiMethod) { - return (PsiMethod) element; - } - - PsiMethod method = null; - if (element instanceof JetNamedFunction) { - method = LightClassUtil.getLightClassMethod((JetNamedFunction) element); - } - else if (element instanceof JetProperty) { - LightClassUtil.PropertyAccessorsPsiMethods propertyMethods = - LightClassUtil.getLightClassPropertyMethods((JetProperty) element); - - if (propertyMethods.getGetter() != null) { - method = propertyMethods.getGetter(); - } - else { - method = propertyMethods.getSetter(); - } - } - - return method != null ? method : getClosestContainingClassConstructor(element); - } - protected static CallHierarchyNodeDescriptor getJavaNodeDescriptor(HierarchyNodeDescriptor originalDescriptor) { if (originalDescriptor instanceof CallHierarchyNodeDescriptor) return (CallHierarchyNodeDescriptor) originalDescriptor; @@ -109,7 +99,9 @@ public abstract class KotlinCallTreeStructure extends HierarchyTreeStructure { return ((KotlinCallHierarchyNodeDescriptor) originalDescriptor).getJavaDelegate(); } - protected final Object[] collectNodeDescriptors(HierarchyNodeDescriptor descriptor, List calleeElements) { + protected Object[] collectNodeDescriptors( + HierarchyNodeDescriptor descriptor, List calleeElements, PsiClass basePsiClass + ) { HashMap declarationToDescriptorMap = new HashMap(); for (PsiElement callee : calleeElements) { if (basePsiClass != null && !isInScope(basePsiClass, callee, scopeType)) continue; diff --git a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCalleeMethodsTreeStructure.java b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCalleeMethodsTreeStructure.java index f5d8051f9aa..e4a3e3f710d 100644 --- a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCalleeMethodsTreeStructure.java +++ b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCalleeMethodsTreeStructure.java @@ -35,10 +35,16 @@ import java.util.List; public class KotlinCalleeMethodsTreeStructure extends KotlinCallTreeStructure { private final CalleeMethodsTreeStructure javaTreeStructure; + private final PsiClass representativePsiClass; public KotlinCalleeMethodsTreeStructure(@NotNull Project project, @NotNull PsiElement element, String scopeType) { super(project, element, scopeType); - this.javaTreeStructure = basePsiMethod != null ? new CalleeMethodsTreeStructure(project, basePsiMethod, scopeType) : null; + + PsiMethod representativePsiMethod = getRepresentativePsiMethod(element); + assert representativePsiMethod != null; + + this.representativePsiClass = representativePsiMethod.getContainingClass(); + this.javaTreeStructure = new CalleeMethodsTreeStructure(project, representativePsiMethod, scopeType); } private static List getCalleeElements(@NotNull JetElement rootElement, BindingContext bindingContext) { @@ -126,6 +132,6 @@ public class KotlinCalleeMethodsTreeStructure extends KotlinCallTreeStructure { BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) targetElement.getContainingFile()).getBindingContext(); List calleeDescriptors = getCalleeElements((JetElement) targetElement, bindingContext); - return collectNodeDescriptors(descriptor, calleeDescriptors); + return collectNodeDescriptors(descriptor, calleeDescriptors, representativePsiClass); } } diff --git a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallerMethodsTreeStructure.java b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallerMethodsTreeStructure.java index 862db48989d..773b58b631d 100644 --- a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallerMethodsTreeStructure.java +++ b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallerMethodsTreeStructure.java @@ -43,156 +43,183 @@ import org.jetbrains.jet.plugin.references.JetPsiReference; import java.util.ArrayList; import java.util.Map; -public class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStructure { - private final CallerMethodsTreeStructure javaTreeStructure; +public abstract class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStructure { + private static class WithLocalRoot extends KotlinCallerMethodsTreeStructure { + private final JetElement codeBlockForLocalDeclaration; - public KotlinCallerMethodsTreeStructure(@NotNull Project project, @NotNull PsiElement element, String scopeType) { + private WithLocalRoot( + @NotNull Project project, + @NotNull PsiElement element, + String scopeType, + JetElement codeBlockForLocalDeclaration + ) { + super(project, element, scopeType); + this.codeBlockForLocalDeclaration = codeBlockForLocalDeclaration; + } + + @Override + protected Object[] buildChildren(HierarchyNodeDescriptor descriptor) { + final PsiElement element = getTargetElement(descriptor); + + BindingContext bindingContext = + AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext(); + + final ArrayList result = new ArrayList(); + codeBlockForLocalDeclaration.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, null); + } + } + + private static class WithNonLocalRoot extends KotlinCallerMethodsTreeStructure { + private final CallerMethodsTreeStructure javaTreeStructure; + private final PsiClass basePsiClass; + + private WithNonLocalRoot(@NotNull Project project, @NotNull PsiElement element, String scopeType, PsiMethod basePsiMethod) { + super(project, element, scopeType); + + this.basePsiClass = basePsiMethod.getContainingClass(); + this.javaTreeStructure = new CallerMethodsTreeStructure(project, basePsiMethod, scopeType); + } + + @Override + protected Object[] buildChildren(HierarchyNodeDescriptor descriptor) { + PsiElement element = getTargetElement(descriptor); + + SearchScope searchScope = getSearchScope(scopeType, basePsiClass); + Map methodToDescriptorMap = + new HashMap(); + + Object[] javaCallers = null; + if (element instanceof PsiMethod && javaTreeStructure != null) { + javaCallers = javaTreeStructure.getChildElements(getJavaNodeDescriptor(descriptor)); + processPsiMethodCallers((PsiMethod) element, descriptor, methodToDescriptorMap, searchScope, true); + } + if (element instanceof JetNamedFunction) { + PsiMethod lightMethod = LightClassUtil.getLightClassMethod((JetNamedFunction) element); + processPsiMethodCallers(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); + } + if (element instanceof JetClassOrObject) { + processJetClassOrObjectCallers((JetClassOrObject) element, descriptor, methodToDescriptorMap, searchScope); + } + + Object[] callers = methodToDescriptorMap.values().toArray(new Object[methodToDescriptorMap.size()]); + return (javaCallers != null) ? ArrayUtil.mergeArrays(javaCallers, callers) : callers; + } + + private void processPsiMethodCallers( + @Nullable PsiMethod lightMethod, + HierarchyNodeDescriptor descriptor, + Map methodToDescriptorMap, + SearchScope searchScope, + boolean kotlinOnly + ) { + if (lightMethod == null) return; + MethodReferencesSearch.search(lightMethod, searchScope, true) + .forEach(defaultQueryProcessor(descriptor, methodToDescriptorMap, kotlinOnly)); + } + + private void processJetClassOrObjectCallers( + final JetClassOrObject classOrObject, + HierarchyNodeDescriptor descriptor, + Map methodToDescriptorMap, + SearchScope searchScope + ) { + Processor processor = new FilteringProcessor( + new Condition() { + @Override + public boolean value(PsiReference reference) { + return FindUsagesUtils.isConstructorUsage(reference.getElement(), classOrObject); + } + }, + defaultQueryProcessor(descriptor, methodToDescriptorMap, false) + ); + ReferencesSearch.search(classOrObject, searchScope, false).forEach(processor); + } + + private Processor defaultQueryProcessor( + final HierarchyNodeDescriptor descriptor, + final Map methodToDescriptorMap, + final boolean kotlinOnly + ) { + return new ReadActionProcessor() { + @Override + public boolean processInReadAction(PsiReference ref) { + // copied from Java + if (!(ref instanceof PsiReferenceExpression || ref instanceof JetPsiReference)) { + if (!(ref instanceof PsiElement)) { + return true; + } + + PsiElement parent = ((PsiElement) ref).getParent(); + if (parent instanceof PsiNewExpression) { + if (((PsiNewExpression) parent).getClassReference() != ref) { + return true; + } + } + else if (parent instanceof PsiAnonymousClass) { + if (((PsiAnonymousClass) parent).getBaseClassReference() != ref) { + return true; + } + } + else { + return true; + } + } + + PsiElement element = HierarchyUtils.getCallHierarchyElement(ref.getElement()); + + if (kotlinOnly && !(element instanceof JetNamedDeclaration)) return true; + + // If reference belongs to property initializer, show enclosing declaration instead + if (element instanceof JetProperty) { + JetProperty property = (JetProperty) element; + if (PsiTreeUtil.isAncestor(property.getInitializer(), ref.getElement(), false)) { + element = HierarchyUtils.getCallHierarchyElement(element.getParent()); + } + } + + if (element != null) { + addNodeDescriptorForElement(element, methodToDescriptorMap, descriptor); + } + + return true; + } + }; + } + } + + private KotlinCallerMethodsTreeStructure(@NotNull Project project, @NotNull PsiElement element, String scopeType) { super(project, element, scopeType); - this.javaTreeStructure = basePsiMethod != null ? new CallerMethodsTreeStructure(project, basePsiMethod, scopeType) : null; } - @Override - protected Object[] buildChildren(HierarchyNodeDescriptor descriptor) { - PsiElement targetElement = getTargetElement(descriptor); + public static KotlinCallerMethodsTreeStructure newInstance(@NotNull Project project, @NotNull PsiElement element, String scopeType) { + JetElement codeBlockForLocalDeclaration = getEnclosingBlockForLocalDeclaration(element); + if (codeBlockForLocalDeclaration != null) return new WithLocalRoot(project, element, scopeType, codeBlockForLocalDeclaration); - if (localizingCodeBlock != null) { - return buildLocalizedChildren(targetElement, (KotlinCallHierarchyNodeDescriptor) descriptor); - } - - return processCallers(targetElement, descriptor); - } - - private Object[] buildLocalizedChildren(final PsiElement element, KotlinCallHierarchyNodeDescriptor descriptor) { - BindingContext bindingContext = - AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext(); - - final ArrayList result = new ArrayList(); - 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 methodToDescriptorMap = - new HashMap(); - - Object[] javaCallers = null; - if (element instanceof PsiMethod && javaTreeStructure != null) { - javaCallers = javaTreeStructure.getChildElements(getJavaNodeDescriptor(descriptor)); - processPsiMethodCallers((PsiMethod) element, descriptor, methodToDescriptorMap, searchScope, true); - } - if (element instanceof JetNamedFunction) { - PsiMethod lightMethod = LightClassUtil.getLightClassMethod((JetNamedFunction) element); - processPsiMethodCallers(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); - } - if (element instanceof JetClassOrObject) { - processJetClassOrObjectCallers((JetClassOrObject) element, descriptor, methodToDescriptorMap, searchScope); - } - - Object[] callers = methodToDescriptorMap.values().toArray(new Object[methodToDescriptorMap.size()]); - return (javaCallers != null) ? ArrayUtil.mergeArrays(javaCallers, callers) : callers; - } - - private void processPsiMethodCallers( - @Nullable PsiMethod lightMethod, - HierarchyNodeDescriptor descriptor, - Map methodToDescriptorMap, - SearchScope searchScope, - boolean kotlinOnly - ) { - if (lightMethod == null) return; - MethodReferencesSearch.search(lightMethod, searchScope, true) - .forEach(defaultQueryProcessor(descriptor, methodToDescriptorMap, kotlinOnly)); - } - - private void processJetClassOrObjectCallers( - final JetClassOrObject classOrObject, - HierarchyNodeDescriptor descriptor, - Map methodToDescriptorMap, - SearchScope searchScope - ) { - Processor processor = new FilteringProcessor( - new Condition() { - @Override - public boolean value(PsiReference reference) { - return FindUsagesUtils.isConstructorUsage(reference.getElement(), classOrObject); - } - }, - defaultQueryProcessor(descriptor, methodToDescriptorMap, false) - ); - ReferencesSearch.search(classOrObject, searchScope, false).forEach(processor); - } - - private Processor defaultQueryProcessor( - final HierarchyNodeDescriptor descriptor, - final Map methodToDescriptorMap, - final boolean kotlinOnly - ) { - return new ReadActionProcessor() { - @Override - public boolean processInReadAction(PsiReference ref) { - // copied from Java - if (!(ref instanceof PsiReferenceExpression || ref instanceof JetPsiReference)) { - if (!(ref instanceof PsiElement)) { - return true; - } - - PsiElement parent = ((PsiElement) ref).getParent(); - if (parent instanceof PsiNewExpression) { - if (((PsiNewExpression) parent).getClassReference() != ref) { - return true; - } - } - else if (parent instanceof PsiAnonymousClass) { - if (((PsiAnonymousClass) parent).getBaseClassReference() != ref) { - return true; - } - } - else { - return true; - } - } - - PsiElement element = HierarchyUtils.getCallHierarchyElement(ref.getElement()); - - if (kotlinOnly && !(element instanceof JetNamedDeclaration)) return true; - - // If reference belongs to property initializer, show enclosing declaration instead - if (element instanceof JetProperty) { - JetProperty property = (JetProperty) element; - if (PsiTreeUtil.isAncestor(property.getInitializer(), ref.getElement(), false)) { - element = HierarchyUtils.getCallHierarchyElement(element.getParent()); - } - } - - if (element != null) { - addNodeDescriptorForElement(element, methodToDescriptorMap, descriptor); - } - - return true; - } - }; + PsiMethod representativeMethod = getRepresentativePsiMethod(element); + assert representativeMethod != null; + return new WithNonLocalRoot(project, element, scopeType, representativeMethod); } } diff --git a/idea/tests/org/jetbrains/jet/plugin/hierarchy/AbstractHierarchyTest.java b/idea/tests/org/jetbrains/jet/plugin/hierarchy/AbstractHierarchyTest.java index 638962d1210..f29e8fa4553 100644 --- a/idea/tests/org/jetbrains/jet/plugin/hierarchy/AbstractHierarchyTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/hierarchy/AbstractHierarchyTest.java @@ -120,7 +120,7 @@ public abstract class AbstractHierarchyTest extends HierarchyViewTestBase { return new Computable() { @Override public HierarchyTreeStructure compute() { - return new KotlinCallerMethodsTreeStructure( + return KotlinCallerMethodsTreeStructure.newInstance( getProject(), getElementAtCaret(LanguageCallHierarchy.INSTANCE.forLanguage(getLanguage())), HierarchyBrowserBaseEx.SCOPE_PROJECT