diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt index 355c39edb78..2bcd71f1201 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt @@ -87,6 +87,7 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.on(source) is ConeTypeMismatchError -> FirErrors.TYPE_MISMATCH.on(source, diagnostic.expectedType, diagnostic.actualType) is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.on(diagnostic.source.safeAs() ?: source) + is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.on(source, diagnostic.name.asString()) is ConeSimpleDiagnostic -> if (source.kind is FirFakeSourceElementKind) { null } else if (diagnostic.kind == SymbolNotFound) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 8954cc74b0f..680282d60f5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PROPERTY_ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_RECEIVER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_CONST_EXPRESSION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CANDIDATE @@ -74,6 +75,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", TO_STRING, TO_STRING) map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", TO_STRING, TO_STRING) + // Annotations + map.put(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING) + // Exposed visibility group map.put(EXPOSED_TYPEALIAS_EXPANDED_TYPE, "{0} typealias exposes {2} in expanded type{1}", TO_STRING, TO_STRING, TO_STRING) map.put(EXPOSED_PROPERTY_TYPE, "{0} property exposes its {2} type{1}", TO_STRING, TO_STRING, TO_STRING) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 8313deebc89..a602ab02c19 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -62,6 +62,7 @@ object FirErrors { val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by existing(Errors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER) val INVALID_TYPE_OF_ANNOTATION_MEMBER by existing(Errors.INVALID_TYPE_OF_ANNOTATION_MEMBER) val VAR_ANNOTATION_PARAMETER by existing(Errors.VAR_ANNOTATION_PARAMETER) + val NOT_AN_ANNOTATION_CLASS by error1() // Exposed visibility group val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 32dd912ff2c..20f8f23c928 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -20,10 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeHiddenCandidateError -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError +import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference @@ -333,24 +330,35 @@ class FirCallResolver( containingDeclarations ) - val resolutionResult = createCandidateForAnnotationCall(annotationCall, callInfo) - ?: ResolutionResult(callInfo, CandidateApplicability.HIDDEN, emptyList()) - val resolvedReference = createResolvedNamedReference( - reference, - reference.name, - callInfo, - resolutionResult.candidates, - resolutionResult.applicability, - explicitReceiver = null - ) + val annotationClassSymbol = annotationCall.getCorrespondingClassSymbolOrNull(session) + val resolvedReference = if (annotationClassSymbol != null && annotationClassSymbol.fir.classKind == ClassKind.ANNOTATION_CLASS) { + val resolutionResult = createCandidateForAnnotationCall(annotationClassSymbol, callInfo) + ?: ResolutionResult(callInfo, CandidateApplicability.HIDDEN, emptyList()) + createResolvedNamedReference( + reference, + reference.name, + callInfo, + resolutionResult.candidates, + resolutionResult.applicability, + explicitReceiver = null + ) + } else { + buildErrorReference( + callInfo, + if (annotationClassSymbol != null) ConeIllegalAnnotationError(reference.name) + else ConeUnresolvedNameError(reference.name), + reference.source, + reference.name + ) + } return annotationCall.transformCalleeReference(StoreNameReference, resolvedReference) } - private fun createCandidateForAnnotationCall(annotationCall: FirAnnotationCall, callInfo: CallInfo): ResolutionResult? { - val annotationClassSymbol = annotationCall.getCorrespondingClassSymbolOrNull(session) - ?.takeIf { it.fir.classKind == ClassKind.ANNOTATION_CLASS } - ?: return null + private fun createCandidateForAnnotationCall( + annotationClassSymbol: FirRegularClassSymbol, + callInfo: CallInfo + ): ResolutionResult? { var constructorSymbol: FirConstructorSymbol? = null annotationClassSymbol.fir.buildUseSiteMemberScope(session, scopeSession)?.processDeclaredConstructors { if (it.fir.isPrimary && constructorSymbol == null) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt index 9236e2ffb78..bf6e50341e9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt @@ -67,6 +67,10 @@ class ConeTypeMismatchError(val expectedType: ConeKotlinType, val actualType: Co class ConeContractDescriptionError(override val reason: String) : ConeDiagnostic() +class ConeIllegalAnnotationError(val name: Name) : ConeDiagnostic() { + override val reason: String get() = "Not a legal annotation: $name" +} + private fun describeSymbol(symbol: AbstractFirBasedSymbol<*>): String { return when (symbol) { is FirClassLikeSymbol<*> -> symbol.classId.asString() diff --git a/compiler/testData/diagnostics/tests/annotations/AmbigiousAnnotationConstructor.fir.kt b/compiler/testData/diagnostics/tests/annotations/AmbigiousAnnotationConstructor.fir.kt index 13e7ab907b6..faa8581a0da 100644 --- a/compiler/testData/diagnostics/tests/annotations/AmbigiousAnnotationConstructor.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/AmbigiousAnnotationConstructor.fir.kt @@ -1,6 +1,6 @@ // !WITH_NEW_INFERENCE import java.util.ArrayList -@ArrayList(1, 1) fun b() {} +@ArrayList(1, 1) fun b() {} @Xoo(x) fun c() {} @java.lang.Deprecated(x) fun a() {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/AnnotationIdentifier.fir.kt b/compiler/testData/diagnostics/tests/annotations/AnnotationIdentifier.fir.kt deleted file mode 100644 index 02bc1bbb3c1..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/AnnotationIdentifier.fir.kt +++ /dev/null @@ -1,19 +0,0 @@ -// FILE: a.kt - -annotation class annotation - -// FILE: test/b.kt - -package test - -@test.annotation class annotation - -// FILE: other/c.kt - -package other - -annotation class My - -@test.annotation class Your - -@My class Our diff --git a/compiler/testData/diagnostics/tests/annotations/AnnotationIdentifier.kt b/compiler/testData/diagnostics/tests/annotations/AnnotationIdentifier.kt index 2dca0da86f2..49f48bda457 100644 --- a/compiler/testData/diagnostics/tests/annotations/AnnotationIdentifier.kt +++ b/compiler/testData/diagnostics/tests/annotations/AnnotationIdentifier.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: a.kt annotation class annotation diff --git a/compiler/testData/diagnostics/tests/annotations/NonAnnotationClass.fir.kt b/compiler/testData/diagnostics/tests/annotations/NonAnnotationClass.fir.kt deleted file mode 100644 index bd22d122e7b..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/NonAnnotationClass.fir.kt +++ /dev/null @@ -1,3 +0,0 @@ -class Foo - -@Foo class Bar diff --git a/compiler/testData/diagnostics/tests/annotations/NonAnnotationClass.kt b/compiler/testData/diagnostics/tests/annotations/NonAnnotationClass.kt index 54466dc249f..895654512f3 100644 --- a/compiler/testData/diagnostics/tests/annotations/NonAnnotationClass.kt +++ b/compiler/testData/diagnostics/tests/annotations/NonAnnotationClass.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class Foo @Foo class Bar \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.fir.kt b/compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.fir.kt index cb60f1f1d27..9c1b0c11faf 100644 --- a/compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.fir.kt @@ -1,2 +1,2 @@ // Class constructor parameter CAN be recursively annotated -class RecursivelyAnnotated(@RecursivelyAnnotated(1) val x: Int) +class RecursivelyAnnotated(@RecursivelyAnnotated(1) val x: Int)