Use target priorities to split annotations to different descriptors

This commit is contained in:
Yan Zhulanow
2015-08-07 03:26:19 +03:00
parent 9838f9c942
commit 3624c4e5dc
8 changed files with 318 additions and 93 deletions
@@ -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
})
}
}
}
@@ -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);
}
@@ -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 {