Merge use-site targeted annotations into corresponding Annotations
Add PropertyDescriptor.backingField/delegateField to store annotations on the field directly in an otherwise almost empty descriptor instance, instead of storing them with use-sites in the corresponding property descriptor. Instead of AnnotationWithTarget, create AnnotationDescriptor instances in AnnotationSplitter. Change DescriptorRenderer to render annotations on "related" declarations when needed, with the explicit use-site target if applicable. Most changes in diagnostic test data are related to the fact that annotations which are known to have an incompatible use-site to the declaration they're applied at (such as `@param:`-annotation on a function), are now not loaded at all. It's fine because the code is erroneous, so it doesn't really matter how do we load annotations with invalid targets (some of this logic is also changed freely in subsequent commits). Some changes are also explained by the fact that for example an annotation on the property which is only applicable to FIELD is now rendered with an explicit use-site target `@field:`, regardless of whether it did have that use-site target syntactically or not. Basically, after this change there's no point in calling Annotations.getUseSiteTargetedAnnotations/getAllAnnotations anymore because it's easier and more intuitive to just use Annotations of the corresponding descriptor -- the backing / delegate field (introduced in this commit) or the extension receiver / setter parameter (related behavior was fixed in previous commits). Usages of use-site-target-related methods will be refactored out in subsequent commits
This commit is contained in:
+5
-5
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.resolve.jvm.annotations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -29,7 +31,7 @@ fun DeclarationDescriptor.findJvmOverloadsAnnotation(): AnnotationDescriptor? =
|
||||
annotations.findAnnotation(JVM_OVERLOADS_FQ_NAME)
|
||||
|
||||
fun DeclarationDescriptor.findJvmFieldAnnotation(): AnnotationDescriptor? =
|
||||
DescriptorUtils.getAnnotationByFqName(annotations, JVM_FIELD_ANNOTATION_FQ_NAME)
|
||||
(this as? PropertyDescriptor)?.backingField?.annotations?.findAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME)
|
||||
|
||||
fun DeclarationDescriptor.hasJvmFieldAnnotation(): Boolean =
|
||||
findJvmFieldAnnotation() != null
|
||||
@@ -40,8 +42,9 @@ fun DeclarationDescriptor.isCallableMemberWithJvmDefaultAnnotation(): Boolean =
|
||||
fun CallableMemberDescriptor.hasJvmDefaultAnnotation(): Boolean =
|
||||
DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)
|
||||
|
||||
fun DeclarationDescriptor.findJvmSyntheticAnnotation(): AnnotationDescriptor? =
|
||||
private fun Annotated.findJvmSyntheticAnnotation(): AnnotationDescriptor? =
|
||||
DescriptorUtils.getAnnotationByFqName(annotations, JVM_SYNTHETIC_ANNOTATION_FQ_NAME)
|
||||
?: (this as? PropertyDescriptor)?.backingField?.annotations?.findAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME)
|
||||
|
||||
fun DeclarationDescriptor.hasJvmSyntheticAnnotation(): Boolean =
|
||||
findJvmSyntheticAnnotation() != null
|
||||
@@ -49,8 +52,5 @@ fun DeclarationDescriptor.hasJvmSyntheticAnnotation(): Boolean =
|
||||
fun DeclarationDescriptor.findStrictfpAnnotation(): AnnotationDescriptor? =
|
||||
DescriptorUtils.getAnnotationByFqName(annotations, STRICTFP_ANNOTATION_FQ_NAME)
|
||||
|
||||
fun DeclarationDescriptor.findVolatileAnnotation(): AnnotationDescriptor? =
|
||||
DescriptorUtils.getAnnotationByFqName(annotations, VOLATILE_ANNOTATION_FQ_NAME)
|
||||
|
||||
fun DeclarationDescriptor.findSynchronizedAnnotation(): AnnotationDescriptor? =
|
||||
DescriptorUtils.getAnnotationByFqName(annotations, SYNCHRONIZED_ANNOTATION_FQ_NAME)
|
||||
|
||||
+5
-2
@@ -50,10 +50,13 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
||||
}
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val annotation = descriptor.findJvmFieldAnnotation() ?: return
|
||||
if (descriptor !is PropertyDescriptor) return
|
||||
|
||||
val annotation = descriptor.findJvmFieldAnnotation()
|
||||
?: descriptor.delegateField?.annotations?.findAnnotation(JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME)
|
||||
?: return
|
||||
|
||||
val problem = when {
|
||||
descriptor !is PropertyDescriptor -> return
|
||||
declaration is KtProperty && declaration.hasDelegate() -> DELEGATE
|
||||
!descriptor.hasBackingField(context.trace.bindingContext) -> return
|
||||
descriptor.isOverridable -> NOT_FINAL
|
||||
|
||||
+4
-5
@@ -17,19 +17,18 @@
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmSyntheticAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
|
||||
class JvmSyntheticApplicabilityChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val annotation = descriptor.findJvmSyntheticAnnotation() ?: return
|
||||
if (declaration is KtProperty && descriptor is VariableDescriptor && declaration.hasDelegate()) {
|
||||
val annotation = (descriptor as? PropertyDescriptor)?.delegateField?.annotations?.findAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME)
|
||||
if (annotation != null) {
|
||||
val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(annotation) ?: return
|
||||
context.trace.report(ErrorsJvm.JVM_SYNTHETIC_ON_DELEGATE.on(annotationEntry))
|
||||
}
|
||||
|
||||
+13
-11
@@ -34,9 +34,9 @@ import org.jetbrains.kotlin.resolve.calls.components.isActualParameterWithCorres
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findSynchronizedAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findVolatileAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
|
||||
@@ -156,16 +156,18 @@ class JvmNameAnnotationChecker : DeclarationChecker {
|
||||
|
||||
class VolatileAnnotationChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val volatileAnnotation = descriptor.findVolatileAnnotation()
|
||||
if (volatileAnnotation != null) {
|
||||
if (descriptor is PropertyDescriptor && !descriptor.isVar) {
|
||||
val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(volatileAnnotation) ?: return
|
||||
context.trace.report(ErrorsJvm.VOLATILE_ON_VALUE.on(annotationEntry))
|
||||
}
|
||||
if (declaration is KtProperty && declaration.hasDelegate()) {
|
||||
val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(volatileAnnotation) ?: return
|
||||
context.trace.report(ErrorsJvm.VOLATILE_ON_DELEGATE.on(annotationEntry))
|
||||
}
|
||||
if (descriptor !is PropertyDescriptor) return
|
||||
|
||||
val fieldAnnotation = descriptor.backingField?.annotations?.findAnnotation(VOLATILE_ANNOTATION_FQ_NAME)
|
||||
if (fieldAnnotation != null && !descriptor.isVar) {
|
||||
val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(fieldAnnotation) ?: return
|
||||
context.trace.report(ErrorsJvm.VOLATILE_ON_VALUE.on(annotationEntry))
|
||||
}
|
||||
|
||||
val delegateAnnotation = descriptor.delegateField?.annotations?.findAnnotation(VOLATILE_ANNOTATION_FQ_NAME)
|
||||
if (delegateAnnotation != null) {
|
||||
val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(delegateAnnotation) ?: return
|
||||
context.trace.report(ErrorsJvm.VOLATILE_ON_DELEGATE.on(annotationEntry))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user