[FIR] move annotation recheck logic to ANNOTATIONS_ARGUMENTS_MAPPING phase

ARGUMENTS_OF_ANNOTATIONS will be dropped, so this check should be moved
This commit also drops class annotations resolution from implicit type
phase and provides the correct scope during argument mapping phase.
This code was effectively unreachable before

^KT-62679
This commit is contained in:
Dmitrii Gridin
2023-10-18 15:01:59 +02:00
committed by Space Team
parent 01905a5a06
commit a60777b9a7
8 changed files with 168 additions and 160 deletions
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.isError
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
@@ -131,7 +132,7 @@ internal object AnnotationArgumentMappingStateKeepers {
source = oldList.source
for ((index, argument) in oldList.arguments.withIndex()) {
val replacement = when {
argument is FirPropertyAccessExpression && argument.calleeReference.isError() -> argument
argument is FirPropertyAccessExpression && argument.calleeReference.let { it.isError() || it is FirResolvedNamedReference } -> argument
else -> newArguments[index]
}
@@ -269,31 +269,27 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict.kt
LAZY_super<R|kotlin/Any|>
}
@R|kotlin/annotation/Target|[Types](Q|Some.AnnotationTarget|.<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.CLASS
- compiler arguments stage: FirEnumEntrySymbol /Some.AnnotationTarget.CLASS
>#) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotation class Ann : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|[Types](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.CLASS|) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotation class Ann : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
LAZY_super<R|kotlin/Any|>
}
}
public final [ResolvedTo(STATUS)] enum class AnnotationTarget : R|kotlin/Enum<Some.AnnotationTarget>| {
private [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| {
public? final? [ResolvedTo(RAW_FIR)] enum class AnnotationTarget : R|kotlin/Enum<Some.AnnotationTarget>| {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| {
LAZY_super<R|kotlin/Enum<Some.AnnotationTarget>|>
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget|
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array<Some.AnnotationTarget>| {
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget|
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array<Some.AnnotationTarget>| {
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(STATUS)] value: R|kotlin/String|): R|Some.AnnotationTarget| {
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(RAW_FIR)] value: R|kotlin/String|): R|Some.AnnotationTarget| {
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public [ResolvedTo(STATUS)] get(): R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public [ResolvedTo(RAW_FIR)] get(): R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
}
@@ -306,31 +302,27 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict.kt
LAZY_super<R|kotlin/Any|>
}
@R|kotlin/annotation/Target|[Types](Q|Some.AnnotationTarget|.<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.CLASS
- compiler arguments stage: FirEnumEntrySymbol /Some.AnnotationTarget.CLASS
>#) public final [ResolvedTo(CONTRACTS)] annotation class Ann : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|[Types](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.CLASS|) public final [ResolvedTo(CONTRACTS)] annotation class Ann : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
LAZY_super<R|kotlin/Any|>
}
}
public final [ResolvedTo(STATUS)] enum class AnnotationTarget : R|kotlin/Enum<Some.AnnotationTarget>| {
private [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| {
public? final? [ResolvedTo(RAW_FIR)] enum class AnnotationTarget : R|kotlin/Enum<Some.AnnotationTarget>| {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| {
LAZY_super<R|kotlin/Enum<Some.AnnotationTarget>|>
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget|
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array<Some.AnnotationTarget>| {
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget|
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array<Some.AnnotationTarget>| {
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(STATUS)] value: R|kotlin/String|): R|Some.AnnotationTarget| {
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(RAW_FIR)] value: R|kotlin/String|): R|Some.AnnotationTarget| {
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public [ResolvedTo(STATUS)] get(): R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public [ResolvedTo(RAW_FIR)] get(): R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
}
@@ -343,31 +335,27 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict.kt
LAZY_super<R|kotlin/Any|>
}
@R|kotlin/annotation/Target|[Types](Q|Some.AnnotationTarget|.<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.CLASS
- compiler arguments stage: FirEnumEntrySymbol /Some.AnnotationTarget.CLASS
>#) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|[Types](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.CLASS|) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
LAZY_super<R|kotlin/Any|>
}
}
public final [ResolvedTo(STATUS)] enum class AnnotationTarget : R|kotlin/Enum<Some.AnnotationTarget>| {
private [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| {
public? final? [ResolvedTo(RAW_FIR)] enum class AnnotationTarget : R|kotlin/Enum<Some.AnnotationTarget>| {
private [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| {
LAZY_super<R|kotlin/Enum<Some.AnnotationTarget>|>
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget|
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array<Some.AnnotationTarget>| {
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget|
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array<Some.AnnotationTarget>| {
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(STATUS)] value: R|kotlin/String|): R|Some.AnnotationTarget| {
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(RAW_FIR)] value: R|kotlin/String|): R|Some.AnnotationTarget| {
}
public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public [ResolvedTo(STATUS)] get(): R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
public [ResolvedTo(RAW_FIR)] get(): R|kotlin/enums/EnumEntries<Some.AnnotationTarget>|
}
@@ -157,11 +157,7 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt
LAZY_super<R|kotlin/Any|>
}
@R|kotlin/annotation/Target|[Types](<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD
- compiler arguments stage: null
>#) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotation class Ann : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|[Types](R|kotlin/annotation/AnnotationTarget.FIELD|) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotation class Ann : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
LAZY_super<R|kotlin/Any|>
}
@@ -180,11 +176,7 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt
LAZY_super<R|kotlin/Any|>
}
@R|kotlin/annotation/Target|[Types](<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD
- compiler arguments stage: null
>#) public final [ResolvedTo(CONTRACTS)] annotation class Ann : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|[Types](R|kotlin/annotation/AnnotationTarget.FIELD|) public final [ResolvedTo(CONTRACTS)] annotation class Ann : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
LAZY_super<R|kotlin/Any|>
}
@@ -203,11 +195,7 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt
LAZY_super<R|kotlin/Any|>
}
@R|kotlin/annotation/Target|[Types](<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD
- compiler arguments stage: null
>#) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|[Types](R|kotlin/annotation/AnnotationTarget.FIELD|) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
LAZY_super<R|kotlin/Any|>
}
@@ -226,19 +214,19 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt
LAZY_super<R|kotlin/Any|>
}
@R|kotlin/annotation/Target|[Types](allowedTargets = vararg(<
@R|kotlin/annotation/Target|[Types](allowedTargets = this@R|/Some|.<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD
- compiler arguments stage: null
>#)) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] annotation class Ann : R|kotlin/Annotation| {
- compiler arguments stage: FirPropertySymbol /Some.FIELD
>#) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] annotation class Ann : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
LAZY_super<R|kotlin/Any|>
}
}
public final const [ResolvedTo(STATUS)] val FIELD: <implicit> = LAZY_EXPRESSION
public [ResolvedTo(STATUS)] [ContainingClassKey=Some] get(): <implicit>
public final const [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val FIELD: R|kotlin/String| = String()
public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] [ContainingClassKey=Some] get(): R|kotlin/String|
}
@@ -249,19 +237,19 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt
LAZY_super<R|kotlin/Any|>
}
@R|kotlin/annotation/Target|[Types](allowedTargets = vararg(<
@R|kotlin/annotation/Target|[Types](allowedTargets = this@R|/Some|.<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD
- compiler arguments stage: null
>#)) public final [ResolvedTo(BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| {
- compiler arguments stage: FirPropertySymbol /Some.FIELD
>#) public final [ResolvedTo(BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
super<R|kotlin/Any|>()
}
}
public final const [ResolvedTo(STATUS)] val FIELD: <implicit> = LAZY_EXPRESSION
public [ResolvedTo(STATUS)] [ContainingClassKey=Some] get(): <implicit>
public final const [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val FIELD: R|kotlin/String| = String()
public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] [ContainingClassKey=Some] get(): R|kotlin/String|
}
@@ -272,11 +260,11 @@ FILE: [ResolvedTo(BODY_RESOLVE)] compilerRequiredAnnotationConflict2.kt
super<R|kotlin/Any|>()
}
@R|kotlin/annotation/Target|[Types](allowedTargets = vararg(<
@R|kotlin/annotation/Target|[Types](allowedTargets = this@R|/Some|.<
Annotation symbol resolved differently on compiler annotation and symbols stages:
- compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD
- compiler arguments stage: null
>#)) public final [ResolvedTo(BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| {
- compiler arguments stage: FirPropertySymbol /Some.FIELD
>#) public final [ResolvedTo(BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| {
super<R|kotlin/Any|>()
}
@@ -630,18 +630,21 @@ open class FirDeclarationsResolveTransformer(
override fun transformRegularClass(
regularClass: FirRegularClass,
data: ResolutionMode
): FirRegularClass =
whileAnalysing(session, regularClass) {
return context.withContainingClass(regularClass) {
if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) {
return regularClass.runAllPhasesForLocalClass(transformer, components, data, transformer.firResolveContextCollector)
}
doTransformTypeParameters(regularClass)
doTransformRegularClass(regularClass, data)
data: ResolutionMode,
): FirRegularClass = whileAnalysing(session, regularClass) {
context.withContainingClass(regularClass) {
val isLocal = regularClass.isLocal
if (isLocal && regularClass !in context.targetedLocalClasses) {
return regularClass.runAllPhasesForLocalClass(transformer, components, data, transformer.firResolveContextCollector)
}
if (isLocal || !implicitTypeOnly) {
doTransformTypeParameters(regularClass)
}
doTransformRegularClass(regularClass, data)
}
}
fun withScript(script: FirScript, action: () -> FirScript): FirScript {
dataFlowAnalyzer.enterScript(script)
@@ -125,6 +125,18 @@ open class FirImplicitAwareBodyResolveTransformer(
outerBodyResolveContext,
firResolveContextCollector
) {
/**
* This is required to avoid transformations of class annotations
*/
override fun transformDeclarationContent(
declaration: FirDeclaration,
data: ResolutionMode,
): FirDeclaration = if (implicitTypeOnly && declaration is FirRegularClass && !declaration.isLocal) {
declaration.transformDeclarations(this, data)
} else {
super.transformDeclarationContent(declaration, data)
}
override fun transformSimpleFunction(
simpleFunction: FirSimpleFunction,
data: ResolutionMode
@@ -5,17 +5,32 @@
package org.jetbrains.kotlin.fir.resolve.transformers.plugin
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirErrorAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguouslyResolvedAnnotationArgument
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.*
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.util.PrivateForInline
open class FirAnnotationArgumentsMappingTransformer(
@@ -64,6 +79,11 @@ open class FirAnnotationArgumentsMappingTransformer(
}
}
/**
* Set of enum class IDs that are resolved in COMPILER_REQUIRED_ANNOTATIONS phase that need to be rechecked here.
*/
private val classIdsToCheck: Set<ClassId> = setOf(StandardClassIds.DeprecationLevel, StandardClassIds.AnnotationTarget)
private class FirExpressionTransformerForAnnotationArgumentsMapping(
private val annotationArgumentsMappingTransformer: FirAnnotationArgumentsMappingTransformer,
) : FirExpressionsResolveTransformer(annotationArgumentsMappingTransformer) {
@@ -80,6 +100,81 @@ private class FirExpressionTransformerForAnnotationArgumentsMapping(
}
}
override fun transformQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression,
data: ResolutionMode
): FirStatement {
if (qualifiedAccessExpression is FirPropertyAccessExpression) {
val calleeReference = qualifiedAccessExpression.calleeReference
if (calleeReference is FirResolvedNamedReference) {
val resolvedSymbol = calleeReference.resolvedSymbol
if (resolvedSymbol is FirEnumEntrySymbol && resolvedSymbol.containingClassLookupTag()?.classId in classIdsToCheck) {
return resolveSpecialPropertyAccess(qualifiedAccessExpression, calleeReference, resolvedSymbol, data)
}
}
}
return super.transformQualifiedAccessExpression(qualifiedAccessExpression, data)
}
private fun resolveSpecialPropertyAccess(
originalAccess: FirPropertyAccessExpression,
originalCalleeReference: FirResolvedNamedReference,
originalResolvedSymbol: FirEnumEntrySymbol,
data: ResolutionMode,
): FirStatement {
val accessCopyForResolution = buildPropertyAccessExpression {
source = originalAccess.source
typeArguments.addAll(originalAccess.typeArguments)
val originalResolvedQualifier = originalAccess.explicitReceiver
if (originalResolvedQualifier is FirResolvedQualifier) {
val fqName = originalResolvedQualifier.classId
?.let { if (originalResolvedQualifier.isFullyQualified) it.asSingleFqName() else it.relativeClassName }
?: originalResolvedQualifier.packageFqName
explicitReceiver = generatePropertyAccessExpression(fqName, originalResolvedQualifier.source)
}
calleeReference = buildSimpleNamedReference {
source = originalCalleeReference.source
name = originalCalleeReference.name
}
}
val resolved = super.transformQualifiedAccessExpression(accessCopyForResolution, data)
if (resolved is FirQualifiedAccessExpression) {
// The initial resolution must have been to an enum entry. Report ambiguity if symbolFromArgumentsPhase is different to
// original symbol including null (meaning we would resolve to something other than an enum entry).
val symbolFromArgumentsPhase = resolved.calleeReference.toResolvedBaseSymbol()
if (originalResolvedSymbol != symbolFromArgumentsPhase) {
resolved.replaceCalleeReference(buildErrorNamedReference {
source = resolved.calleeReference.source
diagnostic = ConeAmbiguouslyResolvedAnnotationArgument(originalResolvedSymbol, symbolFromArgumentsPhase)
})
}
}
return resolved
}
private fun generatePropertyAccessExpression(fqName: FqName, accessSource: KtSourceElement?): FirPropertyAccessExpression {
var result: FirPropertyAccessExpression? = null
val pathSegments = fqName.pathSegments()
for ((index, pathSegment) in pathSegments.withIndex()) {
result = buildPropertyAccessExpression {
calleeReference = buildSimpleNamedReference { name = pathSegment }
explicitReceiver = result
if (index == pathSegments.lastIndex) {
source = accessSource
}
}
}
return result ?: error("Got an empty ClassId")
}
}
private class FirDeclarationsResolveTransformerForAnnotationArgumentsMapping(
@@ -92,9 +187,11 @@ private class FirDeclarationsResolveTransformerForAnnotationArgumentsMapping(
}
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirRegularClass {
regularClass.transformAnnotations(this, data)
doTransformTypeParameters(regularClass)
regularClass.transformSuperTypeRefs(this, data)
context.insideClassHeader {
regularClass.transformAnnotations(this, ResolutionMode.ContextIndependent)
regularClass.transformTypeParameters(this, ResolutionMode.ContextIndependent)
regularClass.transformSuperTypeRefs(this, ResolutionMode.ContextIndependent)
}
doTransformRegularClass(regularClass, data)
return regularClass
@@ -314,90 +314,9 @@ abstract class AbstractFirExpressionsResolveTransformerForAnnotations(transforme
}
}
/**
* Set of enum class IDs that are resolved in COMPILER_REQUIRED_ANNOTATIONS phase that need to be rechecked here.
*/
private val classIdsToCheck: Set<ClassId> = setOf(StandardClassIds.DeprecationLevel, StandardClassIds.AnnotationTarget)
private class FirExpressionsResolveTransformerForSpecificAnnotations(transformer: FirAbstractBodyResolveTransformerDispatcher) :
AbstractFirExpressionsResolveTransformerForAnnotations(transformer) {
override fun transformQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression,
data: ResolutionMode
): FirStatement {
if (qualifiedAccessExpression is FirPropertyAccessExpression) {
val calleeReference = qualifiedAccessExpression.calleeReference
if (calleeReference is FirResolvedNamedReference) {
val resolvedSymbol = calleeReference.resolvedSymbol
if (resolvedSymbol is FirEnumEntrySymbol && resolvedSymbol.containingClassLookupTag()?.classId in classIdsToCheck) {
return resolveSpecialPropertyAccess(qualifiedAccessExpression, calleeReference, resolvedSymbol, data)
}
}
}
return super.transformQualifiedAccessExpression(qualifiedAccessExpression, data)
}
private fun resolveSpecialPropertyAccess(
originalAccess: FirPropertyAccessExpression,
originalCalleeReference: FirResolvedNamedReference,
originalResolvedSymbol: FirEnumEntrySymbol,
data: ResolutionMode,
): FirStatement {
val accessCopyForResolution = buildPropertyAccessExpression {
source = originalAccess.source
typeArguments.addAll(originalAccess.typeArguments)
val originalResolvedQualifier = originalAccess.explicitReceiver
if (originalResolvedQualifier is FirResolvedQualifier) {
val fqName = originalResolvedQualifier.classId
?.let { if (originalResolvedQualifier.isFullyQualified) it.asSingleFqName() else it.relativeClassName }
?: originalResolvedQualifier.packageFqName
explicitReceiver = generatePropertyAccessExpression(fqName, originalResolvedQualifier.source)
}
calleeReference = buildSimpleNamedReference {
source = originalCalleeReference.source
name = originalCalleeReference.name
}
}
val resolved = super.transformQualifiedAccessExpression(accessCopyForResolution, data)
if (resolved is FirQualifiedAccessExpression) {
// The initial resolution must have been to an enum entry. Report ambiguity if symbolFromArgumentsPhase is different to
// original symbol including null (meaning we would resolve to something other than an enum entry).
val symbolFromArgumentsPhase = resolved.calleeReference.toResolvedBaseSymbol()
if (originalResolvedSymbol != symbolFromArgumentsPhase) {
resolved.replaceCalleeReference(buildErrorNamedReference {
source = resolved.calleeReference.source
diagnostic = ConeAmbiguouslyResolvedAnnotationArgument(originalResolvedSymbol, symbolFromArgumentsPhase)
})
}
}
return resolved
}
private fun generatePropertyAccessExpression(fqName: FqName, accessSource: KtSourceElement?): FirPropertyAccessExpression {
var result: FirPropertyAccessExpression? = null
val pathSegments = fqName.pathSegments()
for ((index, pathSegment) in pathSegments.withIndex()) {
result = buildPropertyAccessExpression {
calleeReference = buildSimpleNamedReference { name = pathSegment }
explicitReceiver = result
if (index == pathSegments.lastIndex) {
source = accessSource
}
}
}
return result ?: error("Got an empty ClassId")
}
override fun resolveQualifiedAccessAndSelectCandidate(
qualifiedAccessExpression: FirQualifiedAccessExpression,
isUsedAsReceiver: Boolean,
@@ -8,7 +8,7 @@ object Some {
CLASS
}
@Target(<!AMBIGUOUS_ANNOTATION_ARGUMENT!>FIELD<!>)
@Target(<!AMBIGUOUS_ANNOTATION_ARGUMENT, ARGUMENT_TYPE_MISMATCH!>FIELD<!>)
annotation class Ann2
const val FIELD = ""