diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt index 1f74501bf57..09b13bccfd8 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.asJava import com.intellij.psi.* import com.intellij.psi.search.GlobalSearchScope -import com.intellij.util.IncorrectOperationException import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.elements.KtLightAnnotationForSourceEntry @@ -30,6 +29,7 @@ import org.jetbrains.kotlin.load.java.propertyNameByGetMethodName import org.jetbrains.kotlin.load.java.propertyNameBySetMethodName import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType @@ -37,6 +37,15 @@ import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration fun KtClassOrObject.toLightClass(): KtLightClass? = LightClassGenerationSupport.getInstance(project).getLightClass(this) +fun KtClassOrObject.toLightClassWithBuiltinMapping(): PsiClass? { + toLightClass()?.let { return it } + + val fqName = fqName ?: return null + val javaClassFqName = JavaToKotlinClassMap.mapKotlinToJava(fqName.toUnsafe())?.asSingleFqName() ?: return null + val searchScope = useScope as? GlobalSearchScope ?: return null + return JavaPsiFacade.getInstance(project).findClass(javaClassFqName.asString(), searchScope) +} + fun KtFile.findFacadeClass(): KtLightClass? { return LightClassGenerationSupport.getInstance(project) .getFacadeClassesInPackage(packageFqName, this.useScope as? GlobalSearchScope ?: GlobalSearchScope.projectScope(project)) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/classInheritorsSearch.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/classInheritorsSearch.kt index f3468285f14..7c90d24b380 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/classInheritorsSearch.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/classInheritorsSearch.kt @@ -22,13 +22,13 @@ import com.intellij.psi.PsiModifier import com.intellij.psi.search.searches.ClassInheritorsSearch import com.intellij.util.EmptyQuery import com.intellij.util.Query -import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.asJava.toLightClassWithBuiltinMapping import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.KtClassOrObject fun HierarchySearchRequest<*>.searchInheritors(): Query { val psiClass: PsiClass = when (originalElement) { - is KtClassOrObject -> runReadAction { originalElement.toLightClass() } + is KtClassOrObject -> runReadAction { originalElement.toLightClassWithBuiltinMapping() } is PsiClass -> originalElement else -> null } ?: return EmptyQuery.getEmptyQuery() diff --git a/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyBrowser.kt b/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyBrowser.kt index a78b52a4a06..a23c3af161d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyBrowser.kt +++ b/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyBrowser.kt @@ -16,23 +16,42 @@ package org.jetbrains.kotlin.idea.hierarchy.overrides +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor import com.intellij.ide.hierarchy.HierarchyTreeStructure +import com.intellij.ide.hierarchy.JavaHierarchyUtil import com.intellij.ide.hierarchy.MethodHierarchyBrowserBase -import com.intellij.ide.hierarchy.method.MethodHierarchyBrowser +import com.intellij.openapi.actionSystem.ActionGroup +import com.intellij.openapi.actionSystem.ActionManager +import com.intellij.openapi.actionSystem.ActionPlaces +import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.project.Project import com.intellij.psi.ElementDescriptionUtil import com.intellij.psi.PsiElement -import com.intellij.psi.PsiMethod +import com.intellij.ui.PopupHandler import com.intellij.usageView.UsageViewLongNameLocation -import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtDeclaration import javax.swing.JPanel +import javax.swing.JTree class KotlinOverrideHierarchyBrowser( project: Project, baseElement: PsiElement -) : MethodHierarchyBrowser(project, baseElement.getRepresentativeLightMethod()) { +) : MethodHierarchyBrowserBase(project, baseElement) { + override fun createTrees(trees: MutableMap) { + val actionManager = ActionManager.getInstance() + + val tree = createTree(false) + + val group = actionManager.getAction(IdeActions.GROUP_METHOD_HIERARCHY_POPUP) as ActionGroup + PopupHandler.installPopupHandler(tree, group, ActionPlaces.METHOD_HIERARCHY_VIEW_POPUP, actionManager) + + BaseOnThisMethodAction().registerCustomShortcutSet(actionManager.getAction(IdeActions.ACTION_METHOD_HIERARCHY).shortcutSet, tree) + + trees.put(MethodHierarchyBrowserBase.METHOD_TYPE, tree) + } + override fun createLegendPanel(): JPanel? = MethodHierarchyBrowserBase.createStandardLegendPanel( KotlinBundle.message("hierarchy.legend.member.is.defined.in.class"), @@ -40,18 +59,15 @@ class KotlinOverrideHierarchyBrowser( KotlinBundle.message("hierarchy.legend.member.should.be.defined") ) + override fun getElementFromDescriptor(descriptor: HierarchyNodeDescriptor) = descriptor.psiElement + override fun isApplicableElement(psiElement: PsiElement): Boolean = psiElement.isOverrideHierarchyElement() override fun createHierarchyTreeStructure(typeName: String, psiElement: PsiElement): HierarchyTreeStructure? = - if (typeName == MethodHierarchyBrowserBase.METHOD_TYPE) KotlinOverrideTreeStructure(myProject, psiElement) else null + if (typeName == MethodHierarchyBrowserBase.METHOD_TYPE) KotlinOverrideTreeStructure(myProject, psiElement as KtCallableDeclaration) else null - override fun getBaseMethod(): PsiMethod? { - val builder = myBuilders.get(myCurrentViewType) - if (builder == null) return null - - return (builder.treeStructure as KotlinOverrideTreeStructure).javaTreeStructures.get(0).baseMethod - } + override fun getComparator() = JavaHierarchyUtil.getComparator(myProject)!! override fun getContentDisplayName(typeName: String, element: PsiElement): String? { val targetElement = element.unwrapped diff --git a/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyNodeDescriptor.kt b/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyNodeDescriptor.kt new file mode 100644 index 00000000000..236afa1335c --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyNodeDescriptor.kt @@ -0,0 +1,163 @@ +/* + * Copyright 2010-2017 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.kotlin.idea.hierarchy.overrides + +import com.intellij.icons.AllIcons +import com.intellij.ide.IdeBundle +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor +import com.intellij.openapi.editor.markup.TextAttributes +import com.intellij.openapi.roots.ui.util.CompositeAppearance +import com.intellij.openapi.util.Comparing +import com.intellij.openapi.util.Iconable +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMember +import com.intellij.ui.LayeredIcon +import com.intellij.ui.RowIcon +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.idea.caches.resolve.getJavaMemberDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.parents +import org.jetbrains.kotlin.types.substitutions.getTypeSubstitutor +import org.jetbrains.kotlin.util.findCallableMemberBySignature +import java.awt.Font +import javax.swing.Icon + +class KotlinOverrideHierarchyNodeDescriptor ( + parentNode: HierarchyNodeDescriptor?, + klass: PsiElement, + baseElement: PsiElement +) : HierarchyNodeDescriptor(klass.project, parentNode, klass, parentNode == null) { + private val baseElement = baseElement.createSmartPointer() + + private var rawIcon: Icon? = null + private var stateIcon: Icon? = null + + private fun resolveToDescriptor(psiElement: PsiElement): DeclarationDescriptor? { + return when (psiElement) { + is KtNamedDeclaration -> psiElement.resolveToDescriptor() + is PsiMember -> psiElement.getJavaMemberDescriptor() + else -> null + } + } + + private fun getBaseDescriptor() = baseElement.element?.let { resolveToDescriptor(it) } as? CallableMemberDescriptor + + private fun getCurrentClassDescriptor() = psiElement?.let { resolveToDescriptor(it) } as? ClassDescriptor + + private fun getCurrentDescriptor(): CallableMemberDescriptor? { + val classDescriptor = getCurrentClassDescriptor() ?: return null + val baseDescriptor = getBaseDescriptor() ?: return null + val baseClassDescriptor = baseDescriptor.containingDeclaration as? ClassDescriptor ?: return null + val substitutor = getTypeSubstitutor(baseClassDescriptor.defaultType, classDescriptor.defaultType) ?: return null + return classDescriptor.findCallableMemberBySignature(baseDescriptor.substitute(substitutor) as CallableMemberDescriptor) + } + + internal fun calculateState(): Icon? { + val classDescriptor = getCurrentClassDescriptor() ?: return null + val callableDescriptor = getCurrentDescriptor() ?: return AllIcons.Hierarchy.MethodNotDefined + + if (callableDescriptor.kind == CallableMemberDescriptor.Kind.DECLARATION) { + if (callableDescriptor.modality == Modality.ABSTRACT) return null + return AllIcons.Hierarchy.MethodDefined + } + + val isAbstractClass = classDescriptor.modality == Modality.ABSTRACT + val hasBaseImplementation = DescriptorUtils.getAllOverriddenDeclarations(callableDescriptor).any { it.modality != Modality.ABSTRACT } + return if (isAbstractClass || hasBaseImplementation) AllIcons.Hierarchy.MethodNotDefined else AllIcons.Hierarchy.ShouldDefineMethod + } + + override fun update(): Boolean { + var flags = Iconable.ICON_FLAG_VISIBILITY + if (isMarkReadOnly) { + flags = flags or Iconable.ICON_FLAG_READ_STATUS + } + + var changes = super.update() + + val classPsi = psiElement + val classDescriptor = getCurrentClassDescriptor() + if (classPsi == null || classDescriptor == null) { + val invalidPrefix = IdeBundle.message("node.hierarchy.invalid") + if (!myHighlightedText.text.startsWith(invalidPrefix)) { + myHighlightedText.beginning.addText(invalidPrefix, getInvalidPrefixAttributes()) + } + return true + } + + val newRawIcon = classPsi.getIcon(flags) + val newStateIcon = calculateState() + + if (changes || newRawIcon !== rawIcon || newStateIcon !== stateIcon) { + changes = true + + rawIcon = newRawIcon + stateIcon = newStateIcon + + var newIcon = rawIcon + + if (myIsBase) { + val icon = LayeredIcon(2) + icon.setIcon(newIcon, 0) + icon.setIcon(AllIcons.Hierarchy.Base, 1, -AllIcons.Hierarchy.Base.iconWidth / 2, 0) + newIcon = icon + } + + if (stateIcon != null) { + newIcon = RowIcon(stateIcon, newIcon) + } + + icon = newIcon + } + + val oldText = myHighlightedText + + myHighlightedText = CompositeAppearance() + var classNameAttributes: TextAttributes? = null + if (myColor != null) { + classNameAttributes = TextAttributes(myColor, null, null, null, Font.PLAIN) + } + + with (myHighlightedText.ending) { + addText(classDescriptor.name.asString(), classNameAttributes) + classDescriptor.parents.forEach { parentDescriptor -> + when (parentDescriptor) { + is MemberDescriptor -> { + addText(" in ${parentDescriptor.name.asString()}", classNameAttributes) + if (parentDescriptor is FunctionDescriptor) { + addText("()", classNameAttributes) + } + } + is PackageFragmentDescriptor -> { + addText(" (${parentDescriptor.fqName.asString()})", HierarchyNodeDescriptor.getPackageNameAttributes()) + return@forEach + } + } + } + } + + myName = myHighlightedText.text + + if (!Comparing.equal(myHighlightedText, oldText)) { + changes = true + } + + return changes + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyProvider.kt b/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyProvider.kt index 30384d48799..2505e0705a9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideHierarchyProvider.kt @@ -23,10 +23,9 @@ import com.intellij.ide.hierarchy.MethodHierarchyBrowserBase import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.DataContext import com.intellij.psi.PsiElement -import com.intellij.psi.PsiMethod import org.jetbrains.kotlin.idea.hierarchy.getCurrentElement -import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtCallableDeclaration +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate class KotlinOverrideHierarchyProvider: HierarchyProvider { @@ -44,8 +43,7 @@ class KotlinOverrideHierarchyProvider: HierarchyProvider { } private fun getOverrideHierarchyElement(element: PsiElement?): PsiElement? - = element?.getParentOfTypesAndPredicate() { it.isOverrideHierarchyElement() } + = element?.getParentOfTypesAndPredicate { it.isOverrideHierarchyElement() } } -fun PsiElement.isOverrideHierarchyElement(): Boolean - = this is PsiMethod || this is KtNamedFunction || this is KtProperty +fun PsiElement.isOverrideHierarchyElement() = this is KtCallableDeclaration && containingClassOrObject != null diff --git a/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideTreeStructure.kt b/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideTreeStructure.kt index 41a8bf393db..62d0cb8f7b0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideTreeStructure.kt +++ b/idea/src/org/jetbrains/kotlin/idea/hierarchy/overrides/KotlinOverrideTreeStructure.kt @@ -16,31 +16,35 @@ package org.jetbrains.kotlin.idea.hierarchy.overrides -import com.intellij.ide.hierarchy.HierarchyTreeStructure +import com.intellij.icons.AllIcons import com.intellij.ide.hierarchy.HierarchyNodeDescriptor +import com.intellij.ide.hierarchy.HierarchyTreeStructure import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement -import com.intellij.ide.hierarchy.method.MethodHierarchyNodeDescriptor -import com.intellij.ide.hierarchy.method.MethodHierarchyTreeStructure import com.intellij.util.ArrayUtil -import org.jetbrains.kotlin.asJava.toLightMethods -import com.intellij.util.containers.ContainerUtil - -class KotlinOverrideTreeStructure(project: Project, val element: PsiElement) : HierarchyTreeStructure(project, null) { - val javaTreeStructures = element.toLightMethods().map { method -> MethodHierarchyTreeStructure(project, method) } +import org.jetbrains.kotlin.asJava.unwrapped +import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest +import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors +import org.jetbrains.kotlin.psi.KtCallableDeclaration +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject +import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer +class KotlinOverrideTreeStructure(project: Project, declaration: KtCallableDeclaration) : HierarchyTreeStructure(project, null) { init { - setBaseElement(javaTreeStructures.first().baseDescriptor!!) + setBaseElement(KotlinOverrideHierarchyNodeDescriptor(null, declaration.containingClassOrObject!!, declaration)) } + private val baseElement = declaration.createSmartPointer() + override fun buildChildren(nodeDescriptor: HierarchyNodeDescriptor): Array { - fun buildChildrenByTreeStructure(javaTreeStructure: MethodHierarchyTreeStructure): Array { - return javaTreeStructure.getChildElements(nodeDescriptor as MethodHierarchyNodeDescriptor) ?: ArrayUtil.EMPTY_OBJECT_ARRAY - } - - return javaTreeStructures - .asSequence() - .map (::buildChildrenByTreeStructure) - .reduce { a, b -> ContainerUtil.union(a.toSet(), b.toSet()).toTypedArray() } + val baseElement = baseElement.element ?: return ArrayUtil.EMPTY_OBJECT_ARRAY + val psiElement = nodeDescriptor.psiElement ?: return ArrayUtil.EMPTY_OBJECT_ARRAY + val subclasses = HierarchySearchRequest(psiElement, psiElement.useScope, false).searchInheritors().findAll() + return subclasses + .mapNotNull { + val subclass = it.unwrapped ?: return@mapNotNull null + KotlinOverrideHierarchyNodeDescriptor(nodeDescriptor, subclass, baseElement) + } + .filter { it.calculateState() != AllIcons.Hierarchy.MethodNotDefined } + .toTypedArray() } } diff --git a/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/KotlinBuiltInMemberFunction_verification.xml b/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/KotlinBuiltInMemberFunction_verification.xml new file mode 100644 index 00000000000..dfd8a8ac07b --- /dev/null +++ b/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/KotlinBuiltInMemberFunction_verification.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/main0.kt b/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/main0.kt new file mode 100644 index 00000000000..429b24b4520 --- /dev/null +++ b/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/main0.kt @@ -0,0 +1,3 @@ +fun foo(list: List){ + list.get(1) +} \ No newline at end of file diff --git a/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/KotlinTopLevelFunction_verification.xml b/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/KotlinTopLevelFunction_verification.xml new file mode 100644 index 00000000000..6185cb81886 --- /dev/null +++ b/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/KotlinTopLevelFunction_verification.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/main0.kt b/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/main0.kt new file mode 100644 index 00000000000..0a22ad52658 --- /dev/null +++ b/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/main0.kt @@ -0,0 +1,3 @@ +fun foo() { + +} \ No newline at end of file diff --git a/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/messages.txt b/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/messages.txt new file mode 100644 index 00000000000..ac59d48ed55 --- /dev/null +++ b/idea/testData/hierarchy/overrides/kotlinTopLevelFunction/messages.txt @@ -0,0 +1 @@ +Cannot apply action for element at caret \ No newline at end of file diff --git a/idea/testData/hierarchy/overrides/kotlinVarParameter/KotlinVarParameter_verification.xml b/idea/testData/hierarchy/overrides/kotlinVarParameter/KotlinVarParameter_verification.xml new file mode 100644 index 00000000000..944df5f00a9 --- /dev/null +++ b/idea/testData/hierarchy/overrides/kotlinVarParameter/KotlinVarParameter_verification.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/idea/testData/hierarchy/overrides/kotlinVarParameter/main0.kt b/idea/testData/hierarchy/overrides/kotlinVarParameter/main0.kt new file mode 100644 index 00000000000..dbc59c77018 --- /dev/null +++ b/idea/testData/hierarchy/overrides/kotlinVarParameter/main0.kt @@ -0,0 +1,9 @@ +open class T(open var foo: String = "") + +open class X: T("") { + override var foo: String + get() = "" + set(value: String) {} +} + +open class Y(override var foo: String = ""): T(foo) \ No newline at end of file diff --git a/idea/testData/hierarchy/overrides/kotlinVarParameter/main1.java b/idea/testData/hierarchy/overrides/kotlinVarParameter/main1.java new file mode 100644 index 00000000000..c9738da785c --- /dev/null +++ b/idea/testData/hierarchy/overrides/kotlinVarParameter/main1.java @@ -0,0 +1,15 @@ +class B extends T { + B() { + super(""); + } + + @Override + public String getFoo() { + return ""; + } + + @Override + public void setFoo(String value) { + + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/hierarchy/AbstractHierarchyTest.java b/idea/tests/org/jetbrains/kotlin/idea/hierarchy/AbstractHierarchyTest.java index a10aba160b9..f423c5c70b1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/hierarchy/AbstractHierarchyTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/hierarchy/AbstractHierarchyTest.java @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCalleeTreeStructure; import org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCallerTreeStructure; import org.jetbrains.kotlin.idea.hierarchy.overrides.KotlinOverrideTreeStructure; import org.jetbrains.kotlin.idea.test.PluginTestCaseBase; +import org.jetbrains.kotlin.psi.KtCallableDeclaration; import org.jetbrains.kotlin.psi.KtElement; import java.io.File; @@ -173,7 +174,7 @@ public abstract class AbstractHierarchyTest extends KotlinHierarchyViewTestBase public HierarchyTreeStructure compute() { return new KotlinOverrideTreeStructure( getProject(), - getElementAtCaret(LanguageCallHierarchy.INSTANCE) + (KtCallableDeclaration) getElementAtCaret(LanguageMethodHierarchy.INSTANCE) ); } }; diff --git a/idea/tests/org/jetbrains/kotlin/idea/hierarchy/HierarchyTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/hierarchy/HierarchyTestGenerated.java index 4970fef301d..de9713554da 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/hierarchy/HierarchyTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/hierarchy/HierarchyTestGenerated.java @@ -560,6 +560,12 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/hierarchy/overrides"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false); } + @TestMetadata("kotlinBuiltInMemberFunction") + public void testKotlinBuiltInMemberFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/"); + doOverrideHierarchyTest(fileName); + } + @TestMetadata("kotlinFunctionInClass") public void testKotlinFunctionInClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/overrides/kotlinFunctionInClass/"); @@ -583,5 +589,17 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/overrides/kotlinPropertyInTrait/"); doOverrideHierarchyTest(fileName); } + + @TestMetadata("kotlinTopLevelFunction") + public void testKotlinTopLevelFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/overrides/kotlinTopLevelFunction/"); + doOverrideHierarchyTest(fileName); + } + + @TestMetadata("kotlinVarParameter") + public void testKotlinVarParameter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/overrides/kotlinVarParameter/"); + doOverrideHierarchyTest(fileName); + } } }