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 feb8f67cf19..2832e456178 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 @@ -180,6 +180,19 @@ object DIAGNOSTICS_LIST : DiagnosticList() { parameter("actualTarget") parameter("useSiteTarget") } + val INAPPLICABLE_TARGET_ON_PROPERTY by error { + parameter("useSiteDescription") + } + val INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE by error { + parameter("useSiteDescription") + } + val INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE by error() + val INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD by error() + val INAPPLICABLE_PARAM_TARGET by error() + val REDUNDANT_ANNOTATION_TARGET by warning { + parameter("useSiteDescription") + } + val INAPPLICABLE_FILE_TARGET by error() } val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") { 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 546cc0e7ce6..e07f14ece75 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 @@ -181,6 +181,13 @@ object FirErrors { val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by error0() val WRONG_ANNOTATION_TARGET by error1() val WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET by error2() + val INAPPLICABLE_TARGET_ON_PROPERTY by error1() + val INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE by error1() + val INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE by error0() + val INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD by error0() + val INAPPLICABLE_PARAM_TARGET by error0() + val REDUNDANT_ANNOTATION_TARGET by warning1() + val INAPPLICABLE_FILE_TARGET by error0() // Exposed visibility val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3(SourceElementPositioningStrategies.DECLARATION_NAME) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt index 1b6a34da66c..585d4fc580e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext @@ -77,6 +78,10 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() { return actualTargets.onlyWithUseSiteTarget.any { it in applicableTargets && it == useSiteMapping } } + if (useSiteTarget != null) { + checkAnnotationUseSiteTarget(declaration, annotation, useSiteTarget, context, reporter) + } + if (check(actualTargets.defaultTargets) || check(actualTargets.canBeSubstituted) || checkWithUseSiteTargets()) { return } @@ -100,6 +105,64 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() { } } + private fun checkAnnotationUseSiteTarget( + annotated: FirAnnotatedDeclaration, + annotation: FirAnnotationCall, + target: AnnotationUseSiteTarget, + context: CheckerContext, + reporter: DiagnosticReporter + ) { + when (target) { + AnnotationUseSiteTarget.PROPERTY, + AnnotationUseSiteTarget.PROPERTY_GETTER -> { + } + AnnotationUseSiteTarget.FIELD -> { + if (annotated is FirProperty && annotated.delegateFieldSymbol != null && !annotated.hasBackingField) { + reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD, context) + } + } + AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD -> { + if (annotated is FirProperty && annotated.delegateFieldSymbol == null) { + reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE, context) + } + } + AnnotationUseSiteTarget.PROPERTY_SETTER, + AnnotationUseSiteTarget.SETTER_PARAMETER -> { + if (annotated !is FirProperty || annotated.isLocal) { + reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_TARGET_ON_PROPERTY, target.renderName, context) + } else if (!annotated.isVar) { + reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE, target.renderName, context) + } + } + AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER -> when { + annotated is FirValueParameter -> { + val container = context.containingDeclarations.lastOrNull() + if (container is FirConstructor && container.isPrimary) { + reporter.reportOn(annotation.source, FirErrors.REDUNDANT_ANNOTATION_TARGET, target.renderName, context) + } else { + reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_PARAM_TARGET, context) + } + } + annotated is FirProperty && annotated.source?.kind == FirFakeSourceElementKind.PropertyFromParameter -> { + } + else -> reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_PARAM_TARGET, context) + } + AnnotationUseSiteTarget.FILE -> { + // NB: report once? + if (annotated !is FirFile) { + reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_FILE_TARGET, context) + } + } + AnnotationUseSiteTarget.RECEIVER -> { + // NB: report once? + // annotation with use-site target `receiver` can be only on type reference, but not on declaration + reporter.reportOn( + annotation.source, FirErrors.WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET, "declaration", target.renderName, context + ) + } + } + } + private fun checkDeprecatedCalls( deprecatedSinceKotlinCall: FirAnnotationCall, deprecatedCall: FirAnnotationCall?, 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 e34897f29af..ef0fbdebca3 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 @@ -141,8 +141,14 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_CONST_EXP import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_KOTLIN_VERSION_STRING_VALUE 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_FILE_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_INFIX_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_LATEINIT_MODIFIER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_PARAM_TARGET +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_ON_PROPERTY +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_ENUM_COMPARISON_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_MODIFIERS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_TYPES @@ -238,6 +244,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RECURSION_IN_IMPL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RECURSION_IN_INLINE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RECURSION_IN_SUPERTYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDECLARATION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_ANNOTATION_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_CALL_OF_CONVERSION_METHOD import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_EXPLICIT_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER @@ -449,7 +456,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(NULLABLE_TYPE_OF_ANNOTATION_MEMBER, "An annotation parameter cannot be nullable") map.put(INVALID_TYPE_OF_ANNOTATION_MEMBER, "Invalid type of annotation member") map.put(VAR_ANNOTATION_PARAMETER, "An annotation parameter cannot be 'var'") - map.put(ANNOTATION_CLASS_CONSTRUCTOR_CALL, "Annotation class cannot be instantiated"); + map.put(ANNOTATION_CLASS_CONSTRUCTOR_CALL, "Annotation class cannot be instantiated") map.put(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING) map.put(SUPERTYPES_FOR_ANNOTATION_CLASS, "Annotation class cannot have supertypes") map.put( @@ -478,13 +485,23 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { "DeprecatedSinceKotlin annotation cannot be used outside 'kotlin' subpackages" ) map.put(ANNOTATION_ON_SUPERCLASS, "Annotations on superclass are meaningless") - map.put(WRONG_ANNOTATION_TARGET, "This annotation is not applicable to target ''{0}''", TO_STRING); + map.put(WRONG_ANNOTATION_TARGET, "This annotation is not applicable to target ''{0}''", TO_STRING) + map.put(INAPPLICABLE_TARGET_ON_PROPERTY, "''@{0}:'' annotations could be applied only to property declarations", TO_STRING) + map.put(INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE, "''@{0}:'' annotations could be applied only to mutable properties", TO_STRING) + map.put(INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE, "'@delegate:' annotations could be applied only to delegated properties") + map.put( + INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD, + "'@field:' annotations could be applied only to properties with backing fields" + ) + map.put(INAPPLICABLE_PARAM_TARGET, "'@param:' annotations could be applied only to primary constructor parameters") + map.put(REDUNDANT_ANNOTATION_TARGET, "Redundant annotation target ''{0}''", TO_STRING) + map.put(INAPPLICABLE_FILE_TARGET, "'@file:' annotations can only be applied before package declaration") map.put( WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET, "This annotation is not applicable to target ''{0}'' and use site target ''@{1}''", TO_STRING, TO_STRING - ); + ) // Exposed visibility group // # map.put( diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/DelegateAnnotations.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/DelegateAnnotations.fir.kt deleted file mode 100644 index 86067bff9d7..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/DelegateAnnotations.fir.kt +++ /dev/null @@ -1,33 +0,0 @@ -import kotlin.reflect.KProperty - -@Target(AnnotationTarget.FIELD) annotation class Field - -@Target(AnnotationTarget.PROPERTY) annotation class Prop - -class CustomDelegate { - operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name -} - -@delegate:Field -class SomeClass { - - @delegate:Field - constructor() - - @delegate:Field @delegate:Prop - protected val simpleProperty: String = "text" - - @delegate:Field @delegate:Prop - protected val delegatedProperty: String by CustomDelegate() - - @delegate:Field @delegate:Prop - val propertyWithCustomGetter: Int - get() = 5 - -} - -class WithPrimaryConstructor(@delegate:Field @delegate:Prop val a: String, - @param:Field @param:Prop val b: String) - -fun foo(@delegate:Field @delegate:Prop x: Int) = x - diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/DelegateAnnotations.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/DelegateAnnotations.kt index ec802af51d9..2639c82b0bc 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/DelegateAnnotations.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/DelegateAnnotations.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL import kotlin.reflect.KProperty @Target(AnnotationTarget.FIELD) annotation class Field diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/FieldAnnotations.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/FieldAnnotations.fir.kt deleted file mode 100644 index 1aae9746799..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/FieldAnnotations.fir.kt +++ /dev/null @@ -1,36 +0,0 @@ -import kotlin.reflect.KProperty - -annotation class Ann - -class CustomDelegate { - operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name -} - -@field:Ann -class SomeClass { - - @field:Ann - constructor() - - @field:Ann - protected val simpleProperty: String = "text" - - @field:[Ann] - protected val simplePropertyWithAnnotationList: String = "text" - - @field:Ann - protected val delegatedProperty: String by CustomDelegate() - - @field:Ann - val propertyWithCustomGetter: Int - get() = 5 - - @field:Ann - fun anotherFun(@field:Ann s: String) { - @field:Ann - val localVariable = 5 - } - -} - -class WithPrimaryConstructor(@field:Ann val a: String) diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/FieldAnnotations.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/FieldAnnotations.kt index 633f183e0bd..f4a1b63e485 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/FieldAnnotations.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/FieldAnnotations.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL import kotlin.reflect.KProperty annotation class Ann diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ParamAnnotations.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ParamAnnotations.fir.kt deleted file mode 100644 index 77d6e7a4452..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ParamAnnotations.fir.kt +++ /dev/null @@ -1,24 +0,0 @@ -annotation class Ann -annotation class Second - -@param:Ann -class SomeClass { - - @param:Ann - constructor(@param:Ann a: String) - - @param:Ann - protected val simpleProperty: String = "text" - - @param:Ann - fun anotherFun() { - @param:Ann - val localVariable = 5 - } - -} - -class PrimaryConstructorClass( - @param:Ann a: String, -@param:[Ann Second] b: String, -@param:Ann val c: String) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ParamAnnotations.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ParamAnnotations.kt index b26997ddc8b..5a170e96167 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ParamAnnotations.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ParamAnnotations.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL annotation class Ann annotation class Second diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ReceiverAnnotations.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ReceiverAnnotations.fir.kt deleted file mode 100644 index d9b475be1eb..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ReceiverAnnotations.fir.kt +++ /dev/null @@ -1,25 +0,0 @@ -annotation class Ann - -@receiver:Ann -class SomeClass { - - @receiver:Ann - constructor(@receiver:Ann a: String) - - @receiver:Ann - protected val simpleProperty: String = "text" - - @receiver:Ann - fun anotherFun() { - @receiver:Ann - val localVariable = 5 - } - - val @receiver:Ann String.extensionProperty2: String - get() = "A" -} - -fun @receiver:Ann String.length2() = length - -val @receiver:Ann String.extensionProperty: String - get() = "A" \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ReceiverAnnotations.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ReceiverAnnotations.kt index 6e049fa9e65..ca8e8085afd 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ReceiverAnnotations.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/ReceiverAnnotations.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL annotation class Ann @receiver:Ann diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SetterAnnotations.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SetterAnnotations.fir.kt deleted file mode 100644 index e72ded6e27e..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SetterAnnotations.fir.kt +++ /dev/null @@ -1,38 +0,0 @@ -import kotlin.reflect.KProperty - -annotation class Ann - -class CustomDelegate { - operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name - operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {} -} - -@set:Ann -class SomeClass { - - @set:Ann - protected val simpleProperty: String = "text" - - @set:Ann - protected var mutableProperty: String = "text" - - @set:[Ann] - protected var mutablePropertyWithAnnotationList: String = "text" - - @set:Ann - protected var delegatedProperty: String by CustomDelegate() - - @set:Ann - var propertyWithCustomSetter: Int - get() = 5 - set(v) {} - - @set:Ann - fun annotationOnFunction(a: Int) = a + 5 - - fun anotherFun() { - @set:Ann - val localVariable = 5 - } - -} diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SetterAnnotations.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SetterAnnotations.kt index 6c3bcd699b5..000843656a6 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SetterAnnotations.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SetterAnnotations.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL import kotlin.reflect.KProperty annotation class Ann diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SparamAnnotations.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SparamAnnotations.fir.kt deleted file mode 100644 index a4f6646d47b..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SparamAnnotations.fir.kt +++ /dev/null @@ -1,39 +0,0 @@ -import kotlin.reflect.KProperty - -annotation class Ann - -class CustomDelegate { - operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name - operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {} -} - -@setparam:Ann -class SomeClass { - - @setparam:Ann - constructor() - - @setparam:Ann - protected val simpleProperty: String = "text" - - @setparam:Ann - protected var mutableProperty: String = "text" - - @setparam:[Ann] - protected var mutablePropertyWithAnnotationList: String = "text" - - @setparam:Ann - protected var delegatedProperty: String by CustomDelegate() - - @setparam:Ann - var propertyWithCustomSetter: Int - get() = 5 - set(v) {} - - @setparam:Ann - fun anotherFun() { - @setparam:Ann - val localVariable = 5 - } - -} diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SparamAnnotations.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SparamAnnotations.kt index bb7d1fc45ff..8095c474184 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SparamAnnotations.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/SparamAnnotations.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL import kotlin.reflect.KProperty annotation class Ann diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticFileAnnotationInWrongPlace.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticFileAnnotationInWrongPlace.fir.kt index 4eb44143744..b22a99f7de2 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticFileAnnotationInWrongPlace.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticFileAnnotationInWrongPlace.fir.kt @@ -1,12 +1,12 @@ package bar -@file:foo +@file:foo val prop -@file:[bar baz] +@file:[bar baz] fun func() {} -@file:[baz] +@file:[baz] class C @file: diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticWithoutPackage.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticWithoutPackage.fir.kt index 65b76865d77..8d55b7067c7 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticWithoutPackage.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticWithoutPackage.fir.kt @@ -1,6 +1,6 @@ @file:foo @foo @bar -@file:[baz] +@file:[baz] fun test() {} annotation class foo diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticWithoutPackageWithSimpleAnnotation.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticWithoutPackageWithSimpleAnnotation.fir.kt index 4d51dd582c7..33c6a444e7a 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticWithoutPackageWithSimpleAnnotation.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/diagnosticWithoutPackageWithSimpleAnnotation.fir.kt @@ -1,6 +1,6 @@ @file:foo @foo @bar -@file: baz +@file: baz fun test() {} annotation class foo diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/fileAnnotationWithoutColon_after.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/fileAnnotationWithoutColon_after.fir.kt index f574d4ced6c..ea487f9be3c 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/fileAnnotationWithoutColon_after.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/fileAnnotationWithoutColon_after.fir.kt @@ -1,9 +1,9 @@ // !LANGUAGE: +RestrictionOfWrongAnnotationsWithUseSiteTargetsOnTypes // !DIAGNOSTICS: -UNUSED_PARAMETER -fun test1(@file Suppress("") x: Int) {} +fun test1(@file Suppress("") x: Int) {} -@file @Suppress("") +@file @Suppress("") fun test2() {} class OnType(x: @file Suppress("") Int) diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/fileAnnotationWithoutColon_before.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/fileAnnotationWithoutColon_before.fir.kt index 9a8f7dd76c8..7ec8df1ebc4 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/fileAnnotationWithoutColon_before.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/fileAnnotationWithoutColon_before.fir.kt @@ -1,9 +1,9 @@ // !LANGUAGE: -RestrictionOfWrongAnnotationsWithUseSiteTargetsOnTypes // !DIAGNOSTICS: -UNUSED_PARAMETER -fun test1(@file Suppress("") x: Int) {} +fun test1(@file Suppress("") x: Int) {} -@file @Suppress("") +@file @Suppress("") fun test2() {} class OnType(x: @file Suppress("") Int) diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/repeatable.fir.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/repeatable.fir.kt index 9234dcd817a..2e7a8d1ddd8 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/repeatable.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/repeatable.fir.kt @@ -55,5 +55,5 @@ public class B(@param:fieldOrPro var w: Int @getSetAndParamAnn @get:getSetAndParamAnn get() = 0 // See KT-15470: fake INAPPLICABLE_TARGET_ON_PROPERTY - @getSetAndParamAnn @set:getSetAndParamAnn set(arg) {} + @getSetAndParamAnn @set:getSetAndParamAnn set(arg) {} } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 1ca554dfd0c..19666ef9df3 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -628,6 +628,51 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.INAPPLICABLE_TARGET_ON_PROPERTY) { firDiagnostic -> + InapplicableTargetOnPropertyImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE) { firDiagnostic -> + InapplicableTargetPropertyImmutableImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE) { firDiagnostic -> + InapplicableTargetPropertyHasNoDelegateImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD) { firDiagnostic -> + InapplicableTargetPropertyHasNoBackingFieldImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.INAPPLICABLE_PARAM_TARGET) { firDiagnostic -> + InapplicableParamTargetImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.REDUNDANT_ANNOTATION_TARGET) { firDiagnostic -> + RedundantAnnotationTargetImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.INAPPLICABLE_FILE_TARGET) { firDiagnostic -> + InapplicableFileTargetImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE) { firDiagnostic -> ExposedTypealiasExpandedTypeImpl( firDiagnostic.a, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 496b7df27f5..25a7b5665c7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -449,6 +449,37 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val useSiteTarget: String } + abstract class InapplicableTargetOnProperty : KtFirDiagnostic() { + override val diagnosticClass get() = InapplicableTargetOnProperty::class + abstract val useSiteDescription: String + } + + abstract class InapplicableTargetPropertyImmutable : KtFirDiagnostic() { + override val diagnosticClass get() = InapplicableTargetPropertyImmutable::class + abstract val useSiteDescription: String + } + + abstract class InapplicableTargetPropertyHasNoDelegate : KtFirDiagnostic() { + override val diagnosticClass get() = InapplicableTargetPropertyHasNoDelegate::class + } + + abstract class InapplicableTargetPropertyHasNoBackingField : KtFirDiagnostic() { + override val diagnosticClass get() = InapplicableTargetPropertyHasNoBackingField::class + } + + abstract class InapplicableParamTarget : KtFirDiagnostic() { + override val diagnosticClass get() = InapplicableParamTarget::class + } + + abstract class RedundantAnnotationTarget : KtFirDiagnostic() { + override val diagnosticClass get() = RedundantAnnotationTarget::class + abstract val useSiteDescription: String + } + + abstract class InapplicableFileTarget : KtFirDiagnostic() { + override val diagnosticClass get() = InapplicableFileTarget::class + } + abstract class ExposedTypealiasExpandedType : KtFirDiagnostic() { override val diagnosticClass get() = ExposedTypealiasExpandedType::class abstract val elementVisibility: EffectiveVisibility diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index efeda36cc2e..ce1fd75b4f9 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -729,6 +729,58 @@ internal class WrongAnnotationTargetWithUseSiteTargetImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class InapplicableTargetOnPropertyImpl( + override val useSiteDescription: String, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.InapplicableTargetOnProperty(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class InapplicableTargetPropertyImmutableImpl( + override val useSiteDescription: String, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.InapplicableTargetPropertyImmutable(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class InapplicableTargetPropertyHasNoDelegateImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.InapplicableTargetPropertyHasNoDelegate(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class InapplicableTargetPropertyHasNoBackingFieldImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.InapplicableTargetPropertyHasNoBackingField(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class InapplicableParamTargetImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.InapplicableParamTarget(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class RedundantAnnotationTargetImpl( + override val useSiteDescription: String, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.RedundantAnnotationTarget(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class InapplicableFileTargetImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.InapplicableFileTarget(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class ExposedTypealiasExpandedTypeImpl( override val elementVisibility: EffectiveVisibility, override val restrictingDeclaration: KtSymbol,