Fix deserialization of default property accessor flags
In MemberDeserializer.loadProperty, we incorrectly passed 0 to getAnnotations when loading annotations on property accessors in case the protobuf field getter_flags/setter_flags was not present. The correct behavior, as described in metadata.proto, was to pass a special "default accessor flags" value, constructed from the main property flags. Otherwise in case there were annotations both on the property and on the accessor (as in PropertyAndAccessor.kt) and the accessor was otherwise default, we would assume that it had no annotations and would not load them in compiler and reflection #KT-25499 In Progress
This commit is contained in:
+3
-23
@@ -3,25 +3,6 @@
|
||||
|
||||
// Please make sure that this test is consistent with the diagnostic test "annotationsTargetingNonExistentAccessor.kt"
|
||||
|
||||
// FILE: Temporary.java
|
||||
|
||||
// see https://youtrack.jetbrains.com/issue/KT-25499
|
||||
|
||||
class Temporary {
|
||||
public static void checkX2FromStaticsHasAnnotations() {
|
||||
try {
|
||||
if (Statics.Companion.getClass().getDeclaredMethod("getX2").getAnnotations().length == 0) {
|
||||
throw new RuntimeException("there are no annotations");
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import kotlin.reflect.KAnnotatedElement
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -152,9 +133,9 @@ class Statics {
|
||||
check(::x0.getter, annotationExists = false)
|
||||
check(::x1.getter, annotationExists = false)
|
||||
|
||||
check(::x2.getter, annotationExists = false) // https://youtrack.jetbrains.com/issue/KT-25499
|
||||
check(::x2.setter, annotationExists = false)
|
||||
check(::x2.setter.parameters.first(), annotationExists = false)
|
||||
check(::x2.getter, annotationExists = true)
|
||||
check(::x2.setter, annotationExists = true)
|
||||
check(::x2.setter.parameters.first(), annotationExists = false /* TODO */)
|
||||
|
||||
check(::x3.getter, annotationExists = false)
|
||||
|
||||
@@ -185,7 +166,6 @@ fun box(): String {
|
||||
PrivateProperties(0, "").test()
|
||||
EffetivelyPrivate.test()
|
||||
Statics().test()
|
||||
Temporary.checkX2FromStaticsHasAnnotations()
|
||||
Delegate().test()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// WITH_REFLECT
|
||||
// IGNORE_BACKEND: JVM_IR, JS_IR, JS, NATIVE
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
annotation class Ann1
|
||||
annotation class Ann2
|
||||
|
||||
class Foo {
|
||||
@setparam:Ann1
|
||||
var delegate = " "
|
||||
set(@Ann2 value) {}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val setterParameters = Foo::delegate.setter.parameters
|
||||
assertEquals(2, setterParameters.size)
|
||||
assertEquals("[]", setterParameters.first().annotations.toString())
|
||||
assertEquals("[@Ann2(), @Ann1()]", setterParameters.last().annotations.toString())
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
package test
|
||||
|
||||
annotation class A(val value: String)
|
||||
annotation class B(val value: Array<String>)
|
||||
|
||||
interface I {
|
||||
@A("property")
|
||||
@get:B(["getter"])
|
||||
var propertyAndGetter: Int
|
||||
|
||||
@A("property")
|
||||
@set:B(["setter"])
|
||||
var propertyAndSetter: Int
|
||||
|
||||
@get:A("getter")
|
||||
@set:B(["setter"])
|
||||
var getterAndSetter: Int
|
||||
}
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
package test
|
||||
|
||||
public final annotation class A : kotlin.Annotation {
|
||||
/*primary*/ public constructor A(/*0*/ value: kotlin.String)
|
||||
public final val value: kotlin.String
|
||||
public final fun <get-value>(): kotlin.String
|
||||
}
|
||||
|
||||
public final annotation class B : kotlin.Annotation {
|
||||
/*primary*/ public constructor B(/*0*/ value: kotlin.Array<kotlin.String>)
|
||||
public final val value: kotlin.Array<kotlin.String>
|
||||
public final fun <get-value>(): kotlin.Array<kotlin.String>
|
||||
}
|
||||
|
||||
public interface I {
|
||||
public abstract var getterAndSetter: kotlin.Int
|
||||
@test.A(value = "getter") public abstract fun <get-getterAndSetter>(): kotlin.Int
|
||||
@test.B(value = {"setter"}) public abstract fun <set-getterAndSetter>(/*0*/ <set-?>: kotlin.Int): kotlin.Unit
|
||||
@test.A(value = "property") public abstract var propertyAndGetter: kotlin.Int
|
||||
@test.B(value = {"getter"}) public abstract fun <get-propertyAndGetter>(): kotlin.Int
|
||||
public abstract fun <set-propertyAndGetter>(/*0*/ <set-?>: kotlin.Int): kotlin.Unit
|
||||
@test.A(value = "property") public abstract var propertyAndSetter: kotlin.Int
|
||||
public abstract fun <get-propertyAndSetter>(): kotlin.Int
|
||||
@test.B(value = {"setter"}) public abstract fun <set-propertyAndSetter>(/*0*/ <set-?>: kotlin.Int): kotlin.Unit
|
||||
}
|
||||
Reference in New Issue
Block a user