From 396afb05cb624d15de2eaa610b7535ab47fa522c Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Thu, 13 Feb 2014 14:20:42 +0400 Subject: [PATCH] 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 --- .../declaration/ClassTranslator.java | 63 ++++++++----------- .../declaration/DeclarationBodyVisitor.java | 6 +- .../translate/declaration/FileDeclaration.kt | 4 +- .../expression/InnerObjectTranslator.java | 2 +- .../expression/LiteralFunctionTranslator.java | 56 ++--------------- .../initializer/InitializerUtils.java | 2 +- .../translate/utils/TranslationUtils.java | 23 +++++++ 7 files changed, 61 insertions(+), 95 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java index 3426d1bbb80..45938140f7f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java @@ -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); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java index 04ac7ce7200..bf1cf5a6003 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java @@ -73,7 +73,7 @@ public class DeclarationBodyVisitor extends TranslatorVisitor { ClassDescriptor descriptor = getClassDescriptor(data.bindingContext(), enumEntry); List 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 { @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; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/FileDeclaration.kt b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/FileDeclaration.kt index c5cd3253e94..ffac261c168 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/FileDeclaration.kt +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/FileDeclaration.kt @@ -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 } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/InnerObjectTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/InnerObjectTranslator.java index 579d4890c16..1f27582c3ca 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/InnerObjectTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/InnerObjectTranslator.java @@ -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 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 cbf575ce3e9..ed9aaf69234 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 @@ -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); - } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/InitializerUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/InitializerUtils.java index ce70c80f232..46c41646e5e 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/InitializerUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/InitializerUtils.java @@ -63,8 +63,8 @@ public final class InitializerUtils { @NotNull List 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()); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java index 5f8106e5123..bbbfb2132bf 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java @@ -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 { @Override public int compare(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) {