Issue related to KT-1962

Correctly reference this object in wrapped function literal
This commit is contained in:
pTalanov
2012-05-16 19:30:23 +04:00
parent 31a1aefeb5
commit ce896f931a
5 changed files with 53 additions and 16 deletions
@@ -31,8 +31,11 @@ public final class ClosureTest extends SingleFileTranslationTest {
fooBoxTest();
}
public void testLocalParameterInCallback() throws Exception {
fooBoxTest();
}
public void testClosureReferencingMember() throws Exception {
fooBoxTest();
}
}
@@ -31,10 +31,13 @@ public final class TemporaryVariable {
private final JsExpression assignmentExpression;
@NotNull
private final JsName variableName;
@NotNull
private final JsExpression initExpression;
/*package*/ TemporaryVariable(@NotNull JsName temporaryName, @NotNull JsExpression initExpression) {
this.variableName = temporaryName;
this.assignmentExpression = AstUtil.newAssignment(variableName.makeRef(), initExpression);
this.initExpression = initExpression;
this.assignmentExpression = AstUtil.newAssignment(variableName.makeRef(), this.initExpression);
}
@NotNull
@@ -51,4 +54,9 @@ public final class TemporaryVariable {
public JsExpression assignmentExpression() {
return assignmentExpression;
}
@NotNull
public JsExpression initExpression() {
return initExpression;
}
}
@@ -40,9 +40,9 @@ import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setParameters;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
/**
@@ -52,7 +52,7 @@ public final class FunctionTranslator extends AbstractTranslator {
@NotNull
public static FunctionTranslator newInstance(@NotNull JetDeclarationWithBody function,
@NotNull TranslationContext context) {
@NotNull TranslationContext context) {
return new FunctionTranslator(function, context);
}
@@ -73,7 +73,7 @@ public final class FunctionTranslator extends AbstractTranslator {
private final JsBlock functionBody;
private FunctionTranslator(@NotNull JetDeclarationWithBody functionDeclaration,
@NotNull TranslationContext context) {
@NotNull TranslationContext context) {
super(context);
this.descriptor = getFunctionDescriptor(context.bindingContext(), functionDeclaration);
this.functionDeclaration = functionDeclaration;
@@ -140,7 +140,11 @@ public final class FunctionTranslator extends AbstractTranslator {
public JsExpression translateAsLiteral() {
assert getExpectedThisDescriptor(descriptor) == null;
generateFunctionObject();
return mayBeWrapInClosureCaptureExpression(mayBeWrapWithThisAlias());
ClosureContext closureContext = ClosureUtils.captureClosure(context(), (JetElement) functionDeclaration);
if (closureContext.getDescriptors().isEmpty()) {
return mayBeWrapWithThisAlias();
}
return wrapInClosureCaptureExpression(functionObject, closureContext);
}
@NotNull
@@ -160,23 +164,18 @@ public final class FunctionTranslator extends AbstractTranslator {
return containingClass != null;
}
@NotNull
private JsExpression mayBeWrapInClosureCaptureExpression(@NotNull JsExpression wrappedExpression) {
ClosureContext closureContext = ClosureUtils.captureClosure(context(), (JetElement)functionDeclaration);
if (closureContext.getDescriptors().isEmpty()) {
return wrappedExpression;
}
return wrapInClosureCaptureExpression(wrappedExpression, closureContext);
}
@NotNull
private JsExpression wrapInClosureCaptureExpression(@NotNull JsExpression wrappedExpression,
@NotNull ClosureContext closureContext) {
@NotNull ClosureContext closureContext) {
JsFunction dummyFunction = new JsFunction(context().jsScope());
JsInvocation dummyFunctionInvocation = AstUtil.newInvocation(dummyFunction);
for (VariableDescriptor variableDescriptor : closureContext.getDescriptors()) {
dummyFunction.getParameters().add(new JsParameter(context().getNameForDescriptor(variableDescriptor)));
dummyFunctionInvocation.getArguments().add(ReferenceTranslator.translateAsLocalNameReference(variableDescriptor, context()));
if (aliasForContainingClassThis != null) {
dummyFunction.getParameters().add(new JsParameter(aliasForContainingClassThis.name()));
dummyFunctionInvocation.getArguments().add(aliasForContainingClassThis.initExpression());
}
}
dummyFunction.setBody(AstUtil.newBlock(new JsReturn(wrappedExpression)));
return dummyFunctionInvocation;
@@ -56,6 +56,7 @@ public class CaptureClosureVisitor extends JetTreeVisitor<ClosureContext> {
if (!(descriptor instanceof VariableDescriptor)) {
return null;
}
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
PsiElement variableDeclaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
if (variableDeclaration == null) {
@@ -69,6 +70,8 @@ public class CaptureClosureVisitor extends JetTreeVisitor<ClosureContext> {
context.put(variableDescriptor);
return null;
}
boolean isLoopParameter = variableDeclaration.getNode().getElementType().equals(JetNodeTypes.LOOP_PARAMETER);
if (isLoopParameter) {
context.put(variableDescriptor);
@@ -0,0 +1,24 @@
package foo
class A() {
var i = 0
fun f() {
for (j in 0..2) {
foo {
i += j
}
}
}
}
fun foo(f : ()->Unit) {
f()
}
fun box() : Boolean {
val a = A()
a.f()
return a.i == 3
}