FIR: add getter visibility and setter return type checks
This commit is contained in:
committed by
Mikhail Glukhikh
parent
eedc4d8c3f
commit
1dfc3c0520
Vendored
+1
-1
@@ -75,7 +75,7 @@ open class J {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var buf = 0
|
var buf = 0
|
||||||
private get() = 42
|
<!GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY!>private<!> get() = 42
|
||||||
protected set(value) {
|
protected set(value) {
|
||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -547,6 +547,8 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
|||||||
parameter<ConeKotlinType>("expected")
|
parameter<ConeKotlinType>("expected")
|
||||||
parameter<ConeKotlinType>("actual")
|
parameter<ConeKotlinType>("actual")
|
||||||
}
|
}
|
||||||
|
val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
|
||||||
|
val WRONG_SETTER_RETURN_TYPE by error<KtProperty>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") {
|
val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") {
|
||||||
|
|||||||
@@ -338,6 +338,8 @@ object FirErrors {
|
|||||||
val CONST_VAL_WITH_NON_CONST_INITIALIZER by error0<KtExpression>()
|
val CONST_VAL_WITH_NON_CONST_INITIALIZER by error0<KtExpression>()
|
||||||
val WRONG_SETTER_PARAMETER_TYPE by error2<KtTypeReference, ConeKotlinType, ConeKotlinType>()
|
val WRONG_SETTER_PARAMETER_TYPE by error2<KtTypeReference, ConeKotlinType, ConeKotlinType>()
|
||||||
val INITIALIZER_TYPE_MISMATCH by error2<KtProperty, ConeKotlinType, ConeKotlinType>(SourceElementPositioningStrategies.ASSIGNMENT_VALUE)
|
val INITIALIZER_TYPE_MISMATCH by error2<KtProperty, ConeKotlinType, ConeKotlinType>(SourceElementPositioningStrategies.ASSIGNMENT_VALUE)
|
||||||
|
val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||||
|
val WRONG_SETTER_RETURN_TYPE by error0<KtProperty>()
|
||||||
|
|
||||||
// Multi-platform projects
|
// Multi-platform projects
|
||||||
val EXPECTED_DECLARATION_WITH_BODY by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
val EXPECTED_DECLARATION_WITH_BODY by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
|
|||||||
+21
@@ -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.reportOn
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
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.ConeClassErrorType
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.fir.types.isUnit
|
||||||
|
|
||||||
object FirPropertyAccessorChecker : FirPropertyChecker() {
|
object FirPropertyAccessorChecker : FirPropertyChecker() {
|
||||||
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
checkGetter(declaration, context, reporter)
|
||||||
checkSetter(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) {
|
private fun checkSetter(property: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val setter = property.setter ?: return
|
val setter = property.setter ?: return
|
||||||
|
|
||||||
@@ -43,6 +55,15 @@ object FirPropertyAccessorChecker : FirPropertyChecker() {
|
|||||||
reporter.reportOn(valueSetterTypeSource, FirErrors.WRONG_SETTER_PARAMETER_TYPE, propertyType, valueSetterType, context)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -28,8 +28,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
FirExposedVisibilityDeclarationChecker,
|
FirExposedVisibilityDeclarationChecker,
|
||||||
FirSealedSupertypeChecker,
|
FirSealedSupertypeChecker,
|
||||||
FirTypeAliasChecker,
|
FirTypeAliasChecker,
|
||||||
FirCyclicTypeBoundsChecker,
|
FirCyclicTypeBoundsChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val functionCheckers: Set<FirFunctionChecker>
|
override val functionCheckers: Set<FirFunctionChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
@@ -40,8 +40,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
override val simpleFunctionCheckers: Set<FirSimpleFunctionChecker>
|
override val simpleFunctionCheckers: Set<FirSimpleFunctionChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirFunctionNameChecker,
|
FirFunctionNameChecker,
|
||||||
FirFunctionTypeParametersChecker,
|
FirFunctionTypeParametersChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val propertyCheckers: Set<FirPropertyChecker>
|
override val propertyCheckers: Set<FirPropertyChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
@@ -110,7 +110,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
override val typeParameterCheckers: Set<FirTypeParameterChecker>
|
override val typeParameterCheckers: Set<FirTypeParameterChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirTypeParameterBoundsChecker,
|
FirTypeParameterBoundsChecker,
|
||||||
FirTypeParameterVarianceChecker,
|
FirTypeParameterVarianceChecker,
|
||||||
FirReifiedTypeParameterChecker,
|
FirReifiedTypeParameterChecker,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ abstract class My {
|
|||||||
<!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
|
<!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
|
||||||
|
|
||||||
abstract val y: Int
|
abstract val y: Int
|
||||||
protected get
|
<!GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY!>protected<!> get
|
||||||
|
|
||||||
abstract protected var z: Int
|
abstract protected var z: Int
|
||||||
internal get
|
<!GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY!>internal<!> get
|
||||||
<!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
|
<!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
|
||||||
|
|
||||||
abstract internal val w: Int
|
abstract internal val w: Int
|
||||||
protected get
|
<!GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY!>protected<!> get
|
||||||
|
|
||||||
abstract var u: Int
|
abstract var u: Int
|
||||||
protected set
|
protected set
|
||||||
|
|||||||
-26
@@ -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
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// KT-7042 Providing return type for property setter is not reported as error
|
// KT-7042 Providing return type for property setter is not reported as error
|
||||||
|
|
||||||
var x: Int = 1
|
var x: Int = 1
|
||||||
|
|||||||
+12
@@ -1581,6 +1581,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
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 ->
|
add(FirErrors.EXPECTED_DECLARATION_WITH_BODY) { firDiagnostic ->
|
||||||
ExpectedDeclarationWithBodyImpl(
|
ExpectedDeclarationWithBodyImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic<*>,
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
|||||||
+8
@@ -1112,6 +1112,14 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val actual: KtType
|
abstract val actual: KtType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class GetterVisibilityDiffersFromPropertyVisibility : KtFirDiagnostic<KtModifierListOwner>() {
|
||||||
|
override val diagnosticClass get() = GetterVisibilityDiffersFromPropertyVisibility::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class WrongSetterReturnType : KtFirDiagnostic<KtProperty>() {
|
||||||
|
override val diagnosticClass get() = WrongSetterReturnType::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ExpectedDeclarationWithBody : KtFirDiagnostic<KtDeclaration>() {
|
abstract class ExpectedDeclarationWithBody : KtFirDiagnostic<KtDeclaration>() {
|
||||||
override val diagnosticClass get() = ExpectedDeclarationWithBody::class
|
override val diagnosticClass get() = ExpectedDeclarationWithBody::class
|
||||||
}
|
}
|
||||||
|
|||||||
+14
@@ -1803,6 +1803,20 @@ internal class InitializerTypeMismatchImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class GetterVisibilityDiffersFromPropertyVisibilityImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.GetterVisibilityDiffersFromPropertyVisibility(), KtAbstractFirDiagnostic<KtModifierListOwner> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class WrongSetterReturnTypeImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.WrongSetterReturnType(), KtAbstractFirDiagnostic<KtProperty> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class ExpectedDeclarationWithBodyImpl(
|
internal class ExpectedDeclarationWithBodyImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user