[FIR] Add REPEATABLE_CONTAINER_* diagnostics
REPEATABLE_CONTAINER_MUST_HAVE_VALUE_ARRAY REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION REPEATABLE_CONTAINER_TARGET_SET_NOT_A_SUBSET REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER
This commit is contained in:
committed by
TeamCityServer
parent
6fa1c0353c
commit
fa12e72551
+23
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
|
||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
@@ -122,6 +123,28 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
|
||||
parameter<FqName>("name")
|
||||
parameter<FqName>("explicitContainerName")
|
||||
}
|
||||
|
||||
val REPEATABLE_CONTAINER_MUST_HAVE_VALUE_ARRAY by deprecationError<KtAnnotationEntry>(RepeatableAnnotationContainerConstraints) {
|
||||
parameter<ClassId>("container")
|
||||
parameter<ClassId>("annotation")
|
||||
}
|
||||
val REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER by deprecationError<KtAnnotationEntry>(RepeatableAnnotationContainerConstraints) {
|
||||
parameter<ClassId>("container")
|
||||
parameter<Name>("nonDefault")
|
||||
}
|
||||
val REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION by deprecationError<KtAnnotationEntry>(RepeatableAnnotationContainerConstraints) {
|
||||
parameter<ClassId>("container")
|
||||
parameter<String>("retention")
|
||||
parameter<ClassId>("annotation")
|
||||
parameter<String>("annotationRetention")
|
||||
}
|
||||
val REPEATABLE_CONTAINER_TARGET_SET_NOT_A_SUBSET by deprecationError<KtAnnotationEntry>(RepeatableAnnotationContainerConstraints) {
|
||||
parameter<ClassId>("container")
|
||||
parameter<ClassId>("annotation")
|
||||
}
|
||||
val REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER by deprecationError<KtAnnotationEntry>(
|
||||
RepeatableAnnotationContainerConstraints
|
||||
)
|
||||
}
|
||||
|
||||
val MISC by object : DiagnosticGroup("Misc") {
|
||||
|
||||
+8
@@ -8,10 +8,13 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics.jvm
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.DefaultMethodsCallFromJava6TargetError
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitJvmOverloadsOnConstructorsOfAnnotationClasses
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.RepeatableAnnotationContainerConstraints
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
@@ -95,6 +98,11 @@ object FirJvmErrors {
|
||||
val NON_SOURCE_REPEATED_ANNOTATION by error0<KtAnnotationEntry>()
|
||||
val REPEATED_ANNOTATION_TARGET6 by error0<KtAnnotationEntry>()
|
||||
val REPEATED_ANNOTATION_WITH_CONTAINER by error2<KtAnnotationEntry, FqName, FqName>()
|
||||
val REPEATABLE_CONTAINER_MUST_HAVE_VALUE_ARRAY by deprecationError2<KtAnnotationEntry, ClassId, ClassId>(RepeatableAnnotationContainerConstraints)
|
||||
val REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER by deprecationError2<KtAnnotationEntry, ClassId, Name>(RepeatableAnnotationContainerConstraints)
|
||||
val REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION by deprecationError4<KtAnnotationEntry, ClassId, String, ClassId, String>(RepeatableAnnotationContainerConstraints)
|
||||
val REPEATABLE_CONTAINER_TARGET_SET_NOT_A_SUBSET by deprecationError2<KtAnnotationEntry, ClassId, ClassId>(RepeatableAnnotationContainerConstraints)
|
||||
val REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER by deprecationError0<KtAnnotationEntry>(RepeatableAnnotationContainerConstraints)
|
||||
|
||||
// Misc
|
||||
val INAPPLICABLE_JVM_FIELD by error1<KtAnnotationEntry, String>()
|
||||
|
||||
+174
-20
@@ -7,34 +7,41 @@ package org.jetbrains.kotlin.fir.analysis.jvm.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirAnnotatedDeclarationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getRetention
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
|
||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.isJvm6
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.fqName
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.getSingleClassifier
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() {
|
||||
private val RETENTION_PARAMETER_NAME = Name.identifier("value")
|
||||
private val REPEATABLE_PARAMETER_NAME = Name.identifier("value")
|
||||
private val JAVA_REPEATABLE_ANNOTATION = FqName("java.lang.annotation.Repeatable")
|
||||
private val JAVA_REPEATABLE_ANNOTATION = ClassId.fromString("java/lang/annotation/Repeatable")
|
||||
private val REPEATABLE_ANNOTATION_CONTAINER_NAME = Name.identifier(JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME)
|
||||
|
||||
override fun check(declaration: FirAnnotatedDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val annotationsSet = hashSetOf<FqName>()
|
||||
@@ -75,6 +82,154 @@ object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() {
|
||||
|
||||
annotationsSet.add(fqName)
|
||||
}
|
||||
|
||||
if (declaration is FirRegularClass) {
|
||||
val javaRepeatable = annotations.find { it.fqName(session) == JAVA_REPEATABLE_ANNOTATION }
|
||||
if (javaRepeatable != null) {
|
||||
checkJavaRepeatableAnnotationDeclaration(javaRepeatable, declaration, context, reporter)
|
||||
} else {
|
||||
val kotlinRepeatable = annotations.find { it.fqName(session) == StandardNames.FqNames.repeatable }
|
||||
if (kotlinRepeatable != null) {
|
||||
checkKotlinRepeatableAnnotationDeclaration(kotlinRepeatable, declaration, context, reporter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkJavaRepeatableAnnotationDeclaration(
|
||||
javaRepeatable: FirAnnotationCall,
|
||||
annotationClass: FirRegularClass,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
val containerClassId = javaRepeatable.resolveContainerAnnotation() ?: return
|
||||
val containerClassSymbol = context.session.symbolProvider.getClassLikeSymbolByClassId(containerClassId) as? FirRegularClassSymbol ?: return
|
||||
|
||||
checkRepeatableAnnotationContainer(annotationClass, containerClassSymbol, javaRepeatable.source, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkKotlinRepeatableAnnotationDeclaration(
|
||||
kotlinRepeatable: FirAnnotationCall,
|
||||
declaration: FirRegularClass,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
val unsubsitutedScope = declaration.unsubstitutedScope(context)
|
||||
if (unsubsitutedScope.getSingleClassifier(REPEATABLE_ANNOTATION_CONTAINER_NAME) != null) {
|
||||
reporter.reportOn(kotlinRepeatable.source, FirJvmErrors.REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkRepeatableAnnotationContainer(
|
||||
annotationClass: FirRegularClass,
|
||||
containerClass: FirRegularClassSymbol,
|
||||
annotationSource: FirSourceElement?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
checkContainerParameters(containerClass, annotationClass, annotationSource, context, reporter)
|
||||
checkContainerRetention(containerClass, annotationClass, annotationSource, context, reporter)
|
||||
checkContainerTarget(containerClass, annotationClass, annotationSource, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkContainerParameters(
|
||||
containerClass: FirRegularClassSymbol,
|
||||
annotationClass: FirRegularClass,
|
||||
annotationSource: FirSourceElement?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
val containerCtor =
|
||||
containerClass.declarationSymbols.find { it is FirConstructorSymbol && it.isPrimary } as? FirConstructorSymbol
|
||||
?: return
|
||||
|
||||
val valueParameterSymbols = containerCtor.valueParameterSymbols
|
||||
val parameterName = JavaSymbolProvider.VALUE_METHOD_NAME
|
||||
val value = valueParameterSymbols.find { it.name == parameterName }
|
||||
if (value == null || !value.resolvedReturnTypeRef.isArrayType ||
|
||||
value.resolvedReturnTypeRef.type.typeArguments.single().type != annotationClass.defaultType()
|
||||
) {
|
||||
reporter.reportOn(
|
||||
annotationSource,
|
||||
FirJvmErrors.REPEATABLE_CONTAINER_MUST_HAVE_VALUE_ARRAY,
|
||||
containerClass.classId,
|
||||
annotationClass.classId,
|
||||
context
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
val otherNonDefault = valueParameterSymbols.find { it.name != parameterName && !it.hasDefaultValue }
|
||||
if (otherNonDefault != null) {
|
||||
reporter.reportOn(
|
||||
annotationSource,
|
||||
FirJvmErrors.REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER,
|
||||
containerClass.classId,
|
||||
otherNonDefault.name,
|
||||
context
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkContainerRetention(
|
||||
containerClass: FirRegularClassSymbol,
|
||||
annotationClass: FirRegularClass,
|
||||
annotationSource: FirSourceElement?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
val annotationRetention = annotationClass.symbol.getAnnotationRetention()
|
||||
val containerRetention = containerClass.getAnnotationRetention()
|
||||
if (containerRetention < annotationRetention) {
|
||||
reporter.reportOn(
|
||||
annotationSource,
|
||||
FirJvmErrors.REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION,
|
||||
containerClass.classId,
|
||||
containerRetention.name,
|
||||
annotationClass.classId,
|
||||
annotationRetention.name,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkContainerTarget(
|
||||
containerClass: FirRegularClassSymbol,
|
||||
annotationClass: FirRegularClass,
|
||||
annotationSource: FirSourceElement?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
val annotationTargets = annotationClass.getAllowedAnnotationTargets()
|
||||
val containerTargets = containerClass.getAllowedAnnotationTargets()
|
||||
|
||||
// See https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-9.6.3.
|
||||
// (TBH, the rules about TYPE/TYPE_USE and TYPE_PARAMETER/TYPE_USE don't seem to make a lot of sense, but it's JLS
|
||||
// so we better obey it for full interop with the Java language and reflection.)
|
||||
for (target in containerTargets) {
|
||||
val ok = when (target) {
|
||||
in annotationTargets -> true
|
||||
KotlinTarget.ANNOTATION_CLASS ->
|
||||
KotlinTarget.CLASS in annotationTargets ||
|
||||
KotlinTarget.TYPE in annotationTargets
|
||||
KotlinTarget.CLASS ->
|
||||
KotlinTarget.TYPE in annotationTargets
|
||||
KotlinTarget.TYPE_PARAMETER ->
|
||||
KotlinTarget.TYPE in annotationTargets
|
||||
else -> false
|
||||
}
|
||||
if (!ok) {
|
||||
reporter.reportOn(
|
||||
annotationSource,
|
||||
FirJvmErrors.REPEATABLE_CONTAINER_TARGET_SET_NOT_A_SUBSET,
|
||||
containerClass.classId,
|
||||
annotationClass.classId,
|
||||
context
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirClassLikeSymbol<*>.isRepeatableAnnotation(session: FirSession): Boolean {
|
||||
@@ -85,25 +240,24 @@ object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() {
|
||||
getAnnotationRetention() == AnnotationRetention.SOURCE
|
||||
}
|
||||
|
||||
private fun FirClassLikeSymbol<*>.getAnnotationRetention(): AnnotationRetention? {
|
||||
val repeatableAnnotation = getAnnotationByFqName(StandardNames.FqNames.retention) ?: return null
|
||||
val retentionValue = repeatableAnnotation.findArgumentByName(RETENTION_PARAMETER_NAME) ?: return null
|
||||
val resolvedSymbol = retentionValue.toResolvedCallableSymbol() as? FirEnumEntrySymbol ?: return null
|
||||
val name = resolvedSymbol.name.asString()
|
||||
|
||||
return AnnotationRetention.values().firstOrNull { it.name == name }
|
||||
private fun FirClassLikeSymbol<*>.getAnnotationRetention(): AnnotationRetention {
|
||||
return getAnnotationByFqName(StandardNames.FqNames.retention)?.getRetention() ?: AnnotationRetention.RUNTIME
|
||||
}
|
||||
|
||||
private fun FirClassLikeSymbol<*>.resolveContainerAnnotation(): FqName? {
|
||||
val repeatableAnnotation =
|
||||
getAnnotationByFqName(StandardNames.FqNames.repeatable) ?: getAnnotationByFqName(JAVA_REPEATABLE_ANNOTATION) ?: return null
|
||||
val value = repeatableAnnotation.findArgumentByName(REPEATABLE_PARAMETER_NAME) ?: return null
|
||||
return repeatableAnnotation.resolveContainerAnnotation()?.asSingleFqName()
|
||||
}
|
||||
|
||||
private fun FirAnnotationCall.resolveContainerAnnotation(): ClassId? {
|
||||
val value = findArgumentByName(REPEATABLE_PARAMETER_NAME) ?: return null
|
||||
val classCallArgument = (value as? FirGetClassCall)?.argument ?: return null
|
||||
if (classCallArgument is FirResolvedQualifier) {
|
||||
return classCallArgument.relativeClassFqName
|
||||
return classCallArgument.classId
|
||||
} else if (classCallArgument is FirClassReferenceExpression) {
|
||||
val type = classCallArgument.classTypeRef.coneType.lowerBoundIfFlexible() as? ConeClassLikeType ?: return null
|
||||
return type.lookupTag.classId.asSingleFqName()
|
||||
return type.lookupTag.classId
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
+36
@@ -59,6 +59,11 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_PRIVATE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERRIDE_CANNOT_BE_STATIC
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATABLE_CONTAINER_MUST_HAVE_VALUE_ARRAY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATABLE_CONTAINER_TARGET_SET_NOT_A_SUBSET
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATED_ANNOTATION_TARGET6
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATED_ANNOTATION_WITH_CONTAINER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.STRICTFP_ON_CLASS
|
||||
@@ -219,6 +224,37 @@ object FirJvmDefaultErrorMessages {
|
||||
INTERFACE_CANT_CALL_DEFAULT_METHOD_VIA_SUPER,
|
||||
"Interfaces can call default methods via super only within @JvmDefault members. Please annotate the containing interface member with @JvmDefault"
|
||||
)
|
||||
|
||||
map.put(
|
||||
REPEATABLE_CONTAINER_MUST_HAVE_VALUE_ARRAY,
|
||||
"Container annotation ''{0}'' must have a property ''value'' of type ''Array<{1}>''.",
|
||||
TO_STRING,
|
||||
TO_STRING
|
||||
)
|
||||
map.put(
|
||||
REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER,
|
||||
"Container annotation ''{0}'' does not have a default value for ''{1}''.",
|
||||
TO_STRING,
|
||||
TO_STRING
|
||||
)
|
||||
map.put(
|
||||
REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION,
|
||||
"Container annotation ''{0}'' has shorter retention (''{1}'') than the repeatable annotation ''{2}'' (''{3}'').",
|
||||
TO_STRING,
|
||||
TO_STRING,
|
||||
TO_STRING,
|
||||
TO_STRING
|
||||
)
|
||||
map.put(
|
||||
REPEATABLE_CONTAINER_TARGET_SET_NOT_A_SUBSET,
|
||||
"Target set of container annotation ''{0}'' must be a subset of the target set of contained annotation ''{1}''.",
|
||||
TO_STRING,
|
||||
TO_STRING
|
||||
)
|
||||
map.put(
|
||||
REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER,
|
||||
"Repeatable annotation cannot have a nested class named 'Container'. This name is reserved for auto-generated container class"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-20
@@ -9,17 +9,13 @@ import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.findArgumentByName
|
||||
import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||
@@ -30,19 +26,12 @@ import org.jetbrains.kotlin.name.Name
|
||||
private val RETENTION_PARAMETER_NAME = Name.identifier("value")
|
||||
private val TARGET_PARAMETER_NAME = Name.identifier("allowedTargets")
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
fun FirAnnotationCall.getRetention(session: FirSession): AnnotationRetention {
|
||||
val annotationClassSymbol =
|
||||
(this.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session) as? FirRegularClassSymbol
|
||||
?: return AnnotationRetention.RUNTIME
|
||||
annotationClassSymbol.ensureResolved(FirResolvePhase.BODY_RESOLVE)
|
||||
val annotationClass = annotationClassSymbol.fir
|
||||
return annotationClass.getRetention()
|
||||
fun FirRegularClass.getRetention(): AnnotationRetention {
|
||||
return getRetentionAnnotation()?.getRetention() ?: AnnotationRetention.RUNTIME
|
||||
}
|
||||
|
||||
fun FirRegularClass.getRetention(): AnnotationRetention {
|
||||
val retentionAnnotation = getRetentionAnnotation() ?: return AnnotationRetention.RUNTIME
|
||||
val retentionArgument = retentionAnnotation.findArgumentByName(RETENTION_PARAMETER_NAME) as? FirQualifiedAccessExpression
|
||||
fun FirAnnotationCall.getRetention(): AnnotationRetention {
|
||||
val retentionArgument = findArgumentByName(RETENTION_PARAMETER_NAME) as? FirQualifiedAccessExpression
|
||||
?: return AnnotationRetention.RUNTIME
|
||||
val retentionName = (retentionArgument.calleeReference as? FirResolvedNamedReference)?.name?.asString()
|
||||
?: return AnnotationRetention.RUNTIME
|
||||
@@ -51,17 +40,19 @@ fun FirRegularClass.getRetention(): AnnotationRetention {
|
||||
|
||||
private val defaultAnnotationTargets = KotlinTarget.DEFAULT_TARGET_SET
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
fun FirAnnotationCall.getAllowedAnnotationTargets(session: FirSession): Set<KotlinTarget> {
|
||||
if (annotationTypeRef is FirErrorTypeRef) return KotlinTarget.values().toSet()
|
||||
val annotationClassSymbol = (this.annotationTypeRef.coneType as? ConeClassLikeType)
|
||||
?.fullyExpandedType(session)?.lookupTag?.toSymbol(session) ?: return defaultAnnotationTargets
|
||||
annotationClassSymbol.ensureResolved(FirResolvePhase.BODY_RESOLVE)
|
||||
val annotationClass = annotationClassSymbol.fir as? FirRegularClass
|
||||
return annotationClass?.getAllowedAnnotationTargets() ?: defaultAnnotationTargets
|
||||
return annotationClassSymbol.getAllowedAnnotationTargets()
|
||||
}
|
||||
|
||||
fun FirRegularClass.getAllowedAnnotationTargets(): Set<KotlinTarget> {
|
||||
return symbol.getAllowedAnnotationTargets()
|
||||
}
|
||||
|
||||
fun FirClassLikeSymbol<*>.getAllowedAnnotationTargets(): Set<KotlinTarget> {
|
||||
val targetAnnotation = getTargetAnnotation() ?: return defaultAnnotationTargets
|
||||
if (targetAnnotation.argumentList.arguments.isEmpty()) return emptySet()
|
||||
val arguments = targetAnnotation.findArgumentByName(TARGET_PARAMETER_NAME)?.unfoldArrayOrVararg().orEmpty()
|
||||
@@ -81,6 +72,10 @@ fun FirAnnotatedDeclaration.getTargetAnnotation(): FirAnnotationCall? {
|
||||
return getAnnotationByFqName(StandardNames.FqNames.target)
|
||||
}
|
||||
|
||||
fun FirClassLikeSymbol<*>.getTargetAnnotation(): FirAnnotationCall? {
|
||||
return getAnnotationByFqName(StandardNames.FqNames.target)
|
||||
}
|
||||
|
||||
fun FirAnnotationContainer.getAnnotationByClassId(classId: ClassId): FirAnnotationCall? {
|
||||
return annotations.find {
|
||||
(it.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.classId == classId
|
||||
|
||||
@@ -59,7 +59,7 @@ class JavaSymbolProvider(
|
||||
private val searchScope: GlobalSearchScope,
|
||||
) : FirSymbolProvider(session) {
|
||||
companion object {
|
||||
internal val VALUE_METHOD_NAME = Name.identifier("value")
|
||||
val VALUE_METHOD_NAME = Name.identifier("value")
|
||||
}
|
||||
|
||||
private val classCache =
|
||||
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
// !LANGUAGE: -RepeatableAnnotations -RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
import java.lang.annotation.Repeatable as R
|
||||
|
||||
@R(C1::class)
|
||||
annotation class A1
|
||||
annotation class C1
|
||||
|
||||
@R(C2::class)
|
||||
annotation class A2
|
||||
annotation class C2(val value: A2)
|
||||
|
||||
@R(C3::class)
|
||||
annotation class A3
|
||||
annotation class C3(val value: Array<String>)
|
||||
|
||||
@R(C4::class)
|
||||
annotation class A4
|
||||
annotation class C4(val notValue: Array<A4>)
|
||||
|
||||
@R(C5::class)
|
||||
annotation class A5
|
||||
annotation class C5(val value: Array<A5>, val irrelevant: String)
|
||||
|
||||
@R(C6::class)
|
||||
annotation class A6
|
||||
annotation class C6(val irrelevant: Double, val value: Array<A6> = [])
|
||||
|
||||
// Should be an error after fixing KT-47932.
|
||||
@R(A7::class)
|
||||
annotation class A7(val value: Array<A7>)
|
||||
|
||||
|
||||
|
||||
@R(D1::class)
|
||||
annotation class B1
|
||||
annotation class D1(val value: Array<B1>)
|
||||
|
||||
@R(D2::class)
|
||||
annotation class B2
|
||||
annotation class D2(val value: Array<B2> = [])
|
||||
|
||||
@R(D3::class)
|
||||
annotation class B3
|
||||
annotation class D3(val value: Array<B3>, val other1: String = "", val other2: Int = 42)
|
||||
|
||||
@R(D4::class)
|
||||
annotation class B4
|
||||
annotation class D4(val value1: Array<B4> = [], val value: Array<B4>)
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: -RepeatableAnnotations -RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
// !LANGUAGE: +RepeatableAnnotations +RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
import java.lang.annotation.Repeatable as R
|
||||
|
||||
@R(C1::class)
|
||||
annotation class A1
|
||||
annotation class C1
|
||||
|
||||
@R(C2::class)
|
||||
annotation class A2
|
||||
annotation class C2(val value: A2)
|
||||
|
||||
@R(C3::class)
|
||||
annotation class A3
|
||||
annotation class C3(val value: Array<String>)
|
||||
|
||||
@R(C4::class)
|
||||
annotation class A4
|
||||
annotation class C4(val notValue: Array<A4>)
|
||||
|
||||
@R(C5::class)
|
||||
annotation class A5
|
||||
annotation class C5(val value: Array<A5>, val irrelevant: String)
|
||||
|
||||
@R(C6::class)
|
||||
annotation class A6
|
||||
annotation class C6(val irrelevant: Double, val value: Array<A6> = [])
|
||||
|
||||
// Should be an error after fixing KT-47932.
|
||||
@R(A7::class)
|
||||
annotation class A7(val value: Array<A7>)
|
||||
|
||||
|
||||
|
||||
@R(D1::class)
|
||||
annotation class B1
|
||||
annotation class D1(val value: Array<B1>)
|
||||
|
||||
@R(D2::class)
|
||||
annotation class B2
|
||||
annotation class D2(val value: Array<B2> = [])
|
||||
|
||||
@R(D3::class)
|
||||
annotation class B3
|
||||
annotation class D3(val value: Array<B3>, val other1: String = "", val other2: Int = 42)
|
||||
|
||||
@R(D4::class)
|
||||
annotation class B4
|
||||
annotation class D4(val value1: Array<B4> = [], val value: Array<B4>)
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +RepeatableAnnotations +RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
// !LANGUAGE: -RepeatableAnnotations -RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
import java.lang.annotation.Repeatable as R
|
||||
import kotlin.annotation.AnnotationRetention.*
|
||||
|
||||
@R(C1::class)
|
||||
@Retention(RUNTIME)
|
||||
annotation class A1
|
||||
@Retention(BINARY)
|
||||
annotation class C1(val value: Array<A1>)
|
||||
|
||||
@R(C2::class)
|
||||
@Retention(BINARY)
|
||||
annotation class A2
|
||||
@Retention(SOURCE)
|
||||
annotation class C2(val value: Array<A2>)
|
||||
|
||||
@R(C3::class)
|
||||
annotation class A3
|
||||
@Retention(SOURCE)
|
||||
annotation class C3(val value: Array<A3>)
|
||||
|
||||
|
||||
|
||||
@R(D1::class)
|
||||
annotation class B1
|
||||
@Retention(RUNTIME)
|
||||
annotation class D1(val value: Array<B1>)
|
||||
|
||||
@R(D2::class)
|
||||
@Retention(SOURCE)
|
||||
annotation class B2
|
||||
@Retention(BINARY)
|
||||
annotation class D2(val value: Array<B2>)
|
||||
|
||||
@R(D3::class)
|
||||
@Retention(BINARY)
|
||||
annotation class B3
|
||||
annotation class D3(val value: Array<B3>)
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: -RepeatableAnnotations -RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
// !LANGUAGE: +RepeatableAnnotations +RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
import java.lang.annotation.Repeatable as R
|
||||
import kotlin.annotation.AnnotationRetention.*
|
||||
|
||||
@R(C1::class)
|
||||
@Retention(RUNTIME)
|
||||
annotation class A1
|
||||
@Retention(BINARY)
|
||||
annotation class C1(val value: Array<A1>)
|
||||
|
||||
@R(C2::class)
|
||||
@Retention(BINARY)
|
||||
annotation class A2
|
||||
@Retention(SOURCE)
|
||||
annotation class C2(val value: Array<A2>)
|
||||
|
||||
@R(C3::class)
|
||||
annotation class A3
|
||||
@Retention(SOURCE)
|
||||
annotation class C3(val value: Array<A3>)
|
||||
|
||||
|
||||
|
||||
@R(D1::class)
|
||||
annotation class B1
|
||||
@Retention(RUNTIME)
|
||||
annotation class D1(val value: Array<B1>)
|
||||
|
||||
@R(D2::class)
|
||||
@Retention(SOURCE)
|
||||
annotation class B2
|
||||
@Retention(BINARY)
|
||||
annotation class D2(val value: Array<B2>)
|
||||
|
||||
@R(D3::class)
|
||||
@Retention(BINARY)
|
||||
annotation class B3
|
||||
annotation class D3(val value: Array<B3>)
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +RepeatableAnnotations +RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
// !LANGUAGE: +RepeatableAnnotations +RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
import java.lang.annotation.Repeatable as R
|
||||
import kotlin.annotation.AnnotationTarget.*
|
||||
|
||||
@R(C1::class)
|
||||
annotation class A1
|
||||
@Target(FILE)
|
||||
annotation class C1(val value: Array<A1>)
|
||||
|
||||
@R(C2::class)
|
||||
@Target(CLASS)
|
||||
annotation class A2
|
||||
@Target(CLASS, FUNCTION)
|
||||
annotation class C2(val value: Array<A2>)
|
||||
|
||||
@R(C3::class)
|
||||
@Target(TYPE)
|
||||
annotation class A3
|
||||
annotation class C3(val value: Array<A3>)
|
||||
|
||||
@R(C4::class)
|
||||
@Target(ANNOTATION_CLASS)
|
||||
annotation class A4
|
||||
@Target(CLASS)
|
||||
annotation class C4(val value: Array<A4>)
|
||||
|
||||
|
||||
|
||||
|
||||
@R(D1::class)
|
||||
annotation class B1
|
||||
@Target(CLASS, ANNOTATION_CLASS, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER) // Default target set
|
||||
annotation class D1(val value: Array<B1>)
|
||||
|
||||
@R(D2::class)
|
||||
@Target(CLASS, FILE)
|
||||
annotation class B2
|
||||
@Target(CLASS)
|
||||
annotation class D2(val value: Array<B2>)
|
||||
|
||||
@R(D3::class)
|
||||
@Target(CLASS)
|
||||
annotation class B3
|
||||
@Target(ANNOTATION_CLASS)
|
||||
annotation class D3(val value: Array<B3>)
|
||||
|
||||
@R(D4::class)
|
||||
@Target(TYPE)
|
||||
annotation class B4
|
||||
@Target(ANNOTATION_CLASS, CLASS, TYPE_PARAMETER)
|
||||
annotation class D4(val value: Array<B4>)
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +RepeatableAnnotations +RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
// !LANGUAGE: -RepeatableAnnotations -RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
@Repeatable
|
||||
annotation class A1 {
|
||||
class Container
|
||||
}
|
||||
|
||||
|
||||
@java.lang.annotation.Repeatable(D1::class)
|
||||
annotation class B1 {
|
||||
class Container
|
||||
}
|
||||
annotation class D1(val value: Array<B1>)
|
||||
|
||||
@Repeatable
|
||||
@java.lang.annotation.Repeatable(D2::class)
|
||||
annotation class B2 {
|
||||
class Container
|
||||
}
|
||||
annotation class D2(val value: Array<B2>)
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: -RepeatableAnnotations -RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
// !LANGUAGE: +RepeatableAnnotations +RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
@Repeatable
|
||||
annotation class A1 {
|
||||
class Container
|
||||
}
|
||||
|
||||
|
||||
@java.lang.annotation.Repeatable(D1::class)
|
||||
annotation class B1 {
|
||||
class Container
|
||||
}
|
||||
annotation class D1(val value: Array<B1>)
|
||||
|
||||
@Repeatable
|
||||
@java.lang.annotation.Repeatable(D2::class)
|
||||
annotation class B2 {
|
||||
class Container
|
||||
}
|
||||
annotation class D2(val value: Array<B2>)
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +RepeatableAnnotations +RepeatableAnnotationContainerConstraints
|
||||
// FULL_JDK
|
||||
|
||||
|
||||
+2
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
@@ -335,6 +336,7 @@ private object FirToKtConversionCreator {
|
||||
LanguageVersionSettings::class,
|
||||
Variance::class,
|
||||
FqName::class,
|
||||
ClassId::class,
|
||||
FirModuleData::class,
|
||||
ExpectActualCompatibility.Incompatible::class,
|
||||
DeprecationInfo::class,
|
||||
|
||||
+83
-3
@@ -2526,7 +2526,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
firDiagnostic.b,
|
||||
firDiagnostic.c.mapKeys { (incompatible, _) ->
|
||||
incompatible
|
||||
}.mapValues { (_, collection) ->
|
||||
}.mapValues { (_, collection) ->
|
||||
collection.map { firBasedSymbol ->
|
||||
firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
|
||||
}
|
||||
@@ -2540,7 +2540,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
|
||||
firDiagnostic.b.mapKeys { (incompatible, _) ->
|
||||
incompatible
|
||||
}.mapValues { (_, collection) ->
|
||||
}.mapValues { (_, collection) ->
|
||||
collection.map { firBasedSymbol ->
|
||||
firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
|
||||
}
|
||||
@@ -2575,7 +2575,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
firDiagnostic.b.map { pair ->
|
||||
firSymbolBuilder.buildSymbol(pair.first.fir) to pair.second.mapKeys { (incompatible, _) ->
|
||||
incompatible
|
||||
}.mapValues { (_, collection) ->
|
||||
}.mapValues { (_, collection) ->
|
||||
collection.map { firBasedSymbol ->
|
||||
firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
|
||||
}
|
||||
@@ -3806,6 +3806,86 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_CONTAINER_MUST_HAVE_VALUE_ARRAY.errorFactory) { firDiagnostic ->
|
||||
RepeatableContainerMustHaveValueArrayErrorImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_CONTAINER_MUST_HAVE_VALUE_ARRAY.warningFactory) { firDiagnostic ->
|
||||
RepeatableContainerMustHaveValueArrayWarningImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER.errorFactory) { firDiagnostic ->
|
||||
RepeatableContainerHasNonDefaultParameterErrorImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER.warningFactory) { firDiagnostic ->
|
||||
RepeatableContainerHasNonDefaultParameterWarningImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION.errorFactory) { firDiagnostic ->
|
||||
RepeatableContainerHasShorterRetentionErrorImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic.c,
|
||||
firDiagnostic.d,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION.warningFactory) { firDiagnostic ->
|
||||
RepeatableContainerHasShorterRetentionWarningImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic.c,
|
||||
firDiagnostic.d,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_CONTAINER_TARGET_SET_NOT_A_SUBSET.errorFactory) { firDiagnostic ->
|
||||
RepeatableContainerTargetSetNotASubsetErrorImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_CONTAINER_TARGET_SET_NOT_A_SUBSET.warningFactory) { firDiagnostic ->
|
||||
RepeatableContainerTargetSetNotASubsetWarningImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER.errorFactory) { firDiagnostic ->
|
||||
RepeatableAnnotationHasNestedClassNamedContainerErrorImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER.warningFactory) { firDiagnostic ->
|
||||
RepeatableAnnotationHasNestedClassNamedContainerWarningImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.INAPPLICABLE_JVM_FIELD) { firDiagnostic ->
|
||||
InapplicableJvmFieldImpl(
|
||||
firDiagnostic.a,
|
||||
|
||||
+61
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
@@ -2646,6 +2647,66 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val explicitContainerName: FqName
|
||||
}
|
||||
|
||||
abstract class RepeatableContainerMustHaveValueArrayError : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableContainerMustHaveValueArrayError::class
|
||||
abstract val container: ClassId
|
||||
abstract val annotation: ClassId
|
||||
}
|
||||
|
||||
abstract class RepeatableContainerMustHaveValueArrayWarning : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableContainerMustHaveValueArrayWarning::class
|
||||
abstract val container: ClassId
|
||||
abstract val annotation: ClassId
|
||||
}
|
||||
|
||||
abstract class RepeatableContainerHasNonDefaultParameterError : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableContainerHasNonDefaultParameterError::class
|
||||
abstract val container: ClassId
|
||||
abstract val nonDefault: Name
|
||||
}
|
||||
|
||||
abstract class RepeatableContainerHasNonDefaultParameterWarning : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableContainerHasNonDefaultParameterWarning::class
|
||||
abstract val container: ClassId
|
||||
abstract val nonDefault: Name
|
||||
}
|
||||
|
||||
abstract class RepeatableContainerHasShorterRetentionError : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableContainerHasShorterRetentionError::class
|
||||
abstract val container: ClassId
|
||||
abstract val retention: String
|
||||
abstract val annotation: ClassId
|
||||
abstract val annotationRetention: String
|
||||
}
|
||||
|
||||
abstract class RepeatableContainerHasShorterRetentionWarning : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableContainerHasShorterRetentionWarning::class
|
||||
abstract val container: ClassId
|
||||
abstract val retention: String
|
||||
abstract val annotation: ClassId
|
||||
abstract val annotationRetention: String
|
||||
}
|
||||
|
||||
abstract class RepeatableContainerTargetSetNotASubsetError : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableContainerTargetSetNotASubsetError::class
|
||||
abstract val container: ClassId
|
||||
abstract val annotation: ClassId
|
||||
}
|
||||
|
||||
abstract class RepeatableContainerTargetSetNotASubsetWarning : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableContainerTargetSetNotASubsetWarning::class
|
||||
abstract val container: ClassId
|
||||
abstract val annotation: ClassId
|
||||
}
|
||||
|
||||
abstract class RepeatableAnnotationHasNestedClassNamedContainerError : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableAnnotationHasNestedClassNamedContainerError::class
|
||||
}
|
||||
|
||||
abstract class RepeatableAnnotationHasNestedClassNamedContainerWarning : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = RepeatableAnnotationHasNestedClassNamedContainerWarning::class
|
||||
}
|
||||
|
||||
abstract class InapplicableJvmField : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||
override val diagnosticClass get() = InapplicableJvmField::class
|
||||
abstract val message: String
|
||||
|
||||
+91
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
@@ -4303,6 +4304,96 @@ internal class RepeatedAnnotationWithContainerImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableContainerMustHaveValueArrayErrorImpl(
|
||||
override val container: ClassId,
|
||||
override val annotation: ClassId,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableContainerMustHaveValueArrayError(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableContainerMustHaveValueArrayWarningImpl(
|
||||
override val container: ClassId,
|
||||
override val annotation: ClassId,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableContainerMustHaveValueArrayWarning(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableContainerHasNonDefaultParameterErrorImpl(
|
||||
override val container: ClassId,
|
||||
override val nonDefault: Name,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableContainerHasNonDefaultParameterError(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableContainerHasNonDefaultParameterWarningImpl(
|
||||
override val container: ClassId,
|
||||
override val nonDefault: Name,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableContainerHasNonDefaultParameterWarning(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableContainerHasShorterRetentionErrorImpl(
|
||||
override val container: ClassId,
|
||||
override val retention: String,
|
||||
override val annotation: ClassId,
|
||||
override val annotationRetention: String,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableContainerHasShorterRetentionError(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableContainerHasShorterRetentionWarningImpl(
|
||||
override val container: ClassId,
|
||||
override val retention: String,
|
||||
override val annotation: ClassId,
|
||||
override val annotationRetention: String,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableContainerHasShorterRetentionWarning(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableContainerTargetSetNotASubsetErrorImpl(
|
||||
override val container: ClassId,
|
||||
override val annotation: ClassId,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableContainerTargetSetNotASubsetError(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableContainerTargetSetNotASubsetWarningImpl(
|
||||
override val container: ClassId,
|
||||
override val annotation: ClassId,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableContainerTargetSetNotASubsetWarning(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableAnnotationHasNestedClassNamedContainerErrorImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableAnnotationHasNestedClassNamedContainerError(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatableAnnotationHasNestedClassNamedContainerWarningImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatableAnnotationHasNestedClassNamedContainerWarning(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class InapplicableJvmFieldImpl(
|
||||
override val message: String,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
|
||||
Reference in New Issue
Block a user