Properly reorder arguments in anonymous object super class constructor

#KT-18356 Fixed
This commit is contained in:
Mikhael Bogdanov
2017-09-06 18:03:12 +02:00
parent 44fd8103d4
commit 2fa4c28e0f
13 changed files with 249 additions and 18 deletions
@@ -1072,7 +1072,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
List<ResolvedValueArgument> valueArguments = new ArrayList<>(params);
List<ValueParameterDescriptor> valueParameters = new ArrayList<>(params);
List<Type> mappedTypes = new ArrayList<>(params);
for (ValueParameterDescriptor parameter : superValueParameters) {
for (ValueParameterDescriptor parameter : superCall.getValueArguments().keySet()) {
ResolvedValueArgument argument = superCall.getValueArguments().get(parameter);
if (!(argument instanceof DefaultValueArgument)) {
valueArguments.add(argument);
@@ -16,24 +16,40 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.codegen.AsmUtil.pushDefaultValueOnStack
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
internal class ObjectSuperCallArgumentGenerator(
private val parameters: List<JvmMethodParameterSignature>,
private val iv: InstructionAdapter,
private var offset: Int,
offset: Int,
superConstructorCall: ResolvedCall<ConstructorDescriptor>
) : ArgumentGenerator() {
private val offsets = IntArray(parameters.size) { -1 }
init {
var currentOffset = offset
superConstructorCall.valueArguments.forEach {
(descriptor, argument) ->
if (argument !is DefaultValueArgument) {
val index = descriptor.index
offsets[index] = currentOffset
currentOffset += parameters[index].asmType.size
}
}
}
override fun generate(
valueArgumentsByIndex: List<ResolvedValueArgument>,
actualArgs: List<ResolvedValueArgument>,
calleeDescriptor: CallableDescriptor?
): DefaultCallArgs = super.generate(valueArgumentsByIndex, valueArgumentsByIndex, calleeDescriptor)
public override fun generateExpression(i: Int, argument: ExpressionValueArgument) {
generateSuperCallArgument(i)
}
@@ -49,8 +65,10 @@ internal class ObjectSuperCallArgumentGenerator(
private fun generateSuperCallArgument(i: Int) {
val type = parameters[i].asmType
iv.load(offset, type)
offset += type.size
if (offsets[i] == -1) {
throw AssertionError("Unknown parameter value at index $i with type $type")
}
iv.load(offsets[i], type)
}
override fun reorderArgumentsIfNeeded(args: List<ArgumentAndDeclIndex>) {
@@ -77,6 +77,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
@@ -1420,8 +1421,7 @@ public class KotlinTypeMapper {
boolean hasOuter
) {
ConstructorDescriptor superDescriptor = SamCodegenUtil.resolveSamAdapter(superCall.getResultingDescriptor());
List<ResolvedValueArgument> valueArguments = superCall.getValueArgumentsByIndex();
assert valueArguments != null : "Failed to arrange value arguments by index: " + superDescriptor;
Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = superCall.getValueArguments();
List<JvmMethodParameterSignature> parameters = mapSignatureSkipGeneric(superDescriptor.getOriginal()).getValueParameters();
@@ -1444,10 +1444,11 @@ public class KotlinTypeMapper {
if (isAnonymousObject(descriptor.getContainingDeclaration())) {
// For anonymous objects, also add all real non-default value arguments passed to the super constructor
for (int i = 0; i < args; i++) {
ResolvedValueArgument valueArgument = valueArguments.get(i);
JvmMethodParameterSignature parameter = parameters.get(params - args + i);
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> argumentAndValue : valueArguments.entrySet()) {
ResolvedValueArgument valueArgument = argumentAndValue.getValue();
if (!(valueArgument instanceof DefaultValueArgument)) {
JvmMethodParameterSignature parameter = parameters.get(params - args + argumentAndValue.getKey().getIndex());
writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
}
}