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