K1: report a warning for invisible setter accessed from a derived class

The issue is that during binding fake overrides, the compiler doesn't
 differ setters from its properties, so the compiler uses the same
 visibility for setter and entire property.

 Changing logic at the binding stage can cause some unpredictable consequences so
 the fix is to do this differentiation right at the reporting stage

 ^KT-56662 Fixed

Merge-request: KT-MR-9565
Merged-by: Michail Zarečenskij <Mikhail.Zarechenskiy@jetbrains.com>
This commit is contained in:
Mikhail Zarechenskiy
2023-04-17 11:08:16 +00:00
committed by Space Team
parent d8f253d07b
commit fc37885d6d
14 changed files with 332 additions and 9 deletions
@@ -0,0 +1,56 @@
// !LANGUAGE:-ProhibitAccessToInvisibleSetterFromDerivedClass
// IGNORE_REVERSED_RESOLVE
// MODULE: m1
// FILE: base.kt
open class Base {
var foo: String = ""
internal set
}
// MODULE: m2(m1)
// FILE: derived1.kt
fun testBase(b: Base) {
b.<!INVISIBLE_SETTER!>foo<!> = "other"
}
open class Derived1(foo: String) : Base() {
init {
this.<!INVISIBLE_SETTER!>foo<!> = foo
}
fun bar(param: String) {
<!INVISIBLE_SETTER!>foo<!> = param
this.<!INVISIBLE_SETTER!>foo<!> = param
}
}
open class Derived2 : Derived1("")
fun testFunction(d: Derived1) {
d.<!INVISIBLE_SETTER!>foo<!> = "other"
}
// MODULE: m3(m2, m1)
// FILE: derived2.kt
fun testDerivied1(d: Derived1) {
d.<!INVISIBLE_SETTER!>foo<!> = "other"
}
fun testDerivied2(d: Derived2) {
d.<!INVISIBLE_SETTER!>foo<!> = "other"
}
class Derivied3(foo: String) : Derived2() {
init {
this.<!INVISIBLE_SETTER!>foo<!> = foo
}
fun bar1(param: String) {
<!INVISIBLE_SETTER!>foo<!> = param
this.<!INVISIBLE_SETTER!>foo<!> = param
}
}
@@ -0,0 +1,56 @@
// !LANGUAGE:-ProhibitAccessToInvisibleSetterFromDerivedClass
// IGNORE_REVERSED_RESOLVE
// MODULE: m1
// FILE: base.kt
open class Base {
var foo: String = ""
internal set
}
// MODULE: m2(m1)
// FILE: derived1.kt
fun testBase(b: Base) {
<!INVISIBLE_SETTER!>b.foo<!> = "other"
}
open class Derived1(foo: String) : Base() {
init {
<!INVISIBLE_SETTER_FROM_DERIVED!>this.<!DEBUG_INFO_LEAKING_THIS!>foo<!><!> = foo
}
fun bar(param: String) {
<!INVISIBLE_SETTER_FROM_DERIVED!>foo<!> = param
<!INVISIBLE_SETTER_FROM_DERIVED!>this.foo<!> = param
}
}
open class Derived2 : Derived1("")
fun testFunction(d: Derived1) {
<!INVISIBLE_SETTER_FROM_DERIVED!>d.foo<!> = "other"
}
// MODULE: m3(m2, m1)
// FILE: derived2.kt
fun testDerivied1(d: Derived1) {
<!INVISIBLE_SETTER!>d.foo<!> = "other"
}
fun testDerivied2(d: Derived2) {
<!INVISIBLE_SETTER!>d.foo<!> = "other"
}
class Derivied3(foo: String) : Derived2() {
init {
<!INVISIBLE_SETTER_FROM_DERIVED!>this.foo<!> = foo
}
fun bar1(param: String) {
<!INVISIBLE_SETTER_FROM_DERIVED!>foo<!> = param
<!INVISIBLE_SETTER_FROM_DERIVED!>this.foo<!> = param
}
}
@@ -0,0 +1,56 @@
// !LANGUAGE:+ProhibitAccessToInvisibleSetterFromDerivedClass
// IGNORE_REVERSED_RESOLVE
// MODULE: m1
// FILE: base.kt
open class Base {
var foo: String = ""
internal set
}
// MODULE: m2(m1)
// FILE: derived1.kt
fun testBase(b: Base) {
b.<!INVISIBLE_SETTER!>foo<!> = "other"
}
open class Derived1(foo: String) : Base() {
init {
this.<!INVISIBLE_SETTER!>foo<!> = foo
}
fun bar(param: String) {
<!INVISIBLE_SETTER!>foo<!> = param
this.<!INVISIBLE_SETTER!>foo<!> = param
}
}
open class Derived2 : Derived1("")
fun testFunction(d: Derived1) {
d.<!INVISIBLE_SETTER!>foo<!> = "other"
}
// MODULE: m3(m2, m1)
// FILE: derived2.kt
fun testDerivied1(d: Derived1) {
d.<!INVISIBLE_SETTER!>foo<!> = "other"
}
fun testDerivied2(d: Derived2) {
d.<!INVISIBLE_SETTER!>foo<!> = "other"
}
class Derivied3(foo: String) : Derived2() {
init {
this.<!INVISIBLE_SETTER!>foo<!> = foo
}
fun bar1(param: String) {
<!INVISIBLE_SETTER!>foo<!> = param
this.<!INVISIBLE_SETTER!>foo<!> = param
}
}
@@ -0,0 +1,56 @@
// !LANGUAGE:+ProhibitAccessToInvisibleSetterFromDerivedClass
// IGNORE_REVERSED_RESOLVE
// MODULE: m1
// FILE: base.kt
open class Base {
var foo: String = ""
internal set
}
// MODULE: m2(m1)
// FILE: derived1.kt
fun testBase(b: Base) {
<!INVISIBLE_SETTER!>b.foo<!> = "other"
}
open class Derived1(foo: String) : Base() {
init {
<!INVISIBLE_SETTER!>this.<!DEBUG_INFO_LEAKING_THIS!>foo<!><!> = foo
}
fun bar(param: String) {
<!INVISIBLE_SETTER!>foo<!> = param
<!INVISIBLE_SETTER!>this.foo<!> = param
}
}
open class Derived2 : Derived1("")
fun testFunction(d: Derived1) {
<!INVISIBLE_SETTER!>d.foo<!> = "other"
}
// MODULE: m3(m2, m1)
// FILE: derived2.kt
fun testDerivied1(d: Derived1) {
<!INVISIBLE_SETTER!>d.foo<!> = "other"
}
fun testDerivied2(d: Derived2) {
<!INVISIBLE_SETTER!>d.foo<!> = "other"
}
class Derivied3(foo: String) : Derived2() {
init {
<!INVISIBLE_SETTER!>this.foo<!> = foo
}
fun bar1(param: String) {
<!INVISIBLE_SETTER!>foo<!> = param
<!INVISIBLE_SETTER!>this.foo<!> = param
}
}