More correct way of replacing parameter names to preserve overrides

This commit is contained in:
Valentin Kipyatkov
2016-09-21 19:03:46 +03:00
parent 4513f679de
commit d4050ee074
2 changed files with 25 additions and 16 deletions
@@ -23,14 +23,14 @@ import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
class FunctionInvokeDescriptor private constructor( class FunctionInvokeDescriptor private constructor(
container: DeclarationDescriptor, container: DeclarationDescriptor,
original: FunctionInvokeDescriptor?, original: FunctionInvokeDescriptor?,
callableKind: CallableMemberDescriptor.Kind, callableKind: CallableMemberDescriptor.Kind
private val hasSynthesizedParameterNames: Boolean
) : SimpleFunctionDescriptorImpl( ) : SimpleFunctionDescriptorImpl(
container, container,
original, original,
@@ -41,13 +41,9 @@ class FunctionInvokeDescriptor private constructor(
) { ) {
init { init {
this.isOperator = true this.isOperator = true
this.setHasStableParameterNames(false)
} }
// "p0", "p1", etc. should not be baked into the language
override fun hasStableParameterNames(): Boolean = false
override fun hasSynthesizedParameterNames(): Boolean = hasSynthesizedParameterNames
override fun doSubstitute(configuration: CopyConfiguration): FunctionDescriptor? { override fun doSubstitute(configuration: CopyConfiguration): FunctionDescriptor? {
val substituted = super.doSubstitute(configuration) as FunctionInvokeDescriptor? ?: return null val substituted = super.doSubstitute(configuration) as FunctionInvokeDescriptor? ?: return null
if (substituted.valueParameters.none { it.type.extractParameterNameFromFunctionTypeArgument() != null }) return substituted if (substituted.valueParameters.none { it.type.extractParameterNameFromFunctionTypeArgument() != null }) return substituted
@@ -63,7 +59,7 @@ class FunctionInvokeDescriptor private constructor(
annotations: Annotations, annotations: Annotations,
source: SourceElement source: SourceElement
): FunctionDescriptorImpl { ): FunctionDescriptorImpl {
return FunctionInvokeDescriptor(newOwner, original as FunctionInvokeDescriptor?, kind, hasSynthesizedParameterNames) return FunctionInvokeDescriptor(newOwner, original as FunctionInvokeDescriptor?, kind)
} }
override fun isExternal(): Boolean = false override fun isExternal(): Boolean = false
@@ -72,12 +68,10 @@ class FunctionInvokeDescriptor private constructor(
override fun isTailrec(): Boolean = false override fun isTailrec(): Boolean = false
private fun replaceParameterNames(parameterNames: List<Name?>): FunctionInvokeDescriptor { private fun replaceParameterNames(parameterNames: List<Name?>): FunctionDescriptor {
val indexShift = valueParameters.size - parameterNames.size val indexShift = valueParameters.size - parameterNames.size
assert(indexShift == 0 || indexShift == 1) // indexShift == 1 for extension function type assert(indexShift == 0 || indexShift == 1) // indexShift == 1 for extension function type
val hasSynthesizedParameterNames = parameterNames.any { it == null }
val newDescriptor = FunctionInvokeDescriptor(containingDeclaration, this, kind, hasSynthesizedParameterNames)
val newValueParameters = valueParameters.map { val newValueParameters = valueParameters.map {
var newName = it.name var newName = it.name
val parameterIndex = it.index val parameterIndex = it.index
@@ -88,17 +82,22 @@ class FunctionInvokeDescriptor private constructor(
newName = parameterName newName = parameterName
} }
} }
it.copy(newDescriptor, newName, parameterIndex) it.copy(this, newName, parameterIndex)
} }
newDescriptor.initialize(extensionReceiverParameterType, dispatchReceiverParameter, typeParameters, newValueParameters, returnType, modality, visibility)
return newDescriptor val copyConfiguration = newCopyBuilder(TypeSubstitutor.EMPTY)
.setHasSynthesizedParameterNames(parameterNames.any { it == null })
.setValueParameters(newValueParameters)
.setOriginal(original)
return super.doSubstitute(copyConfiguration)!!
} }
companion object Factory { companion object Factory {
fun create(functionClass: FunctionClassDescriptor): FunctionInvokeDescriptor { fun create(functionClass: FunctionClassDescriptor): FunctionInvokeDescriptor {
val typeParameters = functionClass.declaredTypeParameters val typeParameters = functionClass.declaredTypeParameters
val result = FunctionInvokeDescriptor(functionClass, null, CallableMemberDescriptor.Kind.DECLARATION, hasSynthesizedParameterNames = true) val result = FunctionInvokeDescriptor(functionClass, null, CallableMemberDescriptor.Kind.DECLARATION)
result.initialize( result.initialize(
null, null,
functionClass.thisAsReceiverParameter, functionClass.thisAsReceiverParameter,
@@ -110,6 +109,7 @@ class FunctionInvokeDescriptor private constructor(
Modality.ABSTRACT, Modality.ABSTRACT,
Visibilities.PUBLIC Visibilities.PUBLIC
) )
result.setHasSynthesizedParameterNames(true)
return result return result
} }
@@ -351,6 +351,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
private boolean isHiddenForResolutionEverywhereBesideSupercalls = isHiddenForResolutionEverywhereBesideSupercalls(); private boolean isHiddenForResolutionEverywhereBesideSupercalls = isHiddenForResolutionEverywhereBesideSupercalls();
private SourceElement sourceElement; private SourceElement sourceElement;
private Map<UserDataKey<?>, Object> userDataMap = new LinkedHashMap<UserDataKey<?>, Object>(); private Map<UserDataKey<?>, Object> userDataMap = new LinkedHashMap<UserDataKey<?>, Object>();
private Boolean newHasSynthesizedParameterNames = null;
public CopyConfiguration( public CopyConfiguration(
@NotNull TypeSubstitution substitution, @NotNull TypeSubstitution substitution,
@@ -507,6 +508,11 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
return this; return this;
} }
public CopyConfiguration setHasSynthesizedParameterNames(boolean value) {
this.newHasSynthesizedParameterNames = value;
return this;
}
@NotNull @NotNull
@Override @Override
public CopyConfiguration setSubstitution(@NotNull TypeSubstitution substitution) { public CopyConfiguration setSubstitution(@NotNull TypeSubstitution substitution) {
@@ -626,10 +632,13 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
substitutedDescriptor.setTailrec(isTailrec); substitutedDescriptor.setTailrec(isTailrec);
substitutedDescriptor.setSuspend(isSuspend); substitutedDescriptor.setSuspend(isSuspend);
substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames); substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
substitutedDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames);
substitutedDescriptor.setHiddenToOvercomeSignatureClash(configuration.isHiddenToOvercomeSignatureClash); substitutedDescriptor.setHiddenToOvercomeSignatureClash(configuration.isHiddenToOvercomeSignatureClash);
substitutedDescriptor.setHiddenForResolutionEverywhereBesideSupercalls(configuration.isHiddenForResolutionEverywhereBesideSupercalls); substitutedDescriptor.setHiddenForResolutionEverywhereBesideSupercalls(configuration.isHiddenForResolutionEverywhereBesideSupercalls);
substitutedDescriptor.setHasSynthesizedParameterNames(
configuration.newHasSynthesizedParameterNames != null ? configuration.newHasSynthesizedParameterNames : hasSynthesizedParameterNames
);
if (!configuration.userDataMap.isEmpty() || userDataMap != null) { if (!configuration.userDataMap.isEmpty() || userDataMap != null) {
Map<UserDataKey<?>, Object> newMap = configuration.userDataMap; Map<UserDataKey<?>, Object> newMap = configuration.userDataMap;