[FIR] Deeply copy annotation type ref on COMPILER_REQUIRED_ANNOTATION_PHASE
The original idea was in resolving of annotation type ref using only importing scopes and accepting or discarding that resolution result depending on if this annotation is needed for compiler/plugins or not But there is a problem that resolution of FirUserType with type resolver is not a pure operation: type resolver transforms qualifier parts which may contain type arguments, so if they were unresolved at the first resolve, they will stay unresolved forever. To prevent this we will deeply copy annotation type ref before first resolution ^KT-55286 Fixed
This commit is contained in:
committed by
Space Team
parent
2aad466d00
commit
880b278c40
@@ -6,11 +6,11 @@ FILE: kt55286.kt
|
||||
|
||||
}
|
||||
public open class Base : R|kotlin/Any| {
|
||||
public constructor(@R|Deprecated<ERROR CLASS: Symbol not found for Nested>|() a: R|kotlin/String|): R|Base| {
|
||||
public constructor(@R|Deprecated<Base.Nested>|() a: R|kotlin/String|): R|Base| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@R|Deprecated<ERROR CLASS: Symbol not found for Nested>|() public final val a: R|kotlin/String| = R|<local>/a|
|
||||
@R|Deprecated<Base.Nested>|() public final val a: R|kotlin/String| = R|<local>/a|
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final class Nested : R|kotlin/Any| {
|
||||
@@ -22,11 +22,11 @@ FILE: kt55286.kt
|
||||
|
||||
}
|
||||
public final class Derived : R|Base| {
|
||||
public constructor(@R|Deprecated<ERROR CLASS: Symbol not found for Nested>|() b: R|kotlin/String|): R|Derived| {
|
||||
public constructor(@R|Deprecated<Base.Nested>|() b: R|kotlin/String|): R|Derived| {
|
||||
super<R|Base|>(String())
|
||||
}
|
||||
|
||||
@R|Deprecated<ERROR CLASS: Symbol not found for Nested>|() public final val b: R|kotlin/String| = R|<local>/b|
|
||||
@R|Deprecated<Base.Nested>|() public final val b: R|kotlin/String| = R|<local>/b|
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
annotation class Deprecated<T>
|
||||
|
||||
open class Base(
|
||||
@Deprecated<<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>Nested<!>> val a: String,
|
||||
@Deprecated<Nested> val a: String,
|
||||
) {
|
||||
class Nested
|
||||
}
|
||||
|
||||
class Derived(
|
||||
@Deprecated<<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>Nested<!>> val b: String,
|
||||
@Deprecated<Nested> val b: String,
|
||||
) : Base("")
|
||||
|
||||
+46
-3
@@ -27,6 +27,12 @@ import org.jetbrains.kotlin.fir.resolve.transformers.withClassDeclarationCleanup
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildPlaceholderProjection
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildStarProjection
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildUserTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirTypeArgumentListImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -35,6 +41,7 @@ import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated
|
||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin
|
||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord
|
||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.WasExperimental
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
||||
|
||||
internal abstract class AbstractFirSpecificAnnotationResolveTransformer(
|
||||
protected val session: FirSession,
|
||||
@@ -76,8 +83,8 @@ internal abstract class AbstractFirSpecificAnnotationResolveTransformer(
|
||||
|
||||
if (!shouldRunAnnotationResolve(name)) return annotationCall
|
||||
|
||||
val transformedAnnotationType = annotationCall.typeRef.transformSingle(
|
||||
typeResolverTransformer,
|
||||
val transformedAnnotationType = typeResolverTransformer.transformUserTypeRef(
|
||||
annotationTypeRef.createDeepCopy(),
|
||||
ScopeClassDeclaration(scopes.asReversed(), classDeclarationsStack)
|
||||
) as? FirResolvedTypeRef ?: return annotationCall
|
||||
|
||||
@@ -274,11 +281,47 @@ internal abstract class AbstractFirSpecificAnnotationResolveTransformer(
|
||||
* Gets called after performing transformation of some declaration's nested declarations; can be used to restore the internal
|
||||
* state of the transformer.
|
||||
*
|
||||
* @param parentDeclaration A declaration whose nested declarations were transformed.
|
||||
* @param state A state produced by the [beforeTransformingChildren] call before the transformation.
|
||||
*/
|
||||
private fun afterTransformingChildren(state: PersistentList<FirDeclaration>?) {
|
||||
requireNotNull(state)
|
||||
owners = state
|
||||
}
|
||||
|
||||
private fun FirUserTypeRef.createDeepCopy(): FirUserTypeRef {
|
||||
val original = this
|
||||
return buildUserTypeRef {
|
||||
source = original.source
|
||||
isMarkedNullable = original.isMarkedNullable
|
||||
annotations.addAll(original.annotations)
|
||||
original.qualifier.mapTo(qualifier) { it.createDeepCopy() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirQualifierPart.createDeepCopy(): FirQualifierPart {
|
||||
val newArgumentList = FirTypeArgumentListImpl(typeArgumentList.source).apply {
|
||||
typeArgumentList.typeArguments.mapTo(typeArguments) { it.createDeepCopy() }
|
||||
}
|
||||
return FirQualifierPartImpl(
|
||||
source,
|
||||
name,
|
||||
newArgumentList
|
||||
)
|
||||
}
|
||||
|
||||
private fun FirTypeProjection.createDeepCopy(): FirTypeProjection {
|
||||
return when (val original = this) {
|
||||
is FirTypeProjectionWithVariance -> buildTypeProjectionWithVariance {
|
||||
source = original.source
|
||||
typeRef = when (val originalTypeRef = original.typeRef) {
|
||||
is FirUserTypeRef -> originalTypeRef.createDeepCopy()
|
||||
else -> originalTypeRef
|
||||
}
|
||||
variance = original.variance
|
||||
}
|
||||
is FirStarProjection -> buildStarProjection { source = original.source }
|
||||
is FirPlaceholderProjection -> buildPlaceholderProjection { source = original.source }
|
||||
else -> shouldNotBeCalled()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user