diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/FirDeclarationForCompiledElementSearcher.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/FirDeclarationForCompiledElementSearcher.kt index d34ec0bcf79..9d531d1c139 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/FirDeclarationForCompiledElementSearcher.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/FirDeclarationForCompiledElementSearcher.kt @@ -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>) { withEntry("Candidates count", candidates.size.toString()) for ((index, candidate) in candidates.withIndex()) { diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFirBinary/typeParameter.kt b/analysis/low-level-api-fir/testdata/getOrBuildFirBinary/typeParameter.kt new file mode 100644 index 00000000000..222b8b57466 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFirBinary/typeParameter.kt @@ -0,0 +1,4 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtTypeParameter +class FooBar { + fun doSmth(t: T) {} +} diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFirBinary/typeParameter.txt b/analysis/low-level-api-fir/testdata/getOrBuildFirBinary/typeParameter.txt new file mode 100644 index 00000000000..f701ce85fe6 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFirBinary/typeParameter.txt @@ -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 diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractLibraryGetOrBuildFirTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractLibraryGetOrBuildFirTest.kt index efaf3f59888..07754f14598 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractLibraryGetOrBuildFirTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractLibraryGetOrBuildFirTest.kt @@ -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 } } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/LibraryGetOrBuildFirTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/LibraryGetOrBuildFirTestGenerated.java index 552d3bebe6a..406e68fb8ff 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/LibraryGetOrBuildFirTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/LibraryGetOrBuildFirTestGenerated.java @@ -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")