JS backend: refactoring:

- make static LiteralFunctionTranslator#translate;
    - use TranslationContext#define instead  of  direct use DefinitionPlace.
This commit is contained in:
Zalim Bashorov
2013-12-12 17:09:17 +04:00
parent 9e97f9615b
commit 25c43e7bfc
4 changed files with 21 additions and 24 deletions
@@ -287,10 +287,14 @@ public class TranslationContext {
}
@NotNull
public DefinitionPlace getDefinitionPlace() {
private DefinitionPlace getDefinitionPlace() {
if (definitionPlace != null) return definitionPlace;
if (parent != null) return parent.getDefinitionPlace();
throw new AssertionError("Can not find definition place from rootContext(definitionPlace and parent is null)");
}
public JsNameRef define(String name, JsExpression expression) {
return getDefinitionPlace().define(name, expression);
}
}
@@ -108,7 +108,7 @@ public final class ClassTranslator extends AbstractTranslator {
if (containingClass == null) {
return translate(context());
}
return new LiteralFunctionTranslator(context()).translate(containingClass, context(), classDeclaration, descriptor, this);
return LiteralFunctionTranslator.translate(containingClass, context(), classDeclaration, descriptor, this);
}
@NotNull
@@ -403,13 +403,13 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@Override
@NotNull
public JsNode visitFunctionLiteralExpression(@NotNull JetFunctionLiteralExpression expression, @NotNull TranslationContext context) {
return new LiteralFunctionTranslator(context).translate(expression.getFunctionLiteral(), context);
return LiteralFunctionTranslator.translate(expression.getFunctionLiteral(), context);
}
@Override
@NotNull
public JsNode visitNamedFunction(@NotNull JetNamedFunction expression, @NotNull TranslationContext context) {
JsExpression alias = new LiteralFunctionTranslator(context).translate(expression, context);
JsExpression alias = LiteralFunctionTranslator.translate(expression, context);
FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
JsName name = context.scope().declareFreshName(descriptor.getName().asString());
context.aliasingContext().registerAlias(descriptor, name.makeRef());
@@ -39,21 +39,16 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedRe
public class LiteralFunctionTranslator extends AbstractTranslator {
private static final LabelGenerator FUNCTION_NAME_GENERATOR = new LabelGenerator('f');
@NotNull
private final DefinitionPlace definitionPlace;
// TODO: Maybe we need make it private and add static method `translate`
public LiteralFunctionTranslator(@NotNull TranslationContext context) {
private LiteralFunctionTranslator(@NotNull TranslationContext context) {
super(context);
this.definitionPlace = context.getDefinitionPlace();
}
@NotNull
public JsExpression translate(@NotNull JetDeclarationWithBody declaration, @NotNull TranslationContext outerContext) {
public static JsExpression translate(@NotNull JetDeclarationWithBody declaration, @NotNull TranslationContext outerContext) {
FunctionDescriptor descriptor = getFunctionDescriptor(outerContext.bindingContext(), declaration);
DeclarationDescriptor receiverDescriptor = getExpectedReceiverDescriptor(descriptor);
JsFunction fun = createFunction();
JsFunction fun = new JsFunction(outerContext.scope(), new JsBlock());
AliasingContext aliasingContext;
JsName receiverName;
@@ -95,7 +90,7 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
UsageTracker usageTracker = funContext.usageTracker();
assert usageTracker != null;
if (usageTracker.isUsed()) {
return new JsInvocation(context().namer().kotlin("assignOwner"), fun, JsLiteral.THIS);
return new JsInvocation(outerContext.namer().kotlin("assignOwner"), fun, JsLiteral.THIS);
}
else {
fun.setName(null);
@@ -107,15 +102,11 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
InnerFunctionTranslator translator = new InnerFunctionTranslator(descriptor, funContext, fun);
JsExpression result = translator.translate(defineFunction(fun), outerContext);
JsExpression result = translator.translate(outerContext.define(FUNCTION_NAME_GENERATOR.generate(), fun), outerContext);
addRegularParameters(descriptor, fun, funContext, receiverName);
return result;
}
private JsNameRef defineFunction(JsFunction fun) {
return definitionPlace.define(FUNCTION_NAME_GENERATOR.generate(), fun);
}
private static void addRegularParameters(
@NotNull FunctionDescriptor descriptor,
@NotNull JsFunction fun,
@@ -128,26 +119,28 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
FunctionTranslator.addParameters(fun.getParameters(), descriptor, funContext);
}
private JsFunction createFunction() {
return new JsFunction(context().scope(), new JsBlock());
}
public JsExpression translate(
// TODO: Probably should be moved to other place
@NotNull
public static JsExpression translate(
@NotNull ClassDescriptor outerClass,
@NotNull TranslationContext outerClassContext,
@NotNull JetClassOrObject declaration,
@NotNull ClassDescriptor descriptor,
@NotNull ClassTranslator classTranslator
) {
JsFunction fun = createFunction();
JsFunction fun = new JsFunction(outerClassContext.scope(), new JsBlock());
JsNameRef outerClassRef = fun.getScope().declareName(Namer.OUTER_CLASS_NAME).makeRef();
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;
return new InnerObjectTranslator(funContext, fun).translate(defineFunction(fun), usageTracker.isUsed() ? outerClassRef : null);
JsNameRef define = funContext.define(FUNCTION_NAME_GENERATOR.generate(), fun);
return new InnerObjectTranslator(funContext, fun).translate(define, usageTracker.isUsed() ? outerClassRef : null);
}
}