diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/UsageTracker.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/UsageTracker.java index 458cbfe4874..d6cf44c34a9 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/UsageTracker.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/UsageTracker.java @@ -34,8 +34,6 @@ public final class UsageTracker { @NotNull private final MemberDescriptor memberDescriptor; - @Nullable - private final UsageTracker parent; @Nullable private List children; @@ -47,7 +45,6 @@ public final class UsageTracker { public UsageTracker(@NotNull MemberDescriptor memberDescriptor, @Nullable UsageTracker parent, @Nullable ClassDescriptor trackedClassDescriptor) { this.memberDescriptor = memberDescriptor; this.trackedClassDescriptor = trackedClassDescriptor; - this.parent = parent; if (parent != null) { parent.addChild(this); } @@ -119,16 +116,18 @@ public final class UsageTracker { @Nullable public ClassDescriptor getOuterClassDescriptor() { - if (outerClassDescriptor == null && parent != null) { - UsageTracker p = parent; - do { - if (p.outerClassDescriptor != null) { - return p.outerClassDescriptor; - } - } - while ((p = p.parent) != null); + if (outerClassDescriptor != null || children == null) { + return outerClassDescriptor; } - return outerClassDescriptor; + + for (UsageTracker child : children) { + ClassDescriptor childOuterClassDescriptor = child.getOuterClassDescriptor(); + if (childOuterClassDescriptor != null) { + return childOuterClassDescriptor; + } + } + + return null; } public void forEachCaptured(Consumer consumer) { 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 150a6e36f3d..bf3387cc989 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 @@ -116,7 +116,9 @@ public class LiteralFunctionTranslator { if (asInner) { addRegularParameters(descriptor, fun, funContext, receiverName); if (outerClass != null) { - if (funContext.usageTracker().isUsed()) { + UsageTracker usageTracker = funContext.usageTracker(); + assert usageTracker != null; + if (usageTracker.isUsed()) { return new JsInvocation(rootContext.namer().kotlin("assignOwner"), fun, JsLiteral.THIS); } else { @@ -159,15 +161,15 @@ public class LiteralFunctionTranslator { @NotNull ClassTranslator classTranslator) { JsFunction fun = createFunction(); JsNameRef outerClassRef = fun.getScope().declareName("$this").makeRef(); - TranslationContext funContext = rootContext - .contextWithScope(fun, rootContext.aliasingContext().inner(outerClass, outerClassRef), new UsageTracker(descriptor, null, - outerClass)); + UsageTracker usageTracker = new UsageTracker(descriptor, null, outerClass); + TranslationContext funContext = rootContext.contextWithScope(fun, rootContext.aliasingContext().inner(outerClass, outerClassRef), + 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), funContext.usageTracker().isUsed() ? outerClassRef : null); + return translator.translate(createReference(fun), usageTracker.isUsed() ? outerClassRef : null); } }