From af28455e5bf1c877ee0738c030bc6cd2a375fdc3 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Tue, 21 Feb 2012 17:40:15 +0400 Subject: [PATCH] implement multinamespace translation: creating classes altogether before namespaces better implementation of NamespaceDeclarationTranslator --- .../ClassDeclarationTranslator.java | 4 +- .../NamespaceDeclarationTranslator.java | 76 +++++++++++++++++-- .../declaration/NamespaceTranslator.java | 36 ++------- .../k2js/translate/general/Translation.java | 7 -- 4 files changed, 79 insertions(+), 44 deletions(-) diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java index f45daf0c2b7..a57125ff870 100644 --- a/translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java @@ -39,8 +39,8 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { @Nullable private JsStatement declarationsStatement = null; - public ClassDeclarationTranslator(@NotNull TranslationContext context, - @NotNull List descriptors) { + public ClassDeclarationTranslator(@NotNull List descriptors, + @NotNull TranslationContext context) { super(context); this.descriptors = descriptors; this.localToGlobalClassName = new HashMap(); diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java index b2197d9e76d..ab66bf162a8 100644 --- a/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java @@ -3,15 +3,17 @@ package org.jetbrains.k2js.translate.declaration; import com.google.common.collect.Lists; import com.google.dart.compiler.backend.js.ast.JsStatement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; -import org.jetbrains.k2js.translate.general.Translation; import java.util.List; +import java.util.Set; import static org.jetbrains.k2js.translate.utils.BindingUtils.getAllNonNativeNamespaceDescriptors; +import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getAllClassesDefinedInNamespace; /** * @author Pavel Talanov @@ -19,14 +21,76 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.getAllNonNativeNam public final class NamespaceDeclarationTranslator extends AbstractTranslator { public static List translateFiles(@NotNull List files, @NotNull TranslationContext context) { - List result = Lists.newArrayList(); - for (NamespaceDescriptor namespaceDescriptor : getAllNonNativeNamespaceDescriptors(context.bindingContext(), files)) { - result.add(Translation.translateNamespace(namespaceDescriptor, context)); + Set namespaceDescriptorSet = getAllNonNativeNamespaceDescriptors(context.bindingContext(), files); + return (new NamespaceDeclarationTranslator(Lists.newArrayList(namespaceDescriptorSet), context)).translate(); + } + + @NotNull + private final ClassDeclarationTranslator classDeclarationTranslator; + @NotNull + private final List namespaceDescriptors; + + private NamespaceDeclarationTranslator(@NotNull List namespaceDescriptors, + @NotNull TranslationContext context) { + super(context); + this.namespaceDescriptors = namespaceDescriptors; + this.classDeclarationTranslator = new ClassDeclarationTranslator(getAllClasses(), context); + } + + @NotNull + private List getAllClasses() { + List result = Lists.newArrayList(); + for (NamespaceDescriptor namespaceDescriptor : namespaceDescriptors) { + result.addAll(getAllClassesDefinedInNamespace(namespaceDescriptor)); } return result; } - private NamespaceDeclarationTranslator(@NotNull TranslationContext context) { - super(context); + //TODO: logic seems not so clear, may be a couple of extract method should help + @NotNull + private List translate() { + classDeclarationTranslator.generateDeclarations(); + List result = Lists.newArrayList(); + result.add(classDeclarationsStatement()); + List namespaceTranslators = getTranslatorsForNonEmptyNamespaces(); + result.addAll(declarationStatements(namespaceTranslators)); + result.addAll(initializeStatements(namespaceTranslators)); + return result; + } + + @NotNull + private JsStatement classDeclarationsStatement() { + return classDeclarationTranslator.getDeclarationsStatement(); + } + + @NotNull + private List getTranslatorsForNonEmptyNamespaces() { + List namespaceTranslators = Lists.newArrayList(); + for (NamespaceDescriptor descriptor : namespaceDescriptors) { + NamespaceTranslator namespaceTranslator = + new NamespaceTranslator(descriptor, classDeclarationTranslator, context()); + if (!namespaceTranslator.isNamespaceEmpty()) { + namespaceTranslators.add(namespaceTranslator); + } + } + return namespaceTranslators; + } + + @NotNull + private List declarationStatements(@NotNull List namespaceTranslators) { + List result = Lists.newArrayList(); + for (NamespaceTranslator translator : namespaceTranslators) { + result.add(translator.getDeclarationStatement()); + } + return result; + } + + @NotNull + private List initializeStatements(@NotNull List namespaceTranslators) { + List result = Lists.newArrayList(); + for (NamespaceTranslator translator : namespaceTranslators) { + result.add(translator.getInitializeStatement()); + } + return result; } } diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java index c18ffb584a9..53e45d7e1ae 100644 --- a/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java @@ -13,8 +13,6 @@ import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.ArrayList; import java.util.List; -import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getAllClassesDefinedInNamespace; - /** * @author Pavel.Talanov *

@@ -29,44 +27,24 @@ public final class NamespaceTranslator extends AbstractTranslator { @NotNull private final ClassDeclarationTranslator classDeclarationTranslator; - @NotNull - public static JsStatement translateNamespace(@NotNull NamespaceDescriptor namespace, - @NotNull TranslationContext context) { - return (new NamespaceTranslator(namespace, context)).translateNamespace(); - } - - private NamespaceTranslator(@NotNull NamespaceDescriptor descriptor, @NotNull TranslationContext context) { + /*package*/ NamespaceTranslator(@NotNull NamespaceDescriptor descriptor, + @NotNull ClassDeclarationTranslator classDeclarationTranslator, + @NotNull TranslationContext context) { super(context.newDeclaration(descriptor)); this.descriptor = descriptor; this.namespaceName = context.getNameForDescriptor(descriptor); - this.classDeclarationTranslator = new ClassDeclarationTranslator(context(), - getAllClassesDefinedInNamespace(descriptor)); - } - - @NotNull - public JsStatement translateNamespace() { - if (isNamespaceEmpty()) { - return program().getEmptyStmt(); - } - classDeclarationTranslator.generateDeclarations(); - return AstUtil.newBlock(classDeclarationsStatement(), - namespaceOwnDeclarationStatement(), - namespaceInitializeStatement()); + this.classDeclarationTranslator = classDeclarationTranslator; } //TODO: at the moment this check is very ineffective, possible solution is to cash the result of getDFN // other solution is to determine it's not affecting performance :D - private boolean isNamespaceEmpty() { + public boolean isNamespaceEmpty() { return BindingUtils.getDeclarationsForNamespace(context().bindingContext(), descriptor).isEmpty(); } - @NotNull - private JsStatement classDeclarationsStatement() { - return classDeclarationTranslator.getDeclarationsStatement(); - } @NotNull - private JsStatement namespaceInitializeStatement() { + public JsStatement getInitializeStatement() { JsNameRef initializeMethodReference = Namer.initializeMethodReference(); AstUtil.setQualifier(initializeMethodReference, namespaceName.makeRef()); return AstUtil.newInvocation(initializeMethodReference).makeStmt(); @@ -78,7 +56,7 @@ public final class NamespaceTranslator extends AbstractTranslator { } @NotNull - private JsStatement namespaceOwnDeclarationStatement() { + public JsStatement getDeclarationStatement() { JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation(); addMemberDeclarations(namespaceDeclaration); addClassesDeclarations(namespaceDeclaration); diff --git a/translator/src/org/jetbrains/k2js/translate/general/Translation.java b/translator/src/org/jetbrains/k2js/translate/general/Translation.java index 1c70c401ee9..484eee72039 100644 --- a/translator/src/org/jetbrains/k2js/translate/general/Translation.java +++ b/translator/src/org/jetbrains/k2js/translate/general/Translation.java @@ -14,7 +14,6 @@ import org.jetbrains.k2js.translate.context.StaticContext; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.declaration.ClassTranslator; import org.jetbrains.k2js.translate.declaration.NamespaceDeclarationTranslator; -import org.jetbrains.k2js.translate.declaration.NamespaceTranslator; import org.jetbrains.k2js.translate.expression.ExpressionVisitor; import org.jetbrains.k2js.translate.expression.FunctionTranslator; import org.jetbrains.k2js.translate.expression.PatternTranslator; @@ -38,12 +37,6 @@ public final class Translation { return FunctionTranslator.newInstance(function, context); } - @NotNull - public static JsStatement translateNamespace(@NotNull NamespaceDescriptor namespace, - @NotNull TranslationContext context) { - return NamespaceTranslator.translateNamespace(namespace, context); - } - @NotNull public static List translateFiles(@NotNull List files, @NotNull TranslationContext context) { return NamespaceDeclarationTranslator.translateFiles(files, context);