[kotlin] k2 find usages: don't leak types in from read action

+ test for local data class (failed cause local class is presented by full qName)

GitOrigin-RevId: 690fbce217b8b3f8c3a2d02ab436613c441657da
This commit is contained in:
Anna Kozlova
2023-01-09 23:01:02 +01:00
committed by intellij-monorepo-bot
parent b657d5c11f
commit 2506aedf91
10 changed files with 76 additions and 12 deletions

View File

@@ -226,6 +226,19 @@ public abstract class FindUsagesWithCompilerReferenceIndexTestGenerated extends
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../idea/tests/testData/findUsages/kotlin/conventions/components")
public static class TestDataClassComponentByRefLocal extends AbstractFindUsagesWithCompilerReferenceIndexTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("dataClassComponentByRefLocal.0.kt")
public void testDataClassComponentByRefLocal() throws Exception {
runTest("../../idea/tests/testData/findUsages/kotlin/conventions/components/dataClassComponentByRefLocal.0.kt");
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../idea/tests/testData/findUsages/kotlin/conventions/components")
public static class TestDataClassFromStdlib extends AbstractFindUsagesWithCompilerReferenceIndexTest {

View File

@@ -114,6 +114,11 @@ public abstract class FindUsagesFirTestGenerated extends AbstractFindUsagesFirTe
runTest("../idea/tests/testData/findUsages/kotlin/conventions/components/dataClassComponentByRef.0.kt");
}
@TestMetadata("dataClassComponentByRefLocal.0.kt")
public void testDataClassComponentByRefLocal() throws Exception {
runTest("../idea/tests/testData/findUsages/kotlin/conventions/components/dataClassComponentByRefLocal.0.kt");
}
@TestMetadata("dataClassFromStdlib.0.kt")
public void testDataClassFromStdlib() throws Exception {
runTest("../idea/tests/testData/findUsages/kotlin/conventions/components/dataClassFromStdlib.0.kt");

View File

@@ -53,6 +53,11 @@ public class FindUsagesWithDisableComponentSearchFirTestGenerated extends Abstra
runTest("../idea/tests/testData/findUsages/kotlin/conventions/components/dataClassComponentByRef.0.kt");
}
@TestMetadata("dataClassComponentByRefLocal.0.kt")
public void testDataClassComponentByRefLocal() throws Exception {
runTest("../idea/tests/testData/findUsages/kotlin/conventions/components/dataClassComponentByRefLocal.0.kt");
}
@TestMetadata("dataClassFromStdlib.0.kt")
public void testDataClassFromStdlib() throws Exception {
runTest("../idea/tests/testData/findUsages/kotlin/conventions/components/dataClassFromStdlib.0.kt");

View File

@@ -114,6 +114,11 @@ public abstract class FindUsagesTestGenerated extends AbstractFindUsagesTest {
runTest("testData/findUsages/kotlin/conventions/components/dataClassComponentByRef.0.kt");
}
@TestMetadata("dataClassComponentByRefLocal.0.kt")
public void testDataClassComponentByRefLocal() throws Exception {
runTest("testData/findUsages/kotlin/conventions/components/dataClassComponentByRefLocal.0.kt");
}
@TestMetadata("dataClassFromStdlib.0.kt")
public void testDataClassFromStdlib() throws Exception {
runTest("testData/findUsages/kotlin/conventions/components/dataClassFromStdlib.0.kt");

View File

@@ -53,6 +53,11 @@ public class FindUsagesWithDisableComponentSearchTestGenerated extends AbstractF
runTest("testData/findUsages/kotlin/conventions/components/dataClassComponentByRef.0.kt");
}
@TestMetadata("dataClassComponentByRefLocal.0.kt")
public void testDataClassComponentByRefLocal() throws Exception {
runTest("testData/findUsages/kotlin/conventions/components/dataClassComponentByRefLocal.0.kt");
}
@TestMetadata("dataClassFromStdlib.0.kt")
public void testDataClassFromStdlib() throws Exception {
runTest("testData/findUsages/kotlin/conventions/components/dataClassFromStdlib.0.kt");

View File

@@ -0,0 +1,13 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtParameter
// OPTIONS: usages
// FIND_BY_REF
fun test() {
data class A(val n: Int, val s: String, val o: Any)
val a = A(1, "2", Any())
a.n
a.<caret>component1()
val (x, y, z) = a
}
// FIR_COMPARISON_WITH_DISABLED_COMPONENTS
// IGNORE_FIR_LOG

View File

@@ -0,0 +1,9 @@
Checked type of a
Checked type of x
Checked type of y
Checked type of z
Resolved (x, y, z)
Searched imported static member PROPERTY in [BLOCK]
Searched references to null
Used plain search of parameter n of A(val n: Int, val s: String, val o: Any) in LocalSearchScope:
CLASS:A

View File

@@ -0,0 +1,3 @@
Function call 9 a.component1()
Value read 10 val (x, y, z) = a
Value read 8 a.n

View File

@@ -9,6 +9,7 @@ import com.intellij.psi.impl.source.PsiClassReferenceType
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.SearchScope
import com.intellij.psi.util.MethodSignatureUtil
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.analysis.api.*
import org.jetbrains.kotlin.analysis.api.calls.KtDelegatedConstructorCall
import org.jetbrains.kotlin.analysis.api.calls.symbol
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.descriptors.Modality
@@ -29,6 +31,7 @@ import org.jetbrains.kotlin.idea.search.ReceiverTypeSearcherInfo
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.ImportPath
@@ -153,20 +156,22 @@ internal class KotlinK2SearchUsagesSupport : KotlinSearchUsagesSupport {
is KtValueParameterSymbol -> {
// TODO: The following code handles only constructors. Handle other cases e.g.,
// look for uses of component functions cf [isDestructionDeclarationSearch]
val constructorSymbol =
elementSymbol.getContainingSymbol() as? KtConstructorSymbol ?: return@analyzeWithReadAction null
val containingClassType = getContainingClassType(constructorSymbol) ?: return@analyzeWithReadAction null
val psiClass = getPsiClassOfKtType(containingClassType) ?: return@analyzeWithReadAction null
val psiClass = PsiTreeUtil.getParentOfType(psiElement, KtClassOrObject::class.java)?.toLightClass() ?: return@analyzeWithReadAction null
ReceiverTypeSearcherInfo(psiClass) {
analyze(it) {
val returnType = it.getReturnKtType()
returnType == containingClassType || returnType is KtNonErrorClassType && returnType.ownTypeArguments.any { arg ->
when (arg) {
is KtStarTypeProjection -> false
is KtTypeArgumentWithVariance -> arg.type == containingClassType
}
val classPointer = psiClass.createSmartPointer()
ReceiverTypeSearcherInfo(psiClass) { declaration ->
analyzeWithReadAction(declaration) {
fun KtType.containsClassType(clazz: PsiClass?): Boolean {
if (clazz == null) return false
return this is KtNonErrorClassType && (clazz.isEquivalentTo(getPsiClassOfKtType(this)) || this.ownTypeArguments.any { arg ->
when (arg) {
is KtStarTypeProjection -> false
is KtTypeArgumentWithVariance -> arg.type.containsClassType(clazz)
}
})
}
declaration.getReturnKtType().containsClassType(classPointer.element)
}
}
}