From b122893823010174f32c2f852471219b038ae285 Mon Sep 17 00:00:00 2001 From: develar Date: Tue, 20 Aug 2013 15:32:43 +0400 Subject: [PATCH] JS backend: fixed closure variables in object which declared in another object in method. (cherry picked from commit f3e8325) --- .../k2js/test/semantics/ObjectTest.java | 3 +++ .../declaration/ClassTranslator.java | 2 +- .../expression/LiteralFunctionTranslator.java | 23 ++++++++++--------- .../object/cases/objectInObjectWithClosure.kt | 18 +++++++++++++++ 4 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 js/js.translator/testFiles/object/cases/objectInObjectWithClosure.kt diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ObjectTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ObjectTest.java index ceceaedffb8..5b167222d22 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ObjectTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ObjectTest.java @@ -52,4 +52,7 @@ public final class ObjectTest extends SingleFileTranslationTest { public void testObjectInheritingFromClass() throws Exception { fooBoxTest(); } + public void testObjectInObjectWithClosure() throws Exception { + fooBoxTest(); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java index 199c9b85aad..d8dc7995179 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java @@ -119,7 +119,7 @@ public final class ClassTranslator extends AbstractTranslator { if (containingClass == null) { return translate(context()); } - return context().literalFunctionTranslator().translate(containingClass, classDeclaration, descriptor, this); + return context().literalFunctionTranslator().translate(containingClass, context(), classDeclaration, descriptor, this); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/LiteralFunctionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/LiteralFunctionTranslator.java index ec59593814b..6f482c74974 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/LiteralFunctionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/LiteralFunctionTranslator.java @@ -103,7 +103,7 @@ public class LiteralFunctionTranslator extends AbstractTranslator { } funContext = outerContext.newFunctionBody(fun, aliasingContext, - new UsageTracker(descriptor, outerContext.usageTracker(), outerClass)); + new UsageTracker(descriptor, outerContext.usageTracker(), outerClass)); fun.getBody().getStatements().addAll(translateFunctionBody(descriptor, declaration, funContext).getStatements()); @@ -140,10 +140,12 @@ public class LiteralFunctionTranslator extends AbstractTranslator { return nameRef; } - private static void addRegularParameters(FunctionDescriptor descriptor, - JsFunction fun, - TranslationContext funContext, - JsName receiverName) { + private static void addRegularParameters( + @NotNull FunctionDescriptor descriptor, + @NotNull JsFunction fun, + @NotNull TranslationContext funContext, + @Nullable JsName receiverName + ) { if (receiverName != null) { fun.getParameters().add(new JsParameter(receiverName)); } @@ -156,21 +158,20 @@ public class LiteralFunctionTranslator extends AbstractTranslator { public JsExpression translate( @NotNull ClassDescriptor outerClass, + @NotNull TranslationContext outerClassContext, @NotNull JetClassOrObject declaration, @NotNull ClassDescriptor descriptor, @NotNull ClassTranslator classTranslator ) { JsFunction fun = createFunction(); JsNameRef outerClassRef = fun.getScope().declareName(Namer.OUTER_CLASS_NAME).makeRef(); - UsageTracker usageTracker = new UsageTracker(descriptor, null, outerClass); - TranslationContext funContext = context().newFunctionBody(fun, context().aliasingContext().inner(outerClass, outerClassRef), - usageTracker); + UsageTracker usageTracker = new UsageTracker(descriptor, outerClassContext.usageTracker(), outerClass); + AliasingContext aliasingContext = outerClassContext.aliasingContext().inner(outerClass, outerClassRef); + TranslationContext funContext = outerClassContext.newFunctionBody(fun, aliasingContext, usageTracker); fun.getBody().getStatements().add(new JsReturn(classTranslator.translate(funContext))); JetClassBody body = declaration.getBody(); assert body != null; - InnerObjectTranslator translator = new InnerObjectTranslator(funContext, fun); - return translator.translate(createReference(fun), usageTracker.isUsed() ? outerClassRef : null); + return new InnerObjectTranslator(funContext, fun).translate(createReference(fun), usageTracker.isUsed() ? outerClassRef : null); } } - diff --git a/js/js.translator/testFiles/object/cases/objectInObjectWithClosure.kt b/js/js.translator/testFiles/object/cases/objectInObjectWithClosure.kt new file mode 100644 index 00000000000..dfd3d65d374 --- /dev/null +++ b/js/js.translator/testFiles/object/cases/objectInObjectWithClosure.kt @@ -0,0 +1,18 @@ +package foo + +class Foo { + fun bar(param: String): String { + val local = "world!" + var a = object { + object b { + val bar = param + local + } + } + return a.b.bar + } +} + +fun box(): Boolean { + return Foo().bar("hello ") == "hello world!" +} +