diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.kt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.kt index a15f0c1c62a..f1105e45754 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.kt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.kt @@ -75,7 +75,7 @@ open class J { } var buf = 0 - private get() = 42 + private get() = 42 protected set(value) { field = value } 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 325cd045bcc..55e595f7bdd 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 @@ -547,6 +547,8 @@ object DIAGNOSTICS_LIST : DiagnosticList() { parameter("expected") parameter("actual") } + val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error(PositioningStrategy.VISIBILITY_MODIFIER) + val WRONG_SETTER_RETURN_TYPE by error() } val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") { 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 7d4edacdf37..377452bb95a 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 @@ -338,6 +338,8 @@ object FirErrors { val CONST_VAL_WITH_NON_CONST_INITIALIZER by error0() val WRONG_SETTER_PARAMETER_TYPE by error2() val INITIALIZER_TYPE_MISMATCH by error2(SourceElementPositioningStrategies.ASSIGNMENT_VALUE) + val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) + val WRONG_SETTER_RETURN_TYPE by error0() // Multi-platform projects val EXPECTED_DECLARATION_WITH_BODY by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPropertyAccessorChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPropertyAccessorChecker.kt index 8393732ca1c..27866e5982f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPropertyAccessorChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPropertyAccessorChecker.kt @@ -11,14 +11,26 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.visibility import org.jetbrains.kotlin.fir.types.ConeClassErrorType import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.isUnit object FirPropertyAccessorChecker : FirPropertyChecker() { override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { + checkGetter(declaration, context, reporter) checkSetter(declaration, context, reporter) } + private fun checkGetter(property: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { + val getter = property.getter ?: return + withSuppressedDiagnostics(getter, context) { + if (getter.visibility != property.visibility) { + reporter.reportOn(getter.source, FirErrors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, context) + } + } + } + private fun checkSetter(property: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { val setter = property.setter ?: return @@ -43,6 +55,15 @@ object FirPropertyAccessorChecker : FirPropertyChecker() { reporter.reportOn(valueSetterTypeSource, FirErrors.WRONG_SETTER_PARAMETER_TYPE, propertyType, valueSetterType, context) } } + + val setterReturnType = setter.returnTypeRef.coneType + if (propertyType is ConeClassErrorType || valueSetterType is ConeClassErrorType) { + return + } + + if (!setterReturnType.isUnit) { + reporter.reportOn(setter.returnTypeRef.source, FirErrors.WRONG_SETTER_RETURN_TYPE, context) + } } } } diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt index 80a77b4bd8d..a4d6af67955 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt @@ -28,8 +28,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirExposedVisibilityDeclarationChecker, FirSealedSupertypeChecker, FirTypeAliasChecker, - FirCyclicTypeBoundsChecker, - ) + FirCyclicTypeBoundsChecker, + ) override val functionCheckers: Set get() = setOf( @@ -40,8 +40,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() { override val simpleFunctionCheckers: Set get() = setOf( FirFunctionNameChecker, - FirFunctionTypeParametersChecker, - ) + FirFunctionTypeParametersChecker, + ) override val propertyCheckers: Set get() = setOf( @@ -110,7 +110,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { override val typeParameterCheckers: Set get() = setOf( FirTypeParameterBoundsChecker, - FirTypeParameterVarianceChecker, - FirReifiedTypeParameterChecker, - ) + FirTypeParameterVarianceChecker, + FirReifiedTypeParameterChecker, + ) } diff --git a/compiler/testData/diagnostics/tests/AbstractAccessor.fir.kt b/compiler/testData/diagnostics/tests/AbstractAccessor.fir.kt index 697c2c842c4..ff8116a5e8a 100644 --- a/compiler/testData/diagnostics/tests/AbstractAccessor.fir.kt +++ b/compiler/testData/diagnostics/tests/AbstractAccessor.fir.kt @@ -4,14 +4,14 @@ abstract class My { private set abstract val y: Int - protected get + protected get abstract protected var z: Int - internal get + internal get private set abstract internal val w: Int - protected get + protected get abstract var u: Int protected set diff --git a/compiler/testData/diagnostics/tests/backingField/SetterWithExplicitType.fir.kt b/compiler/testData/diagnostics/tests/backingField/SetterWithExplicitType.fir.kt deleted file mode 100644 index 2a343535976..00000000000 --- a/compiler/testData/diagnostics/tests/backingField/SetterWithExplicitType.fir.kt +++ /dev/null @@ -1,26 +0,0 @@ -// KT-7042 Providing return type for property setter is not reported as error - -var x: Int = 1 - -// No backing field! -var y: Int - get() = x - set(value): Any { - x = value - } - -var z: Int - get() = x - set(value): Unit { - x = value - } - -var u: String = "" - set(value): Unit { - field = value - } - -var v: String = "" - set(value): String { - field = value - } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/backingField/SetterWithExplicitType.kt b/compiler/testData/diagnostics/tests/backingField/SetterWithExplicitType.kt index 0502a9bf943..62b5d45e2a1 100644 --- a/compiler/testData/diagnostics/tests/backingField/SetterWithExplicitType.kt +++ b/compiler/testData/diagnostics/tests/backingField/SetterWithExplicitType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // KT-7042 Providing return type for property setter is not reported as error var x: Int = 1 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 8a4a6d52f7f..4c7d7ea5a27 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 @@ -1581,6 +1581,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY) { firDiagnostic -> + GetterVisibilityDiffersFromPropertyVisibilityImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.WRONG_SETTER_RETURN_TYPE) { firDiagnostic -> + WrongSetterReturnTypeImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.EXPECTED_DECLARATION_WITH_BODY) { firDiagnostic -> ExpectedDeclarationWithBodyImpl( firDiagnostic as FirPsiDiagnostic<*>, 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 745ac1a0942..887ddfc7ec5 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 @@ -1112,6 +1112,14 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val actual: KtType } + abstract class GetterVisibilityDiffersFromPropertyVisibility : KtFirDiagnostic() { + override val diagnosticClass get() = GetterVisibilityDiffersFromPropertyVisibility::class + } + + abstract class WrongSetterReturnType : KtFirDiagnostic() { + override val diagnosticClass get() = WrongSetterReturnType::class + } + abstract class ExpectedDeclarationWithBody : KtFirDiagnostic() { override val diagnosticClass get() = ExpectedDeclarationWithBody::class } 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 e1b39e34084..bb56475e023 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 @@ -1803,6 +1803,20 @@ internal class InitializerTypeMismatchImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class GetterVisibilityDiffersFromPropertyVisibilityImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.GetterVisibilityDiffersFromPropertyVisibility(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class WrongSetterReturnTypeImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.WrongSetterReturnType(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class ExpectedDeclarationWithBodyImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken,