[FIR] Add enum entry to body resolve context containers

This fixes processing of annotations on enum entries.
Before, the check in BodyResolveContext.forAnnotation would set the
tower data mode to CLASS_HEADER_ANNOTATIONS because no containers were
present.
This would lead to some tower data elements like nested classifiers
missing, which would lead to false positive unresolved references.

#KT-63761 Fixed
This commit is contained in:
Kirill Rakhman
2023-11-24 14:49:46 +01:00
committed by Space Team
parent bb5e219c1d
commit 06811dfc2f
5 changed files with 36 additions and 7 deletions
@@ -441,7 +441,7 @@ private class ContextCollectorVisitor(
onActiveBody { onActiveBody {
enumEntry.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) enumEntry.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
context.forEnumEntry { context.withEnumEntry(enumEntry) {
dumpContext(enumEntry, ContextKind.BODY) dumpContext(enumEntry, ContextKind.BODY)
onActive { onActive {
@@ -770,9 +770,12 @@ class BodyResolveContext(
} }
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
inline fun <T> forEnumEntry( inline fun <T> withEnumEntry(
enumEntry: FirEnumEntry,
f: () -> T f: () -> T
): T = withTowerDataMode(FirTowerDataMode.ENUM_ENTRY, f) ): T = withTowerDataMode(FirTowerDataMode.ENUM_ENTRY) {
withContainer(enumEntry, f)
}
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
inline fun <T> forAnnotation( inline fun <T> forAnnotation(
@@ -106,7 +106,7 @@ open class FirDeclarationsResolveTransformer(
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: ResolutionMode): FirEnumEntry { override fun transformEnumEntry(enumEntry: FirEnumEntry, data: ResolutionMode): FirEnumEntry {
if (implicitTypeOnly || enumEntry.initializerResolved) return enumEntry if (implicitTypeOnly || enumEntry.initializerResolved) return enumEntry
return context.forEnumEntry { return context.withEnumEntry(enumEntry) {
(enumEntry.transformChildren(this, data) as FirEnumEntry) (enumEntry.transformChildren(this, data) as FirEnumEntry)
} }
} }
@@ -294,7 +294,7 @@ private class FirDeclarationsResolveTransformerForAnnotationArguments(
} }
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: ResolutionMode): FirEnumEntry { override fun transformEnumEntry(enumEntry: FirEnumEntry, data: ResolutionMode): FirEnumEntry {
context.forEnumEntry { context.withEnumEntry(enumEntry) {
enumEntry enumEntry
.transformAnnotations(transformer, data) .transformAnnotations(transformer, data)
.transformReceiverParameter(transformer, data) .transformReceiverParameter(transformer, data)
@@ -1,12 +1,38 @@
// FIR_IDENTICAL // FIR_IDENTICAL
import kotlin.reflect.KClass import kotlin.reflect.KClass
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPE) @Target(
AnnotationTarget.CLASS,
AnnotationTarget.TYPE_PARAMETER,
AnnotationTarget.TYPE,
AnnotationTarget.PROPERTY,
AnnotationTarget.FUNCTION,
AnnotationTarget.CONSTRUCTOR
)
annotation class Special(val why: KClass<*>) annotation class Special(val why: KClass<*>)
interface Interface interface Interface
class Outer { class Outer @Special(Nested::class) constructor(
@Special(Nested::class)
val why: KClass<*>
) {
@Special(Nested::class) @Special(Nested::class)
class Nested<@Special(Nested::class) T> : @Special(Nested::class) Interface class Nested<@Special(Nested::class) T> : @Special(Nested::class) Interface
@Special(Nested::class)
val why2: KClass<*>? = null
@Special(Nested::class)
fun why3() {}
}
enum class E(
@Special(Nested::class)
val why: KClass<*>
) {
@Special(Nested::class)
Foo(Nested::class);
class Nested
} }