[FIR] Introduce NOT_AN_ANNOTATION_CLASS diagnostic
This commit is contained in:
+1
@@ -87,6 +87,7 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
|
|||||||
is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.on(source)
|
is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.on(source)
|
||||||
is ConeTypeMismatchError -> FirErrors.TYPE_MISMATCH.on(source, diagnostic.expectedType, diagnostic.actualType)
|
is ConeTypeMismatchError -> FirErrors.TYPE_MISMATCH.on(source, diagnostic.expectedType, diagnostic.actualType)
|
||||||
is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.on(diagnostic.source.safeAs() ?: source)
|
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) {
|
is ConeSimpleDiagnostic -> if (source.kind is FirFakeSourceElementKind) {
|
||||||
null
|
null
|
||||||
} else if (diagnostic.kind == SymbolNotFound) {
|
} else if (diagnostic.kind == SymbolNotFound) {
|
||||||
|
|||||||
+4
@@ -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_RECEIVER_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_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.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_CONST_EXPRESSION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CANDIDATE
|
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(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)
|
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
|
// 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_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)
|
map.put(EXPOSED_PROPERTY_TYPE, "{0} property exposes its {2} type{1}", TO_STRING, TO_STRING, TO_STRING)
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ object FirErrors {
|
|||||||
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by existing<FirSourceElement, KtTypeReference>(Errors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER)
|
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by existing<FirSourceElement, KtTypeReference>(Errors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER)
|
||||||
val INVALID_TYPE_OF_ANNOTATION_MEMBER by existing<FirSourceElement, KtTypeReference>(Errors.INVALID_TYPE_OF_ANNOTATION_MEMBER)
|
val INVALID_TYPE_OF_ANNOTATION_MEMBER by existing<FirSourceElement, KtTypeReference>(Errors.INVALID_TYPE_OF_ANNOTATION_MEMBER)
|
||||||
val VAR_ANNOTATION_PARAMETER by existing<FirSourceElement, KtParameter>(Errors.VAR_ANNOTATION_PARAMETER)
|
val VAR_ANNOTATION_PARAMETER by existing<FirSourceElement, KtParameter>(Errors.VAR_ANNOTATION_PARAMETER)
|
||||||
|
val NOT_AN_ANNOTATION_CLASS by error1<FirSourceElement, PsiElement, String>()
|
||||||
|
|
||||||
// Exposed visibility group
|
// Exposed visibility group
|
||||||
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
|
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
|
||||||
|
|||||||
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.*
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
|
import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager
|
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||||
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.inference.ResolvedCallableReferenceAtom
|
import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference
|
import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference
|
||||||
@@ -333,24 +330,35 @@ class FirCallResolver(
|
|||||||
containingDeclarations
|
containingDeclarations
|
||||||
)
|
)
|
||||||
|
|
||||||
val resolutionResult = createCandidateForAnnotationCall(annotationCall, callInfo)
|
val annotationClassSymbol = annotationCall.getCorrespondingClassSymbolOrNull(session)
|
||||||
?: ResolutionResult(callInfo, CandidateApplicability.HIDDEN, emptyList())
|
val resolvedReference = if (annotationClassSymbol != null && annotationClassSymbol.fir.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||||
val resolvedReference = createResolvedNamedReference(
|
val resolutionResult = createCandidateForAnnotationCall(annotationClassSymbol, callInfo)
|
||||||
reference,
|
?: ResolutionResult(callInfo, CandidateApplicability.HIDDEN, emptyList())
|
||||||
reference.name,
|
createResolvedNamedReference(
|
||||||
callInfo,
|
reference,
|
||||||
resolutionResult.candidates,
|
reference.name,
|
||||||
resolutionResult.applicability,
|
callInfo,
|
||||||
explicitReceiver = null
|
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)
|
return annotationCall.transformCalleeReference(StoreNameReference, resolvedReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCandidateForAnnotationCall(annotationCall: FirAnnotationCall, callInfo: CallInfo): ResolutionResult? {
|
private fun createCandidateForAnnotationCall(
|
||||||
val annotationClassSymbol = annotationCall.getCorrespondingClassSymbolOrNull(session)
|
annotationClassSymbol: FirRegularClassSymbol,
|
||||||
?.takeIf { it.fir.classKind == ClassKind.ANNOTATION_CLASS }
|
callInfo: CallInfo
|
||||||
?: return null
|
): ResolutionResult? {
|
||||||
var constructorSymbol: FirConstructorSymbol? = null
|
var constructorSymbol: FirConstructorSymbol? = null
|
||||||
annotationClassSymbol.fir.buildUseSiteMemberScope(session, scopeSession)?.processDeclaredConstructors {
|
annotationClassSymbol.fir.buildUseSiteMemberScope(session, scopeSession)?.processDeclaredConstructors {
|
||||||
if (it.fir.isPrimary && constructorSymbol == null) {
|
if (it.fir.isPrimary && constructorSymbol == null) {
|
||||||
|
|||||||
+4
@@ -67,6 +67,10 @@ class ConeTypeMismatchError(val expectedType: ConeKotlinType, val actualType: Co
|
|||||||
|
|
||||||
class ConeContractDescriptionError(override val reason: String) : ConeDiagnostic()
|
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 {
|
private fun describeSymbol(symbol: AbstractFirBasedSymbol<*>): String {
|
||||||
return when (symbol) {
|
return when (symbol) {
|
||||||
is FirClassLikeSymbol<*> -> symbol.classId.asString()
|
is FirClassLikeSymbol<*> -> symbol.classId.asString()
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
// !WITH_NEW_INFERENCE
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
@ArrayList<Int>(1, 1) fun b() {}
|
<!NOT_AN_ANNOTATION_CLASS!>@ArrayList<Int>(1, 1)<!> fun b() {}
|
||||||
@<!UNRESOLVED_REFERENCE!>Xoo<!>(<!UNRESOLVED_REFERENCE!>x<!>) fun c() {}
|
@<!UNRESOLVED_REFERENCE!>Xoo<!>(<!UNRESOLVED_REFERENCE!>x<!>) fun c() {}
|
||||||
<!INAPPLICABLE_CANDIDATE!>@java.lang.Deprecated(<!UNRESOLVED_REFERENCE!>x<!>)<!> fun a() {}
|
<!INAPPLICABLE_CANDIDATE!>@java.lang.Deprecated(<!UNRESOLVED_REFERENCE!>x<!>)<!> fun a() {}
|
||||||
@@ -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
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// FILE: a.kt
|
// FILE: a.kt
|
||||||
|
|
||||||
annotation class annotation
|
annotation class annotation
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
class Foo
|
|
||||||
|
|
||||||
@Foo class Bar
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
class Foo
|
class Foo
|
||||||
|
|
||||||
<!NOT_AN_ANNOTATION_CLASS!>@Foo<!> class Bar
|
<!NOT_AN_ANNOTATION_CLASS!>@Foo<!> class Bar
|
||||||
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
// Class constructor parameter CAN be recursively annotated
|
// Class constructor parameter CAN be recursively annotated
|
||||||
class RecursivelyAnnotated(@RecursivelyAnnotated(1) val x: Int)
|
class RecursivelyAnnotated(<!NOT_AN_ANNOTATION_CLASS, NOT_AN_ANNOTATION_CLASS!>@RecursivelyAnnotated(1)<!> val x: Int)
|
||||||
|
|||||||
Reference in New Issue
Block a user