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 @NotNull
public DefinitionPlace getDefinitionPlace() { private DefinitionPlace getDefinitionPlace() {
if (definitionPlace != null) return definitionPlace; if (definitionPlace != null) return definitionPlace;
if (parent != null) return parent.getDefinitionPlace(); if (parent != null) return parent.getDefinitionPlace();
throw new AssertionError("Can not find definition place from rootContext(definitionPlace and parent is null)"); 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) { if (containingClass == null) {
return translate(context()); return translate(context());
} }
return new LiteralFunctionTranslator(context()).translate(containingClass, context(), classDeclaration, descriptor, this); return LiteralFunctionTranslator.translate(containingClass, context(), classDeclaration, descriptor, this);
} }
@NotNull @NotNull
@@ -403,13 +403,13 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@Override @Override
@NotNull @NotNull
public JsNode visitFunctionLiteralExpression(@NotNull JetFunctionLiteralExpression expression, @NotNull TranslationContext context) { public JsNode visitFunctionLiteralExpression(@NotNull JetFunctionLiteralExpression expression, @NotNull TranslationContext context) {
return new LiteralFunctionTranslator(context).translate(expression.getFunctionLiteral(), context); return LiteralFunctionTranslator.translate(expression.getFunctionLiteral(), context);
} }
@Override @Override
@NotNull @NotNull
public JsNode visitNamedFunction(@NotNull JetNamedFunction expression, @NotNull TranslationContext context) { 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); FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
JsName name = context.scope().declareFreshName(descriptor.getName().asString()); JsName name = context.scope().declareFreshName(descriptor.getName().asString());
context.aliasingContext().registerAlias(descriptor, name.makeRef()); context.aliasingContext().registerAlias(descriptor, name.makeRef());
@@ -39,21 +39,16 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedRe
public class LiteralFunctionTranslator extends AbstractTranslator { public class LiteralFunctionTranslator extends AbstractTranslator {
private static final LabelGenerator FUNCTION_NAME_GENERATOR = new LabelGenerator('f'); private static final LabelGenerator FUNCTION_NAME_GENERATOR = new LabelGenerator('f');
@NotNull private LiteralFunctionTranslator(@NotNull TranslationContext context) {
private final DefinitionPlace definitionPlace;
// TODO: Maybe we need make it private and add static method `translate`
public LiteralFunctionTranslator(@NotNull TranslationContext context) {
super(context); super(context);
this.definitionPlace = context.getDefinitionPlace();
} }
@NotNull @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); FunctionDescriptor descriptor = getFunctionDescriptor(outerContext.bindingContext(), declaration);
DeclarationDescriptor receiverDescriptor = getExpectedReceiverDescriptor(descriptor); DeclarationDescriptor receiverDescriptor = getExpectedReceiverDescriptor(descriptor);
JsFunction fun = createFunction(); JsFunction fun = new JsFunction(outerContext.scope(), new JsBlock());
AliasingContext aliasingContext; AliasingContext aliasingContext;
JsName receiverName; JsName receiverName;
@@ -95,7 +90,7 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
UsageTracker usageTracker = funContext.usageTracker(); UsageTracker usageTracker = funContext.usageTracker();
assert usageTracker != null; assert usageTracker != null;
if (usageTracker.isUsed()) { if (usageTracker.isUsed()) {
return new JsInvocation(context().namer().kotlin("assignOwner"), fun, JsLiteral.THIS); return new JsInvocation(outerContext.namer().kotlin("assignOwner"), fun, JsLiteral.THIS);
} }
else { else {
fun.setName(null); fun.setName(null);
@@ -107,15 +102,11 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
InnerFunctionTranslator translator = new InnerFunctionTranslator(descriptor, funContext, fun); 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); addRegularParameters(descriptor, fun, funContext, receiverName);
return result; return result;
} }
private JsNameRef defineFunction(JsFunction fun) {
return definitionPlace.define(FUNCTION_NAME_GENERATOR.generate(), fun);
}
private static void addRegularParameters( private static void addRegularParameters(
@NotNull FunctionDescriptor descriptor, @NotNull FunctionDescriptor descriptor,
@NotNull JsFunction fun, @NotNull JsFunction fun,
@@ -128,26 +119,28 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
FunctionTranslator.addParameters(fun.getParameters(), descriptor, funContext); 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 ClassDescriptor outerClass,
@NotNull TranslationContext outerClassContext, @NotNull TranslationContext outerClassContext,
@NotNull JetClassOrObject declaration, @NotNull JetClassOrObject declaration,
@NotNull ClassDescriptor descriptor, @NotNull ClassDescriptor descriptor,
@NotNull ClassTranslator classTranslator @NotNull ClassTranslator classTranslator
) { ) {
JsFunction fun = createFunction(); JsFunction fun = new JsFunction(outerClassContext.scope(), new JsBlock());
JsNameRef outerClassRef = fun.getScope().declareName(Namer.OUTER_CLASS_NAME).makeRef(); JsNameRef outerClassRef = fun.getScope().declareName(Namer.OUTER_CLASS_NAME).makeRef();
UsageTracker usageTracker = new UsageTracker(descriptor, outerClassContext.usageTracker(), outerClass); UsageTracker usageTracker = new UsageTracker(descriptor, outerClassContext.usageTracker(), outerClass);
AliasingContext aliasingContext = outerClassContext.aliasingContext().inner(outerClass, outerClassRef); AliasingContext aliasingContext = outerClassContext.aliasingContext().inner(outerClass, outerClassRef);
TranslationContext funContext = outerClassContext.newFunctionBody(fun, aliasingContext, usageTracker); TranslationContext funContext = outerClassContext.newFunctionBody(fun, aliasingContext, usageTracker);
fun.getBody().getStatements().add(new JsReturn(classTranslator.translate(funContext))); fun.getBody().getStatements().add(new JsReturn(classTranslator.translate(funContext)));
JetClassBody body = declaration.getBody(); JetClassBody body = declaration.getBody();
assert body != null; 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);
} }
} }