Private setter for open property: take containing class modality into account #KT-10325 Fixed
This commit is contained in:
@@ -681,14 +681,17 @@ class DeclarationsChecker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (propertyDescriptor.modality != Modality.FINAL
|
if (propertyDescriptor.isOverridable
|
||||||
&& accessorDescriptor.visibility == Visibilities.PRIVATE
|
&& accessorDescriptor.visibility == Visibilities.PRIVATE
|
||||||
&& propertyDescriptor.visibility != Visibilities.PRIVATE) {
|
&& propertyDescriptor.visibility != Visibilities.PRIVATE) {
|
||||||
if (propertyDescriptor.modality == Modality.ABSTRACT) {
|
if (propertyDescriptor.modality == Modality.ABSTRACT) {
|
||||||
reportVisibilityModifierDiagnostics(tokens.values, Errors.PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY)
|
reportVisibilityModifierDiagnostics(tokens.values, Errors.PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
reportVisibilityModifierDiagnostics(tokens.values, Errors.PRIVATE_SETTER_FOR_OPEN_PROPERTY)
|
val parentDescriptor = propertyDescriptor.containingDeclaration
|
||||||
|
if (parentDescriptor !is ClassDescriptor || !parentDescriptor.isFinal) {
|
||||||
|
reportVisibilityModifierDiagnostics(tokens.values, Errors.PRIVATE_SETTER_FOR_OPEN_PROPERTY)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (propertyDescriptor.isLateInit && accessorDescriptor.visibility != propertyDescriptor.visibility) {
|
else if (propertyDescriptor.isLateInit && accessorDescriptor.visibility != propertyDescriptor.visibility) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ abstract class ATest {
|
|||||||
class Test: ATest(), ITest {
|
class Test: ATest(), ITest {
|
||||||
override var prop : Int
|
override var prop : Int
|
||||||
get() = 12
|
get() = 12
|
||||||
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE, PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set(value) {}
|
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>private<!> set(value) {}
|
||||||
|
|
||||||
override var prop2 : Int
|
override var prop2 : Int
|
||||||
get() = 14
|
get() = 14
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
// See KT-10325: private setters are allowed for overridden properties in final class
|
||||||
|
|
||||||
|
interface A {
|
||||||
|
val a: Int
|
||||||
|
|
||||||
|
var b: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AA {
|
||||||
|
abstract val c: Int
|
||||||
|
|
||||||
|
abstract var d: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : A, AA() {
|
||||||
|
override var a: Int = 0
|
||||||
|
// Ok
|
||||||
|
private set
|
||||||
|
|
||||||
|
override var b: Int = 1
|
||||||
|
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>private<!> set
|
||||||
|
|
||||||
|
override var c: Int = 2
|
||||||
|
// Ok
|
||||||
|
private set
|
||||||
|
|
||||||
|
override var d: Int = 3
|
||||||
|
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>private<!> set
|
||||||
|
}
|
||||||
|
|
||||||
|
open class C : A, AA() {
|
||||||
|
override var a: Int = 0
|
||||||
|
// Errors here and below
|
||||||
|
<!PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set
|
||||||
|
|
||||||
|
override var b: Int = 1
|
||||||
|
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE, PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set
|
||||||
|
|
||||||
|
override var c: Int = 2
|
||||||
|
<!PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set
|
||||||
|
|
||||||
|
override var d: Int = 3
|
||||||
|
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE, PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class D : A, AA() {
|
||||||
|
override var a: Int = 0
|
||||||
|
// Errors here and below
|
||||||
|
<!PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set
|
||||||
|
|
||||||
|
override var b: Int = 1
|
||||||
|
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE, PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set
|
||||||
|
|
||||||
|
override var c: Int = 2
|
||||||
|
<!PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set
|
||||||
|
|
||||||
|
override var d: Int = 3
|
||||||
|
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE, PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set
|
||||||
|
}
|
||||||
|
|
||||||
|
interface E : A {
|
||||||
|
override var a: Int
|
||||||
|
get() = 0
|
||||||
|
// Errors here and below
|
||||||
|
<!PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set(arg) {}
|
||||||
|
|
||||||
|
override var b: Int
|
||||||
|
get() = 0
|
||||||
|
<!CANNOT_WEAKEN_ACCESS_PRIVILEGE, PRIVATE_SETTER_FOR_OPEN_PROPERTY!>private<!> set(arg) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public interface A {
|
||||||
|
public abstract val a: kotlin.Int
|
||||||
|
public abstract var b: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class AA {
|
||||||
|
public constructor AA()
|
||||||
|
public abstract val c: kotlin.Int
|
||||||
|
public abstract var d: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class B : A, AA {
|
||||||
|
public constructor B()
|
||||||
|
public open override /*1*/ var a: kotlin.Int
|
||||||
|
public open override /*1*/ var b: kotlin.Int
|
||||||
|
public open override /*1*/ var c: kotlin.Int
|
||||||
|
public open override /*1*/ var d: kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class C : A, AA {
|
||||||
|
public constructor C()
|
||||||
|
public open override /*1*/ var a: kotlin.Int
|
||||||
|
public open override /*1*/ var b: kotlin.Int
|
||||||
|
public open override /*1*/ var c: kotlin.Int
|
||||||
|
public open override /*1*/ var d: kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class D : A, AA {
|
||||||
|
public constructor D()
|
||||||
|
public open override /*1*/ var a: kotlin.Int
|
||||||
|
public open override /*1*/ var b: kotlin.Int
|
||||||
|
public open override /*1*/ var c: kotlin.Int
|
||||||
|
public open override /*1*/ var d: kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface E : A {
|
||||||
|
public open override /*1*/ var a: kotlin.Int
|
||||||
|
public open override /*1*/ var b: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -499,6 +499,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("PrivateSetterForOverridden.kt")
|
||||||
|
public void testPrivateSetterForOverridden() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/PrivateSetterForOverridden.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ProcessingEmptyImport.kt")
|
@TestMetadata("ProcessingEmptyImport.kt")
|
||||||
public void testProcessingEmptyImport() throws Exception {
|
public void testProcessingEmptyImport() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/ProcessingEmptyImport.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/ProcessingEmptyImport.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user