Method Hierarchy: Refactoring

- Do not rely on light methods and Java method hierarchy
- Support val/var parameters
- Support built-in member functions

 #KT-14346 Fixed
This commit is contained in:
Alexey Sedunov
2017-07-03 20:44:41 +03:00
parent 10941ae732
commit 53d12e6cf7
16 changed files with 316 additions and 39 deletions
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.asJava
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.KtLightAnnotationForSourceEntry 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.load.java.propertyNameBySetMethodName
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType 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.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? { fun KtFile.findFacadeClass(): KtLightClass? {
return LightClassGenerationSupport.getInstance(project) return LightClassGenerationSupport.getInstance(project)
.getFacadeClassesInPackage(packageFqName, this.useScope as? GlobalSearchScope ?: GlobalSearchScope.projectScope(project)) .getFacadeClassesInPackage(packageFqName, this.useScope as? GlobalSearchScope ?: GlobalSearchScope.projectScope(project))
@@ -22,13 +22,13 @@ import com.intellij.psi.PsiModifier
import com.intellij.psi.search.searches.ClassInheritorsSearch import com.intellij.psi.search.searches.ClassInheritorsSearch
import com.intellij.util.EmptyQuery import com.intellij.util.EmptyQuery
import com.intellij.util.Query 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.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
fun HierarchySearchRequest<*>.searchInheritors(): Query<PsiClass> { fun HierarchySearchRequest<*>.searchInheritors(): Query<PsiClass> {
val psiClass: PsiClass = when (originalElement) { val psiClass: PsiClass = when (originalElement) {
is KtClassOrObject -> runReadAction { originalElement.toLightClass() } is KtClassOrObject -> runReadAction { originalElement.toLightClassWithBuiltinMapping() }
is PsiClass -> originalElement is PsiClass -> originalElement
else -> null else -> null
} ?: return EmptyQuery.getEmptyQuery() } ?: return EmptyQuery.getEmptyQuery()
@@ -16,23 +16,42 @@
package org.jetbrains.kotlin.idea.hierarchy.overrides package org.jetbrains.kotlin.idea.hierarchy.overrides
import com.intellij.ide.hierarchy.HierarchyNodeDescriptor
import com.intellij.ide.hierarchy.HierarchyTreeStructure import com.intellij.ide.hierarchy.HierarchyTreeStructure
import com.intellij.ide.hierarchy.JavaHierarchyUtil
import com.intellij.ide.hierarchy.MethodHierarchyBrowserBase 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.openapi.project.Project
import com.intellij.psi.ElementDescriptionUtil import com.intellij.psi.ElementDescriptionUtil
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod import com.intellij.ui.PopupHandler
import com.intellij.usageView.UsageViewLongNameLocation import com.intellij.usageView.UsageViewLongNameLocation
import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod
import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import javax.swing.JPanel import javax.swing.JPanel
import javax.swing.JTree
class KotlinOverrideHierarchyBrowser( class KotlinOverrideHierarchyBrowser(
project: Project, baseElement: PsiElement project: Project, baseElement: PsiElement
) : MethodHierarchyBrowser(project, baseElement.getRepresentativeLightMethod()) { ) : MethodHierarchyBrowserBase(project, baseElement) {
override fun createTrees(trees: MutableMap<String, JTree>) {
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? = override fun createLegendPanel(): JPanel? =
MethodHierarchyBrowserBase.createStandardLegendPanel( MethodHierarchyBrowserBase.createStandardLegendPanel(
KotlinBundle.message("hierarchy.legend.member.is.defined.in.class"), KotlinBundle.message("hierarchy.legend.member.is.defined.in.class"),
@@ -40,18 +59,15 @@ class KotlinOverrideHierarchyBrowser(
KotlinBundle.message("hierarchy.legend.member.should.be.defined") KotlinBundle.message("hierarchy.legend.member.should.be.defined")
) )
override fun getElementFromDescriptor(descriptor: HierarchyNodeDescriptor) = descriptor.psiElement
override fun isApplicableElement(psiElement: PsiElement): Boolean = override fun isApplicableElement(psiElement: PsiElement): Boolean =
psiElement.isOverrideHierarchyElement() psiElement.isOverrideHierarchyElement()
override fun createHierarchyTreeStructure(typeName: String, psiElement: PsiElement): HierarchyTreeStructure? = 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? { override fun getComparator() = JavaHierarchyUtil.getComparator(myProject)!!
val builder = myBuilders.get(myCurrentViewType)
if (builder == null) return null
return (builder.treeStructure as KotlinOverrideTreeStructure).javaTreeStructures.get(0).baseMethod
}
override fun getContentDisplayName(typeName: String, element: PsiElement): String? { override fun getContentDisplayName(typeName: String, element: PsiElement): String? {
val targetElement = element.unwrapped val targetElement = element.unwrapped
@@ -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
}
}
@@ -23,10 +23,9 @@ import com.intellij.ide.hierarchy.MethodHierarchyBrowserBase
import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext import com.intellij.openapi.actionSystem.DataContext
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.idea.hierarchy.getCurrentElement import org.jetbrains.kotlin.idea.hierarchy.getCurrentElement
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
class KotlinOverrideHierarchyProvider: HierarchyProvider { class KotlinOverrideHierarchyProvider: HierarchyProvider {
@@ -44,8 +43,7 @@ class KotlinOverrideHierarchyProvider: HierarchyProvider {
} }
private fun getOverrideHierarchyElement(element: PsiElement?): PsiElement? private fun getOverrideHierarchyElement(element: PsiElement?): PsiElement?
= element?.getParentOfTypesAndPredicate() { it.isOverrideHierarchyElement() } = element?.getParentOfTypesAndPredicate { it.isOverrideHierarchyElement() }
} }
fun PsiElement.isOverrideHierarchyElement(): Boolean fun PsiElement.isOverrideHierarchyElement() = this is KtCallableDeclaration && containingClassOrObject != null
= this is PsiMethod || this is KtNamedFunction || this is KtProperty
@@ -16,31 +16,35 @@
package org.jetbrains.kotlin.idea.hierarchy.overrides 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.HierarchyNodeDescriptor
import com.intellij.ide.hierarchy.HierarchyTreeStructure
import com.intellij.openapi.project.Project 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 com.intellij.util.ArrayUtil
import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.asJava.unwrapped
import com.intellij.util.containers.ContainerUtil import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
class KotlinOverrideTreeStructure(project: Project, val element: PsiElement) : HierarchyTreeStructure(project, null) { import org.jetbrains.kotlin.psi.KtCallableDeclaration
val javaTreeStructures = element.toLightMethods().map { method -> MethodHierarchyTreeStructure(project, method) } import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
class KotlinOverrideTreeStructure(project: Project, declaration: KtCallableDeclaration) : HierarchyTreeStructure(project, null) {
init { init {
setBaseElement(javaTreeStructures.first().baseDescriptor!!) setBaseElement(KotlinOverrideHierarchyNodeDescriptor(null, declaration.containingClassOrObject!!, declaration))
} }
private val baseElement = declaration.createSmartPointer()
override fun buildChildren(nodeDescriptor: HierarchyNodeDescriptor): Array<Any> { override fun buildChildren(nodeDescriptor: HierarchyNodeDescriptor): Array<Any> {
fun buildChildrenByTreeStructure(javaTreeStructure: MethodHierarchyTreeStructure): Array<Any> { val baseElement = baseElement.element ?: return ArrayUtil.EMPTY_OBJECT_ARRAY
return javaTreeStructure.getChildElements(nodeDescriptor as MethodHierarchyNodeDescriptor) ?: ArrayUtil.EMPTY_OBJECT_ARRAY val psiElement = nodeDescriptor.psiElement ?: return ArrayUtil.EMPTY_OBJECT_ARRAY
} val subclasses = HierarchySearchRequest(psiElement, psiElement.useScope, false).searchInheritors().findAll()
return subclasses
return javaTreeStructures .mapNotNull {
.asSequence() val subclass = it.unwrapped ?: return@mapNotNull null
.map (::buildChildrenByTreeStructure) KotlinOverrideHierarchyNodeDescriptor(nodeDescriptor, subclass, baseElement)
.reduce { a, b -> ContainerUtil.union(a.toSet(), b.toSet()).toTypedArray() } }
.filter { it.calculateState() != AllIcons.Hierarchy.MethodNotDefined }
.toTypedArray()
} }
} }
@@ -0,0 +1,20 @@
<node text="List (kotlin.collections)" base="true">
<node text="UnmodifiableList in Collections (java.util)"/>
<node text="CheckedList in Collections (java.util)"/>
<node text="SynchronizedList in Collections (java.util)"/>
<node text="AbstractList (java.util)">
<node text="ArrayList in Arrays (java.util)"/>
<node text="EmptyList in Collections (java.util)"/>
<node text="SubList in ArrayList (java.util)"/>
<node text="AbstractSequentialList (java.util)"/>
<node text="CopiesList in Collections (java.util)"/>
<node text="SingletonList in Collections (java.util)"/>
<node text="ArrayList (java.util)"/>
</node>
<node text="ArrayList (java.util)"/>
<node text="AbstractList (kotlin.collections)">
<node text="SubList in AbstractList (kotlin.collections)"/>
<node text="ReversedListReadOnly (kotlin.collections)"/>
</node>
<node text="EmptyList (kotlin.collections)"/>
</node>
@@ -0,0 +1,3 @@
fun foo(list: List<String>){
list.<caret>get(1)
}
@@ -0,0 +1,12 @@
<node text="T ()" base="true">
<node text="B ()"/>
<node text="X ()"/>
<node text="Y ()">
<node text="A ()">
<node text="C ()"/>
</node>
<node text="Z ()">
<node text="D ()"/>
</node>
</node>
</node>
@@ -0,0 +1,3 @@
fun <caret>foo() {
}
@@ -0,0 +1 @@
Cannot apply action for element at caret
@@ -0,0 +1,5 @@
<node text="T ()" base="true">
<node text="B ()"/>
<node text="X ()"/>
<node text="Y ()"/>
</node>
@@ -0,0 +1,9 @@
open class T(open var <caret>foo: String = "")
open class X: T("") {
override var foo: String
get() = ""
set(value: String) {}
}
open class Y(override var foo: String = ""): T(foo)
@@ -0,0 +1,15 @@
class B extends T {
B() {
super("");
}
@Override
public String getFoo() {
return "";
}
@Override
public void setFoo(String value) {
}
}
@@ -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.calls.KotlinCallerTreeStructure;
import org.jetbrains.kotlin.idea.hierarchy.overrides.KotlinOverrideTreeStructure; import org.jetbrains.kotlin.idea.hierarchy.overrides.KotlinOverrideTreeStructure;
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase; import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
import org.jetbrains.kotlin.psi.KtCallableDeclaration;
import org.jetbrains.kotlin.psi.KtElement; import org.jetbrains.kotlin.psi.KtElement;
import java.io.File; import java.io.File;
@@ -173,7 +174,7 @@ public abstract class AbstractHierarchyTest extends KotlinHierarchyViewTestBase
public HierarchyTreeStructure compute() { public HierarchyTreeStructure compute() {
return new KotlinOverrideTreeStructure( return new KotlinOverrideTreeStructure(
getProject(), getProject(),
getElementAtCaret(LanguageCallHierarchy.INSTANCE) (KtCallableDeclaration) getElementAtCaret(LanguageMethodHierarchy.INSTANCE)
); );
} }
}; };
@@ -560,6 +560,12 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/hierarchy/overrides"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false); 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") @TestMetadata("kotlinFunctionInClass")
public void testKotlinFunctionInClass() throws Exception { public void testKotlinFunctionInClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/overrides/kotlinFunctionInClass/"); 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/"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/hierarchy/overrides/kotlinPropertyInTrait/");
doOverrideHierarchyTest(fileName); 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);
}
} }
} }