JS backend: minor refactorings

- dropped useless constructor and factory method from ClassTranslator.
  - moved method which translate an object expression inside a class code to ClassTranslator.
  - LiteralFunctionTranslator#getSuggestedName -> TranslationUtils#getSuggestedName
This commit is contained in:
Zalim Bashorov
2014-02-13 14:20:42 +04:00
parent 5f847bc7e7
commit 396afb05cb
7 changed files with 61 additions and 95 deletions
@@ -22,14 +22,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.JetClassBody;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.k2js.translate.context.DefinitionPlace;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator;
import org.jetbrains.k2js.translate.context.*;
import org.jetbrains.k2js.translate.expression.InnerObjectTranslator;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
@@ -38,6 +38,7 @@ import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
import static org.jetbrains.jet.lang.types.TypeUtils.topologicallySortSuperclassesAndRecordAllInstances;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getSuggestedName;
import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createClassObjectInitializer;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter;
@@ -62,44 +63,14 @@ public final class ClassTranslator extends AbstractTranslator {
}
@NotNull
public static JsInvocation generateClassCreation(@NotNull JetClassOrObject classDeclaration,
@NotNull ClassDescriptor descriptor,
@NotNull TranslationContext context) {
return new ClassTranslator(classDeclaration, descriptor, context).translate();
}
@NotNull
public static JsExpression generateObjectLiteral(
@NotNull JetObjectDeclaration objectDeclaration,
@NotNull TranslationContext context
) {
public static JsExpression generateObjectLiteral(@NotNull JetObjectDeclaration objectDeclaration, @NotNull TranslationContext context) {
return new ClassTranslator(objectDeclaration, context).translateObjectLiteralExpression();
}
@NotNull
public static JsExpression generateObjectLiteral(
@NotNull JetObjectDeclaration objectDeclaration,
@NotNull ClassDescriptor descriptor,
@NotNull TranslationContext context
) {
return new ClassTranslator(objectDeclaration, descriptor, context).translateObjectLiteralExpression();
}
ClassTranslator(
@NotNull JetClassOrObject classDeclaration,
@NotNull TranslationContext context
) {
this(classDeclaration, getClassDescriptor(context.bindingContext(), classDeclaration), context);
}
ClassTranslator(
@NotNull JetClassOrObject classDeclaration,
@NotNull ClassDescriptor descriptor,
@NotNull TranslationContext context
) {
private ClassTranslator(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) {
super(context);
this.descriptor = descriptor;
this.classDeclaration = classDeclaration;
this.descriptor = getClassDescriptor(context.bindingContext(), classDeclaration);
}
@NotNull
@@ -108,7 +79,8 @@ public final class ClassTranslator extends AbstractTranslator {
if (containingClass == null) {
return translate(context());
}
return LiteralFunctionTranslator.translate(containingClass, context(), classDeclaration, descriptor, this);
return translateObjectInsideClass(containingClass, context());
}
@NotNull
@@ -249,4 +221,21 @@ public final class ClassTranslator extends AbstractTranslator {
}
}
}
@NotNull
private JsExpression translateObjectInsideClass(@NotNull ClassDescriptor outerClass, @NotNull TranslationContext outerClassContext) {
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(translate(funContext)));
JetClassBody body = classDeclaration.getBody();
assert body != null;
JsNameRef define = funContext.define(getSuggestedName(funContext, descriptor), fun);
return new InnerObjectTranslator(funContext, fun).translate(define, usageTracker.isUsed() ? outerClassRef : null);
}
}
@@ -73,7 +73,7 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
ClassDescriptor descriptor = getClassDescriptor(data.bindingContext(), enumEntry);
List<JetType> supertypes = getSupertypesWithoutFakes(descriptor);
if (enumEntry.getBody() != null || supertypes.size() > 1) {
jsEnumEntryCreation = ClassTranslator.generateClassCreation(enumEntry, descriptor, data);
jsEnumEntryCreation = ClassTranslator.generateClassCreation(enumEntry, data);
} else {
assert supertypes.size() == 1 : "Simple Enum entry must have one supertype";
jsEnumEntryCreation = new ClassInitializerTranslator(enumEntry, data).generateEnumEntryInstanceCreation(supertypes.get(0));
@@ -85,9 +85,9 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
@Override
public Void visitClassObject(@NotNull JetClassObject classObject, TranslationContext context) {
JetObjectDeclaration declaration = classObject.getObjectDeclaration();
ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration);
JsExpression value = ClassTranslator.generateClassCreation(declaration, descriptor, context);
JsExpression value = ClassTranslator.generateClassCreation(declaration, context);
ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration);
JsFunction fun = TranslationUtils.simpleReturnFunction(context.getScopeForDescriptor(descriptor), value);
staticResult.add(createClassObjectInitializer(fun, context));
return null;
@@ -51,8 +51,8 @@ class FileDeclarationVisitor(
public override fun visitClass(expression: JetClass, context: TranslationContext?): Void? {
val classDescriptor = getClassDescriptor(context!!.bindingContext(), expression)
val value = ClassTranslator(expression, context).translate()
val entry = JsPropertyInitializer(context.getNameForDescriptor(classDescriptor).makeRef()!!, value)
val value = ClassTranslator.generateClassCreation(expression, context)
val entry = JsPropertyInitializer(context.getNameForDescriptor(classDescriptor).makeRef(), value)
result.add(entry)
return null
}
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
class InnerObjectTranslator extends InnerDeclarationTranslator {
public class InnerObjectTranslator extends InnerDeclarationTranslator {
public InnerObjectTranslator(
@NotNull TranslationContext context,
@NotNull JsFunction fun
@@ -20,17 +20,16 @@ import com.google.dart.compiler.backend.js.ast.*;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetClassBody;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
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;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
@@ -39,6 +38,7 @@ import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedReceiverDescriptor;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getSuggestedName;
public class LiteralFunctionTranslator extends AbstractTranslator {
private static final String CAPTURED_VALUE_FIELD = "v";
@@ -192,28 +192,6 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
FunctionTranslator.addParameters(fun.getParameters(), descriptor, funContext);
}
private static String getSuggestedName(TranslationContext context, DeclarationDescriptor descriptor) {
String suggestedName = "";
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration != null &&
!(containingDeclaration instanceof ClassOrPackageFragmentDescriptor) &&
!(containingDeclaration instanceof AnonymousFunctionDescriptor)) {
suggestedName = context.getNameForDescriptor(containingDeclaration).getIdent();
}
if (!suggestedName.isEmpty() && !suggestedName.endsWith("$")) {
suggestedName += "$";
}
if (descriptor.getName().isSpecial()) {
suggestedName += "f";
}
else {
suggestedName += context.getNameForDescriptor(descriptor).getIdent();
}
return suggestedName;
}
@NotNull
public static JsVars translateLocalNamedFunction(@NotNull JetDeclarationWithBody declaration, @NotNull TranslationContext outerContext) {
return new LiteralFunctionTranslator(declaration, outerContext).translateLocalNamedFunction();
@@ -223,28 +201,4 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
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
public static JsExpression translate(
@NotNull ClassDescriptor outerClass,
@NotNull TranslationContext outerClassContext,
@NotNull JetClassOrObject declaration,
@NotNull ClassDescriptor descriptor,
@NotNull ClassTranslator classTranslator
) {
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;
JsNameRef define = funContext.define(getSuggestedName(funContext, descriptor), fun);
return new InnerObjectTranslator(funContext, fun).translate(define, usageTracker.isUsed() ? outerClassRef : null);
}
}
@@ -63,8 +63,8 @@ public final class InitializerUtils {
@NotNull List<JsStatement> initializers,
@NotNull TranslationContext context
) {
JsExpression value = ClassTranslator.generateObjectLiteral(declaration, context);
ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration);
JsExpression value = ClassTranslator.generateObjectLiteral(declaration, descriptor, context);
JsExpression expression = assignment(new JsNameRef(descriptor.getName().asString(), JsLiteral.THIS), value);
initializers.add(expression.makeStmt());
}
@@ -24,6 +24,7 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -410,6 +411,28 @@ public final class TranslationUtils {
return ensureNotNull;
}
public static String getSuggestedName(TranslationContext context, DeclarationDescriptor descriptor) {
String suggestedName = "";
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration != null &&
!(containingDeclaration instanceof ClassOrPackageFragmentDescriptor) &&
!(containingDeclaration instanceof AnonymousFunctionDescriptor)) {
suggestedName = context.getNameForDescriptor(containingDeclaration).getIdent();
}
if (!suggestedName.isEmpty() && !suggestedName.endsWith("$")) {
suggestedName += "$";
}
if (descriptor.getName().isSpecial()) {
suggestedName += "f";
}
else {
suggestedName += context.getNameForDescriptor(descriptor).getIdent();
}
return suggestedName;
}
private static class OverloadedFunctionComparator implements Comparator<FunctionDescriptor> {
@Override
public int compare(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) {