[FIR] Implement DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE diagnostic
#KT-59409 Fixed
This commit is contained in:
committed by
Space Team
parent
d93ffe0aec
commit
53ff4584d4
+6
@@ -2868,6 +2868,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE) { firDiagnostic ->
|
||||||
|
DefaultValueNotAllowedInOverrideImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE) { firDiagnostic ->
|
add(FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE) { firDiagnostic ->
|
||||||
FunInterfaceConstructorReferenceImpl(
|
FunInterfaceConstructorReferenceImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+4
@@ -2032,6 +2032,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = DataObjectCustomEqualsOrHashCode::class
|
override val diagnosticClass get() = DataObjectCustomEqualsOrHashCode::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DefaultValueNotAllowedInOverride : KtFirDiagnostic<KtElement> {
|
||||||
|
override val diagnosticClass get() = DefaultValueNotAllowedInOverride::class
|
||||||
|
}
|
||||||
|
|
||||||
interface FunInterfaceConstructorReference : KtFirDiagnostic<KtExpression> {
|
interface FunInterfaceConstructorReference : KtFirDiagnostic<KtExpression> {
|
||||||
override val diagnosticClass get() = FunInterfaceConstructorReference::class
|
override val diagnosticClass get() = FunInterfaceConstructorReference::class
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -2439,6 +2439,11 @@ internal class DataObjectCustomEqualsOrHashCodeImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<KtNamedFunction>(firDiagnostic, token), KtFirDiagnostic.DataObjectCustomEqualsOrHashCode
|
) : KtAbstractFirDiagnostic<KtNamedFunction>(firDiagnostic, token), KtFirDiagnostic.DataObjectCustomEqualsOrHashCode
|
||||||
|
|
||||||
|
internal class DefaultValueNotAllowedInOverrideImpl(
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.DefaultValueNotAllowedInOverride
|
||||||
|
|
||||||
internal class FunInterfaceConstructorReferenceImpl(
|
internal class FunInterfaceConstructorReferenceImpl(
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
|
|||||||
+4
@@ -1009,6 +1009,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE by error<KtNamedFunction>(PositioningStrategy.OVERRIDE_MODIFIER)
|
val DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE by error<KtNamedFunction>(PositioningStrategy.OVERRIDE_MODIFIER)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val PARAMETER_DEFAULT_VALUES by object : DiagnosticGroup("Parameter default values") {
|
||||||
|
val DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE by error<KtElement>()
|
||||||
|
}
|
||||||
|
|
||||||
val FUN_INTERFACES by object : DiagnosticGroup("Fun interfaces") {
|
val FUN_INTERFACES by object : DiagnosticGroup("Fun interfaces") {
|
||||||
val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
|
val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
|
||||||
val FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS by error<KtClass>(PositioningStrategy.FUN_MODIFIER)
|
val FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS by error<KtClass>(PositioningStrategy.FUN_MODIFIER)
|
||||||
|
|||||||
@@ -527,6 +527,9 @@ object FirErrors {
|
|||||||
val TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED by warning0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED by warning0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE by error0<KtNamedFunction>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
|
val DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE by error0<KtNamedFunction>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
|
||||||
|
|
||||||
|
// Parameter default values
|
||||||
|
val DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE by error0<KtElement>()
|
||||||
|
|
||||||
// Fun interfaces
|
// Fun interfaces
|
||||||
val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error0<KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val FUN_INTERFACE_CONSTRUCTOR_REFERENCE by error0<KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
val FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS by error0<KtClass>(SourceElementPositioningStrategies.FUN_MODIFIER)
|
val FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS by error0<KtClass>(SourceElementPositioningStrategies.FUN_MODIFIER)
|
||||||
|
|||||||
+17
@@ -217,6 +217,19 @@ object FirOverrideChecker : FirClassChecker() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(SymbolInternals::class)
|
||||||
|
private fun FirFunctionSymbol<*>.checkDefaultValues(
|
||||||
|
reporter: DiagnosticReporter,
|
||||||
|
context: CheckerContext,
|
||||||
|
) {
|
||||||
|
for (valueParameterSymbol in valueParameterSymbols) {
|
||||||
|
val defaultValue = valueParameterSymbol.fir.defaultValue
|
||||||
|
if (defaultValue != null) {
|
||||||
|
reporter.reportOn(defaultValue.source, FirErrors.DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkMember(
|
private fun checkMember(
|
||||||
member: FirCallableSymbol<*>,
|
member: FirCallableSymbol<*>,
|
||||||
containingClass: FirClass,
|
containingClass: FirClass,
|
||||||
@@ -299,6 +312,10 @@ object FirOverrideChecker : FirClassChecker() {
|
|||||||
|
|
||||||
member.checkDeprecation(reporter, overriddenMemberSymbols, context)
|
member.checkDeprecation(reporter, overriddenMemberSymbols, context)
|
||||||
|
|
||||||
|
if (member is FirFunctionSymbol) {
|
||||||
|
member.checkDefaultValues(reporter, context)
|
||||||
|
}
|
||||||
|
|
||||||
val restriction = member.checkReturnType(
|
val restriction = member.checkReturnType(
|
||||||
overriddenSymbols = overriddenMemberSymbols,
|
overriddenSymbols = overriddenMemberSymbols,
|
||||||
typeCheckerState = typeCheckerState,
|
typeCheckerState = typeCheckerState,
|
||||||
|
|||||||
+4
@@ -153,6 +153,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_WITHOU
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DECLARATION_CANT_BE_INLINED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DECLARATION_CANT_BE_INLINED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEFAULT_ARGUMENTS_IN_EXPECT_WITH_ACTUAL_TYPEALIAS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEFAULT_ARGUMENTS_IN_EXPECT_WITH_ACTUAL_TYPEALIAS
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEFINITELY_NON_NULLABLE_AS_REIFIED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEFINITELY_NON_NULLABLE_AS_REIFIED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_VALUE_CLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_VALUE_CLASS
|
||||||
@@ -1643,6 +1644,9 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
map.put(TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED, "Tail recursion optimization inside try/catch/finally is not supported")
|
map.put(TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED, "Tail recursion optimization inside try/catch/finally is not supported")
|
||||||
map.put(DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE, "Data object cannot have a custom implementation of 'equals' or 'hashCode'")
|
map.put(DATA_OBJECT_CUSTOM_EQUALS_OR_HASH_CODE, "Data object cannot have a custom implementation of 'equals' or 'hashCode'")
|
||||||
|
|
||||||
|
// Parameter default values
|
||||||
|
map.put(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE, "An overriding function is not allowed to specify default values for its parameters.")
|
||||||
|
|
||||||
// Fun interfaces
|
// Fun interfaces
|
||||||
map.put(FUN_INTERFACE_CONSTRUCTOR_REFERENCE, "Functional/SAM interface constructor references are prohibited")
|
map.put(FUN_INTERFACE_CONSTRUCTOR_REFERENCE, "Functional/SAM interface constructor references are prohibited")
|
||||||
|
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/dataClasses/dataClassExplicitlyOverridingCopyWithDefaults.fir.kt
Vendored
+2
-2
@@ -5,5 +5,5 @@ interface WithCopy<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class Test(val str: String) : WithCopy<String> {
|
data class Test(val str: String) : WithCopy<String> {
|
||||||
override fun copy(str: String = this.str) = Test(str)
|
override fun copy(str: String = <!DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE!>this.str<!>) = Test(str)
|
||||||
}
|
}
|
||||||
|
|||||||
-36
@@ -1,36 +0,0 @@
|
|||||||
// MODULE: m1-common
|
|
||||||
// FILE: common.kt
|
|
||||||
|
|
||||||
interface Foo {
|
|
||||||
fun ok(x: Int, y: String = "")
|
|
||||||
|
|
||||||
fun failX(x: Int, y: String = "")
|
|
||||||
|
|
||||||
fun failY(x: Int, y: String = "")
|
|
||||||
}
|
|
||||||
|
|
||||||
expect class Bar : Foo {
|
|
||||||
override fun ok(x: Int, y: String)
|
|
||||||
|
|
||||||
override fun failX(x: Int, y: String)
|
|
||||||
|
|
||||||
override fun failY(x: Int, y: String)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun test(foo: Foo, bar: Bar) {
|
|
||||||
foo.ok(42)
|
|
||||||
foo.ok(42, "OK")
|
|
||||||
bar.ok(42)
|
|
||||||
bar.ok(42, "OK")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MODULE: m2-jvm()()(m1-common)
|
|
||||||
// FILE: jvm.kt
|
|
||||||
|
|
||||||
actual class Bar : Foo {
|
|
||||||
actual override fun ok(x: Int, y: String) {}
|
|
||||||
|
|
||||||
actual override fun failX(<!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>x: Int = 0<!>, y: String) {}
|
|
||||||
|
|
||||||
actual override fun failY(x: Int, <!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>y: String = ""<!>) {}
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
|
|
||||||
|
|||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
open class A {
|
|
||||||
open fun foo(a : Int) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class C : A() {
|
|
||||||
override fun foo(a : Int = 1) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class D : A() {
|
|
||||||
override fun foo(a : Int = 1) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
open class A {
|
open class A {
|
||||||
open fun foo(a : Int) {}
|
open fun foo(a : Int) {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user