[FIR] Implement DATA_CLASS_OVERRIDE_DEFAULT_VALUES diagnostic

#KT-59415 Fixed
This commit is contained in:
Kirill Rakhman
2023-07-24 15:53:15 +02:00
committed by Space Team
parent 53ff4584d4
commit 06d2befb72
12 changed files with 57 additions and 5 deletions
@@ -2463,6 +2463,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.DATA_CLASS_OVERRIDE_DEFAULT_VALUES) { firDiagnostic ->
DataClassOverrideDefaultValuesImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a),
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE) { firDiagnostic ->
CannotWeakenAccessPrivilegeImpl(
firDiagnostic.a,
@@ -1747,6 +1747,12 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
val baseMember: KtCallableSymbol
}
interface DataClassOverrideDefaultValues : KtFirDiagnostic<KtElement> {
override val diagnosticClass get() = DataClassOverrideDefaultValues::class
val overridingMember: KtCallableSymbol
val baseType: KtClassLikeSymbol
}
interface CannotWeakenAccessPrivilege : KtFirDiagnostic<KtModifierListOwner> {
override val diagnosticClass get() = CannotWeakenAccessPrivilege::class
val overridingVisibility: Visibility
@@ -2100,6 +2100,13 @@ internal class DataClassOverrideConflictImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtClassOrObject>(firDiagnostic, token), KtFirDiagnostic.DataClassOverrideConflict
internal class DataClassOverrideDefaultValuesImpl(
override val overridingMember: KtCallableSymbol,
override val baseType: KtClassLikeSymbol,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.DataClassOverrideDefaultValues
internal class CannotWeakenAccessPrivilegeImpl(
override val overridingVisibility: Visibility,
override val overridden: KtCallableSymbol,
@@ -823,6 +823,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirCallableSymbol<*>>("baseMember")
}
val DATA_CLASS_OVERRIDE_DEFAULT_VALUES by error<KtElement>(PositioningStrategy.DATA_MODIFIER) {
parameter<FirCallableSymbol<*>>("overridingMember")
parameter<FirClassSymbol<*>>("baseType")
}
val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<Visibility>("overridingVisibility")
parameter<FirCallableSymbol<*>>("overridden")
@@ -468,6 +468,7 @@ object FirErrors {
val NOTHING_TO_OVERRIDE by error1<KtModifierListOwner, FirCallableSymbol<*>>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val CANNOT_OVERRIDE_INVISIBLE_MEMBER by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val DATA_CLASS_OVERRIDE_CONFLICT by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DATA_MODIFIER)
val DATA_CLASS_OVERRIDE_DEFAULT_VALUES by error2<KtElement, FirCallableSymbol<*>, FirClassSymbol<*>>(SourceElementPositioningStrategies.DATA_MODIFIER)
val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error3<KtModifierListOwner, Visibility, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val CANNOT_CHANGE_ACCESS_PRIVILEGE by error3<KtModifierListOwner, Visibility, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val OVERRIDING_FINAL_MEMBER by error2<KtNamedDeclaration, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtRealSourceElementKind
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseChecker
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseChecker.Experimentality
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.overridesBackwardCompatibilityHelper
@@ -230,6 +232,17 @@ object FirOverrideChecker : FirClassChecker() {
}
}
private fun FirCallableSymbol<*>.checkDataClassCopy(
reporter: DiagnosticReporter,
overriddenMemberSymbols: List<FirCallableSymbol<*>>,
containingClass: FirClass,
context: CheckerContext,
) {
val overridden = overriddenMemberSymbols.firstOrNull() ?: return
val overriddenClass = overridden.getContainingClassSymbol(context.session) as? FirClassSymbol<*> ?: return
reporter.reportOn(containingClass.source, FirErrors.DATA_CLASS_OVERRIDE_DEFAULT_VALUES, this, overriddenClass, context)
}
private fun checkMember(
member: FirCallableSymbol<*>,
containingClass: FirClass,
@@ -259,6 +272,9 @@ object FirOverrideChecker : FirClassChecker() {
context
)
}
if (member.name == StandardNames.DATA_CLASS_COPY) {
member.checkDataClassCopy(reporter, overriddenMemberSymbols, containingClass, context)
}
return
}
@@ -148,6 +148,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_INHERITANC
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DANGEROUS_CHARACTERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_OVERRIDE_CONFLICT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_OVERRIDE_DEFAULT_VALUES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_VARARG_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_WITHOUT_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE
@@ -1521,6 +1522,12 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
FQ_NAMES_IN_TYPES,
FQ_NAMES_IN_TYPES
)
map.put(
DATA_CLASS_OVERRIDE_DEFAULT_VALUES,
"Generated function ''{0}'' of the data class has default values for parameters which conflicts with the overriden member of supertype ''{1}''.",
DECLARATION_NAME,
DECLARATION_NAME
)
map.put(
GENERIC_THROWABLE_SUBCLASS,
@@ -1,4 +1,6 @@
// !LANGUAGE: -ProhibitDataClassesOverridingCopy
// IGNORE_BACKEND_K2: ANY
// FIR status: Disabling ProhibitDataClassesOverridingCopy is not supported
fun box(): String {
val a: A = B(1)
@@ -4,6 +4,6 @@ interface WithCopy<T> {
fun copy(str: T): WithCopy<T>
}
data class Test(val str: String) : WithCopy<String> {
<!DATA_CLASS_OVERRIDE_DEFAULT_VALUES!>data<!> class Test(val str: String) : WithCopy<String> {
override fun copy(str: String) = Test(str)
}
}
@@ -4,6 +4,6 @@ interface WithCopy<T> {
fun copy(str: T): WithCopy<T>
}
data class Test(val str: String) : WithCopy<String> {
<!DATA_CLASS_OVERRIDE_DEFAULT_VALUES!>data<!> class Test(val str: String) : WithCopy<String> {
override fun copy(str: String = <!DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE!>this.str<!>) = Test(str)
}
@@ -4,4 +4,4 @@ interface WithCopy<T> {
fun copy(str: T): WithCopy<T>
}
data class Test(val str: String): WithCopy<String>
<!DATA_CLASS_OVERRIDE_DEFAULT_VALUES!>data<!> class Test(val str: String): WithCopy<String>
@@ -4,4 +4,4 @@ interface WithCopy<T> {
fun copy(str: T): WithCopy<T>
}
data class Test(val str: String): WithCopy<String>
<!DATA_CLASS_OVERRIDE_DEFAULT_VALUES!>data<!> class Test(val str: String): WithCopy<String>