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:
Alexander Udalov
2018-08-07 20:10:30 +02:00
parent 779d9aafe7
commit 823a24e0a3
15 changed files with 93 additions and 82 deletions
@@ -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)