[LL FIR] FirElementBuilder: avoid body resolution for type references inside 'where'

^KT-62691 Fixed
This commit is contained in:
Dmitrii Gridin
2023-10-18 19:19:38 +02:00
committed by Space Team
parent 35567d453b
commit 500de9f9bb
5 changed files with 29 additions and 16 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter 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.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.utils.correspondingValueParameterFromPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.utils.correspondingValueParameterFromPrimaryConstructor
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
@@ -164,7 +165,7 @@ internal class FirElementBuilder(
declarationProvider = { declarationProvider = {
when (val parent = it.parent) { when (val parent = it.parent) {
is KtDeclaration -> parent is KtDeclaration -> parent
is KtSuperTypeListEntry, is KtConstructorCalleeExpression -> parent.parentOfType<KtClassOrObject>() is KtSuperTypeListEntry, is KtConstructorCalleeExpression, is KtTypeConstraint -> parent.parentOfType<KtDeclaration>()
else -> null else -> null
} }
}, },
@@ -199,14 +200,14 @@ internal class FirElementBuilder(
if (this is FirCallableDeclaration) { if (this is FirCallableDeclaration) {
returnTypeRef.takeIf { it.psi == typeReference }?.let { return it } returnTypeRef.takeIf { it.psi == typeReference }?.let { return it }
receiverParameter?.takeIf { it.typeRef.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) { if (this is FirTypeParameter) {
for (typeRef in bounds) { findTypeRefAnchor(typeReference)?.let { return it }
if (typeRef.psi == typeReference) {
return typeRef
}
}
} }
if (this is FirClass) { if (this is FirClass) {
@@ -220,6 +221,18 @@ internal class FirElementBuilder(
return null 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? { private fun FirDeclaration.resolveAndFindAnnotation(annotationEntry: KtAnnotationEntry, goDeep: Boolean = false): FirAnnotation? {
lazyResolveToPhase(FirResolvePhase.ANNOTATION_ARGUMENTS) lazyResolveToPhase(FirResolvePhase.ANNOTATION_ARGUMENTS)
findAnnotation(annotationEntry)?.let { return it } findAnnotation(annotationEntry)?.let { return it }
@@ -20,6 +20,6 @@ FILE: [ResolvedTo(IMPORTS)] annotationInsideWhereFunction.kt
} }
public? final? [ResolvedTo(RAW_FIR)] interface Two : R|kotlin/Any| { 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|<local>/t| ^foo R|<local>/t|
} }
@@ -20,7 +20,7 @@ FILE: [ResolvedTo(IMPORTS)] annotationInsideWhereProperty.kt
} }
public abstract [ResolvedTo(STATUS)] interface Two : R|kotlin/Any| { 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 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(BODY_RESOLVE)] get(): R|T| { public [ResolvedTo(ANNOTATION_ARGUMENTS)] get(): R|T| {
^ this@R|/foo| ^ this@R|/foo|
} }
@@ -11,6 +11,6 @@ FILE: [ResolvedTo(IMPORTS)] whereFunction.kt
} }
public? final? [ResolvedTo(RAW_FIR)] interface Two : R|kotlin/Any| { 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|<local>/t| ^foo R|<local>/t|
} }
@@ -11,7 +11,7 @@ FILE: [ResolvedTo(IMPORTS)] whereProperty.kt
} }
public abstract [ResolvedTo(STATUS)] interface Two : R|kotlin/Any| { 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 final [ResolvedTo(ANNOTATION_ARGUMENTS)] val <[ResolvedTo(ANNOTATION_ARGUMENTS)] T : R|One|, R|Two|> R|T|.foo: R|T|
public [ResolvedTo(BODY_RESOLVE)] get(): R|T| { public [ResolvedTo(ANNOTATION_ARGUMENTS)] get(): R|T| {
^ this@R|/foo| ^ this@R|/foo|
} }