[LL] support search for decompiled fir for type parameters
^ KTIJ-25976
This commit is contained in:
+16
-11
@@ -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
|
||||
+3
@@ -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 }
|
||||
}
|
||||
|
||||
+6
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user