[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
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.providers.LLFirModuleWithDependenciesSymbolProvider
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 KtParameter -> findParameter(ktDeclaration)
is KtPropertyAccessor -> findNonLocalPropertyAccessor(ktDeclaration)
is KtTypeParameter -> findNonLocalTypeParameter(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 {
val ownerFunction = param.ownerFunction ?: errorWithFirSpecificEntries("Unsupported compiled parameter", psi = param)
val firDeclaration = findNonLocalDeclaration(ownerFunction)
@@ -53,7 +66,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
psi = ownerFunction,
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)
}
@@ -66,7 +79,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
?: errorWithFirSpecificEntries("We should be able to find a symbol for $classId", psi = declaration)
return (classCandidate.fir as? FirRegularClass)?.declarations?.first {
it is FirEnumEntry && it.name == declaration.nameAsName
it is FirEnumEntry && it.realPsi === declaration
} as FirEnumEntry
}
@@ -107,7 +120,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
val constructorCandidate =
symbolProvider.getClassDeclaredConstructors(classId)
.singleOrNull { representSameConstructor(declaration, it.fir) }
.singleOrNull { it.fir.realPsi === declaration }
?: errorWithFirSpecificEntries("We should be able to find a constructor", psi = declaration)
return constructorCandidate.fir
@@ -192,14 +205,6 @@ private fun FirSymbolProvider.findCallableCandidates(
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<*>>) {
withEntry("Candidates count", candidates.size.toString())
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) {
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)) {
decl.primaryConstructor?.let { return it }
}
@@ -78,6 +78,12 @@ public class LibraryGetOrBuildFirTestGenerated extends AbstractLibraryGetOrBuild
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
@TestMetadata("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/publishedApi")
@TestDataPath("$PROJECT_ROOT")