Refine signature calculation for methods with default parameters
The problem was that he number of mask parameters for defaults when generating methods declaration was being calculated upon resulting signature (with additional parameters: extension receivers, enum name/ordinal), while on call-sites the masks number was calculated by the arguments number in resolved call, i.e. by the number of real value parameters. And because of the additional synthetic parameters (like enum.ordinal) these two numbers could be different. The solution is just to use value parameters number in both places. Note, that we only count value parameters from the original sourse declaration, ignoring synthetic ones generated by backend (e.g. Continuation for suspend functions) #KT-14565 Fixed
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
@@ -31,7 +32,12 @@ abstract class ArgumentGenerator {
|
||||
*
|
||||
* @see kotlin.reflect.jvm.internal.KCallableImpl.callBy
|
||||
*/
|
||||
open fun generate(valueArgumentsByIndex: List<ResolvedValueArgument>, actualArgs: List<ResolvedValueArgument>): DefaultCallArgs {
|
||||
open fun generate(
|
||||
valueArgumentsByIndex: List<ResolvedValueArgument>,
|
||||
actualArgs: List<ResolvedValueArgument>,
|
||||
// may be null for a constructor of an object literal
|
||||
calleeDescriptor: CallableDescriptor?
|
||||
): DefaultCallArgs {
|
||||
assert(valueArgumentsByIndex.size == actualArgs.size) {
|
||||
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size} != ${actualArgs.size}"
|
||||
}
|
||||
@@ -48,7 +54,8 @@ abstract class ArgumentGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
val defaultArgs = DefaultCallArgs(valueArgumentsByIndex.size)
|
||||
// Use unwrapped version, because additional synthetic parameters can't have default values
|
||||
val defaultArgs = DefaultCallArgs(calleeDescriptor?.unwrapFrontendVersion()?.valueParameters?.size ?: 0)
|
||||
|
||||
for (argumentWithDeclIndex in actualArgsWithDeclIndex) {
|
||||
val argument = argumentWithDeclIndex.arg
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.ValueArgument;
|
||||
@@ -54,11 +56,12 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
||||
@Override
|
||||
public DefaultCallArgs generate(
|
||||
@NotNull List<? extends ResolvedValueArgument> valueArgumentsByIndex,
|
||||
@NotNull List<? extends ResolvedValueArgument> valueArgs
|
||||
@NotNull List<? extends ResolvedValueArgument> valueArgs,
|
||||
@Nullable CallableDescriptor calleeDescriptor
|
||||
) {
|
||||
boolean shouldMarkLineNumbers = this.codegen.isShouldMarkLineNumbers();
|
||||
this.codegen.setShouldMarkLineNumbers(false);
|
||||
DefaultCallArgs defaultArgs = super.generate(valueArgumentsByIndex, valueArgs);
|
||||
DefaultCallArgs defaultArgs = super.generate(valueArgumentsByIndex, valueArgs, calleeDescriptor);
|
||||
this.codegen.setShouldMarkLineNumbers(shouldMarkLineNumbers);
|
||||
return defaultArgs;
|
||||
}
|
||||
|
||||
@@ -1709,7 +1709,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
ArgumentGenerator argumentGenerator =
|
||||
new CallBasedArgumentGenerator(ExpressionCodegen.this, defaultCallGenerator, valueParameters, mappedTypes);
|
||||
|
||||
argumentGenerator.generate(valueArguments, valueArguments);
|
||||
argumentGenerator.generate(valueArguments, valueArguments, null);
|
||||
}
|
||||
|
||||
Collection<ClassConstructorDescriptor> constructors = classDescriptor.getConstructors();
|
||||
@@ -2867,7 +2867,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
assert valueArguments != null : "Failed to arrange value arguments by index: " + resolvedCall.getResultingDescriptor();
|
||||
|
||||
DefaultCallArgs defaultArgs =
|
||||
argumentGenerator.generate(valueArguments, new ArrayList<ResolvedValueArgument>(resolvedCall.getValueArguments().values()));
|
||||
argumentGenerator.generate(
|
||||
valueArguments,
|
||||
new ArrayList<ResolvedValueArgument>(resolvedCall.getValueArguments().values()),
|
||||
resolvedCall.getResultingDescriptor()
|
||||
);
|
||||
|
||||
if (tailRecursionCodegen.isTailRecursion(resolvedCall)) {
|
||||
tailRecursionCodegen.generateTailRecursion(resolvedCall);
|
||||
|
||||
@@ -883,7 +883,7 @@ public abstract class StackValue {
|
||||
newReceiver.put(newReceiver.type, v);
|
||||
callGenerator.processAndPutHiddenParameters(false);
|
||||
|
||||
defaultArgs = generator.generate(valueArguments, valueArguments);
|
||||
defaultArgs = generator.generate(valueArguments, valueArguments, call.getResultingDescriptor());
|
||||
}
|
||||
|
||||
private ArgumentGenerator createArgumentGenerator() {
|
||||
|
||||
@@ -1154,13 +1154,13 @@ public class KotlinTypeMapper {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getDefaultDescriptor(@NotNull Method method, @Nullable String dispatchReceiverDescriptor, boolean isExtension) {
|
||||
private static String getDefaultDescriptor(
|
||||
@NotNull Method method,
|
||||
@Nullable String dispatchReceiverDescriptor,
|
||||
@NotNull CallableDescriptor callableDescriptor
|
||||
) {
|
||||
String descriptor = method.getDescriptor();
|
||||
int argumentsCount = Type.getArgumentTypes(descriptor).length;
|
||||
if (isExtension) {
|
||||
argumentsCount--;
|
||||
}
|
||||
int maskArgumentsCount = (argumentsCount + Integer.SIZE - 1) / Integer.SIZE;
|
||||
int maskArgumentsCount = (callableDescriptor.getValueParameters().size() + Integer.SIZE - 1) / Integer.SIZE;
|
||||
String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount);
|
||||
additionalArgs += (isConstructor(method) ? DEFAULT_CONSTRUCTOR_MARKER : OBJECT_TYPE).getDescriptor();
|
||||
String result = descriptor.replace(")", additionalArgs + ")");
|
||||
@@ -1186,7 +1186,7 @@ public class KotlinTypeMapper {
|
||||
String descriptor = getDefaultDescriptor(
|
||||
jvmSignature,
|
||||
isStaticMethod(kind, functionDescriptor) || isConstructor ? null : ownerType.getDescriptor(),
|
||||
functionDescriptor.getExtensionReceiverParameter() != null
|
||||
CodegenUtilKt.unwrapFrontendVersion(functionDescriptor)
|
||||
);
|
||||
|
||||
return new Method(isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor);
|
||||
|
||||
Reference in New Issue
Block a user