[LL] support search for decompiled fir for type parameters

^ KTIJ-25976
This commit is contained in:
Anna Kozlova
2023-06-22 12:27:19 +02:00
committed by Space Team
parent d439bdd49f
commit abdc44c18a
5 changed files with 37 additions and 11 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.util package org.jetbrains.kotlin.analysis.low.level.api.fir.util
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.containingDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirBuiltinsAndCloneableSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirBuiltinsAndCloneableSession
@@ -40,11 +41,23 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
is KtProperty -> findNonLocalProperty(ktDeclaration) is KtProperty -> findNonLocalProperty(ktDeclaration)
is KtParameter -> findParameter(ktDeclaration) is KtParameter -> findParameter(ktDeclaration)
is KtPropertyAccessor -> findNonLocalPropertyAccessor(ktDeclaration) is KtPropertyAccessor -> findNonLocalPropertyAccessor(ktDeclaration)
is KtTypeParameter -> findNonLocalTypeParameter(ktDeclaration)
else -> errorWithFirSpecificEntries("Unsupported compiled declaration of type", psi = ktDeclaration) else -> errorWithFirSpecificEntries("Unsupported compiled declaration of type", psi = ktDeclaration)
} }
} }
private fun findNonLocalTypeParameter(param: KtTypeParameter): FirDeclaration {
val owner = param.containingDeclaration ?: errorWithFirSpecificEntries("Unsupported compiled type parameter", psi = param)
val firDeclaration = findNonLocalDeclaration(owner)
val firTypeParameterRefOwner = firDeclaration as? FirTypeParameterRefsOwner ?: errorWithFirSpecificEntries(
"No fir found by $owner",
psi = owner,
fir = firDeclaration
)
return firTypeParameterRefOwner.typeParameters.find { it.realPsi === param } as FirDeclaration
}
private fun findParameter(param: KtParameter): FirDeclaration { private fun findParameter(param: KtParameter): FirDeclaration {
val ownerFunction = param.ownerFunction ?: errorWithFirSpecificEntries("Unsupported compiled parameter", psi = param) val ownerFunction = param.ownerFunction ?: errorWithFirSpecificEntries("Unsupported compiled parameter", psi = param)
val firDeclaration = findNonLocalDeclaration(ownerFunction) val firDeclaration = findNonLocalDeclaration(ownerFunction)
@@ -53,7 +66,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
psi = ownerFunction, psi = ownerFunction,
fir = firDeclaration fir = firDeclaration
) )
return firFunction.valueParameters.find { it.name == param.nameAsSafeName } return firFunction.valueParameters.find { it.realPsi === param }
?: errorWithFirSpecificEntries("No fir value parameter found", psi = param, fir = firFunction) ?: errorWithFirSpecificEntries("No fir value parameter found", psi = param, fir = firFunction)
} }
@@ -66,7 +79,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
?: errorWithFirSpecificEntries("We should be able to find a symbol for $classId", psi = declaration) ?: errorWithFirSpecificEntries("We should be able to find a symbol for $classId", psi = declaration)
return (classCandidate.fir as? FirRegularClass)?.declarations?.first { return (classCandidate.fir as? FirRegularClass)?.declarations?.first {
it is FirEnumEntry && it.name == declaration.nameAsName it is FirEnumEntry && it.realPsi === declaration
} as FirEnumEntry } as FirEnumEntry
} }
@@ -107,7 +120,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
val constructorCandidate = val constructorCandidate =
symbolProvider.getClassDeclaredConstructors(classId) symbolProvider.getClassDeclaredConstructors(classId)
.singleOrNull { representSameConstructor(declaration, it.fir) } .singleOrNull { it.fir.realPsi === declaration }
?: errorWithFirSpecificEntries("We should be able to find a constructor", psi = declaration) ?: errorWithFirSpecificEntries("We should be able to find a constructor", psi = declaration)
return constructorCandidate.fir return constructorCandidate.fir
@@ -192,14 +205,6 @@ private fun FirSymbolProvider.findCallableCandidates(
getClassDeclaredPropertySymbols(containerClassId, shortName) getClassDeclaredPropertySymbols(containerClassId, shortName)
} }
private fun representSameConstructor(psiConstructor: KtConstructor<*>, firConstructor: FirConstructor): Boolean {
if ((firConstructor.isPrimary) != (psiConstructor is KtPrimaryConstructor)) {
return false
}
return firConstructor.realPsi === psiConstructor
}
private fun ExceptionAttachmentBuilder.withCandidates(candidates: List<FirBasedSymbol<*>>) { private fun ExceptionAttachmentBuilder.withCandidates(candidates: List<FirBasedSymbol<*>>) {
withEntry("Candidates count", candidates.size.toString()) withEntry("Candidates count", candidates.size.toString())
for ((index, candidate) in candidates.withIndex()) { for ((index, candidate) in candidates.withIndex()) {
@@ -0,0 +1,4 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtTypeParameter
class FooBar<T> {
fun doSmth(t: T) {}
}
@@ -0,0 +1,8 @@
KT element: KtTypeParameter
KT element text:
T
FIR element: FirTypeParameterImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
[ResolvedTo(BODY_RESOLVE)] T
@@ -63,6 +63,9 @@ abstract class AbstractLibraryGetOrBuildFirTest : AbstractLowLevelApiSingleFileT
if (decl is KtProperty) { if (decl is KtProperty) {
findFirstDeclaration(decl.accessors, expectedClass)?.let { return it } findFirstDeclaration(decl.accessors, expectedClass)?.let { return it }
} }
if (decl is KtTypeParameterListOwner) {
findFirstDeclaration(decl.typeParameters, expectedClass)?.let { return it }
}
if (decl is KtClass && KtConstructor::class.java.isAssignableFrom(expectedClass)) { if (decl is KtClass && KtConstructor::class.java.isAssignableFrom(expectedClass)) {
decl.primaryConstructor?.let { return it } decl.primaryConstructor?.let { return it }
} }
@@ -78,6 +78,12 @@ public class LibraryGetOrBuildFirTestGenerated extends AbstractLibraryGetOrBuild
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/topLevelFunction.kt"); runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/topLevelFunction.kt");
} }
@Test
@TestMetadata("typeParameter.kt")
public void testTypeParameter() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/typeParameter.kt");
}
@Nested @Nested
@TestMetadata("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/publishedApi") @TestMetadata("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/publishedApi")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")