[kotlin] k2: find usages on class: allow to filter out constructor usages in kmp projects

- for k1 constructor usages are filtered in the current source set as before

^KTIJ-29819 fixed
^KTIJ-29820 fixed

GitOrigin-RevId: 9df16dc174bc05c4fdff672feabd40f9b2aba0b8
This commit is contained in:
Anna Kozlova
2024-05-06 23:09:43 +00:00
committed by intellij-monorepo-bot
parent 57f3d47e46
commit 5383d8e169
20 changed files with 81 additions and 14 deletions
@@ -63,6 +63,9 @@ interface KotlinSearchUsagesSupport {
fun PsiReference.isUsageInContainingDeclaration(declaration: KtNamedDeclaration): Boolean =
getInstance(declaration.project).isUsageInContainingDeclaration(this, declaration)
fun PsiReference.isUsageOfActual(declaration: KtNamedDeclaration): Boolean =
getInstance(declaration.project).isUsageOfActual(this, declaration)
fun PsiReference.isExtensionOfDeclarationClassUsage(declaration: KtNamedDeclaration): Boolean =
getInstance(declaration.project).isExtensionOfDeclarationClassUsage(this, declaration)
@@ -109,6 +112,8 @@ interface KotlinSearchUsagesSupport {
getInstance(psiMethod.project).createConstructorHandle(psiMethod)
}
fun isUsageOfActual(reference: PsiReference, declaration: KtNamedDeclaration): Boolean
fun isInvokeOfCompanionObject(psiReference: PsiReference, searchTarget: KtNamedDeclaration): Boolean
fun isCallableOverrideUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean
@@ -10,11 +10,16 @@ import com.intellij.psi.ReferenceRange
import com.intellij.psi.search.RequestResultProcessor
import com.intellij.util.Processor
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.idea.base.psi.isExpectDeclaration
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
import org.jetbrains.kotlin.idea.references.unwrappedTargets
import org.jetbrains.kotlin.idea.search.ExpectActualSupport
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.isCallableOverrideUsage
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.isExtensionOfDeclarationClassUsage
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.isInvokeOfCompanionObject
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.isUsageInContainingDeclaration
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.isUsageOfActual
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedDeclaration
@@ -55,7 +60,13 @@ class KotlinRequestResultProcessor(
if (resolve()?.unwrapped == element.originalElement) {
return true
}
if (originalElement is KtNamedDeclaration) {
if (options.searchForExpectedUsages && isUsageOfActual(originalElement)
) {
return true
}
if (isInvokeOfCompanionObject(originalElement)) {
return true
}
@@ -21,6 +21,11 @@ class KotlinSearchUsagesSupportImpl : KotlinSearchUsagesSupport {
return false
}
override fun isUsageOfActual(
reference: PsiReference,
declaration: KtNamedDeclaration
): Boolean = false
override fun isCallableOverrideUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean =
reference.isCallableOverrideUsage(declaration)
@@ -69,6 +69,14 @@ open class FindUsagesMultiModuleTest : AbstractFindUsagesMultiModuleTest() {
doTest()
}
fun testFindClassConstructors() {
doTest()
}
fun testFindClassUsagesWithoutConstructors() {
doTest()
}
private fun doTest() {
setupMppProjectFromDirStructure(getTestdataFile())
doFindUsagesTest()
@@ -0,0 +1,2 @@
expect open class Clazz004()
val ac = Clazz004()
@@ -0,0 +1,5 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtClass
// OPTIONS: constructorUsages, expected
actual open class Cla<caret>zz004 actual constructor()
val a1 = Clazz004()
// IGNORE_K2_LOG
@@ -0,0 +1,3 @@
[common.kt] New instance creation 2 val ac = Clazz004()
[js.kt] New instance creation 4 val a1 = Clazz004()
[jvm.kt] New instance creation 2 val a2 = Clazz004()
@@ -0,0 +1,2 @@
actual open class Clazz004 actual constructor()
val a2 = Clazz004()
@@ -0,0 +1,2 @@
expect open class Clazz004()
val ac = Clazz004()
@@ -0,0 +1,5 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtClass
// OPTIONS: usages, expected
actual open class Cla<caret>zz004 actual constructor()
val a1 = Clazz004()
// IGNORE_K2_LOG
@@ -0,0 +1,2 @@
[common.kt] New instance creation 2 val ac = Clazz004()
[jvm.kt] New instance creation 2 val a2 = Clazz004()
@@ -0,0 +1,2 @@
actual open class Clazz004 actual constructor()
val a2 = Clazz004()
@@ -1,5 +1,5 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtClass
// OPTIONS: usages, expected
// OPTIONS: usages, constructorUsages, expected
actual class <caret>My(val s: String) {
actual fun boo() {}
@@ -1,5 +1,5 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtClass
// OPTIONS: usages, expected
// OPTIONS: usages, constructorUsages, expected
expect open class O<caret>Class(i: Int)
expect class Inheritor : OClass
@@ -15,8 +15,9 @@ import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtRendererAnn
import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer
import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForSource
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow
import org.jetbrains.kotlin.idea.base.analysis.api.utils.getImplicitReceivers
@@ -108,8 +109,13 @@ internal class KotlinK2FindUsagesSupport : KotlinFindUsagesSupport {
is KtFunctionCall<*> -> {
val constructorSymbol = call.symbol as? KtConstructorSymbol ?: return@withResolvedCall false
val constructedClassSymbol =
constructorSymbol.getContainingSymbol() as? KtClassifierSymbol ?: return@withResolvedCall false
constructedClassSymbol == ktClassOrObject.getClassOrObjectSymbol()
constructorSymbol.getContainingSymbol() as? KtClassLikeSymbol ?: return@withResolvedCall false
val classOrObjectSymbol = ktClassOrObject.getClassOrObjectSymbol()
fun KtClassLikeSymbol.getExpectsOrSelf(): List<KtDeclarationSymbol> = (listOf(this).takeIf { isExpect } ?: getExpectsForActual())
constructedClassSymbol == classOrObjectSymbol ||
constructedClassSymbol.getExpectsOrSelf() == classOrObjectSymbol?.getExpectsOrSelf()
}
else -> false
@@ -84,12 +84,16 @@ internal class KotlinK2SearchUsagesSupport : KotlinSearchUsagesSupport {
}
}
override fun isCallableOverrideUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean {
if (declaration.isExpectDeclaration() &&
reference.unwrappedTargets.any { target -> target is KtDeclaration && ExpectActualSupport.getInstance(declaration.project).expectedDeclarationIfAny(target) == declaration }) {
return true
}
override fun isUsageOfActual(
reference: PsiReference,
declaration: KtNamedDeclaration
): Boolean = declaration.isExpectDeclaration() &&
reference.unwrappedTargets.any { target ->
target is KtDeclaration && ExpectActualSupport.getInstance(declaration.project)
.expectedDeclarationIfAny(target) == declaration
}
override fun isCallableOverrideUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean {
fun KtDeclaration.isTopLevelCallable() = when (this) {
is KtNamedFunction -> isTopLevel
is KtProperty -> isTopLevel
@@ -35,6 +35,8 @@ import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
import org.jetbrains.kotlin.idea.facet.initializeIfNeeded
import org.jetbrains.kotlin.idea.test.KotlinTestUtils.allowProjectRootAccess
import org.jetbrains.kotlin.idea.test.KotlinTestUtils.disposeVfsRootAccess
import org.jetbrains.kotlin.idea.test.util.checkPluginIsCorrect
import org.jetbrains.kotlin.idea.test.util.setUpWithKotlinPlugin
import org.jetbrains.kotlin.idea.test.util.slashedPath
import org.jetbrains.kotlin.idea.util.sourceRoots
import org.jetbrains.kotlin.konan.target.TargetSupportException
@@ -62,11 +64,12 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase(),
}
override fun setUp() {
super.setUp()
enableKotlinOfficialCodeStyle(project)
setUpWithKotlinPlugin(isFirPlugin()) {
super.setUp()
enableKotlinOfficialCodeStyle(project)
vfsDisposable = allowProjectRootAccess(this)
assertKotlinPluginMode()
vfsDisposable = allowProjectRootAccess(this)
}
}
// [TargetSupportException] can be thrown by the multiplatform test setup when a test artifact doesn't exist for the host platform.