weird bug with nested closures using outer receiver
This commit is contained in:
@@ -155,7 +155,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor);
|
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor);
|
||||||
answer.addArg(valueDescriptor.getOuterValue());
|
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);
|
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor);
|
||||||
answer.addArg(valueDescriptor.getOuterValue());
|
answer.addArg(valueDescriptor.getOuterValue());
|
||||||
}
|
}
|
||||||
@@ -257,7 +257,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
argCount++;
|
argCount++;
|
||||||
variableDescriptors.add(descriptor);
|
variableDescriptors.add(descriptor);
|
||||||
}
|
}
|
||||||
else if(descriptor instanceof NamedFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||||
argCount++;
|
argCount++;
|
||||||
variableDescriptors.add(descriptor);
|
variableDescriptors.add(descriptor);
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
final Type type = sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
|
final Type type = sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
|
||||||
argTypes[i++] = type;
|
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)));
|
final Type type = Type.getObjectType(state.getTypeMapper().classNameForAnonymousClass((JetElement) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor)));
|
||||||
argTypes[i++] = type;
|
argTypes[i++] = type;
|
||||||
}
|
}
|
||||||
@@ -294,7 +294,6 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
if (cv.generateCode()) {
|
if (cv.generateCode()) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state);
|
|
||||||
|
|
||||||
iv.load(0, Type.getObjectType(funClass));
|
iv.load(0, Type.getObjectType(funClass));
|
||||||
// expressionCodegen.generateTypeInfo(new ProjectionErasingJetType(returnType));
|
// expressionCodegen.generateTypeInfo(new ProjectionErasingJetType(returnType));
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ public abstract class CodegenContext {
|
|||||||
public boolean isStatic() {
|
public boolean isStatic() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ROOT";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
|
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
@@ -73,7 +78,7 @@ public abstract class CodegenContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ClassDescriptor getThisDescriptor ();
|
protected abstract ClassDescriptor getThisDescriptor ();
|
||||||
|
|
||||||
public DeclarationDescriptor getClassOrNamespaceDescriptor() {
|
public DeclarationDescriptor getClassOrNamespaceDescriptor() {
|
||||||
CodegenContext c = this;
|
CodegenContext c = this;
|
||||||
while(true) {
|
while(true) {
|
||||||
@@ -331,6 +336,11 @@ public abstract class CodegenContext {
|
|||||||
protected StackValue getOuterExpression(StackValue prefix) {
|
protected StackValue getOuterExpression(StackValue prefix) {
|
||||||
return getParentContext().getOuterExpression(prefix);
|
return getParentContext().getOuterExpression(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Method: " + getContextDescriptor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ConstructorContext extends MethodContext {
|
public static class ConstructorContext extends MethodContext {
|
||||||
@@ -346,6 +356,11 @@ public abstract class CodegenContext {
|
|||||||
protected StackValue getOuterExpression(StackValue prefix) {
|
protected StackValue getOuterExpression(StackValue prefix) {
|
||||||
return outerExpression;
|
return outerExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Constructor: " + getContextDescriptor().getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ClassContext extends CodegenContext {
|
public static class ClassContext extends CodegenContext {
|
||||||
@@ -388,6 +403,11 @@ public abstract class CodegenContext {
|
|||||||
public boolean isStatic() {
|
public boolean isStatic() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Anonymous: " + getThisDescriptor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ClosureContext extends ReceiverContext {
|
public static class ClosureContext extends ReceiverContext {
|
||||||
@@ -417,6 +437,11 @@ public abstract class CodegenContext {
|
|||||||
public boolean isStatic() {
|
public boolean isStatic() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Closure: " + classDescriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NamespaceContext extends CodegenContext {
|
public static class NamespaceContext extends CodegenContext {
|
||||||
@@ -433,5 +458,10 @@ public abstract class CodegenContext {
|
|||||||
public boolean isStatic() {
|
public boolean isStatic() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Namespace: " + getContextDescriptor().getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import gnu.trove.THashSet;
|
import gnu.trove.THashSet;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassObject;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
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() &&
|
return myClass instanceof JetObjectDeclaration && !((JetObjectDeclaration) myClass).isObjectLiteral() &&
|
||||||
!(myClass.getParent() instanceof JetClassObject);
|
!(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;
|
return innerValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(d instanceof NamedFunctionDescriptor && d.getContainingDeclaration() instanceof FunctionDescriptor) {
|
if(CodegenUtil.isNamedFun(d, state.getBindingContext()) && d.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||||
FunctionDescriptor vd = (FunctionDescriptor) d;
|
FunctionDescriptor vd = (FunctionDescriptor) d;
|
||||||
|
|
||||||
final int idx = exprContext.lookupLocal(vd);
|
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");
|
blackBoxFile("regressions/kt475.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKtNested() throws Exception {
|
||||||
|
createEnvironmentWithFullJdk();
|
||||||
|
blackBoxFile("extensionFunctions/nested.kt");
|
||||||
|
}
|
||||||
|
|
||||||
public void testKt865() throws Exception {
|
public void testKt865() throws Exception {
|
||||||
createEnvironmentWithFullJdk();
|
createEnvironmentWithFullJdk();
|
||||||
blackBoxFile("regressions/kt865.jet");
|
blackBoxFile("regressions/kt865.jet");
|
||||||
|
|||||||
Reference in New Issue
Block a user