KT-4118 Closures mix makes code fail on runtime

#KT-4118 Fixed
This commit is contained in:
Mikhael Bogdanov
2013-11-11 11:57:43 +04:00
parent 5e2e6e557d
commit 1795b2a0bc
9 changed files with 124 additions and 20 deletions
@@ -309,9 +309,9 @@ public class AsmUtil {
null);
}
ClassifierDescriptor captureReceiver = closure.getCaptureReceiver();
if (captureReceiver != null) {
v.newField(null, access, CAPTURED_RECEIVER_FIELD, typeMapper.mapType(captureReceiver).getDescriptor(),
JetType captureReceiverType = closure.getCaptureReceiverType();
if (captureReceiverType != null) {
v.newField(null, access, CAPTURED_RECEIVER_FIELD, typeMapper.mapType(captureReceiverType).getDescriptor(),
null, null);
}
@@ -249,9 +249,9 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
Type type = typeMapper.mapType(captureThis);
args.add(FieldInfo.createForHiddenField(ownerType, type, CAPTURED_THIS_FIELD));
}
ClassifierDescriptor captureReceiver = closure.getCaptureReceiver();
if (captureReceiver != null) {
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiver), CAPTURED_RECEIVER_FIELD));
JetType captureReceiverType = closure.getCaptureReceiverType();
if (captureReceiverType != null) {
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiverType), CAPTURED_RECEIVER_FIELD));
}
for (DeclarationDescriptor descriptor : closure.getCaptureVariables().keySet()) {
@@ -268,7 +268,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
args.add(FieldInfo.createForHiddenField(ownerType, classType, "$" + descriptor.getName().asString()));
}
else if (descriptor instanceof FunctionDescriptor) {
assert captureReceiver != null;
assert captureReceiverType != null;
}
}
return args;
@@ -129,7 +129,7 @@ public class CodegenUtil {
}
public static boolean isConst(CalculatedClosure closure) {
return closure.getCaptureThis() == null && closure.getCaptureReceiver() == null && closure.getCaptureVariables().isEmpty();
return closure.getCaptureThis() == null && closure.getCaptureReceiverType() == null && closure.getCaptureVariables().isEmpty();
}
public static <T> T peekFromStack(Stack<T> stack) {
@@ -1374,9 +1374,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
generateThisOrOuter(captureThis, false).put(OBJECT_TYPE, v);
}
ClassifierDescriptor captureReceiver = closure.getCaptureReceiver();
JetType captureReceiver = closure.getCaptureReceiverType();
if (captureReceiver != null) {
v.load(context.isStatic() ? 0 : 1, typeMapper.mapClass(captureReceiver));
v.load(context.isStatic() ? 0 : 1, typeMapper.mapType(captureReceiver));
}
}
@@ -22,9 +22,9 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.types.JetType;
import java.util.List;
import java.util.Map;
@@ -41,7 +41,7 @@ public interface CalculatedClosure {
ClassDescriptor getCaptureThis();
@Nullable
ClassifierDescriptor getCaptureReceiver();
JetType getCaptureReceiverType();
@NotNull
Map<DeclarationDescriptor, EnclosedValueDescriptor> getCaptureVariables();
@@ -23,9 +23,10 @@ import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.types.JetType;
import java.util.*;
@@ -72,10 +73,14 @@ public final class MutableClosure implements CalculatedClosure {
}
@Override
public ClassifierDescriptor getCaptureReceiver() {
return captureReceiver
? enclosingReceiverDescriptor.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor()
: null;
public JetType getCaptureReceiverType() {
if (captureReceiver) {
ReceiverParameterDescriptor parameter = enclosingReceiverDescriptor.getReceiverParameter();
assert parameter != null : "Receiver parameter should exist in " + enclosingReceiverDescriptor;
return parameter.getType();
}
return null;
}
public void setCaptureReceiver() {
@@ -812,10 +812,10 @@ public class JetTypeMapper extends BindingTraceAware {
signatureWriter.writeParameterTypeEnd();
}
ClassifierDescriptor captureReceiver = closure != null ? closure.getCaptureReceiver() : null;
if (captureReceiver != null) {
JetType captureReceiverType = closure != null ? closure.getCaptureReceiverType() : null;
if (captureReceiverType != null) {
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
mapType(captureReceiver.getDefaultType(), signatureWriter, JetTypeMapperMode.VALUE);
mapType(captureReceiverType, signatureWriter, JetTypeMapperMode.VALUE);
signatureWriter.writeParameterTypeEnd();
}