diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt index 4e19ade561b..7635d27ab4e 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.utils.correspondingValueParameterFromPrimaryConstructor import org.jetbrains.kotlin.fir.expressions.FirAnnotation @@ -164,7 +165,7 @@ internal class FirElementBuilder( declarationProvider = { when (val parent = it.parent) { is KtDeclaration -> parent - is KtSuperTypeListEntry, is KtConstructorCalleeExpression -> parent.parentOfType() + is KtSuperTypeListEntry, is KtConstructorCalleeExpression, is KtTypeConstraint -> parent.parentOfType() else -> null } }, @@ -199,14 +200,14 @@ internal class FirElementBuilder( if (this is FirCallableDeclaration) { returnTypeRef.takeIf { it.psi == typeReference }?.let { return it } receiverParameter?.takeIf { it.typeRef.psi == typeReference }?.let { return it } + + for (typeParameterRef in typeParameters) { + typeParameterRef.findTypeRefAnchor(typeReference)?.let { return it } + } } if (this is FirTypeParameter) { - for (typeRef in bounds) { - if (typeRef.psi == typeReference) { - return typeRef - } - } + findTypeRefAnchor(typeReference)?.let { return it } } if (this is FirClass) { @@ -220,6 +221,18 @@ internal class FirElementBuilder( return null } + private fun FirTypeParameterRef.findTypeRefAnchor(typeReference: KtTypeReference): FirElement? { + if (this !is FirTypeParameter) return null + + for (typeRef in bounds) { + if (typeRef.psi == typeReference) { + return typeRef + } + } + + return null + } + private fun FirDeclaration.resolveAndFindAnnotation(annotationEntry: KtAnnotationEntry, goDeep: Boolean = false): FirAnnotation? { lazyResolveToPhase(FirResolvePhase.ANNOTATION_ARGUMENTS) findAnnotation(annotationEntry)?.let { return it } diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/annotationInsideWhereFunction.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/annotationInsideWhereFunction.txt index d2de8dc7998..a39cddef173 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/annotationInsideWhereFunction.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/annotationInsideWhereFunction.txt @@ -20,6 +20,6 @@ FILE: [ResolvedTo(IMPORTS)] annotationInsideWhereFunction.kt } public? final? [ResolvedTo(RAW_FIR)] interface Two : R|kotlin/Any| { } - public final [ResolvedTo(BODY_RESOLVE)] fun <[ResolvedTo(BODY_RESOLVE)] T : R|One|, R|@R|Anno|(s = String(str)) Two|> foo([ResolvedTo(BODY_RESOLVE)] t: R|T|): R|T| { + public final [ResolvedTo(ANNOTATION_ARGUMENTS)] fun <[ResolvedTo(ANNOTATION_ARGUMENTS)] T : R|One|, R|@R|Anno|(s = String(str)) Two|> foo([ResolvedTo(ANNOTATION_ARGUMENTS)] t: R|T|): R|T| { ^foo R|/t| - } + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/annotationInsideWhereProperty.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/annotationInsideWhereProperty.txt index b3c8e5a4722..77862bd67c8 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/annotationInsideWhereProperty.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/annotationInsideWhereProperty.txt @@ -20,7 +20,7 @@ FILE: [ResolvedTo(IMPORTS)] annotationInsideWhereProperty.kt } public abstract [ResolvedTo(STATUS)] interface Two : R|kotlin/Any| { } - public final [ResolvedTo(BODY_RESOLVE)] val <[ResolvedTo(BODY_RESOLVE)] T : R|One|, R|@R|Anno|(s = String(str)) Two|> R|T|.foo: R|T| - public [ResolvedTo(BODY_RESOLVE)] get(): R|T| { + public final [ResolvedTo(ANNOTATION_ARGUMENTS)] val <[ResolvedTo(ANNOTATION_ARGUMENTS)] T : R|One|, R|@R|Anno|(s = String(str)) Two|> R|T|.foo: R|T| + public [ResolvedTo(ANNOTATION_ARGUMENTS)] get(): R|T| { ^ this@R|/foo| - } + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/types/whereFunction.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/types/whereFunction.txt index a6dfaeb8841..b14d16f6447 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/types/whereFunction.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/types/whereFunction.txt @@ -11,6 +11,6 @@ FILE: [ResolvedTo(IMPORTS)] whereFunction.kt } public? final? [ResolvedTo(RAW_FIR)] interface Two : R|kotlin/Any| { } - public final [ResolvedTo(BODY_RESOLVE)] fun <[ResolvedTo(BODY_RESOLVE)] T : R|One|, R|Two|> foo([ResolvedTo(BODY_RESOLVE)] t: R|T|): R|T| { + public final [ResolvedTo(ANNOTATION_ARGUMENTS)] fun <[ResolvedTo(ANNOTATION_ARGUMENTS)] T : R|One|, R|Two|> foo([ResolvedTo(ANNOTATION_ARGUMENTS)] t: R|T|): R|T| { ^foo R|/t| - } + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/types/whereProperty.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/types/whereProperty.txt index 07186641969..b14518cd1d2 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/types/whereProperty.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/types/whereProperty.txt @@ -11,7 +11,7 @@ FILE: [ResolvedTo(IMPORTS)] whereProperty.kt } public abstract [ResolvedTo(STATUS)] interface Two : R|kotlin/Any| { } - public final [ResolvedTo(BODY_RESOLVE)] val <[ResolvedTo(BODY_RESOLVE)] T : R|One|, R|Two|> R|T|.foo: R|T| - public [ResolvedTo(BODY_RESOLVE)] get(): R|T| { + public final [ResolvedTo(ANNOTATION_ARGUMENTS)] val <[ResolvedTo(ANNOTATION_ARGUMENTS)] T : R|One|, R|Two|> R|T|.foo: R|T| + public [ResolvedTo(ANNOTATION_ARGUMENTS)] get(): R|T| { ^ this@R|/foo| - } + } \ No newline at end of file