diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClosureTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClosureTest.java index e3380fc94c4..e339c280616 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClosureTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ClosureTest.java @@ -30,4 +30,9 @@ public final class ClosureTest extends SingleFileTranslationTest { public void testIteratingCallbacks() throws Exception { fooBoxTest(); } + + + public void testLocalParameterInCallback() throws Exception { + fooBoxTest(); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/closure/CaptureClosureVisitor.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/closure/CaptureClosureVisitor.java index e018b57297a..021417724f8 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/closure/CaptureClosureVisitor.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/closure/CaptureClosureVisitor.java @@ -21,8 +21,10 @@ import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.psi.JetTreeVisitor; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -48,6 +50,7 @@ public class CaptureClosureVisitor extends JetTreeVisitor { @Override public Void visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, @NotNull ClosureContext context) { + //TODO: this gets as dirty as it can be, should clean up and test more or use different approach expression.acceptChildren(this, context); DeclarationDescriptor descriptor = BindingUtils.getNullableDescriptorForReferenceExpression(bindingContext, expression); if (!(descriptor instanceof VariableDescriptor)) { @@ -61,6 +64,11 @@ public class CaptureClosureVisitor extends JetTreeVisitor { if (PsiTreeUtil.isAncestor(functionElement, variableDeclaration, false)) { return null; } + boolean isProperty = variableDescriptor instanceof PropertyDescriptor; + if (!isProperty && !variableDescriptor.isVar() && variableDeclaration instanceof JetProperty) { + context.put(variableDescriptor); + return null; + } boolean isLoopParameter = variableDeclaration.getNode().getElementType().equals(JetNodeTypes.LOOP_PARAMETER); if (isLoopParameter) { context.put(variableDescriptor); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/closure/ClosureContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/closure/ClosureContext.java index e2fec87d2d9..f6761904b17 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/closure/ClosureContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/closure/ClosureContext.java @@ -17,10 +17,13 @@ package org.jetbrains.k2js.translate.utils.closure; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import java.util.Collection; import java.util.List; +import java.util.Set; /** * @author Pavel Talanov @@ -28,14 +31,14 @@ import java.util.List; public final class ClosureContext { @NotNull - private List descriptors = Lists.newArrayList(); + private Set descriptors = Sets.newHashSet(); /*package*/ void put(@NotNull VariableDescriptor descriptor) { descriptors.add(descriptor); } @NotNull - public List getDescriptors() { + public Collection getDescriptors() { return descriptors; } } diff --git a/js/js.translator/testFiles/closure/cases/iteratingCallbacks.kt b/js/js.translator/testFiles/closure/cases/iteratingCallbacks.kt index 5928ac14768..a01dd483b94 100644 --- a/js/js.translator/testFiles/closure/cases/iteratingCallbacks.kt +++ b/js/js.translator/testFiles/closure/cases/iteratingCallbacks.kt @@ -24,7 +24,3 @@ fun box() : Boolean { } return (sum == 27) } - -fun main(args : Array) { - println(box()) -} diff --git a/js/js.translator/testFiles/closure/cases/localParameterInCallBack.kt b/js/js.translator/testFiles/closure/cases/localParameterInCallBack.kt new file mode 100644 index 00000000000..4a7e66a3c31 --- /dev/null +++ b/js/js.translator/testFiles/closure/cases/localParameterInCallBack.kt @@ -0,0 +1,27 @@ +package foo + +import java.util.* + +fun box() : Boolean { + val oneTwo = Array(2) { + it + 1 + } + val a = ArrayList<()->Int>() + for (i in oneTwo) { + for (l in 1..2) { + val j = l + a.add({ + var res = 0 + for (t in 0..2) { + res += i * j + } + res + }) + } + } + var sum = 0 + for (f in a) { + sum += f() + } + return (sum == 27) +}