[LL FIR] avoid body resolve during getOrBuildFir for super types

This also covers a case with annotations on a super type entry

^KT-61789 Fixed
This commit is contained in:
Dmitrii Gridin
2023-10-10 16:02:04 +02:00
committed by Space Team
parent 515e05cd94
commit 90102ad8b7
14 changed files with 97 additions and 86 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.correspondingProperty
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirProperty
@@ -160,7 +161,13 @@ internal class FirElementBuilder(
element = element,
firResolveSession = firResolveSession,
anchorElementProvider = { it.parentsOfType<KtTypeReference>(withSelf = true).lastOrNull() },
declarationProvider = { it.parent as? KtDeclaration },
declarationProvider = {
when (val parent = it.parent) {
is KtDeclaration -> parent
is KtSuperTypeListEntry, is KtConstructorCalleeExpression -> parent.parentOfType<KtClassOrObject>()
else -> null
}
},
resolveAndFindFirForAnchor = { declaration, anchor -> declaration.resolveAndFindTypeRefAnchor(anchor) },
)?.let { firElement ->
if (firElement is FirReceiverParameter) {
@@ -202,6 +209,14 @@ internal class FirElementBuilder(
}
}
if (this is FirClass) {
for (typeRef in superTypeRefs) {
if (typeRef.psi == typeReference) {
return typeRef
}
}
}
return null
}
@@ -13,15 +13,15 @@ FILE: [ResolvedTo(IMPORTS)] superCallAnnotation.kt
}
}
public open [ResolvedTo(STATUS)] class A : R|kotlin/Any| {
public [ResolvedTo(STATUS)] [ContainingClassKey=A] constructor(): R|A| {
public? open [ResolvedTo(SUPER_TYPES)] class A : R|kotlin/Any| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=A] constructor(): R|A| {
LAZY_super<R|kotlin/Any|>
}
}
public final [ResolvedTo(BODY_RESOLVE)] class B : R|@R|Anno|() A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|@R|Anno|() A|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class B : R|@R|Anno|() A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<@R|Anno|[Types]() A>
}
}
}
@@ -13,11 +13,11 @@ FILE: [ResolvedTo(IMPORTS)] superCallAnnotation2.kt
}
}
public abstract [ResolvedTo(STATUS)] interface A : R|kotlin/Any| {
public? final? [ResolvedTo(SUPER_TYPES)] interface A : R|kotlin/Any| {
}
public final [ResolvedTo(BODY_RESOLVE)] class B : R|@R|Anno|() A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|kotlin/Any|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class B : R|@R|Anno|() A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<<implicit>>
}
}
}
@@ -18,16 +18,16 @@ FILE: [ResolvedTo(IMPORTS)] superCallAnnotationScript.kts
}
public open [ResolvedTo(STATUS)] class A : R|kotlin/Any| {
public [ResolvedTo(STATUS)] [ContainingClassKey=A] constructor(): R|A| {
public? open [ResolvedTo(SUPER_TYPES)] class A : R|kotlin/Any| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=A] constructor(): R|A| {
LAZY_super<R|kotlin/Any|>
}
}
public final [ResolvedTo(BODY_RESOLVE)] class B : R|@R|Anno|() A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|@R|Anno|() A|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class B : R|@R|Anno|() A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<@R|Anno|[Types]() A>
}
}
}
@@ -7,11 +7,11 @@ R|A|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superType.kt
public abstract [ResolvedTo(STATUS)] interface A : R|kotlin/Any| {
public? final? [ResolvedTo(SUPER_TYPES)] interface A : R|kotlin/Any| {
}
public final [ResolvedTo(BODY_RESOLVE)] class C : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=C] constructor(): R|C| {
super<R|kotlin/Any|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class C : R|A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
LAZY_super<<implicit>>
}
}
}
@@ -11,12 +11,12 @@ FILE: [ResolvedTo(IMPORTS)] superTypeScript.kts
SCRIPT: [ResolvedTo(TYPES)] <script-superTypeScript.kts>
[ResolvedTo(RAW_FIR)] lval args: R|kotlin/Array<kotlin/String>|
public abstract [ResolvedTo(STATUS)] interface A : R|kotlin/Any| {
public? final? [ResolvedTo(SUPER_TYPES)] interface A : R|kotlin/Any| {
}
public final [ResolvedTo(BODY_RESOLVE)] class C : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=C] constructor(): R|C| {
super<R|kotlin/Any|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class C : R|A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
LAZY_super<<implicit>>
}
}
}
@@ -7,15 +7,15 @@ R|A|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superType.kt
public open [ResolvedTo(STATUS)] class A : R|kotlin/Any| {
public [ResolvedTo(STATUS)] [ContainingClassKey=A] constructor(): R|A| {
public? open [ResolvedTo(SUPER_TYPES)] class A : R|kotlin/Any| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=A] constructor(): R|A| {
LAZY_super<R|kotlin/Any|>
}
}
public final [ResolvedTo(BODY_RESOLVE)] class B : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|A|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class B : R|A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<A>
}
}
@@ -7,11 +7,11 @@ R|A|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superType2.kt
public abstract [ResolvedTo(STATUS)] interface A : R|kotlin/Any| {
public? final? [ResolvedTo(SUPER_TYPES)] interface A : R|kotlin/Any| {
}
public final [ResolvedTo(BODY_RESOLVE)] class B : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|kotlin/Any|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class B : R|A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<<implicit>>
}
}
}
@@ -7,13 +7,13 @@ R|A|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superType3.kt
public abstract [ResolvedTo(STATUS)] interface A : R|kotlin/Any| {
public? final? [ResolvedTo(SUPER_TYPES)] interface A : R|kotlin/Any| {
}
public final [ResolvedTo(BODY_RESOLVE)] [DelegateFieldsMapKey={0=FirFieldSymbol /B.$$delegate_0}] class B : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|kotlin/Any|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] [DelegateFieldsMapKey={0=FirFieldSymbol /B.$$delegate_0}] class B : R|A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<<implicit>>
}
private final [ResolvedTo(BODY_RESOLVE)] field $$delegate_0: R|A| = <Unresolved name: f>#
private final [ResolvedTo(RAW_FIR)] field $$delegate_0: A = LAZY_EXPRESSION
}
}
@@ -7,21 +7,19 @@ R|A|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superTypeAndGeneratedProperty.kt
public open [ResolvedTo(STATUS)] class A : R|kotlin/Any| {
public [ResolvedTo(STATUS)] [ContainingClassKey=A] constructor(): R|A| {
public? open [ResolvedTo(SUPER_TYPES)] class A : R|kotlin/Any| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=A] constructor(): R|A| {
LAZY_super<R|kotlin/Any|>
}
}
public final [ResolvedTo(BODY_RESOLVE)] class B : R|A| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor([ResolvedTo(BODY_RESOLVE)] [CorrespondingProperty=/B.prop] prop: R|kotlin/String| = <strcat>(R|/foo|())): R|B| {
super<R|A|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class B : R|A| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/B.prop] prop: String = LAZY_EXPRESSION): R|B| {
LAZY_super<A>
}
public final [ResolvedTo(BODY_RESOLVE)] [IsFromPrimaryConstructor=true] val prop: R|kotlin/String| = R|<local>/prop|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] get(): R|kotlin/String|
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val prop: String = R|<local>/prop|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] get(): String
}
public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun foo(): R|kotlin/Int| {
^foo Int(42)
}
public? final? [ResolvedTo(RAW_FIR)] fun foo(): <implicit> { LAZY_BLOCK }
@@ -7,15 +7,15 @@ R|A|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superTypeInObject.kt
public open [ResolvedTo(STATUS)] class A : R|kotlin/Any| {
public [ResolvedTo(STATUS)] [ContainingClassKey=A] constructor(): R|A| {
public? open [ResolvedTo(SUPER_TYPES)] class A : R|kotlin/Any| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=A] constructor(): R|A| {
LAZY_super<R|kotlin/Any|>
}
}
public final [ResolvedTo(BODY_RESOLVE)] object B : R|A| {
private [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|A|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] object B : R|A| {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<A>
}
}
}
@@ -7,11 +7,11 @@ R|A|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superTypeInObject2.kt
public abstract [ResolvedTo(STATUS)] interface A : R|kotlin/Any| {
public? final? [ResolvedTo(SUPER_TYPES)] interface A : R|kotlin/Any| {
}
public final [ResolvedTo(BODY_RESOLVE)] object B : R|A| {
private [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|kotlin/Any|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] object B : R|A| {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<<implicit>>
}
}
}
@@ -7,13 +7,13 @@ R|A|
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superTypeInObject3.kt
public abstract [ResolvedTo(STATUS)] interface A : R|kotlin/Any| {
public? final? [ResolvedTo(SUPER_TYPES)] interface A : R|kotlin/Any| {
}
public final [ResolvedTo(BODY_RESOLVE)] [DelegateFieldsMapKey={0=FirFieldSymbol /B.$$delegate_0}] object B : R|A| {
private [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=B] constructor(): R|B| {
super<R|kotlin/Any|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] [DelegateFieldsMapKey={0=FirFieldSymbol /B.$$delegate_0}] object B : R|A| {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor(): R|B| {
LAZY_super<<implicit>>
}
private final [ResolvedTo(BODY_RESOLVE)] field $$delegate_0: R|A| = <Unresolved name: f>#
private final [ResolvedTo(RAW_FIR)] field $$delegate_0: A = LAZY_EXPRESSION
}
}
@@ -7,28 +7,26 @@ FIR element rendered:
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] superTypeOnEnumClass.kt
public final [ResolvedTo(BODY_RESOLVE)] enum class MyClass : <ERROR TYPE REF: Symbol not found for UnresolvedInterface>, R|kotlin/Enum<MyClass>| {
private [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=MyClass] constructor([ResolvedTo(BODY_RESOLVE)] [CorrespondingProperty=/MyClass.i] i: R|kotlin/Int| = R|/foo|()): R|MyClass| {
super<R|kotlin/Enum<MyClass>|>()
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] enum class MyClass : <ERROR TYPE REF: Symbol not found for UnresolvedInterface>, R|kotlin/Enum<MyClass>| {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=MyClass] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/MyClass.i] i: Int = LAZY_EXPRESSION): R|MyClass| {
LAZY_super<R|kotlin/Enum<MyClass>|>
}
public final [ResolvedTo(BODY_RESOLVE)] [IsFromPrimaryConstructor=true] val i: R|kotlin/Int| = R|<local>/i|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=MyClass] get(): R|kotlin/Int|
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val i: Int = R|<local>/i|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=MyClass] get(): Int
public final static [ResolvedTo(STATUS)] [ContainingClassKey=MyClass] enum entry ENTRY1: R|MyClass| = LAZY_EXPRESSION
public final static [ResolvedTo(STATUS)] [ContainingClassKey=MyClass] enum entry ENTRY2: R|MyClass| = LAZY_EXPRESSION
public final [ResolvedTo(STATUS)] fun boo([ResolvedTo(STATUS)] a: R|kotlin/String|): R|kotlin/Unit| { LAZY_BLOCK }
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=MyClass] enum entry ENTRY1: R|MyClass| = LAZY_EXPRESSION
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=MyClass] enum entry ENTRY2: R|MyClass| = LAZY_EXPRESSION
public? final? [ResolvedTo(RAW_FIR)] fun boo([ResolvedTo(RAW_FIR)] a: String): R|kotlin/Unit| { LAZY_BLOCK }
public final static [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=MyClass] fun values(): R|kotlin/Array<MyClass>| {
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=MyClass] fun values(): R|kotlin/Array<MyClass>| {
}
public final static [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=MyClass] fun valueOf([ResolvedTo(BODY_RESOLVE)] value: R|kotlin/String|): R|MyClass| {
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=MyClass] fun valueOf([ResolvedTo(RAW_FIR)] value: R|kotlin/String|): R|MyClass| {
}
public final static [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=MyClass] val entries: R|kotlin/enums/EnumEntries<MyClass>|
public [ResolvedTo(BODY_RESOLVE)] get(): R|kotlin/enums/EnumEntries<MyClass>|
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=MyClass] val entries: R|kotlin/enums/EnumEntries<MyClass>|
public [ResolvedTo(RAW_FIR)] get(): R|kotlin/enums/EnumEntries<MyClass>|
}
public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun foo(): R|kotlin/Int| {
^foo Int(42)
}
public? final? [ResolvedTo(RAW_FIR)] fun foo(): <implicit> { LAZY_BLOCK }