diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index be73d4be3eb..cd531eb7c7e 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -1007,6 +1007,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.AMBIGUOUS_ANNOTATION_ARGUMENT) { firDiagnostic -> + AmbiguousAnnotationArgumentImpl( + firDiagnostic.a.map { firBasedSymbol -> + firSymbolBuilder.buildSymbol(firBasedSymbol) + }, + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirJsErrors.WRONG_JS_QUALIFIER) { firDiagnostic -> WrongJsQualifierImpl( firDiagnostic as KtPsiDiagnostic, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 31db23eaff1..0968eb46859 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -728,6 +728,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val typeFromTypesPhase: KtType } + abstract class AmbiguousAnnotationArgument : KtFirDiagnostic() { + override val diagnosticClass get() = AmbiguousAnnotationArgument::class + abstract val symbols: List + } + abstract class WrongJsQualifier : KtFirDiagnostic() { override val diagnosticClass get() = WrongJsQualifier::class } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 1629a02bf12..3bcc10ec767 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -873,6 +873,12 @@ internal class PluginAnnotationAmbiguityImpl( override val token: KtLifetimeToken, ) : KtFirDiagnostic.PluginAnnotationAmbiguity(), KtAbstractFirDiagnostic +internal class AmbiguousAnnotationArgumentImpl( + override val symbols: List, + override val firDiagnostic: KtPsiDiagnostic, + override val token: KtLifetimeToken, +) : KtFirDiagnostic.AmbiguousAnnotationArgument(), KtAbstractFirDiagnostic + internal class WrongJsQualifierImpl( override val firDiagnostic: KtPsiDiagnostic, override val token: KtLifetimeToken, diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 52065169cb9..1aa953305e5 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -35874,6 +35874,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true); } + @Test + @TestMetadata("annotationTargetResolvedAmbiguously.kt") + public void testAnnotationTargetResolvedAmbiguously() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt"); + } + @Test @TestMetadata("annotationsTargetingLateinitAccessors.kt") public void testAnnotationsTargetingLateinitAccessors() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index a5eb5f59f23..0a0fbdb957a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -35874,6 +35874,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true); } + @Test + @TestMetadata("annotationTargetResolvedAmbiguously.kt") + public void testAnnotationTargetResolvedAmbiguously() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt"); + } + @Test @TestMetadata("annotationsTargetingLateinitAccessors.kt") public void testAnnotationsTargetingLateinitAccessors() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index f54cf9a3ffe..51aaaafe160 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -35970,6 +35970,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true); } + @Test + @TestMetadata("annotationTargetResolvedAmbiguously.kt") + public void testAnnotationTargetResolvedAmbiguously() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt"); + } + @Test @TestMetadata("annotationsTargetingLateinitAccessors.kt") public void testAnnotationsTargetingLateinitAccessors() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 7fa9ced1b7f..c3f08c69e36 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -309,10 +309,14 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val WRONG_EXTENSION_FUNCTION_TYPE_WARNING by warning() val ANNOTATION_IN_WHERE_CLAUSE_ERROR by error() - val PLUGIN_ANNOTATION_AMBIGUITY by error() { + val PLUGIN_ANNOTATION_AMBIGUITY by error { parameter("typeFromCompilerPhase") parameter("typeFromTypesPhase") } + + val AMBIGUOUS_ANNOTATION_ARGUMENT by error { + parameter>>("symbols") + } } val OPT_IN by object : DiagnosticGroup("OptIn") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 231297d7809..5ffb69e39c5 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -264,6 +264,7 @@ object FirErrors { val WRONG_EXTENSION_FUNCTION_TYPE_WARNING by warning0() val ANNOTATION_IN_WHERE_CLAUSE_ERROR by error0() val PLUGIN_ANNOTATION_AMBIGUITY by error2() + val AMBIGUOUS_ANNOTATION_ARGUMENT by error1>>() // OptIn val OPT_IN_USAGE by warning2(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index bd9a14fe1e3..39fa60f9b9d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -58,6 +58,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_WITHOUT_EXPECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ACTUALS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ALTERED_ASSIGN +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ANNOTATION_ARGUMENT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ANONYMOUS_TYPE_INFERRED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_EXPECTS @@ -928,10 +929,15 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { ) map.put( PLUGIN_ANNOTATION_AMBIGUITY, - "Resolution of annotation type is ambigous between {1} and plugin annotation {0}. Please specify fully qualified name of annotation", + "Resolution of annotation type is ambiguous between {1} and plugin annotation {0}. Please specify fully qualified name of annotation", RENDER_TYPE, RENDER_TYPE ) + map.put( + AMBIGUOUS_ANNOTATION_ARGUMENT, + "Resolution of annotation argument is ambiguous between {0}. Please specify fully qualified name of argument", + SYMBOLS, + ) // Exposed visibility group // # map.put( diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index abeba3a7c54..0b69cdef3f5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -132,6 +132,8 @@ private fun ConeDiagnostic.toKtDiagnostic( is ConeAmbiguouslyResolvedAnnotationFromPlugin -> { FirErrors.PLUGIN_ANNOTATION_AMBIGUITY.createOn(source, typeFromCompilerPhase, typeFromTypesPhase) } + is ConeAmbiguouslyResolvedAnnotationArgument -> + FirErrors.AMBIGUOUS_ANNOTATION_ARGUMENT.createOn(source, listOfNotNull(symbolFromCompilerPhase, symbolFromAnnotationArgumentsPhase)) is ConeAmbiguousFunctionTypeKinds -> FirErrors.AMBIGUOUS_FUNCTION_TYPE_KIND.createOn(source, kinds) else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}") } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/QualifiedNameResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/QualifiedNameResolution.kt index 2bce29f79ef..3da6a5b45b5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/QualifiedNameResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/QualifiedNameResolution.kt @@ -111,6 +111,7 @@ fun FirResolvedQualifier.continueQualifier( packageFqName = this@continueQualifier.packageFqName relativeClassFqName = this@continueQualifier.relativeClassFqName?.child(name) symbol = nestedClassSymbol as FirClassLikeSymbol<*> + isFullyQualified = true val outerTypeArguments = this.typeArguments.toList() this.typeArguments.clear() @@ -180,6 +181,7 @@ private fun FqName.continueQualifierInPackage( apiVersion ) ) + isFullyQualified = true }.apply { resultType = components.typeForQualifier(this) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt index f7ee78dc751..4a7479b657d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt @@ -139,6 +139,7 @@ internal abstract class AbstractFirSpecificAnnotationResolveTransformer( relativeClassFqName = symbol.classId.relativeClassName typeRef = FirImplicitUnitTypeRef(receiver.typeRef.source) this.symbol = symbol + isFullyQualified = segments.isNotEmpty() } // Resolve enum entry by name from the declarations of the receiver. diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt index 87a8d29daba..8b171f910d0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt @@ -7,12 +7,26 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression +import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.references.FirErrorNamedReference +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.transformers.body.resolve.* +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguouslyResolvedAnnotationArgument +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer +import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.StandardClassIds open class FirAnnotationArgumentsResolveTransformer( session: FirSession, @@ -252,9 +266,74 @@ 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 = setOf(StandardClassIds.DeprecationLevel, StandardClassIds.AnnotationTarget) + private class FirExpressionsResolveTransformerForSpecificAnnotations(transformer: FirAbstractBodyResolveTransformerDispatcher) : AbstractFirExpressionsResolveTransformerForAnnotations(transformer) { + override fun transformQualifiedAccessExpression( + qualifiedAccessExpression: FirQualifiedAccessExpression, + data: ResolutionMode + ): FirStatement { + val calleeReference = qualifiedAccessExpression.calleeReference + if (calleeReference is FirResolvedNamedReference && + calleeReference.resolvedSymbol.let { it is FirEnumEntrySymbol && it.containingClassLookupTag()?.classId in classIdsToCheck } && + qualifiedAccessExpression is FirPropertyAccessExpression + ) { + val symbolFromCompilerPhase = calleeReference.resolvedSymbol + + (qualifiedAccessExpression.explicitReceiver as? FirResolvedQualifier)?.let { + qualifiedAccessExpression.replaceResolvedQualifierReceiver(it) + } + qualifiedAccessExpression.replaceDispatchReceiver(FirNoReceiverExpression) + qualifiedAccessExpression.replaceTypeRef(noExpectedType) + qualifiedAccessExpression.replaceCalleeReference(buildSimpleNamedReference { + source = calleeReference.source + name = calleeReference.name + }) + + val resolved = super.transformQualifiedAccessExpression(qualifiedAccessExpression, 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 (symbolFromCompilerPhase != symbolFromArgumentsPhase) { + resolved.replaceCalleeReference(buildErrorNamedReference { + source = resolved.calleeReference.source + diagnostic = ConeAmbiguouslyResolvedAnnotationArgument(symbolFromCompilerPhase, symbolFromArgumentsPhase) + }) + } + } + + return resolved + } + + return super.transformQualifiedAccessExpression(qualifiedAccessExpression, data) + } + + private fun FirQualifiedAccessExpression.replaceResolvedQualifierReceiver(receiver: FirResolvedQualifier) { + var lastReceiver = buildPropertyAccessExpression { + source = receiver.source + this.calleeReference = buildSimpleNamedReference { + val classId = receiver.classId ?: return + name = classId.relativeClassName.shortName() + } + } + replaceExplicitReceiver(lastReceiver) + + if (receiver.isFullyQualified) { + for (segment in receiver.packageFqName.pathSegments().asReversed()) { + lastReceiver.replaceExplicitReceiver(buildPropertyAccessExpression { + this.calleeReference = buildSimpleNamedReference { name = segment } + }.also { lastReceiver = it }) + } + } + } + override fun resolveQualifiedAccessAndSelectCandidate( qualifiedAccessExpression: FirQualifiedAccessExpression, isUsedAsReceiver: Boolean, diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt index 33e74280032..e40f01603ec 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt @@ -251,3 +251,15 @@ class ConeAmbiguouslyResolvedAnnotationFromPlugin( - types stage: $typeFromTypesPhase """ } + +class ConeAmbiguouslyResolvedAnnotationArgument( + val symbolFromCompilerPhase: FirBasedSymbol<*>, + val symbolFromAnnotationArgumentsPhase: FirBasedSymbol<*>? +) : ConeDiagnostic { + override val reason: String + get() = """ + Annotation symbol resolved differently on compiler annotation and symbols stages: + - compiler annotations: $symbolFromCompilerPhase + - compiler arguments stage: $symbolFromAnnotationArgumentsPhase + """ +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirErrorResolvedQualifier.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirErrorResolvedQualifier.kt index c6d7de4f5d7..3ae93d9b069 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirErrorResolvedQualifier.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirErrorResolvedQualifier.kt @@ -31,6 +31,7 @@ abstract class FirErrorResolvedQualifier : FirResolvedQualifier(), FirDiagnostic abstract override val symbol: FirClassLikeSymbol<*>? abstract override val isNullableLHSForCallableReference: Boolean abstract override val resolvedToCompanionObject: Boolean + abstract override val isFullyQualified: Boolean abstract override val nonFatalDiagnostics: List abstract override val typeArguments: List abstract override val diagnostic: ConeDiagnostic diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirResolvedQualifier.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirResolvedQualifier.kt index 1da8e043a0f..0dacfccd540 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirResolvedQualifier.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirResolvedQualifier.kt @@ -30,6 +30,7 @@ abstract class FirResolvedQualifier : FirExpression() { abstract val symbol: FirClassLikeSymbol<*>? abstract val isNullableLHSForCallableReference: Boolean abstract val resolvedToCompanionObject: Boolean + abstract val isFullyQualified: Boolean abstract val nonFatalDiagnostics: List abstract val typeArguments: List diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAbstractResolvedQualifierBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAbstractResolvedQualifierBuilder.kt index 9911416e31e..30a6bd79698 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAbstractResolvedQualifierBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAbstractResolvedQualifierBuilder.kt @@ -35,6 +35,7 @@ interface FirAbstractResolvedQualifierBuilder { abstract var symbol: FirClassLikeSymbol<*>? abstract var isNullableLHSForCallableReference: Boolean abstract var resolvedToCompanionObject: Boolean + abstract var isFullyQualified: Boolean abstract val nonFatalDiagnostics: MutableList abstract val typeArguments: MutableList diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorResolvedQualifierBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorResolvedQualifierBuilder.kt index 6d69210ebe4..37b2c543b19 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorResolvedQualifierBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorResolvedQualifierBuilder.kt @@ -39,6 +39,7 @@ class FirErrorResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, Fi override var relativeClassFqName: FqName? = null override var symbol: FirClassLikeSymbol<*>? = null override var isNullableLHSForCallableReference: Boolean = false + override var isFullyQualified: Boolean = false override val nonFatalDiagnostics: MutableList = mutableListOf() override val typeArguments: MutableList = mutableListOf() lateinit var diagnostic: ConeDiagnostic @@ -51,6 +52,7 @@ class FirErrorResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, Fi relativeClassFqName, symbol, isNullableLHSForCallableReference, + isFullyQualified, nonFatalDiagnostics.toMutableOrEmpty(), typeArguments.toMutableOrEmpty(), diagnostic, diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirResolvedQualifierBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirResolvedQualifierBuilder.kt index c75ab46e6d2..0b5439e9f32 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirResolvedQualifierBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirResolvedQualifierBuilder.kt @@ -41,6 +41,7 @@ class FirResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, FirAnno override var relativeClassFqName: FqName? = null override var symbol: FirClassLikeSymbol<*>? = null override var isNullableLHSForCallableReference: Boolean = false + override var isFullyQualified: Boolean = false override val nonFatalDiagnostics: MutableList = mutableListOf() override val typeArguments: MutableList = mutableListOf() @@ -53,6 +54,7 @@ class FirResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, FirAnno relativeClassFqName, symbol, isNullableLHSForCallableReference, + isFullyQualified, nonFatalDiagnostics.toMutableOrEmpty(), typeArguments.toMutableOrEmpty(), ) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorResolvedQualifierImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorResolvedQualifierImpl.kt index 758d1ee3d99..98ac33e40c4 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorResolvedQualifierImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorResolvedQualifierImpl.kt @@ -33,6 +33,7 @@ internal class FirErrorResolvedQualifierImpl( override val relativeClassFqName: FqName?, override val symbol: FirClassLikeSymbol<*>?, override var isNullableLHSForCallableReference: Boolean, + override val isFullyQualified: Boolean, override var nonFatalDiagnostics: MutableOrEmptyList, override var typeArguments: MutableOrEmptyList, override val diagnostic: ConeDiagnostic, diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirResolvedQualifierImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirResolvedQualifierImpl.kt index 3c55b7c679a..ebadf5f709e 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirResolvedQualifierImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirResolvedQualifierImpl.kt @@ -34,6 +34,7 @@ internal class FirResolvedQualifierImpl( override var relativeClassFqName: FqName?, override val symbol: FirClassLikeSymbol<*>?, override var isNullableLHSForCallableReference: Boolean, + override val isFullyQualified: Boolean, override var nonFatalDiagnostics: MutableOrEmptyList, override var typeArguments: MutableOrEmptyList, ) : FirResolvedQualifier() { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt index 46b1e023d03..f8e1a651e95 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt @@ -354,12 +354,12 @@ object BuilderConfigurator : AbstractBuilderConfigurator(FirTree builder(resolvedQualifier) { parents += abstractResolvedQualifierBuilder - defaultFalse("isNullableLHSForCallableReference") + defaultFalse("isNullableLHSForCallableReference", "isFullyQualified") } builder(errorResolvedQualifier) { parents += abstractResolvedQualifierBuilder - defaultFalse("isNullableLHSForCallableReference") + defaultFalse("isNullableLHSForCallableReference", "isFullyQualified") } // builder(safeCallExpression) { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index f747ccc08ef..03be26cae17 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -595,6 +595,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild +field("symbol", classLikeSymbolType, nullable = true) +booleanField("isNullableLHSForCallableReference", withReplace = true) +booleanField("resolvedToCompanionObject", withReplace = true) + +booleanField("isFullyQualified") +fieldList("nonFatalDiagnostics", coneDiagnosticType, useMutableOrEmpty = true) +typeArguments.withTransform() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.fir.kt new file mode 100644 index 00000000000..42b6cd5a77f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.fir.kt @@ -0,0 +1,43 @@ +import kotlin.annotation.AnnotationTarget.FIELD + +object Some { + @Target(AnnotationTarget.CLASS) + annotation class Ann + + enum class AnnotationTarget { + CLASS + } + + @Target(FIELD) + annotation class Ann2 + + const val FIELD = "" +} + +object SomeMore { + @Target(kotlin.annotation.AnnotationTarget.FUNCTION) + annotation class Ann3 + + object kotlin { + object annotation { + enum class AnnotationTarget { + FUNCTION + } + } + } +} + +abstract class Base { + annotation class Target(val target: AnnotationTarget) + + enum class AnnotationTarget { + TYPE + } +} + +class Derived : Base() { + @Target(AnnotationTarget.TYPE) + annotation class Ann + + fun foo(x: @Ann String) {} +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt new file mode 100644 index 00000000000..00c9caa488e --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt @@ -0,0 +1,43 @@ +import kotlin.annotation.AnnotationTarget.FIELD + +object Some { + @Target(AnnotationTarget.CLASS) + annotation class Ann + + enum class AnnotationTarget { + CLASS + } + + @Target(FIELD) + annotation class Ann2 + + const val FIELD = "" +} + +object SomeMore { + @Target(kotlin.annotation.AnnotationTarget.FUNCTION) + annotation class Ann3 + + object kotlin { + object annotation { + enum class AnnotationTarget { + FUNCTION + } + } + } +} + +abstract class Base { + annotation class Target(val target: AnnotationTarget) + + enum class AnnotationTarget { + TYPE + } +} + +class Derived : Base() { + @Target(AnnotationTarget.TYPE) + annotation class Ann + + fun foo(x: @Ann String) {} +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index ce01eb52e71..77c607ea41c 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -35970,6 +35970,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true); } + @Test + @TestMetadata("annotationTargetResolvedAmbiguously.kt") + public void testAnnotationTargetResolvedAmbiguously() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt"); + } + @Test @TestMetadata("annotationsTargetingLateinitAccessors.kt") public void testAnnotationsTargetingLateinitAccessors() throws Exception { diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt b/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt index 4de7aebec4f..5247349e931 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt @@ -136,6 +136,7 @@ object StandardClassIds { val AnnotationRetention = "AnnotationRetention".annotationId() val AnnotationTarget = "AnnotationTarget".annotationId() + val DeprecationLevel = "DeprecationLevel".baseId() val EnumEntries = "EnumEntries".enumsId()