Refactoring: introduce CopyBuilder for CallableMemberDescriptor and PropertyDescriptor.
Allow providing new dispatchReceiverParameter via CopyBuilder (required for proper dispatch receiver for delegates).
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.kotlin.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitution;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -51,4 +53,33 @@ public interface CallableMemberDescriptor extends CallableDescriptor, MemberDesc
|
||||
|
||||
@NotNull
|
||||
CallableMemberDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides);
|
||||
|
||||
@NotNull
|
||||
CopyBuilder<? extends CallableMemberDescriptor> newCopyBuilder();
|
||||
|
||||
interface CopyBuilder<D extends CallableMemberDescriptor> {
|
||||
@NotNull
|
||||
CopyBuilder<D> setOwner(@NotNull DeclarationDescriptor owner);
|
||||
|
||||
@NotNull
|
||||
CopyBuilder<D> setModality(@NotNull Modality modality);
|
||||
|
||||
@NotNull
|
||||
CopyBuilder<D> setVisibility(@NotNull Visibility visibility);
|
||||
|
||||
@NotNull
|
||||
CopyBuilder<D> setKind(@NotNull Kind kind);
|
||||
|
||||
@NotNull
|
||||
CopyBuilder<D> setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter);
|
||||
|
||||
@NotNull
|
||||
CopyBuilder<D> setSubstitution(@NotNull TypeSubstitution substitution);
|
||||
|
||||
@NotNull
|
||||
CopyBuilder<D> setCopyOverrides(boolean copyOverrides);
|
||||
|
||||
@Nullable
|
||||
D build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,22 +86,28 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
|
||||
<V> V getUserData(UserDataKey<V> key);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<? extends FunctionDescriptor> newCopyBuilder();
|
||||
|
||||
interface CopyBuilder<D extends FunctionDescriptor> {
|
||||
interface CopyBuilder<D extends FunctionDescriptor> extends CallableMemberDescriptor.CopyBuilder<D> {
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<D> setOwner(@NotNull DeclarationDescriptor owner);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<D> setModality(@NotNull Modality modality);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<D> setVisibility(@NotNull Visibility visibility);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<D> setKind(@NotNull Kind kind);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<D> setCopyOverrides(boolean copyOverrides);
|
||||
|
||||
@NotNull
|
||||
@@ -120,6 +126,7 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
|
||||
CopyBuilder<D> setExtensionReceiverType(@Nullable KotlinType type);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<D> setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter);
|
||||
|
||||
@NotNull
|
||||
@@ -147,12 +154,14 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
|
||||
CopyBuilder<D> setAdditionalAnnotations(@NotNull Annotations additionalAnnotations);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<D> setSubstitution(@NotNull TypeSubstitution substitution);
|
||||
|
||||
@NotNull
|
||||
<V> CopyBuilder<D> putUserData(@NotNull UserDataKey<V> userDataKey, V value);
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
D build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitution;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -57,4 +58,8 @@ public interface PropertyDescriptor extends VariableDescriptorWithAccessors, Cal
|
||||
PropertyDescriptor substitute(@NotNull TypeSubstitutor substitutor);
|
||||
|
||||
boolean isLateInit();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<? extends PropertyDescriptor> newCopyBuilder();
|
||||
}
|
||||
|
||||
+110
-25
@@ -23,10 +23,7 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory;
|
||||
import org.jetbrains.kotlin.types.DescriptorSubstitutor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
import org.jetbrains.kotlin.types.Variance;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.utils.SmartSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -236,25 +233,106 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
if (originalSubstitutor.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility, getOriginal(), true, getKind());
|
||||
|
||||
return newCopyBuilder()
|
||||
.setSubstitution(originalSubstitutor.getSubstitution())
|
||||
.setOwner(getContainingDeclaration())
|
||||
.setModality(modality)
|
||||
.setVisibility(visibility)
|
||||
.setOriginal(getOriginal())
|
||||
.setCopyOverrides(true)
|
||||
.setKind(getKind())
|
||||
.build();
|
||||
}
|
||||
|
||||
public class CopyConfiguration implements PropertyDescriptor.CopyBuilder<PropertyDescriptor> {
|
||||
private DeclarationDescriptor owner;
|
||||
private Modality modality;
|
||||
private Visibility visibility;
|
||||
private PropertyDescriptor original = null;
|
||||
private Kind kind;
|
||||
private TypeSubstitution substitution = TypeSubstitution.EMPTY;
|
||||
private boolean copyOverrides = true;
|
||||
private ReceiverParameterDescriptor dispatchReceiverParameter = PropertyDescriptorImpl.this.dispatchReceiverParameter;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setOwner(@NotNull DeclarationDescriptor owner) {
|
||||
this.owner = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CopyConfiguration setOriginal(@Nullable PropertyDescriptor original) {
|
||||
this.original = original;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setModality(@NotNull Modality modality) {
|
||||
this.modality = modality;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setVisibility(@NotNull Visibility visibility) {
|
||||
this.visibility = visibility;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setKind(@NotNull Kind kind) {
|
||||
this.kind = kind;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter) {
|
||||
this.dispatchReceiverParameter = dispatchReceiverParameter;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setSubstitution(@NotNull TypeSubstitution substitution) {
|
||||
this.substitution = substitution;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setCopyOverrides(boolean copyOverrides) {
|
||||
this.copyOverrides = copyOverrides;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PropertyDescriptor build() {
|
||||
return doSubstitute(this);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration newCopyBuilder() {
|
||||
return new CopyConfiguration();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected PropertyDescriptor doSubstitute(
|
||||
@NotNull TypeSubstitutor originalSubstitutor,
|
||||
@NotNull DeclarationDescriptor newOwner,
|
||||
@NotNull Modality newModality,
|
||||
@NotNull Visibility newVisibility,
|
||||
@Nullable PropertyDescriptor original,
|
||||
boolean copyOverrides,
|
||||
@NotNull Kind kind
|
||||
) {
|
||||
PropertyDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, newModality, newVisibility, original, kind);
|
||||
protected PropertyDescriptor doSubstitute(@NotNull CopyConfiguration copyConfiguration) {
|
||||
PropertyDescriptorImpl substitutedDescriptor = createSubstitutedCopy(
|
||||
copyConfiguration.owner, copyConfiguration.modality, copyConfiguration.visibility,
|
||||
copyConfiguration.original, copyConfiguration.kind);
|
||||
|
||||
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
|
||||
List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
|
||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
|
||||
originalTypeParameters, originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
|
||||
originalTypeParameters, copyConfiguration.substitution, substitutedDescriptor, substitutedTypeParameters
|
||||
);
|
||||
|
||||
KotlinType originalOutType = getType();
|
||||
@@ -263,9 +341,8 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
return null; // TODO : tell the user that the property was projected out
|
||||
}
|
||||
|
||||
|
||||
ReceiverParameterDescriptor substitutedDispatchReceiver;
|
||||
ReceiverParameterDescriptor dispatchReceiver = getDispatchReceiverParameter();
|
||||
ReceiverParameterDescriptor dispatchReceiver = copyConfiguration.dispatchReceiverParameter;
|
||||
if (dispatchReceiver != null) {
|
||||
substitutedDispatchReceiver = dispatchReceiver.substitute(substitutor);
|
||||
if (substitutedDispatchReceiver == null) return null;
|
||||
@@ -286,8 +363,8 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
substitutedDescriptor.setType(outType, substitutedTypeParameters, substitutedDispatchReceiver, substitutedReceiverType);
|
||||
|
||||
PropertyGetterDescriptorImpl newGetter = getter == null ? null : new PropertyGetterDescriptorImpl(
|
||||
substitutedDescriptor, getter.getAnnotations(), newModality, normalizeVisibility(getter.getVisibility(), kind),
|
||||
getter.isDefault(), getter.isExternal(), getter.isInline(), kind, original == null ? null : original.getGetter(),
|
||||
substitutedDescriptor, getter.getAnnotations(), copyConfiguration.modality, normalizeVisibility(getter.getVisibility(), copyConfiguration.kind),
|
||||
getter.isDefault(), getter.isExternal(), getter.isInline(), copyConfiguration.kind, copyConfiguration.original == null ? null : copyConfiguration.original.getGetter(),
|
||||
SourceElement.NO_SOURCE
|
||||
);
|
||||
if (newGetter != null) {
|
||||
@@ -296,8 +373,8 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
newGetter.initialize(returnType != null ? substitutor.substitute(returnType, Variance.OUT_VARIANCE) : null);
|
||||
}
|
||||
PropertySetterDescriptorImpl newSetter = setter == null ? null : new PropertySetterDescriptorImpl(
|
||||
substitutedDescriptor, setter.getAnnotations(), newModality, normalizeVisibility(setter.getVisibility(), kind),
|
||||
setter.isDefault(), setter.isExternal(), setter.isInline(), kind, original == null ? null : original.getSetter(),
|
||||
substitutedDescriptor, setter.getAnnotations(), copyConfiguration.modality, normalizeVisibility(setter.getVisibility(), copyConfiguration.kind),
|
||||
setter.isDefault(), setter.isExternal(), setter.isInline(), copyConfiguration.kind, copyConfiguration.original == null ? null : copyConfiguration.original.getSetter(),
|
||||
SourceElement.NO_SOURCE
|
||||
);
|
||||
if (newSetter != null) {
|
||||
@@ -313,7 +390,7 @@ 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(newOwner).getNothingType())
|
||||
PropertySetterDescriptorImpl.createSetterParameter(newSetter, getBuiltIns(copyConfiguration.owner).getNothingType())
|
||||
);
|
||||
}
|
||||
if (substitutedValueParameters.size() != 1) {
|
||||
@@ -325,7 +402,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
|
||||
substitutedDescriptor.initialize(newGetter, newSetter);
|
||||
|
||||
if (copyOverrides) {
|
||||
if (copyConfiguration.copyOverrides) {
|
||||
Collection<CallableMemberDescriptor> overridden = SmartSet.create();
|
||||
for (PropertyDescriptor propertyDescriptor : getOverriddenDescriptors()) {
|
||||
overridden.add(propertyDescriptor.substitute(substitutor));
|
||||
@@ -412,6 +489,14 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertyDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides) {
|
||||
return doSubstitute(TypeSubstitutor.EMPTY, newOwner, modality, visibility, null, copyOverrides, kind);
|
||||
//noinspection ConstantConditions
|
||||
return newCopyBuilder()
|
||||
.setOwner(newOwner)
|
||||
.setOriginal(null)
|
||||
.setModality(modality)
|
||||
.setVisibility(visibility)
|
||||
.setKind(kind)
|
||||
.setCopyOverrides(copyOverrides)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user