From c92f118e5e2f4050f02490927f6c52e269c335ac Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 1 Mar 2017 15:32:57 +0300 Subject: [PATCH] Refactoring: introduce CopyBuilder for CallableMemberDescriptor and PropertyDescriptor. Allow providing new dispatchReceiverParameter via CopyBuilder (required for proper dispatch receiver for delegates). --- .../descriptors/CallableMemberDescriptor.java | 31 ++++ .../descriptors/FunctionDescriptor.java | 11 +- .../descriptors/PropertyDescriptor.java | 5 + .../impl/PropertyDescriptorImpl.java | 135 ++++++++++++++---- 4 files changed, 156 insertions(+), 26 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/CallableMemberDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/CallableMemberDescriptor.java index 999f3e9f5f5..28f0544f976 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/CallableMemberDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/CallableMemberDescriptor.java @@ -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 newCopyBuilder(); + + interface CopyBuilder { + @NotNull + CopyBuilder setOwner(@NotNull DeclarationDescriptor owner); + + @NotNull + CopyBuilder setModality(@NotNull Modality modality); + + @NotNull + CopyBuilder setVisibility(@NotNull Visibility visibility); + + @NotNull + CopyBuilder setKind(@NotNull Kind kind); + + @NotNull + CopyBuilder setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter); + + @NotNull + CopyBuilder setSubstitution(@NotNull TypeSubstitution substitution); + + @NotNull + CopyBuilder setCopyOverrides(boolean copyOverrides); + + @Nullable + D build(); + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/FunctionDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/FunctionDescriptor.java index 75bbda81cf6..57d7da55171 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/FunctionDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/FunctionDescriptor.java @@ -86,22 +86,28 @@ public interface FunctionDescriptor extends CallableMemberDescriptor { V getUserData(UserDataKey key); @NotNull + @Override CopyBuilder newCopyBuilder(); - interface CopyBuilder { + interface CopyBuilder extends CallableMemberDescriptor.CopyBuilder { @NotNull + @Override CopyBuilder setOwner(@NotNull DeclarationDescriptor owner); @NotNull + @Override CopyBuilder setModality(@NotNull Modality modality); @NotNull + @Override CopyBuilder setVisibility(@NotNull Visibility visibility); @NotNull + @Override CopyBuilder setKind(@NotNull Kind kind); @NotNull + @Override CopyBuilder setCopyOverrides(boolean copyOverrides); @NotNull @@ -120,6 +126,7 @@ public interface FunctionDescriptor extends CallableMemberDescriptor { CopyBuilder setExtensionReceiverType(@Nullable KotlinType type); @NotNull + @Override CopyBuilder setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter); @NotNull @@ -147,12 +154,14 @@ public interface FunctionDescriptor extends CallableMemberDescriptor { CopyBuilder setAdditionalAnnotations(@NotNull Annotations additionalAnnotations); @NotNull + @Override CopyBuilder setSubstitution(@NotNull TypeSubstitution substitution); @NotNull CopyBuilder putUserData(@NotNull UserDataKey userDataKey, V value); @Nullable + @Override D build(); } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/PropertyDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/PropertyDescriptor.java index 1162bfa6e5e..2e967804b0f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/PropertyDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/PropertyDescriptor.java @@ -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 newCopyBuilder(); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java index 24e7fd8ca96..04d4a5bf2b2 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java @@ -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 { + 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 originalTypeParameters = getTypeParameters(); List substitutedTypeParameters = new ArrayList(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.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 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(); } }