Use target priorities to split annotations to different descriptors
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
|
||||
import kotlin.platform.platformStatic
|
||||
|
||||
public class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnotationChecker>) {
|
||||
|
||||
@@ -54,7 +55,7 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
}
|
||||
|
||||
public fun checkExpression(expression: JetExpression, trace: BindingTrace) {
|
||||
checkEntries(expression.getAnnotationEntries(), targetList(KotlinTarget.EXPRESSION), trace)
|
||||
checkEntries(expression.getAnnotationEntries(), TargetLists.T_EXPRESSION, trace)
|
||||
if (expression is JetFunctionLiteralExpression) {
|
||||
for (parameter in expression.valueParameters) {
|
||||
parameter.typeReference?.let { check(it, trace) }
|
||||
@@ -81,37 +82,34 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
|
||||
existingTargetsForAnnotation.add(useSiteTarget)
|
||||
}
|
||||
additionalCheckers.forEach { it.checkEntries(entries, actualTargets.declarationSite, trace) }
|
||||
additionalCheckers.forEach { it.checkEntries(entries, actualTargets.defaultTargets, trace) }
|
||||
}
|
||||
|
||||
private fun checkAnnotationEntry(entry: JetAnnotationEntry, actualTargets: TargetList, trace: BindingTrace) {
|
||||
val applicableTargets = applicableTargetSet(entry, trace)
|
||||
val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget()
|
||||
|
||||
if (actualTargets.declarationSite.any {
|
||||
fun check(targets: List<KotlinTarget>) = targets.any {
|
||||
it in applicableTargets && (useSiteTarget == null || KotlinTarget.USE_SITE_MAPPING[useSiteTarget] == it)
|
||||
}) return
|
||||
}
|
||||
|
||||
if (useSiteTarget != null && actualTargets.useSite.any {
|
||||
if (check(actualTargets.defaultTargets) || check(actualTargets.canBeSubstituted)) return
|
||||
|
||||
if (useSiteTarget != null && actualTargets.onlyWithUseSiteTarget.any {
|
||||
it in applicableTargets && KotlinTarget.USE_SITE_MAPPING[useSiteTarget] == it
|
||||
}) return
|
||||
|
||||
if (useSiteTarget != null) {
|
||||
trace.report(Errors.WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET.on(
|
||||
entry, actualTargets.declarationSite.firstOrNull()?.description ?: "unidentified target", useSiteTarget.renderName))
|
||||
entry, actualTargets.defaultTargets.firstOrNull()?.description ?: "unidentified target", useSiteTarget.renderName))
|
||||
}
|
||||
else {
|
||||
trace.report(Errors.WRONG_ANNOTATION_TARGET.on(
|
||||
entry, actualTargets.declarationSite.firstOrNull()?.description ?: "unidentified target"))
|
||||
entry, actualTargets.defaultTargets.firstOrNull()?.description ?: "unidentified target"))
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val PROPERTY_USE_SITE_TARGETS = listOf(
|
||||
KotlinTarget.FIELD, KotlinTarget.PROPERTY_GETTER, KotlinTarget.PROPERTY_SETTER, KotlinTarget.VALUE_PARAMETER)
|
||||
private val VALUE_PARAMETER_USE_SITE_TARGETS = PROPERTY_USE_SITE_TARGETS + KotlinTarget.PROPERTY
|
||||
|
||||
private fun applicableTargetSet(entry: JetAnnotationEntry, trace: BindingTrace): Set<KotlinTarget> {
|
||||
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return KotlinTarget.DEFAULT_TARGET_SET
|
||||
// For descriptor with error type, all targets are considered as possible
|
||||
@@ -120,6 +118,12 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
return applicableTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
|
||||
}
|
||||
|
||||
platformStatic
|
||||
public fun applicableTargetSet(descriptor: AnnotationDescriptor): Set<KotlinTarget> {
|
||||
val classDescriptor = descriptor.type.constructor.declarationDescriptor as? ClassDescriptor ?: return emptySet()
|
||||
return applicableTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
|
||||
}
|
||||
|
||||
public fun applicableTargetSet(classDescriptor: ClassDescriptor): Set<KotlinTarget>? {
|
||||
val targetEntryDescriptor = classDescriptor.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.target)
|
||||
?: return null
|
||||
@@ -131,70 +135,134 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
}
|
||||
|
||||
public fun getDeclarationSiteActualTargetList(annotated: JetElement, descriptor: ClassDescriptor?): List<KotlinTarget> {
|
||||
return getActualTargetList(annotated, descriptor).declarationSite
|
||||
return getActualTargetList(annotated, descriptor).defaultTargets
|
||||
}
|
||||
|
||||
private fun getActualTargetList(annotated: JetElement, descriptor: ClassDescriptor?): TargetList {
|
||||
return when (annotated) {
|
||||
is JetClassOrObject -> descriptor?.let { TargetList(KotlinTarget.classActualTargets(it)) } ?: targetList(CLASSIFIER)
|
||||
is JetProperty ->
|
||||
if (annotated.isLocal) {
|
||||
extendedTargetList(PROPERTY_USE_SITE_TARGETS, LOCAL_VARIABLE)
|
||||
}
|
||||
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody) {
|
||||
extendedTargetList(PROPERTY_USE_SITE_TARGETS, MEMBER_PROPERTY, PROPERTY)
|
||||
}
|
||||
else {
|
||||
extendedTargetList(PROPERTY_USE_SITE_TARGETS, TOP_LEVEL_PROPERTY, PROPERTY)
|
||||
}
|
||||
is JetClassOrObject -> descriptor?.let { TargetList(KotlinTarget.classActualTargets(it)) } ?: TargetLists.T_CLASSIFIER
|
||||
is JetProperty -> {
|
||||
if (annotated.isLocal)
|
||||
TargetLists.T_LOCAL_VARIABLE
|
||||
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody)
|
||||
TargetLists.T_MEMBER_PROPERTY
|
||||
else
|
||||
TargetLists.T_TOP_LEVEL_PROPERTY
|
||||
}
|
||||
is JetParameter -> {
|
||||
if (annotated.hasValOrVar()) {
|
||||
extendedTargetList(VALUE_PARAMETER_USE_SITE_TARGETS, PROPERTY_PARAMETER, MEMBER_PROPERTY, PROPERTY)
|
||||
}
|
||||
else {
|
||||
extendedTargetList(VALUE_PARAMETER_USE_SITE_TARGETS, VALUE_PARAMETER)
|
||||
}
|
||||
if (annotated.hasValOrVar())
|
||||
TargetLists.T_VALUE_PARAMETER_WITH_VAL
|
||||
else
|
||||
TargetLists.T_VALUE_PARAMETER_WITHOUT_VAL
|
||||
}
|
||||
is JetConstructor<*> -> targetList(CONSTRUCTOR)
|
||||
is JetConstructor<*> -> TargetLists.T_CONSTRUCTOR
|
||||
is JetFunction -> {
|
||||
val extendedTargets = listOf(KotlinTarget.VALUE_PARAMETER)
|
||||
if (annotated.isLocal) {
|
||||
extendedTargetList(extendedTargets, LOCAL_FUNCTION, FUNCTION)
|
||||
}
|
||||
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody) {
|
||||
extendedTargetList(extendedTargets, MEMBER_FUNCTION, FUNCTION)
|
||||
}
|
||||
else {
|
||||
extendedTargetList(extendedTargets, TOP_LEVEL_FUNCTION, FUNCTION)
|
||||
}
|
||||
if (annotated.isLocal)
|
||||
TargetLists.T_LOCAL_FUNCTION
|
||||
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody)
|
||||
TargetLists.T_MEMBER_FUNCTION
|
||||
else
|
||||
TargetLists.T_TOP_LEVEL_FUNCTION
|
||||
}
|
||||
is JetPropertyAccessor -> if (annotated.isGetter) targetList(PROPERTY_GETTER) else targetList(PROPERTY_SETTER)
|
||||
is JetPackageDirective -> targetList(PACKAGE)
|
||||
is JetTypeReference -> extendedTargetList(listOf(VALUE_PARAMETER), TYPE)
|
||||
is JetFile -> targetList(FILE)
|
||||
is JetTypeParameter -> targetList(TYPE_PARAMETER)
|
||||
is JetTypeProjection -> {
|
||||
if (annotated.projectionKind == JetProjectionKind.STAR) {
|
||||
targetList(STAR_PROJECTION)
|
||||
}
|
||||
else {
|
||||
targetList(TYPE_PROJECTION)
|
||||
}
|
||||
}
|
||||
is JetClassInitializer -> targetList(INITIALIZER)
|
||||
else -> targetList()
|
||||
is JetPropertyAccessor -> if (annotated.isGetter) TargetLists.T_PROPERTY_GETTER else TargetLists.T_PROPERTY_SETTER
|
||||
is JetPackageDirective -> TargetLists.T_PACKAGE
|
||||
is JetTypeReference -> TargetLists.T_TYPE_REFERENCE
|
||||
is JetFile -> TargetLists.T_FILE
|
||||
is JetTypeParameter -> TargetLists.T_TYPE_PARAMETER
|
||||
is JetTypeProjection ->
|
||||
if (annotated.projectionKind == JetProjectionKind.STAR) TargetLists.T_STAR_PROJECTION else TargetLists.T_TYPE_PROJECTION
|
||||
is JetClassInitializer -> TargetLists.T_INITIALIZER
|
||||
else -> TargetLists.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
private class TargetList(val declarationSite: List<KotlinTarget>, val useSite: List<KotlinTarget> = emptyList())
|
||||
private object TargetLists {
|
||||
val T_CLASSIFIER = targetList(CLASSIFIER)
|
||||
|
||||
private fun targetList(vararg target: KotlinTarget): TargetList {
|
||||
return TargetList(listOf(*target), emptyList())
|
||||
val T_LOCAL_VARIABLE = targetList(LOCAL_VARIABLE) {
|
||||
onlyWithUseSiteTarget(PROPERTY, FIELD, PROPERTY_GETTER, PROPERTY_SETTER, VALUE_PARAMETER)
|
||||
}
|
||||
|
||||
val T_MEMBER_PROPERTY = targetList(MEMBER_PROPERTY, PROPERTY) {
|
||||
canBeSubstituted(PROPERTY_GETTER, PROPERTY_SETTER, FIELD)
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER)
|
||||
}
|
||||
|
||||
val T_TOP_LEVEL_PROPERTY = targetList(TOP_LEVEL_PROPERTY, PROPERTY) {
|
||||
canBeSubstituted(FIELD, PROPERTY_GETTER, PROPERTY_SETTER)
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER)
|
||||
}
|
||||
|
||||
val T_PROPERTY_GETTER = targetList(PROPERTY_GETTER)
|
||||
val T_PROPERTY_SETTER = targetList(PROPERTY_SETTER)
|
||||
|
||||
val T_VALUE_PARAMETER_WITHOUT_VAL = targetList(VALUE_PARAMETER) {
|
||||
onlyWithUseSiteTarget(PROPERTY, FIELD, PROPERTY_GETTER, PROPERTY_SETTER)
|
||||
}
|
||||
|
||||
val T_VALUE_PARAMETER_WITH_VAL = targetList(VALUE_PARAMETER, PROPERTY, MEMBER_PROPERTY) {
|
||||
canBeSubstituted(FIELD, PROPERTY_GETTER, PROPERTY_SETTER)
|
||||
}
|
||||
|
||||
val T_FILE = targetList(FILE)
|
||||
val T_PACKAGE = targetList(PACKAGE)
|
||||
|
||||
val T_CONSTRUCTOR = targetList(CONSTRUCTOR)
|
||||
|
||||
val T_LOCAL_FUNCTION = targetList(LOCAL_FUNCTION, FUNCTION) {
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER)
|
||||
}
|
||||
|
||||
val T_MEMBER_FUNCTION = targetList(MEMBER_FUNCTION, FUNCTION) {
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER)
|
||||
}
|
||||
|
||||
val T_TOP_LEVEL_FUNCTION = targetList(TOP_LEVEL_FUNCTION, FUNCTION) {
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER)
|
||||
}
|
||||
|
||||
val T_EXPRESSION = targetList(EXPRESSION)
|
||||
|
||||
val T_TYPE_REFERENCE = targetList(TYPE) {
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER)
|
||||
}
|
||||
|
||||
val T_TYPE_PARAMETER = targetList(TYPE_PARAMETER)
|
||||
|
||||
val T_STAR_PROJECTION = targetList(STAR_PROJECTION)
|
||||
val T_TYPE_PROJECTION = targetList(TYPE_PROJECTION)
|
||||
|
||||
val T_INITIALIZER = targetList(INITIALIZER)
|
||||
|
||||
|
||||
private fun targetList(vararg target: KotlinTarget, otherTargets: TargetListBuilder.() -> Unit = {}): TargetList {
|
||||
val builder = TargetListBuilder(*target)
|
||||
builder.otherTargets()
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
val EMPTY = targetList()
|
||||
|
||||
private class TargetListBuilder(vararg val defaultTargets: KotlinTarget) {
|
||||
private var canBeSubstituted: List<KotlinTarget> = listOf()
|
||||
private var onlyWithUseSiteTarget: List<KotlinTarget> = listOf()
|
||||
|
||||
fun canBeSubstituted(vararg targets: KotlinTarget) {
|
||||
canBeSubstituted = targets.toList()
|
||||
}
|
||||
|
||||
fun onlyWithUseSiteTarget(vararg targets: KotlinTarget) {
|
||||
onlyWithUseSiteTarget = targets.toList()
|
||||
}
|
||||
|
||||
fun build() = TargetList(defaultTargets.toList(), canBeSubstituted, onlyWithUseSiteTarget)
|
||||
}
|
||||
}
|
||||
|
||||
private fun extendedTargetList(extended: List<KotlinTarget>, vararg target: KotlinTarget): TargetList {
|
||||
return TargetList(listOf(*target), extended)
|
||||
}
|
||||
private class TargetList(
|
||||
val defaultTargets: List<KotlinTarget>,
|
||||
val canBeSubstituted: List<KotlinTarget> = emptyList(),
|
||||
val onlyWithUseSiteTarget: List<KotlinTarget> = emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,15 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.KotlinPackage;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.*;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
@@ -44,9 +47,11 @@ import org.jetbrains.kotlin.storage.StorageManager;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.kotlin.util.AnnotationSplitter;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
import static org.jetbrains.kotlin.lexer.JetTokens.OVERRIDE_KEYWORD;
|
||||
import static org.jetbrains.kotlin.lexer.JetTokens.VARARG_KEYWORD;
|
||||
@@ -328,11 +333,28 @@ public class DescriptorResolver {
|
||||
varargElementType = type;
|
||||
variableType = getVarargParameterType(type);
|
||||
}
|
||||
|
||||
JetModifierList modifierList = valueParameter.getModifierList();
|
||||
|
||||
Annotations allAnnotations =
|
||||
annotationResolver.resolveAnnotationsWithoutArguments(scope, valueParameter.getModifierList(), trace);
|
||||
Annotations valueParameterAnnotations = Annotations.EMPTY;
|
||||
|
||||
if (modifierList != null) {
|
||||
if (valueParameter.hasValOrVar()) {
|
||||
AnnotationSplitter annotationSplitter = new AnnotationSplitter(allAnnotations, KotlinPackage.setOf(CONSTRUCTOR_PARAMETER));
|
||||
valueParameterAnnotations = annotationSplitter.getAnnotationsForTarget(CONSTRUCTOR_PARAMETER);
|
||||
}
|
||||
else {
|
||||
valueParameterAnnotations = allAnnotations;
|
||||
}
|
||||
}
|
||||
|
||||
ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(
|
||||
owner,
|
||||
null,
|
||||
index,
|
||||
annotationResolver.resolveAnnotationsWithoutArguments(scope, valueParameter.getModifierList(), trace),
|
||||
valueParameterAnnotations,
|
||||
JetPsiUtil.safeName(valueParameter.getName()),
|
||||
variableType,
|
||||
valueParameter.hasDefaultValue(),
|
||||
@@ -645,13 +667,13 @@ public class DescriptorResolver {
|
||||
private static void initializeWithDefaultGetterSetter(PropertyDescriptorImpl propertyDescriptor) {
|
||||
PropertyGetterDescriptorImpl getter = propertyDescriptor.getGetter();
|
||||
if (getter == null && !Visibilities.isPrivate(propertyDescriptor.getVisibility())) {
|
||||
getter = DescriptorFactory.createDefaultGetter(propertyDescriptor);
|
||||
getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, Annotations.EMPTY);
|
||||
getter.initialize(propertyDescriptor.getType());
|
||||
}
|
||||
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
if (setter == null && propertyDescriptor.isVar()) {
|
||||
setter = DescriptorFactory.createDefaultSetter(propertyDescriptor);
|
||||
setter = DescriptorFactory.createDefaultSetter(propertyDescriptor, Annotations.EMPTY);
|
||||
}
|
||||
propertyDescriptor.initialize(getter, setter);
|
||||
}
|
||||
@@ -691,9 +713,24 @@ public class DescriptorResolver {
|
||||
Modality modality = containingDeclaration instanceof ClassDescriptor
|
||||
? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody))
|
||||
: Modality.FINAL;
|
||||
|
||||
JetPropertyAccessor propertyGetter = property.getGetter();
|
||||
|
||||
boolean hasBackingField = modality != Modality.ABSTRACT
|
||||
&& property.hasDelegateExpressionOrInitializer()
|
||||
&& (propertyGetter == null || !propertyGetter.hasBody());
|
||||
|
||||
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace);
|
||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(allAnnotations,
|
||||
/*parameter =*/ false, /*hasBackingField =*/ hasBackingField, /*isMutable =*/ isVar);
|
||||
|
||||
Annotations propertyAnnotations = new CompositeAnnotations(KotlinPackage.listOf(
|
||||
annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD),
|
||||
annotationSplitter.getOtherAnnotations()));
|
||||
|
||||
PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
|
||||
containingDeclaration,
|
||||
annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace),
|
||||
propertyAnnotations,
|
||||
modality,
|
||||
visibility,
|
||||
isVar,
|
||||
@@ -742,8 +779,10 @@ public class DescriptorResolver {
|
||||
propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration),
|
||||
receiverDescriptor);
|
||||
|
||||
PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
|
||||
PropertySetterDescriptor setter = resolvePropertySetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
|
||||
PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(
|
||||
scopeWithTypeParameters, property, propertyDescriptor, annotationSplitter, trace);
|
||||
PropertySetterDescriptor setter = resolvePropertySetterDescriptor(
|
||||
scopeWithTypeParameters, property, propertyDescriptor, annotationSplitter, trace);
|
||||
|
||||
propertyDescriptor.initialize(getter, setter);
|
||||
|
||||
@@ -923,13 +962,15 @@ public class DescriptorResolver {
|
||||
@NotNull LexicalScope scope,
|
||||
@NotNull JetProperty property,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull AnnotationSplitter annotationSplitter,
|
||||
BindingTrace trace
|
||||
) {
|
||||
JetPropertyAccessor setter = property.getSetter();
|
||||
PropertySetterDescriptorImpl setterDescriptor = null;
|
||||
if (setter != null) {
|
||||
Annotations annotations =
|
||||
annotationResolver.resolveAnnotationsWithoutArguments(scope, setter.getModifierList(), trace);
|
||||
Annotations annotations = new CompositeAnnotations(KotlinPackage.listOf(
|
||||
annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER),
|
||||
annotationResolver.resolveAnnotationsWithoutArguments(scope, setter.getModifierList(), trace)));
|
||||
JetParameter parameter = setter.getParameter();
|
||||
|
||||
setterDescriptor = new PropertySetterDescriptorImpl(propertyDescriptor, annotations,
|
||||
@@ -973,7 +1014,8 @@ public class DescriptorResolver {
|
||||
trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
|
||||
}
|
||||
else if (property.isVar()) {
|
||||
setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, !property.hasDelegate());
|
||||
Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
|
||||
setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, setterAnnotations, !property.hasDelegate());
|
||||
}
|
||||
|
||||
if (!property.isVar()) {
|
||||
@@ -990,13 +1032,16 @@ public class DescriptorResolver {
|
||||
@NotNull LexicalScope scope,
|
||||
@NotNull JetProperty property,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull AnnotationSplitter annotationSplitter,
|
||||
BindingTrace trace
|
||||
) {
|
||||
PropertyGetterDescriptorImpl getterDescriptor;
|
||||
JetPropertyAccessor getter = property.getGetter();
|
||||
if (getter != null) {
|
||||
Annotations annotations =
|
||||
annotationResolver.resolveAnnotationsWithoutArguments(scope, getter.getModifierList(), trace);
|
||||
Annotations getterAnnotations = new CompositeAnnotations(KotlinPackage.listOf(
|
||||
annotationSplitter.getAnnotationsForTarget(PROPERTY_GETTER),
|
||||
annotationSplitter.getOtherAnnotations(),
|
||||
annotationResolver.resolveAnnotationsWithoutArguments(scope, getter.getModifierList(), trace)));
|
||||
|
||||
JetType outType = propertyDescriptor.getType();
|
||||
JetType returnType = outType;
|
||||
@@ -1008,7 +1053,7 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
getterDescriptor = new PropertyGetterDescriptorImpl(propertyDescriptor, annotations,
|
||||
getterDescriptor = new PropertyGetterDescriptorImpl(propertyDescriptor, getterAnnotations,
|
||||
resolveModalityFromModifiers(getter, propertyDescriptor.getModality()),
|
||||
resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()),
|
||||
getter.hasBody(), false,
|
||||
@@ -1017,7 +1062,8 @@ public class DescriptorResolver {
|
||||
trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
|
||||
}
|
||||
else {
|
||||
getterDescriptor = DescriptorFactory.createGetter(propertyDescriptor, !property.hasDelegate());
|
||||
Annotations getterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_GETTER);
|
||||
getterDescriptor = DescriptorFactory.createGetter(propertyDescriptor, getterAnnotations, !property.hasDelegate());
|
||||
getterDescriptor.initialize(propertyDescriptor.getType());
|
||||
}
|
||||
return getterDescriptor;
|
||||
@@ -1041,9 +1087,17 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, parameter.getModifierList(), trace);
|
||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(allAnnotations,
|
||||
/*parameter =*/ true, /*hasBackingField =*/ true, /*isMutable =*/ isMutable);
|
||||
|
||||
Annotations propertyAnnotations = new CompositeAnnotations(
|
||||
annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD),
|
||||
annotationSplitter.getOtherAnnotations());
|
||||
|
||||
PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
|
||||
classDescriptor,
|
||||
valueParameter.getAnnotations(),
|
||||
propertyAnnotations,
|
||||
resolveModalityFromModifiers(parameter, Modality.FINAL),
|
||||
resolveVisibilityFromModifiers(parameter, getDefaultVisibility(parameter, classDescriptor)),
|
||||
isMutable,
|
||||
@@ -1054,9 +1108,13 @@ public class DescriptorResolver {
|
||||
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
getDispatchReceiverParameterIfNeeded(classDescriptor), (ReceiverParameterDescriptor) null);
|
||||
|
||||
PropertyGetterDescriptorImpl getter = DescriptorFactory.createDefaultGetter(propertyDescriptor);
|
||||
Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
|
||||
Annotations getterAnnotations = new CompositeAnnotations(KotlinPackage.listOf(
|
||||
annotationSplitter.getAnnotationsForTarget(PROPERTY_GETTER)));
|
||||
|
||||
PropertyGetterDescriptorImpl getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, getterAnnotations);
|
||||
PropertySetterDescriptor setter =
|
||||
propertyDescriptor.isVar() ? DescriptorFactory.createDefaultSetter(propertyDescriptor) : null;
|
||||
propertyDescriptor.isVar() ? DescriptorFactory.createDefaultSetter(propertyDescriptor, setterAnnotations) : null;
|
||||
|
||||
propertyDescriptor.initialize(getter, setter);
|
||||
getter.initialize(propertyDescriptor.getType());
|
||||
|
||||
@@ -103,9 +103,9 @@ object DynamicCallableDescriptors {
|
||||
null: JetType?
|
||||
)
|
||||
|
||||
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor)
|
||||
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, Annotations.EMPTY)
|
||||
getter.initialize(propertyDescriptor.getType())
|
||||
val setter = DescriptorFactory.createDefaultSetter(propertyDescriptor)
|
||||
val setter = DescriptorFactory.createDefaultSetter(propertyDescriptor, Annotations.EMPTY)
|
||||
|
||||
propertyDescriptor.initialize(getter, setter)
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.annotations.*
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
|
||||
import kotlin.platform.platformStatic
|
||||
|
||||
public class AnnotationSplitter(original: Annotations, applicableTargets: Set<AnnotationUseSiteTarget>) {
|
||||
private val annotations: Map<AnnotationUseSiteTarget, List<AnnotationWithTarget>>
|
||||
public val otherAnnotations: Annotations
|
||||
|
||||
init {
|
||||
val map = hashMapOf<AnnotationUseSiteTarget, MutableList<AnnotationWithTarget>>()
|
||||
val other = arrayListOf<AnnotationWithTarget>()
|
||||
|
||||
outer@ for (annotationWithTarget in original.getAllAnnotations()) {
|
||||
val useSiteTarget = annotationWithTarget.target
|
||||
if (useSiteTarget != null) {
|
||||
if (useSiteTarget in applicableTargets)
|
||||
map.getOrPut(useSiteTarget, { arrayListOf() }).add(annotationWithTarget)
|
||||
else
|
||||
other.add(annotationWithTarget)
|
||||
|
||||
continue@outer
|
||||
}
|
||||
|
||||
for (target in TARGET_PRIORITIES) {
|
||||
if (target !in applicableTargets) continue
|
||||
|
||||
val declarationSiteTargetForCurrentTarget = KotlinTarget.USE_SITE_MAPPING[target] ?: continue
|
||||
val applicableTargetsForAnnotation = AnnotationChecker.applicableTargetSet(annotationWithTarget.annotation)
|
||||
val applicable = applicableTargetsForAnnotation.any { it == declarationSiteTargetForCurrentTarget }
|
||||
|
||||
if (applicable) {
|
||||
map.getOrPut(target, { arrayListOf() }).add(annotationWithTarget)
|
||||
continue@outer
|
||||
}
|
||||
}
|
||||
|
||||
other.add(annotationWithTarget)
|
||||
}
|
||||
annotations = map
|
||||
otherAnnotations = AnnotationsImpl.create(other)
|
||||
}
|
||||
|
||||
public fun getAnnotationsForTarget(target: AnnotationUseSiteTarget): Annotations {
|
||||
val annotations = annotations[target] ?: return Annotations.EMPTY
|
||||
return AnnotationsImpl.create(annotations)
|
||||
}
|
||||
|
||||
public fun getAnnotationsForTargets(vararg targets: AnnotationUseSiteTarget): Annotations {
|
||||
return CompositeAnnotations(targets.map { getAnnotationsForTarget(it) })
|
||||
}
|
||||
|
||||
public companion object {
|
||||
private val TARGET_PRIORITIES = setOf(CONSTRUCTOR_PARAMETER, FIELD, PROPERTY, PROPERTY_SETTER, PROPERTY_GETTER)
|
||||
|
||||
platformStatic
|
||||
public fun create(original: Annotations, parameter: Boolean, hasBackingField: Boolean, isMutable: Boolean): AnnotationSplitter {
|
||||
return AnnotationSplitter(original, with(hashSetOf(PROPERTY, PROPERTY_GETTER)) {
|
||||
if (parameter) add(CONSTRUCTOR_PARAMETER)
|
||||
if (hasBackingField) add(FIELD)
|
||||
if (isMutable) add(PROPERTY_SETTER)
|
||||
this
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -107,7 +107,7 @@ public class LazyJavaClassMemberScope(
|
||||
)
|
||||
|
||||
// default getter is necessary because there is no real field in annotation
|
||||
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor)
|
||||
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, Annotations.EMPTY)
|
||||
propertyDescriptor.initialize(getter, null)
|
||||
|
||||
val returnType = computeMethodReturnType(method, annotations, c.child(propertyDescriptor, method))
|
||||
|
||||
@@ -44,14 +44,21 @@ public class DescriptorFactory {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PropertySetterDescriptorImpl createDefaultSetter(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return createSetter(propertyDescriptor, true);
|
||||
public static PropertySetterDescriptorImpl createDefaultSetter(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull Annotations annotations
|
||||
) {
|
||||
return createSetter(propertyDescriptor, annotations, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PropertySetterDescriptorImpl createSetter(@NotNull PropertyDescriptor propertyDescriptor, boolean isDefault) {
|
||||
public static PropertySetterDescriptorImpl createSetter(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull Annotations annotations,
|
||||
boolean isDefault
|
||||
) {
|
||||
PropertySetterDescriptorImpl setterDescriptor =
|
||||
new PropertySetterDescriptorImpl(propertyDescriptor, Annotations.EMPTY, propertyDescriptor.getModality(),
|
||||
new PropertySetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
|
||||
propertyDescriptor.getVisibility(), !isDefault, isDefault,
|
||||
CallableMemberDescriptor.Kind.DECLARATION, null, SourceElement.NO_SOURCE);
|
||||
setterDescriptor.initializeDefault();
|
||||
@@ -59,13 +66,19 @@ public class DescriptorFactory {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PropertyGetterDescriptorImpl createDefaultGetter(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return createGetter(propertyDescriptor, true);
|
||||
public static PropertyGetterDescriptorImpl createDefaultGetter(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull Annotations annotations
|
||||
) {
|
||||
return createGetter(propertyDescriptor, annotations, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PropertyGetterDescriptorImpl createGetter(@NotNull PropertyDescriptor propertyDescriptor, boolean isDefault) {
|
||||
return new PropertyGetterDescriptorImpl(propertyDescriptor, Annotations.EMPTY, propertyDescriptor.getModality(),
|
||||
public static PropertyGetterDescriptorImpl createGetter(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull Annotations annotations,
|
||||
boolean isDefault) {
|
||||
return new PropertyGetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
|
||||
propertyDescriptor.getVisibility(), !isDefault, isDefault,
|
||||
CallableMemberDescriptor.Kind.DECLARATION, null, SourceElement.NO_SOURCE);
|
||||
}
|
||||
|
||||
+2
-2
@@ -88,7 +88,7 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
||||
)
|
||||
}
|
||||
else {
|
||||
DescriptorFactory.createDefaultGetter(property)
|
||||
DescriptorFactory.createDefaultGetter(property, Annotations.EMPTY)
|
||||
}
|
||||
getter.initialize(property.getReturnType())
|
||||
getter
|
||||
@@ -116,7 +116,7 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
||||
setter
|
||||
}
|
||||
else {
|
||||
DescriptorFactory.createDefaultSetter(property)
|
||||
DescriptorFactory.createDefaultSetter(property, Annotations.EMPTY)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.lang.reflect.Field
|
||||
@@ -50,7 +51,7 @@ interface KPropertyImpl<out R> : KProperty<R>, KCallableImpl<R> {
|
||||
|
||||
override val descriptor: PropertyGetterDescriptor by ReflectProperties.lazySoft {
|
||||
// TODO: default getter created this way won't have any source information
|
||||
property.descriptor.getter ?: DescriptorFactory.createDefaultGetter(property.descriptor)
|
||||
property.descriptor.getter ?: DescriptorFactory.createDefaultGetter(property.descriptor, Annotations.EMPTY)
|
||||
}
|
||||
|
||||
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
|
||||
@@ -72,7 +73,7 @@ interface KMutablePropertyImpl<R> : KMutableProperty<R>, KPropertyImpl<R> {
|
||||
|
||||
override val descriptor: PropertySetterDescriptor by ReflectProperties.lazySoft {
|
||||
// TODO: default setter created this way won't have any source information
|
||||
property.descriptor.setter ?: DescriptorFactory.createDefaultSetter(property.descriptor)
|
||||
property.descriptor.setter ?: DescriptorFactory.createDefaultSetter(property.descriptor, Annotations.EMPTY)
|
||||
}
|
||||
|
||||
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
|
||||
|
||||
Reference in New Issue
Block a user