[FIR] Support MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES

^KT-59408 Fixed
This commit is contained in:
Nikolay Lunyak
2023-07-17 14:50:12 +03:00
committed by Space Team
parent 9850987415
commit 61448531cb
21 changed files with 146 additions and 31 deletions
@@ -2502,6 +2502,20 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES) { firDiagnostic ->
MultipleDefaultsInheritedFromSupertypesImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE) { firDiagnostic ->
MultipleDefaultsInheritedFromSupertypesWhenNoExplicitOverrideImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.OVERRIDING_FINAL_MEMBER) { firDiagnostic ->
OverridingFinalMemberImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a),
@@ -1778,6 +1778,16 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
val containingClassName: Name
}
interface MultipleDefaultsInheritedFromSupertypes : KtFirDiagnostic<KtElement> {
override val diagnosticClass get() = MultipleDefaultsInheritedFromSupertypes::class
val valueParameter: KtSymbol
}
interface MultipleDefaultsInheritedFromSupertypesWhenNoExplicitOverride : KtFirDiagnostic<KtElement> {
override val diagnosticClass get() = MultipleDefaultsInheritedFromSupertypesWhenNoExplicitOverride::class
val valueParameter: KtSymbol
}
interface OverridingFinalMember : KtFirDiagnostic<KtNamedDeclaration> {
override val diagnosticClass get() = OverridingFinalMember::class
val overriddenDeclaration: KtCallableSymbol
@@ -2136,6 +2136,18 @@ internal class CannotChangeAccessPrivilegeImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtModifierListOwner>(firDiagnostic, token), KtFirDiagnostic.CannotChangeAccessPrivilege
internal class MultipleDefaultsInheritedFromSupertypesImpl(
override val valueParameter: KtSymbol,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.MultipleDefaultsInheritedFromSupertypes
internal class MultipleDefaultsInheritedFromSupertypesWhenNoExplicitOverrideImpl(
override val valueParameter: KtSymbol,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.MultipleDefaultsInheritedFromSupertypesWhenNoExplicitOverride
internal class OverridingFinalMemberImpl(
override val overriddenDeclaration: KtCallableSymbol,
override val containingClassName: Name,
@@ -846,6 +846,13 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<Name>("containingClassName")
}
val MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<FirValueParameterSymbol>("valueParameter")
}
val MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE by error<KtElement>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirValueParameterSymbol>("valueParameter")
}
val OVERRIDING_FINAL_MEMBER by error<KtNamedDeclaration>(PositioningStrategy.OVERRIDE_MODIFIER) {
parameter<FirCallableSymbol<*>>("overriddenDeclaration")
parameter<Name>("containingClassName")
@@ -475,6 +475,8 @@ object FirErrors {
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 MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES by error1<KtElement, FirValueParameterSymbol>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE by error1<KtElement, FirValueParameterSymbol>(SourceElementPositioningStrategies.DECLARATION_NAME)
val OVERRIDING_FINAL_MEMBER by error2<KtNamedDeclaration, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
@@ -124,6 +124,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirOuterClassArgumentsRequiredChecker,
FirPropertyInitializationChecker,
FirDelegateFieldTypeMismatchChecker,
FirMultipleDefaultsInheritedFromSupertypesChecker,
)
override val constructorCheckers: Set<FirConstructorChecker>
@@ -0,0 +1,60 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.directOverriddenFunctions
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
import org.jetbrains.kotlin.fir.scopes.processAllFunctions
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverrideFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction
import org.jetbrains.kotlin.utils.addToStdlib.castAll
object FirMultipleDefaultsInheritedFromSupertypesChecker : FirRegularClassChecker() {
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
declaration.unsubstitutedScope(context).processAllFunctions {
checkFunction(declaration, it, context, reporter)
}
}
private fun checkFunction(
declaration: FirRegularClass,
function: FirNamedFunctionSymbol,
context: CheckerContext,
reporter: DiagnosticReporter,
) {
@OptIn(UnsafeCastFunction::class)
val overriddenFunctions = when (function) {
is FirIntersectionOverrideFunctionSymbol -> function.intersections.castAll<FirFunctionSymbol<*>>()
else -> function.directOverriddenFunctions(context)
}
for ((index, parameter) in function.valueParameterSymbols.withIndex()) {
val basesWithDefaultValues = overriddenFunctions.count { it.valueParameterSymbols[index].hasDefaultValue }
when {
basesWithDefaultValues <= 1 -> {
continue
}
function.isSubstitutionOrIntersectionOverride -> reporter.reportOn(
declaration.source, FirErrors.MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE,
parameter, context,
)
else -> reporter.reportOn(
parameter.source, FirErrors.MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES,
parameter, context,
)
}
}
}
}
@@ -351,6 +351,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_AN
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND_FUN
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_ARGUMENTS_APPLICABLE_FOR_CONTEXT_RECEIVER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTI_FIELD_VALUE_CLASS_PRIMARY_CONSTRUCTOR_DEFAULT_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
@@ -1429,6 +1431,10 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
FQ_NAMES_IN_TYPES
)
val multipleDefaultsMessage = "More than one overridden descriptor declares a default value for ''{0}''. As the compiler can not make sure these values agree, this is not allowed."
map.put(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES, multipleDefaultsMessage, SYMBOL)
map.put(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE, multipleDefaultsMessage, SYMBOL)
map.put(OVERRIDING_FINAL_MEMBER, "''{0}'' in ''{1}'' is final and cannot be overridden", DECLARATION_NAME, TO_STRING)
map.put(
+2 -1
View File
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6
// IGNORE_BACKEND_K1: JS, JS_IR, JS_IR_ES6
// IGNORE_BACKEND_K2: ANY
// The code in this test should be prohibited in the frontend, see KT-36188.
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6
// IGNORE_BACKEND_K1: JS, JS_IR, JS_IR_ES6
// IGNORE_BACKEND_K2: ANY
// !JVM_DEFAULT_MODE: all
// JVM_TARGET: 1.8
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS
// IGNORE_BACKEND_K2: ANY
// Test for KT-36188 bug compatibility between non-IR and IR backends
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS
// IGNORE_BACKEND_K2: ANY
// Test for KT-36188 bug compatibility between non-IR and IR backends
@@ -17,10 +17,10 @@ interface B {
fun foo(@An a: @An Int = @An 2)
}
class AB1 : A, B
<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE("@An() a: @R|An|() Int = ...")!>class AB1<!> : A, B
@An
class AB2 : A, B {
@An
override fun foo(@An a: @An Int) {}
override fun foo(<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES("@An() a: @R|An|() Int")!>@An a: @An Int<!>) {}
}
@@ -1,15 +0,0 @@
interface X {
fun foo(a : Int = 1)
}
interface Y {
fun foo(a : Int = 1)
}
class Z : X, Y {
override fun foo(a : Int) {}
}
object ZO : X, Y {
override fun foo(a : Int) {}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface X {
fun foo(a : Int = 1)
}
@@ -0,0 +1,15 @@
interface X {
fun foo(a : Int = 1)
}
interface Y {
fun foo(a : Int = 1)
}
class Z : X, Y {
fun <!VIRTUAL_MEMBER_HIDDEN!>foo<!>(<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES!>a : Int<!>) {}
}
object ZO : X, Y {
fun <!VIRTUAL_MEMBER_HIDDEN!>foo<!>(<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES!>a : Int<!>) {}
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
interface X {
fun foo(a : Int = 1)
}
@@ -11,4 +11,4 @@ interface C {
}
// TODO DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES reported twice
class Z : A, B(), C
<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE!>class Z<!> : A, B(), C
@@ -1,10 +0,0 @@
interface X {
fun foo(a : Int = 1)
}
interface Y {
fun foo(a : Int = 1)
}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Z1<!> : X, Y {} // BUG
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>object Z1O<!> : X, Y {} // BUG
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface X {
fun foo(a : Int = 1)
}
@@ -89,6 +89,14 @@ inline fun <reified T> List<*>.castAll(): List<@kotlin.internal.NoInfer T> {
return this as List<T>
}
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@UnsafeCastFunction
inline fun <reified T> Collection<*>.castAll(): Collection<@kotlin.internal.NoInfer T> {
for (element in this) element as T
@Suppress("UNCHECKED_CAST")
return this as Collection<T>
}
fun <T> sequenceOfLazyValues(vararg elements: () -> T): Sequence<T> = elements.asSequence().map { it() }
fun <T1, T2> Pair<T1, T2>.swap(): Pair<T2, T1> = Pair(second, first)