[FIR] Report warnings for inconsistent visibilities of accessors

K1 didn't report diagnostics for accessors
of intersection overrides, so this change
prevents a BC.

^KT-66046 Fixed
This commit is contained in:
Nikolay Lunyak
2024-03-06 16:08:29 +02:00
committed by Space Team
parent 7ecbaf7d1e
commit d3dfbec01a
15 changed files with 233 additions and 5 deletions
@@ -2718,6 +2718,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE_WARNING) { firDiagnostic ->
CannotWeakenAccessPrivilegeWarningImpl(
firDiagnostic.a,
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b),
firDiagnostic.c,
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE) { firDiagnostic ->
CannotChangeAccessPrivilegeImpl(
firDiagnostic.a,
@@ -2727,6 +2736,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE_WARNING) { firDiagnostic ->
CannotChangeAccessPrivilegeWarningImpl(
firDiagnostic.a,
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b),
firDiagnostic.c,
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.CANNOT_INFER_VISIBILITY) { firDiagnostic ->
CannotInferVisibilityImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a),
@@ -2734,6 +2752,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.CANNOT_INFER_VISIBILITY_WARNING) { firDiagnostic ->
CannotInferVisibilityWarningImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES) { firDiagnostic ->
MultipleDefaultsInheritedFromSupertypesImpl(
firDiagnostic.a,
@@ -1925,6 +1925,13 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
val containingClassName: Name
}
interface CannotWeakenAccessPrivilegeWarning : KtFirDiagnostic<KtModifierListOwner> {
override val diagnosticClass get() = CannotWeakenAccessPrivilegeWarning::class
val overridingVisibility: Visibility
val overridden: KtCallableSymbol
val containingClassName: Name
}
interface CannotChangeAccessPrivilege : KtFirDiagnostic<KtModifierListOwner> {
override val diagnosticClass get() = CannotChangeAccessPrivilege::class
val overridingVisibility: Visibility
@@ -1932,11 +1939,23 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
val containingClassName: Name
}
interface CannotChangeAccessPrivilegeWarning : KtFirDiagnostic<KtModifierListOwner> {
override val diagnosticClass get() = CannotChangeAccessPrivilegeWarning::class
val overridingVisibility: Visibility
val overridden: KtCallableSymbol
val containingClassName: Name
}
interface CannotInferVisibility : KtFirDiagnostic<KtDeclaration> {
override val diagnosticClass get() = CannotInferVisibility::class
val callable: KtCallableSymbol
}
interface CannotInferVisibilityWarning : KtFirDiagnostic<KtDeclaration> {
override val diagnosticClass get() = CannotInferVisibilityWarning::class
val callable: KtCallableSymbol
}
interface MultipleDefaultsInheritedFromSupertypes : KtFirDiagnostic<KtElement> {
override val diagnosticClass get() = MultipleDefaultsInheritedFromSupertypes::class
val name: Name
@@ -2313,6 +2313,14 @@ internal class CannotWeakenAccessPrivilegeImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtModifierListOwner>(firDiagnostic, token), KtFirDiagnostic.CannotWeakenAccessPrivilege
internal class CannotWeakenAccessPrivilegeWarningImpl(
override val overridingVisibility: Visibility,
override val overridden: KtCallableSymbol,
override val containingClassName: Name,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtModifierListOwner>(firDiagnostic, token), KtFirDiagnostic.CannotWeakenAccessPrivilegeWarning
internal class CannotChangeAccessPrivilegeImpl(
override val overridingVisibility: Visibility,
override val overridden: KtCallableSymbol,
@@ -2321,12 +2329,26 @@ internal class CannotChangeAccessPrivilegeImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtModifierListOwner>(firDiagnostic, token), KtFirDiagnostic.CannotChangeAccessPrivilege
internal class CannotChangeAccessPrivilegeWarningImpl(
override val overridingVisibility: Visibility,
override val overridden: KtCallableSymbol,
override val containingClassName: Name,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtModifierListOwner>(firDiagnostic, token), KtFirDiagnostic.CannotChangeAccessPrivilegeWarning
internal class CannotInferVisibilityImpl(
override val callable: KtCallableSymbol,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtDeclaration>(firDiagnostic, token), KtFirDiagnostic.CannotInferVisibility
internal class CannotInferVisibilityWarningImpl(
override val callable: KtCallableSymbol,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtDeclaration>(firDiagnostic, token), KtFirDiagnostic.CannotInferVisibilityWarning
internal class MultipleDefaultsInheritedFromSupertypesImpl(
override val name: Name,
override val valueParameter: KtSymbol,
@@ -657,6 +657,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesForNonAbstractPropertyAccessors.kt");
}
@Test
@TestMetadata("intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt")
public void testIntersectedVisibilitiesPropertyAccessorsAdditionalWarnigns() {
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt");
}
@Test
@TestMetadata("intersectionWithMultipleDefaultsInJava.kt")
public void testIntersectionWithMultipleDefaultsInJava() {
@@ -657,6 +657,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesForNonAbstractPropertyAccessors.kt");
}
@Test
@TestMetadata("intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt")
public void testIntersectedVisibilitiesPropertyAccessorsAdditionalWarnigns() {
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt");
}
@Test
@TestMetadata("intersectionWithMultipleDefaultsInJava.kt")
public void testIntersectionWithMultipleDefaultsInJava() {
@@ -657,6 +657,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesForNonAbstractPropertyAccessors.kt");
}
@Test
@TestMetadata("intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt")
public void testIntersectedVisibilitiesPropertyAccessorsAdditionalWarnigns() {
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt");
}
@Test
@TestMetadata("intersectionWithMultipleDefaultsInJava.kt")
public void testIntersectionWithMultipleDefaultsInJava() {
@@ -657,6 +657,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesForNonAbstractPropertyAccessors.kt");
}
@Test
@TestMetadata("intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt")
public void testIntersectedVisibilitiesPropertyAccessorsAdditionalWarnigns() {
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt");
}
@Test
@TestMetadata("intersectionWithMultipleDefaultsInJava.kt")
public void testIntersectionWithMultipleDefaultsInJava() {
@@ -924,14 +924,27 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirCallableSymbol<*>>("overridden")
parameter<Name>("containingClassName")
}
val CANNOT_WEAKEN_ACCESS_PRIVILEGE_WARNING by warning<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<Visibility>("overridingVisibility")
parameter<FirCallableSymbol<*>>("overridden")
parameter<Name>("containingClassName")
}
val CANNOT_CHANGE_ACCESS_PRIVILEGE by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<Visibility>("overridingVisibility")
parameter<FirCallableSymbol<*>>("overridden")
parameter<Name>("containingClassName")
}
val CANNOT_CHANGE_ACCESS_PRIVILEGE_WARNING by warning<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<Visibility>("overridingVisibility")
parameter<FirCallableSymbol<*>>("overridden")
parameter<Name>("containingClassName")
}
val CANNOT_INFER_VISIBILITY by error<KtDeclaration>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableSymbol<*>>("callable")
}
val CANNOT_INFER_VISIBILITY_WARNING by warning<KtDeclaration>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableSymbol<*>>("callable")
}
val MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<Name>("name")
@@ -518,8 +518,11 @@ object FirErrors {
val DATA_CLASS_OVERRIDE_CONFLICT: KtDiagnosticFactory2<FirCallableSymbol<*>, FirCallableSymbol<*>> by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DATA_MODIFIER)
val DATA_CLASS_OVERRIDE_DEFAULT_VALUES: KtDiagnosticFactory2<FirCallableSymbol<*>, FirClassSymbol<*>> by error2<KtElement, FirCallableSymbol<*>, FirClassSymbol<*>>(SourceElementPositioningStrategies.DATA_MODIFIER)
val CANNOT_WEAKEN_ACCESS_PRIVILEGE: KtDiagnosticFactory3<Visibility, FirCallableSymbol<*>, Name> by error3<KtModifierListOwner, Visibility, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val CANNOT_WEAKEN_ACCESS_PRIVILEGE_WARNING: KtDiagnosticFactory3<Visibility, FirCallableSymbol<*>, Name> by warning3<KtModifierListOwner, Visibility, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val CANNOT_CHANGE_ACCESS_PRIVILEGE: KtDiagnosticFactory3<Visibility, FirCallableSymbol<*>, Name> by error3<KtModifierListOwner, Visibility, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val CANNOT_CHANGE_ACCESS_PRIVILEGE_WARNING: KtDiagnosticFactory3<Visibility, FirCallableSymbol<*>, Name> by warning3<KtModifierListOwner, Visibility, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val CANNOT_INFER_VISIBILITY: KtDiagnosticFactory1<FirCallableSymbol<*>> by error1<KtDeclaration, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val CANNOT_INFER_VISIBILITY_WARNING: KtDiagnosticFactory1<FirCallableSymbol<*>> by warning1<KtDeclaration, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES: KtDiagnosticFactory3<Name, FirValueParameterSymbol, List<FirCallableSymbol<*>>> by error3<KtElement, Name, FirValueParameterSymbol, List<FirCallableSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE: KtDiagnosticFactory3<Name, FirValueParameterSymbol, List<FirCallableSymbol<*>>> by error3<KtElement, Name, FirValueParameterSymbol, List<FirCallableSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_DEPRECATION: KtDiagnosticFactoryForDeprecation3<Name, FirValueParameterSymbol, List<FirCallableSymbol<*>>> by deprecationError3<KtElement, Name, FirValueParameterSymbol, List<FirCallableSymbol<*>>>(ProhibitAllMultipleDefaultsInheritedFromSupertypes, SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
@@ -166,9 +166,27 @@ sealed class FirOverrideChecker(mppKind: MppCheckerKind) : FirAbstractOverrideCh
source: KtSourceElement? = this.source,
) = when {
visibility != Visibilities.Unknown -> true
else -> false.also { reporter.reportOn(source, FirErrors.CANNOT_INFER_VISIBILITY, this, context) }
else -> false.also { reporter.reportOn(source, chooseCannotInferVisibilityFor(this), this, context) }
}
private fun chooseCannotInferVisibilityFor(symbol: FirCallableSymbol<*>) = when {
!symbol.wouldMissDiagnosticInK1 -> FirErrors.CANNOT_INFER_VISIBILITY
else -> FirErrors.CANNOT_INFER_VISIBILITY_WARNING
}
private fun chooseCannotChangeAccessPrivilegeFor(symbol: FirCallableSymbol<*>) = when {
!symbol.wouldMissDiagnosticInK1 -> FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE
else -> FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE_WARNING
}
private fun chooseCannotWeakenAccessPrivilegeFor(symbol: FirCallableSymbol<*>) = when {
!symbol.wouldMissDiagnosticInK1 -> FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE
else -> FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE_WARNING
}
private val FirCallableSymbol<*>.wouldMissDiagnosticInK1 get() =
this is FirPropertyAccessorSymbol && propertySymbol.isIntersectionOverride
private fun checkModality(
overriddenSymbols: List<FirCallableSymbol<*>>,
): FirCallableSymbol<*>? {
@@ -494,7 +512,7 @@ sealed class FirOverrideChecker(mppKind: MppCheckerKind) : FirAbstractOverrideCh
val containingClass = overridden.containingClassLookupTag() ?: return
reportOn(
overriding.source,
FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE,
chooseCannotWeakenAccessPrivilegeFor(overriding),
overriding.visibility,
overridden,
containingClass.name,
@@ -510,7 +528,7 @@ sealed class FirOverrideChecker(mppKind: MppCheckerKind) : FirAbstractOverrideCh
val containingClass = overridden.containingClassLookupTag() ?: return
reportOn(
overriding.source,
FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE,
chooseCannotChangeAccessPrivilegeFor(overriding),
overriding.visibility,
overridden,
containingClass.name,
@@ -122,11 +122,14 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENC
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_BE_IMPORTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE_WARNING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHECK_FOR_ERASED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_INFER_PARAMETER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_INFER_VISIBILITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_INFER_VISIBILITY_WARNING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_OVERRIDE_INVISIBLE_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE_WARNING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_VAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAPTURED_MEMBER_VAL_INITIALIZATION
@@ -1655,6 +1658,13 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
DECLARATION_NAME,
TO_STRING
)
map.put(
CANNOT_WEAKEN_ACCESS_PRIVILEGE_WARNING,
"Cannot weaken access privilege {0} for ''{1}'' in ''{2}''. This will be prohibited in the future.",
VISIBILITY,
DECLARATION_NAME,
TO_STRING
)
map.put(
CANNOT_CHANGE_ACCESS_PRIVILEGE,
"Cannot change access privilege {0} for ''{1}'' in ''{2}''.",
@@ -1662,9 +1672,21 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
DECLARATION_NAME,
TO_STRING
)
map.put(
CANNOT_CHANGE_ACCESS_PRIVILEGE_WARNING,
"Cannot change access privilege {0} for ''{1}'' in ''{2}''. This will be prohibited in the future.",
VISIBILITY,
DECLARATION_NAME,
TO_STRING
)
map.put(
CANNOT_INFER_VISIBILITY,
"Cannot infer visibility for ''{0}''. Please specify it explicitly",
"Cannot infer visibility for ''{0}''. Please specify it explicitly.",
DECLARATION_NAME,
)
map.put(
CANNOT_INFER_VISIBILITY_WARNING,
"Cannot infer visibility for ''{0}''. Please specify it explicitly. This will be prohibited in the future.",
DECLARATION_NAME,
)
@@ -9,7 +9,7 @@ interface I1 {
var a: Int
}
abstract class <!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>B1<!> : A1(), I1
abstract class <!CANNOT_WEAKEN_ACCESS_PRIVILEGE_WARNING!>B1<!> : A1(), I1
open class A2 {
protected fun foo(): Int = 10
@@ -0,0 +1,38 @@
// ISSUE: KT-66046
open class A1 {
var a: Int = 10
protected set
}
interface I1 {
var a: Int
}
interface I12 {
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>internal<!> var a: Int
}
abstract class <!CANNOT_WEAKEN_ACCESS_PRIVILEGE_WARNING!>B1<!> : A1(), I1
abstract class <!CANNOT_CHANGE_ACCESS_PRIVILEGE_WARNING!>B12<!> : A1(), I12
open class A2 {
protected fun foo(): Int = 10
}
interface I2 {
fun foo(): Int
}
abstract class <!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>B2<!> : A2(), I2
interface I3 {
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>internal<!> var bar: String
}
interface I4 {
var bar: String
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> set
}
abstract <!CANNOT_INFER_VISIBILITY_WARNING!>class B3<!> : I3, I4
@@ -0,0 +1,38 @@
// ISSUE: KT-66046
open class A1 {
var a: Int = 10
protected set
}
interface I1 {
var a: Int
}
interface I12 {
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>internal<!> var a: Int
}
abstract class B1 : A1(), I1
abstract class B12 : A1(), I12
open class A2 {
protected fun foo(): Int = 10
}
interface I2 {
fun foo(): Int
}
abstract class <!CANNOT_INFER_VISIBILITY!>B2<!> : A2(), I2
interface I3 {
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>internal<!> var bar: String
}
interface I4 {
var bar: String
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> set
}
abstract class B3 : I3, I4
@@ -657,6 +657,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesForNonAbstractPropertyAccessors.kt");
}
@Test
@TestMetadata("intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt")
public void testIntersectedVisibilitiesPropertyAccessorsAdditionalWarnigns() {
runTest("compiler/testData/diagnostics/tests/intersectedVisibilitiesPropertyAccessorsAdditionalWarnigns.kt");
}
@Test
@TestMetadata("intersectionWithMultipleDefaultsInJava.kt")
public void testIntersectionWithMultipleDefaultsInJava() {