Use AnnotationSplitter for annotations on setter parameter
Make it possible to specify annotations of the setter parameter when constructing the default setter via DescriptorFactory; pass the split annotations in DescriptorResolver.resolvePropertySetterDescriptor #KT-25500 Fixed
This commit is contained in:
@@ -533,21 +533,10 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
if (kind == JvmMethodParameterKind.VALUE) {
|
||||
ValueParameterDescriptor parameter = iterator.next();
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper);
|
||||
|
||||
if (functionDescriptor instanceof PropertySetterDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = ((PropertySetterDescriptor) functionDescriptor).getCorrespondingProperty();
|
||||
Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(propertyDescriptor);
|
||||
annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), SETTER_PARAMETER);
|
||||
}
|
||||
|
||||
if (functionDescriptor instanceof ConstructorDescriptor) {
|
||||
annotationCodegen.genAnnotations(parameter, parameterSignature.getAsmType(), CONSTRUCTOR_PARAMETER);
|
||||
}
|
||||
else {
|
||||
annotationCodegen.genAnnotations(parameter, parameterSignature.getAsmType());
|
||||
}
|
||||
AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper).genAnnotations(
|
||||
iterator.next(),
|
||||
parameterSignature.getAsmType()
|
||||
);
|
||||
}
|
||||
else if (kind == JvmMethodParameterKind.RECEIVER) {
|
||||
ReceiverParameterDescriptor receiver = JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter();
|
||||
|
||||
@@ -503,12 +503,18 @@ public class PropertyCodegen {
|
||||
: DescriptorFactory.createDefaultGetter(descriptor, Annotations.Companion.getEMPTY()));
|
||||
}
|
||||
|
||||
public void generateSetter(@Nullable KtNamedDeclaration p, @NotNull PropertyDescriptor descriptor, @Nullable KtPropertyAccessor setter) {
|
||||
public void generateSetter(
|
||||
@Nullable KtNamedDeclaration p,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable KtPropertyAccessor setter
|
||||
) {
|
||||
if (!descriptor.isVar()) return;
|
||||
|
||||
generateAccessor(p, setter, descriptor.getSetter() != null
|
||||
? descriptor.getSetter()
|
||||
: DescriptorFactory.createDefaultSetter(descriptor, Annotations.Companion.getEMPTY()));
|
||||
: DescriptorFactory.createDefaultSetter(
|
||||
descriptor, Annotations.Companion.getEMPTY(), Annotations.Companion.getEMPTY()
|
||||
));
|
||||
}
|
||||
|
||||
private void generateAccessor(
|
||||
|
||||
+4
-1
@@ -76,7 +76,10 @@ class AnnotationSplitter(
|
||||
add(PROPERTY_SETTER)
|
||||
}
|
||||
if (hasBackingField) add(FIELD)
|
||||
if (isVar) add(PROPERTY_SETTER)
|
||||
if (isVar) {
|
||||
add(PROPERTY_SETTER)
|
||||
add(SETTER_PARAMETER)
|
||||
}
|
||||
if (hasDelegate) add(PROPERTY_DELEGATE_FIELD)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +299,8 @@ public class DescriptorResolver {
|
||||
@NotNull KtParameter valueParameter,
|
||||
int index,
|
||||
@NotNull KotlinType type,
|
||||
@NotNull BindingTrace trace
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull Annotations additionalAnnotations
|
||||
) {
|
||||
KotlinType varargElementType = null;
|
||||
KotlinType variableType = type;
|
||||
@@ -308,22 +309,7 @@ public class DescriptorResolver {
|
||||
variableType = getVarargParameterType(type);
|
||||
}
|
||||
|
||||
KtModifierList modifierList = valueParameter.getModifierList();
|
||||
|
||||
Annotations allAnnotations =
|
||||
annotationResolver.resolveAnnotationsWithoutArguments(scope, valueParameter.getModifierList(), trace);
|
||||
Annotations valueParameterAnnotations = Annotations.Companion.getEMPTY();
|
||||
|
||||
if (modifierList != null) {
|
||||
if (valueParameter.hasValOrVar()) {
|
||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(
|
||||
storageManager, allAnnotations, SetsKt.setOf(CONSTRUCTOR_PARAMETER));
|
||||
valueParameterAnnotations = annotationSplitter.getAnnotationsForTarget(CONSTRUCTOR_PARAMETER);
|
||||
}
|
||||
else {
|
||||
valueParameterAnnotations = allAnnotations;
|
||||
}
|
||||
}
|
||||
Annotations valueParameterAnnotations = resolveValueParameterAnnotations(scope, valueParameter, trace, additionalAnnotations);
|
||||
|
||||
KtDestructuringDeclaration destructuringDeclaration = valueParameter.getDestructuringDeclaration();
|
||||
|
||||
@@ -392,6 +378,27 @@ public class DescriptorResolver {
|
||||
return valueParameterDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Annotations resolveValueParameterAnnotations(
|
||||
@NotNull LexicalScope scope,
|
||||
@NotNull KtParameter parameter,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull Annotations additionalAnnotations
|
||||
) {
|
||||
KtModifierList modifierList = parameter.getModifierList();
|
||||
if (modifierList == null) {
|
||||
return additionalAnnotations;
|
||||
}
|
||||
|
||||
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace);
|
||||
if (!parameter.hasValOrVar()) {
|
||||
return new CompositeAnnotations(allAnnotations, additionalAnnotations);
|
||||
}
|
||||
|
||||
AnnotationSplitter splitter = AnnotationSplitter.create(storageManager, allAnnotations, SetsKt.setOf(CONSTRUCTOR_PARAMETER));
|
||||
return new CompositeAnnotations(splitter.getAnnotationsForTarget(CONSTRUCTOR_PARAMETER), additionalAnnotations);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private KotlinType getVarargParameterType(@NotNull KotlinType elementType) {
|
||||
KotlinType primitiveArrayType = builtIns.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(elementType);
|
||||
@@ -1068,8 +1075,10 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
ValueParameterDescriptorImpl valueParameterDescriptor =
|
||||
resolveValueParameterDescriptor(scopeWithTypeParameters, setterDescriptor, parameter, 0, type, trace);
|
||||
ValueParameterDescriptorImpl valueParameterDescriptor = resolveValueParameterDescriptor(
|
||||
scopeWithTypeParameters, setterDescriptor, parameter, 0, type, trace,
|
||||
annotationSplitter.getAnnotationsForTarget(SETTER_PARAMETER)
|
||||
);
|
||||
setterDescriptor.initialize(valueParameterDescriptor);
|
||||
}
|
||||
else {
|
||||
@@ -1079,15 +1088,17 @@ public class DescriptorResolver {
|
||||
trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
|
||||
}
|
||||
else if (property.isVar()) {
|
||||
Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
|
||||
setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, setterAnnotations, !hasDelegate,
|
||||
/* isExternal = */ false, property.hasModifier(KtTokens.INLINE_KEYWORD),
|
||||
propertyDescriptor.getSource());
|
||||
setterDescriptor = DescriptorFactory.createSetter(
|
||||
propertyDescriptor,
|
||||
annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER),
|
||||
annotationSplitter.getAnnotationsForTarget(SETTER_PARAMETER),
|
||||
!hasDelegate, false, property.hasModifier(KtTokens.INLINE_KEYWORD),
|
||||
propertyDescriptor.getSource()
|
||||
);
|
||||
}
|
||||
|
||||
if (!property.isVar()) {
|
||||
if (setter != null) {
|
||||
// trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
|
||||
trace.report(VAL_WITH_SETTER.on(setter));
|
||||
}
|
||||
}
|
||||
@@ -1238,7 +1249,11 @@ public class DescriptorResolver {
|
||||
|
||||
PropertyGetterDescriptorImpl getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, getterAnnotations);
|
||||
PropertySetterDescriptor setter =
|
||||
propertyDescriptor.isVar() ? DescriptorFactory.createDefaultSetter(propertyDescriptor, setterAnnotations) : null;
|
||||
propertyDescriptor.isVar()
|
||||
? DescriptorFactory.createDefaultSetter(
|
||||
propertyDescriptor, setterAnnotations, annotationSplitter.getAnnotationsForTarget(SETTER_PARAMETER)
|
||||
)
|
||||
: null;
|
||||
|
||||
propertyDescriptor.initialize(getter, setter);
|
||||
getter.initialize(propertyDescriptor.getType());
|
||||
|
||||
@@ -438,8 +438,7 @@ class FunctionDescriptorResolver(
|
||||
}
|
||||
|
||||
val valueParameterDescriptor = descriptorResolver.resolveValueParameterDescriptor(
|
||||
parameterScope, functionDescriptor,
|
||||
valueParameter, i, type, trace
|
||||
parameterScope, functionDescriptor, valueParameter, i, type, trace, Annotations.EMPTY
|
||||
)
|
||||
|
||||
// Do not report NAME_SHADOWING for lambda destructured parameters as they may be not fully resolved at this time
|
||||
|
||||
@@ -205,7 +205,7 @@ class LocalVariableResolver(
|
||||
|
||||
var setter = propertyDescriptor.setter
|
||||
if (setter == null && propertyDescriptor.isVar) {
|
||||
setter = DescriptorFactory.createDefaultSetter(propertyDescriptor, Annotations.EMPTY)
|
||||
setter = DescriptorFactory.createDefaultSetter(propertyDescriptor, Annotations.EMPTY, Annotations.EMPTY)
|
||||
}
|
||||
propertyDescriptor.initialize(getter, setter)
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ class DynamicCallableDescriptors(storageManager: StorageManager, builtIns: Kotli
|
||||
|
||||
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, Annotations.EMPTY)
|
||||
getter.initialize(propertyDescriptor.type)
|
||||
val setter = DescriptorFactory.createDefaultSetter(propertyDescriptor, Annotations.EMPTY)
|
||||
val setter = DescriptorFactory.createDefaultSetter(propertyDescriptor, Annotations.EMPTY, Annotations.EMPTY)
|
||||
|
||||
propertyDescriptor.initialize(getter, setter)
|
||||
|
||||
|
||||
+2
-17
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -13,10 +12,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
|
||||
class AnnotationGenerator(
|
||||
context: GeneratorContext
|
||||
) : IrElementVisitorVoid {
|
||||
|
||||
class AnnotationGenerator(context: GeneratorContext) : IrElementVisitorVoid {
|
||||
private val typeTranslator = context.typeTranslator
|
||||
private val constantValueGenerator = context.constantValueGenerator
|
||||
|
||||
@@ -38,16 +34,7 @@ class AnnotationGenerator(
|
||||
override fun visitValueParameter(declaration: IrValueParameter) {
|
||||
super.visitValueParameter(declaration)
|
||||
|
||||
val descriptor = declaration.descriptor
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
|
||||
if (containingDeclaration is PropertySetterDescriptor) {
|
||||
containingDeclaration.correspondingProperty.annotations.getUseSiteTargetedAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.SETTER_PARAMETER }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
descriptor.type.annotations.getAllAnnotations()
|
||||
declaration.descriptor.type.annotations.getAllAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.RECEIVER }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
@@ -81,5 +68,3 @@ class AnnotationGenerator(
|
||||
else -> target == null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -171,7 +171,7 @@ class Delegate {
|
||||
fun test() {
|
||||
check(::delegate.getter, annotationExists = true)
|
||||
check(::delegate.setter, annotationExists = true)
|
||||
check(::delegate.setter.parameters.first(), annotationExists = false) // https://youtrack.jetbrains.com/issue/KT-25500
|
||||
check(::delegate.setter.parameters.first(), annotationExists = true)
|
||||
}
|
||||
|
||||
class CustomDelegate {
|
||||
|
||||
+4
-3
@@ -529,14 +529,15 @@ class LazyJavaClassMemberScope(
|
||||
initialize(propertyDescriptor.type)
|
||||
}
|
||||
|
||||
val setter = setterMethod?.let { setterMethod ->
|
||||
val setter = if (setterMethod != null) {
|
||||
val parameter = setterMethod.valueParameters.firstOrNull() ?: throw AssertionError("No parameter found for $setterMethod")
|
||||
DescriptorFactory.createSetter(
|
||||
propertyDescriptor, setterMethod.annotations, /* isDefault = */false,
|
||||
propertyDescriptor, setterMethod.annotations, parameter.annotations, /* isDefault = */false,
|
||||
/* isExternal = */ false, /* isInline = */ false, setterMethod.visibility, setterMethod.source
|
||||
).apply {
|
||||
initialSignatureDescriptor = setterMethod
|
||||
}
|
||||
}
|
||||
} else null
|
||||
|
||||
return propertyDescriptor.apply { initialize(getter, setter) }
|
||||
}
|
||||
|
||||
+5
-1
@@ -399,7 +399,11 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
// it can not be assigned to because of the projection
|
||||
substitutedDescriptor.setSetterProjectedOut(true);
|
||||
substitutedValueParameters = Collections.<ValueParameterDescriptor>singletonList(
|
||||
PropertySetterDescriptorImpl.createSetterParameter(newSetter, getBuiltIns(copyConfiguration.owner).getNothingType())
|
||||
PropertySetterDescriptorImpl.createSetterParameter(
|
||||
newSetter,
|
||||
getBuiltIns(copyConfiguration.owner).getNothingType(),
|
||||
setter.getValueParameters().get(0).getAnnotations()
|
||||
)
|
||||
);
|
||||
}
|
||||
if (substitutedValueParameters.size() != 1) {
|
||||
|
||||
+4
-4
@@ -58,16 +58,16 @@ public class PropertySetterDescriptorImpl extends PropertyAccessorDescriptorImpl
|
||||
}
|
||||
|
||||
public void initializeDefault() {
|
||||
assert parameter == null;
|
||||
parameter = createSetterParameter(this, getCorrespondingProperty().getReturnType());
|
||||
initialize(createSetterParameter(this, getCorrespondingProperty().getType(), Annotations.Companion.getEMPTY()));
|
||||
}
|
||||
|
||||
public static ValueParameterDescriptorImpl createSetterParameter(
|
||||
@NotNull PropertySetterDescriptor setterDescriptor,
|
||||
@NotNull KotlinType type
|
||||
@NotNull KotlinType type,
|
||||
@NotNull Annotations annotations
|
||||
) {
|
||||
return new ValueParameterDescriptorImpl(
|
||||
setterDescriptor, null, 0, Annotations.Companion.getEMPTY(), Name.special("<set-?>"), type,
|
||||
setterDescriptor, null, 0, annotations, Name.special("<set-?>"), type,
|
||||
/* declaresDefaultValue = */ false,
|
||||
/* isCrossinline = */ false,
|
||||
/* isNoinline = */ false,
|
||||
|
||||
@@ -46,27 +46,33 @@ public class DescriptorFactory {
|
||||
@NotNull
|
||||
public static PropertySetterDescriptorImpl createDefaultSetter(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull Annotations annotations
|
||||
@NotNull Annotations annotations,
|
||||
@NotNull Annotations parameterAnnotations
|
||||
) {
|
||||
return createSetter(propertyDescriptor, annotations, true, false, false, propertyDescriptor.getSource());
|
||||
return createSetter(propertyDescriptor, annotations, parameterAnnotations, true, false, false, propertyDescriptor.getSource());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PropertySetterDescriptorImpl createSetter(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull Annotations annotations,
|
||||
@NotNull Annotations parameterAnnotations,
|
||||
boolean isDefault,
|
||||
boolean isExternal,
|
||||
boolean isInline,
|
||||
@NotNull SourceElement sourceElement
|
||||
) {
|
||||
return createSetter(propertyDescriptor, annotations, isDefault, isExternal, isInline, propertyDescriptor.getVisibility(), sourceElement);
|
||||
return createSetter(
|
||||
propertyDescriptor, annotations, parameterAnnotations, isDefault, isExternal, isInline,
|
||||
propertyDescriptor.getVisibility(), sourceElement
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PropertySetterDescriptorImpl createSetter(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull Annotations annotations,
|
||||
@NotNull Annotations parameterAnnotations,
|
||||
boolean isDefault,
|
||||
boolean isExternal,
|
||||
boolean isInline,
|
||||
@@ -77,7 +83,9 @@ public class DescriptorFactory {
|
||||
propertyDescriptor, annotations, propertyDescriptor.getModality(), visibility, isDefault, isExternal,
|
||||
isInline, CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement
|
||||
);
|
||||
setterDescriptor.initializeDefault();
|
||||
ValueParameterDescriptorImpl parameter =
|
||||
PropertySetterDescriptorImpl.createSetterParameter(setterDescriptor, propertyDescriptor.getType(), parameterAnnotations);
|
||||
setterDescriptor.initialize(parameter);
|
||||
return setterDescriptor;
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -118,7 +118,10 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
setter.initialize(valueParameters.single())
|
||||
setter
|
||||
} else {
|
||||
DescriptorFactory.createDefaultSetter(property, annotations)
|
||||
DescriptorFactory.createDefaultSetter(
|
||||
property, annotations,
|
||||
Annotations.EMPTY /* Otherwise presumably the setter is not default */
|
||||
)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
|
||||
@@ -8,11 +8,10 @@ package kotlin.reflect.jvm.internal
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Modifier
|
||||
@@ -22,7 +21,6 @@ import kotlin.reflect.KMutableProperty
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.full.IllegalPropertyDelegateAccessException
|
||||
import kotlin.reflect.jvm.internal.JvmPropertySignature.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
|
||||
internal abstract class KPropertyImpl<out R> private constructor(
|
||||
override val container: KDeclarationContainerImpl,
|
||||
@@ -159,7 +157,7 @@ internal abstract class KPropertyImpl<out R> private constructor(
|
||||
|
||||
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, Annotations.EMPTY)
|
||||
property.descriptor.setter ?: DescriptorFactory.createDefaultSetter(property.descriptor, Annotations.EMPTY, Annotations.EMPTY)
|
||||
}
|
||||
|
||||
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
|
||||
|
||||
Reference in New Issue
Block a user