From 1f17b55c278b3d70e83c21dd1ec87885ae009797 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Mon, 16 Dec 2013 21:27:46 +0400 Subject: [PATCH] JS backend: minor refactoring -- make LiteralFunctionTranslator stateful. --- .../expression/LiteralFunctionTranslator.java | 85 ++++++++++++------- 1 file changed, 56 insertions(+), 29 deletions(-) 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 60adf7bea5d..d95282a9369 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 @@ -28,7 +28,10 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetDeclarationWithBody; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.k2js.translate.LabelGenerator; -import org.jetbrains.k2js.translate.context.*; +import org.jetbrains.k2js.translate.context.AliasingContext; +import org.jetbrains.k2js.translate.context.Namer; +import org.jetbrains.k2js.translate.context.TranslationContext; +import org.jetbrains.k2js.translate.context.UsageTracker; import org.jetbrains.k2js.translate.declaration.ClassTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator; @@ -39,74 +42,94 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedRe public class LiteralFunctionTranslator extends AbstractTranslator { private static final LabelGenerator FUNCTION_NAME_GENERATOR = new LabelGenerator('f'); - private LiteralFunctionTranslator(@NotNull TranslationContext context) { - super(context); - } + private final JetDeclarationWithBody declaration; + private final FunctionDescriptor descriptor; + private final JsFunction jsFunction; + private final TranslationContext functionContext; + private final boolean inConstructorOrTopLevel; + private final ClassDescriptor outerClass; + private final JsName receiverName; - @NotNull - public static JsExpression translate(@NotNull JetDeclarationWithBody declaration, @NotNull TranslationContext outerContext) { - FunctionDescriptor descriptor = getFunctionDescriptor(outerContext.bindingContext(), declaration); + private LiteralFunctionTranslator(@NotNull JetDeclarationWithBody declaration, @NotNull TranslationContext context) { + super(context); + + this.declaration = declaration; + this.descriptor = getFunctionDescriptor(context().bindingContext(), declaration); DeclarationDescriptor receiverDescriptor = getExpectedReceiverDescriptor(descriptor); - JsFunction fun = new JsFunction(outerContext.scope(), new JsBlock()); + jsFunction = new JsFunction(context().scope(), new JsBlock()); AliasingContext aliasingContext; - JsName receiverName; if (receiverDescriptor == null) { receiverName = null; aliasingContext = null; } else { - receiverName = fun.getScope().declareName(Namer.getReceiverParameterName()); - aliasingContext = outerContext.aliasingContext().inner(receiverDescriptor, receiverName.makeRef()); + receiverName = jsFunction.getScope().declareName(Namer.getReceiverParameterName()); + aliasingContext = context().aliasingContext().inner(receiverDescriptor, receiverName.makeRef()); } - boolean asInner; - ClassDescriptor outerClass; if (descriptor.getContainingDeclaration() instanceof ConstructorDescriptor) { // KT-2388 - asInner = true; - fun.setName(fun.getScope().declareName(Namer.CALLEE_NAME)); + inConstructorOrTopLevel = true; + jsFunction.setName(jsFunction.getScope().declareName(Namer.CALLEE_NAME)); outerClass = (ClassDescriptor) descriptor.getContainingDeclaration().getContainingDeclaration(); assert outerClass != null; if (receiverDescriptor == null) { - aliasingContext = outerContext.aliasingContext().notShareableThisAliased(outerClass, new JsNameRef("o", fun.getName().makeRef())); + aliasingContext = context().aliasingContext().notShareableThisAliased(outerClass, new JsNameRef("o", jsFunction.getName().makeRef())); } } else { outerClass = null; - asInner = DescriptorUtils.isTopLevelDeclaration(descriptor); + inConstructorOrTopLevel = DescriptorUtils.isTopLevelDeclaration(descriptor); } - UsageTracker funTracker = new UsageTracker(descriptor, outerContext.usageTracker(), outerClass); - TranslationContext funContext = outerContext.newFunctionBody(fun, aliasingContext, funTracker); + UsageTracker funTracker = new UsageTracker(descriptor, context().usageTracker(), outerClass); + functionContext = context().newFunctionBody(jsFunction, aliasingContext, funTracker); + } - fun.getBody().getStatements().addAll(translateFunctionBody(descriptor, declaration, funContext).getStatements()); + private void translateBody() { + JsBlock functionBody = translateFunctionBody(descriptor, declaration, functionContext); + jsFunction.getBody().getStatements().addAll(functionBody.getStatements()); + } + + @NotNull + private JsExpression finish() { + JsExpression result; + + if (inConstructorOrTopLevel) { + result = jsFunction; - if (asInner) { - addRegularParameters(descriptor, fun, funContext, receiverName); if (outerClass != null) { - UsageTracker usageTracker = funContext.usageTracker(); + UsageTracker usageTracker = functionContext.usageTracker(); assert usageTracker != null; if (usageTracker.isUsed()) { - return new JsInvocation(outerContext.namer().kotlin("assignOwner"), fun, JsLiteral.THIS); + result = new JsInvocation(context().namer().kotlin("assignOwner"), jsFunction, JsLiteral.THIS); } else { - fun.setName(null); + jsFunction.setName(null); } } + } + else { + JsNameRef funReference = context().define(FUNCTION_NAME_GENERATOR.generate(), jsFunction); - return fun; + InnerFunctionTranslator innerTranslator = new InnerFunctionTranslator(descriptor, functionContext, jsFunction); + result = innerTranslator.translate(funReference, context()); } - InnerFunctionTranslator translator = new InnerFunctionTranslator(descriptor, funContext, fun); + addRegularParameters(descriptor, jsFunction, functionContext, receiverName); - JsExpression result = translator.translate(outerContext.define(FUNCTION_NAME_GENERATOR.generate(), fun), outerContext); - addRegularParameters(descriptor, fun, funContext, receiverName); return result; } + @NotNull + private JsExpression translate() { + translateBody(); + return finish(); + } + private static void addRegularParameters( @NotNull FunctionDescriptor descriptor, @NotNull JsFunction fun, @@ -119,6 +142,10 @@ public class LiteralFunctionTranslator extends AbstractTranslator { FunctionTranslator.addParameters(fun.getParameters(), descriptor, funContext); } + @NotNull + public static JsExpression translate(@NotNull JetDeclarationWithBody declaration, @NotNull TranslationContext outerContext) { + return new LiteralFunctionTranslator(declaration, outerContext).translate(); + } // TODO: Probably should be moved to other place @NotNull