Consider property accessor non-default if it has annotations
Otherwise we're not trying to load annotations on the parameter of the property setter in MemberDeserializer.loadProperty. Note that after this commit, we could now also assume that if getter/setter is default, it has no annotations, and thus use Annotations.EMPTY for default getter/setter in loadProperty. However, this would cause reflection to work incorrectly on classes compiled by an older Kotlin compiler, so we'll still try to load annotations on default accessors for an indefinite time. #KT-25499 Fixed
This commit is contained in:
+13
-4
@@ -50,18 +50,18 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
||||
}
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (descriptor !is PropertyDescriptor) return
|
||||
if (descriptor !is PropertyDescriptor || declaration !is KtProperty) return
|
||||
|
||||
val annotation = descriptor.findJvmFieldAnnotation()
|
||||
?: descriptor.delegateField?.annotations?.findAnnotation(JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME)
|
||||
?: return
|
||||
|
||||
val problem = when {
|
||||
declaration is KtProperty && declaration.hasDelegate() -> DELEGATE
|
||||
declaration.hasDelegate() -> DELEGATE
|
||||
!descriptor.hasBackingField(context.trace.bindingContext) -> return
|
||||
descriptor.isOverridable -> NOT_FINAL
|
||||
Visibilities.isPrivate(descriptor.visibility) -> PRIVATE
|
||||
descriptor.hasCustomAccessor() -> CUSTOM_ACCESSOR
|
||||
declaration.hasCustomAccessor() -> CUSTOM_ACCESSOR
|
||||
descriptor.overriddenDescriptors.isNotEmpty() -> OVERRIDES
|
||||
descriptor.isLateInit -> LATEINIT
|
||||
descriptor.isConst -> CONST
|
||||
@@ -95,7 +95,16 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun PropertyDescriptor.hasCustomAccessor() = !(getter?.isDefault ?: true) || !(setter?.isDefault ?: true)
|
||||
// This logic has been effectively used since 1.0. It'd be nice to call [PropertyAccessorDescriptor.isDefault] here instead,
|
||||
// but that would be a breaking change because in the following case:
|
||||
//
|
||||
// @JvmField
|
||||
// @get:Anno
|
||||
// val foo = 42
|
||||
//
|
||||
// we'd start considering foo as having a custom getter and disallow the JvmField annotation on it
|
||||
private fun KtProperty.hasCustomAccessor(): Boolean =
|
||||
getter != null || setter != null
|
||||
|
||||
private fun PropertyDescriptor.hasBackingField(bindingContext: BindingContext) =
|
||||
bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, this) ?: false
|
||||
|
||||
Reference in New Issue
Block a user