weird bug with nested closures using outer receiver

This commit is contained in:
Alex Tkachman
2012-02-20 12:14:39 +02:00
parent 046c13a264
commit 436c298e47
6 changed files with 73 additions and 10 deletions
@@ -155,7 +155,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor);
answer.addArg(valueDescriptor.getOuterValue());
}
else if(descriptor instanceof NamedFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor);
answer.addArg(valueDescriptor.getOuterValue());
}
@@ -257,7 +257,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
argCount++;
variableDescriptors.add(descriptor);
}
else if(descriptor instanceof NamedFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
argCount++;
variableDescriptors.add(descriptor);
}
@@ -283,7 +283,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
final Type type = sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
argTypes[i++] = type;
}
else if(descriptor instanceof NamedFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
final Type type = Type.getObjectType(state.getTypeMapper().classNameForAnonymousClass((JetElement) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor)));
argTypes[i++] = type;
}
@@ -294,7 +294,6 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
if (cv.generateCode()) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state);
iv.load(0, Type.getObjectType(funClass));
// expressionCodegen.generateTypeInfo(new ProjectionErasingJetType(returnType));
@@ -44,6 +44,11 @@ public abstract class CodegenContext {
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "ROOT";
}
};
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
@@ -73,7 +78,7 @@ public abstract class CodegenContext {
}
protected abstract ClassDescriptor getThisDescriptor ();
public DeclarationDescriptor getClassOrNamespaceDescriptor() {
CodegenContext c = this;
while(true) {
@@ -331,6 +336,11 @@ public abstract class CodegenContext {
protected StackValue getOuterExpression(StackValue prefix) {
return getParentContext().getOuterExpression(prefix);
}
@Override
public String toString() {
return "Method: " + getContextDescriptor();
}
}
public static class ConstructorContext extends MethodContext {
@@ -346,6 +356,11 @@ public abstract class CodegenContext {
protected StackValue getOuterExpression(StackValue prefix) {
return outerExpression;
}
@Override
public String toString() {
return "Constructor: " + getContextDescriptor().getName();
}
}
public static class ClassContext extends CodegenContext {
@@ -388,6 +403,11 @@ public abstract class CodegenContext {
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Anonymous: " + getThisDescriptor();
}
}
public static class ClosureContext extends ReceiverContext {
@@ -417,6 +437,11 @@ public abstract class CodegenContext {
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Closure: " + classDescriptor;
}
}
public static class NamespaceContext extends CodegenContext {
@@ -433,5 +458,10 @@ public abstract class CodegenContext {
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "Namespace: " + getContextDescriptor().getName();
}
}
}
@@ -16,12 +16,12 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import gnu.trove.THashSet;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetClassObject;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
@@ -144,9 +144,17 @@ public class CodegenUtil {
}
}
static boolean isNonLiteralObject(JetClassOrObject myClass) {
public static boolean isNonLiteralObject(JetClassOrObject myClass) {
return myClass instanceof JetObjectDeclaration && !((JetObjectDeclaration) myClass).isObjectLiteral() &&
!(myClass.getParent() instanceof JetClassObject);
}
public static boolean isNamedFun(DeclarationDescriptor fd, BindingContext bindingContext) {
PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, fd);
if(psiElement instanceof JetNamedFunction) {
return true;
}
return false;
}
}
@@ -76,7 +76,7 @@ public class ObjectOrClosureCodegen {
return innerValue;
}
if(d instanceof NamedFunctionDescriptor && d.getContainingDeclaration() instanceof FunctionDescriptor) {
if(CodegenUtil.isNamedFun(d, state.getBindingContext()) && d.getContainingDeclaration() instanceof FunctionDescriptor) {
FunctionDescriptor vd = (FunctionDescriptor) d;
final int idx = exprContext.lookupLocal(vd);
@@ -0,0 +1,21 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
fun <T> Int.latch(op: CountDownLatch.() -> T) : T {
val cdl = CountDownLatch(this)
val res = cdl.op()
cdl.await()
return res
}
fun id(op : ()->Unit) = op()
fun box() : String {
1.latch{
id {
countDown()
}
}
return "OK"
}
@@ -55,6 +55,11 @@ public class ExtensionFunctionsTest extends CodegenTestCase {
blackBoxFile("regressions/kt475.jet");
}
public void testKtNested() throws Exception {
createEnvironmentWithFullJdk();
blackBoxFile("extensionFunctions/nested.kt");
}
public void testKt865() throws Exception {
createEnvironmentWithFullJdk();
blackBoxFile("regressions/kt865.jet");