From f5e5ac42dde602e612662c257df755f160500574 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Tue, 22 Nov 2011 21:06:36 +0400 Subject: [PATCH] Finished work on namespaces. --- .../google/dart/compiler/util/AstUtil.java | 1 + .../k2js/translate/BindingUtils.java | 4 ++ .../k2js/translate/InitializerGenerator.java | 2 + .../org/jetbrains/k2js/translate/Namer.java | 4 ++ .../NamespaceInitializerVisitor.java | 15 +++++++ .../k2js/translate/NamespaceTranslator.java | 41 ++++++++++++------- .../translate/PropertyAccessTranslator.java | 3 +- .../k2js/translate/ReferenceProvider.java | 9 ++-- .../jetbrains/k2js/translate/Translation.java | 17 ++++++-- .../k2js/translate/TranslatorVisitor.java | 6 ++- .../jetbrains/k2js/test/KotlinLibTest.java | 6 --- .../testFiles/kotlinLib/cases/namespace2.js | 35 ---------------- 12 files changed, 78 insertions(+), 65 deletions(-) delete mode 100644 translator/testFiles/kotlinLib/cases/namespace2.js diff --git a/js/src/com/google/dart/compiler/util/AstUtil.java b/js/src/com/google/dart/compiler/util/AstUtil.java index 4e92a7f4fe0..1b583c11257 100644 --- a/js/src/com/google/dart/compiler/util/AstUtil.java +++ b/js/src/com/google/dart/compiler/util/AstUtil.java @@ -290,6 +290,7 @@ public class AstUtil { return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2); } + //TODO public static void setQualifier(JsExpression selector, JsExpression receiver) { if (selector instanceof JsInvocation) { setQualifier(((JsInvocation) selector).getQualifier(), receiver); diff --git a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java index 6859bd95209..c54c0bc5341 100644 --- a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java @@ -149,6 +149,10 @@ public final class BindingUtils { return null; } + static public boolean belongsToNamespace(@NotNull BindingContext context, @NotNull JetProperty property) { + return getPropertyDescriptor(context, property).getContainingDeclaration() instanceof NamespaceDescriptor; + } + @Nullable static public ResolvedCall getResolvedCall(@NotNull BindingContext context, @NotNull JetExpression expression) { diff --git a/translator/src/org/jetbrains/k2js/translate/InitializerGenerator.java b/translator/src/org/jetbrains/k2js/translate/InitializerGenerator.java index 99bc7f5f0f3..2126333201f 100644 --- a/translator/src/org/jetbrains/k2js/translate/InitializerGenerator.java +++ b/translator/src/org/jetbrains/k2js/translate/InitializerGenerator.java @@ -7,6 +7,8 @@ import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetNamedDeclaration; import org.jetbrains.jet.lang.psi.JetNamespace; + +//TODO: thing about redesigning this class public class InitializerGenerator { @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/Namer.java b/translator/src/org/jetbrains/k2js/translate/Namer.java index 3744f452a0a..794c56eb618 100644 --- a/translator/src/org/jetbrains/k2js/translate/Namer.java +++ b/translator/src/org/jetbrains/k2js/translate/Namer.java @@ -79,5 +79,9 @@ public final class Namer { return AstUtil.newQualifiedNameRef("isType"); } + public static JsNameRef initializeMethodReference() { + return AstUtil.newQualifiedNameRef("initialize"); + } + } diff --git a/translator/src/org/jetbrains/k2js/translate/NamespaceInitializerVisitor.java b/translator/src/org/jetbrains/k2js/translate/NamespaceInitializerVisitor.java index eb5a32e12fd..4915eb42e78 100644 --- a/translator/src/org/jetbrains/k2js/translate/NamespaceInitializerVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/NamespaceInitializerVisitor.java @@ -2,10 +2,15 @@ package org.jetbrains.k2js.translate; import com.google.dart.compiler.backend.js.ast.JsFunction; import com.google.dart.compiler.backend.js.ast.JsScope; +import com.google.dart.compiler.backend.js.ast.JsStatement; import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetNamespace; +import java.util.ArrayList; +import java.util.List; + /** * @author Talanov Pavel */ @@ -28,4 +33,14 @@ public final class NamespaceInitializerVisitor extends AbstractInitializerVisito return result; } + @Override + @NotNull + public List visitNamespace(@NotNull JetNamespace expression, @NotNull TranslationContext context) { + List initializerStatements = new ArrayList(); + for (JetDeclaration declaration : expression.getDeclarations()) { + initializerStatements.addAll(declaration.accept(this, context)); + } + return initializerStatements; + } + } diff --git a/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java b/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java index 910f98776d2..eb7fb486b95 100644 --- a/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java @@ -14,48 +14,61 @@ import java.util.List; public final class NamespaceTranslator extends AbstractTranslator { @NotNull - public static NamespaceTranslator newInstance(@NotNull TranslationContext context) { - return new NamespaceTranslator(context); + private final JetNamespace namespace; + @NotNull + private final JsName namespaceName; + + @NotNull + public static JsStatement translate(@NotNull TranslationContext context, + @NotNull JetNamespace namespace) { + return (new NamespaceTranslator(context, namespace)).translateNamespace(); } - private NamespaceTranslator(@NotNull TranslationContext context) { + private NamespaceTranslator(@NotNull TranslationContext context, @NotNull JetNamespace namespace) { super(context); + this.namespace = namespace; + this.namespaceName = context.getNameForElement(namespace); } @NotNull - public JsStatement translateNamespace(@NotNull JetNamespace namespace) { + public JsStatement translateNamespace() { ClassDeclarationTranslator translator = new ClassDeclarationTranslator(translationContext(), namespace); translator.generateDeclarations(); JsName declarationsObjectName = translator.getDeclarationsObjectName(); JsBlock result = new JsBlock(); - JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation(namespace); + JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation(); namespaceDeclaration.getArguments().add(declarationsObjectName.makeRef()); - addMemberDeclarations(namespace, namespaceDeclaration); + addMemberDeclarations(namespaceDeclaration); result.addStatement(translator.getDeclarationsStatement()); - result.addStatement(namespaceDeclarationStatement(namespace, namespaceDeclaration)); + result.addStatement(namespaceDeclarationStatement(namespaceDeclaration)); + result.addStatement(namespaceInitializeStatement()); return result; } + private JsStatement namespaceInitializeStatement() { + JsNameRef initializeMethodReference = Namer.initializeMethodReference(); + AstUtil.setQualifier(initializeMethodReference, namespaceName.makeRef()); + return AstUtil.newInvocation(initializeMethodReference).makeStmt(); + } + @NotNull - private JsInvocation namespaceCreateMethodInvocation(@NotNull JetNamespace namespace) { + private JsInvocation namespaceCreateMethodInvocation() { return AstUtil.newInvocation(Namer.namespaceCreationMethodReference()); } @NotNull - private JsStatement namespaceDeclarationStatement(@NotNull JetNamespace namespace, - @NotNull JsInvocation namespaceDeclaration) { + private JsStatement namespaceDeclarationStatement(@NotNull JsInvocation namespaceDeclaration) { return AstUtil.newAssignmentStatement (translationContext().getNameForElement(namespace).makeRef(), namespaceDeclaration); } - private void addMemberDeclarations(@NotNull JetNamespace namespace, - @NotNull JsInvocation jsNamespace) { - JsObjectLiteral jsClassDescription = translateNamespaceMemberDeclarations(namespace); + private void addMemberDeclarations(@NotNull JsInvocation jsNamespace) { + JsObjectLiteral jsClassDescription = translateNamespaceMemberDeclarations(); jsNamespace.getArguments().add(jsClassDescription); } @NotNull - private JsObjectLiteral translateNamespaceMemberDeclarations(@NotNull JetNamespace namespace) { + private JsObjectLiteral translateNamespaceMemberDeclarations() { List propertyList = new ArrayList(); propertyList.add(InitializerGenerator.generateInitializeMethod(namespace, translationContext())); propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(namespace, diff --git a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java index 6ceeee62ce4..2ef432566fa 100644 --- a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java @@ -92,7 +92,8 @@ public final class PropertyAccessTranslator extends AbstractTranslator { if (setterName == null) { return null; } - return AstUtil.newInvocation(AstUtil.thisQualifiedReference(setterName)); + JsNameRef setterReference = Translation.generateCorrectReference(translationContext(), expression, setterName); + return AstUtil.newInvocation(setterReference); } @Nullable diff --git a/translator/src/org/jetbrains/k2js/translate/ReferenceProvider.java b/translator/src/org/jetbrains/k2js/translate/ReferenceProvider.java index 2b98dbee769..e64dba921ff 100644 --- a/translator/src/org/jetbrains/k2js/translate/ReferenceProvider.java +++ b/translator/src/org/jetbrains/k2js/translate/ReferenceProvider.java @@ -32,10 +32,10 @@ public final class ReferenceProvider { //TODO @NotNull public JsNameRef generateCorrectReference() { - if (requiresThisQualifier) { - return AstUtil.thisQualifiedReference(referencedName); - } else if (requiresNamespaceQualifier) { + if (requiresNamespaceQualifier) { return context.getNamespaceQualifiedReference(referencedName); + } else if (requiresThisQualifier) { + return AstUtil.thisQualifiedReference(referencedName); } return referencedName.makeRef(); } @@ -46,9 +46,8 @@ public final class ReferenceProvider { private boolean requiresThisQualifier(@NotNull JetSimpleNameExpression expression) { JsName name = context.enclosingScope().findExistingName(referencedName.getIdent()); - boolean isNamespaceMember = requiresNamespaceQualifier; boolean isClassMember = context.classScope().ownsName(name); boolean isBackingFieldAccess = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER; - return (isNamespaceMember && !isClassMember) || isClassMember || isBackingFieldAccess; + return isClassMember || isBackingFieldAccess; } } diff --git a/translator/src/org/jetbrains/k2js/translate/Translation.java b/translator/src/org/jetbrains/k2js/translate/Translation.java index 8d049e8b3e6..95f45474b52 100644 --- a/translator/src/org/jetbrains/k2js/translate/Translation.java +++ b/translator/src/org/jetbrains/k2js/translate/Translation.java @@ -5,6 +5,7 @@ import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.psi.JetWhenExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.k2js.declarations.Declarations; @@ -32,8 +33,9 @@ public final class Translation { } @NotNull - static public NamespaceTranslator namespaceTranslator(@NotNull TranslationContext context) { - return NamespaceTranslator.newInstance(context); + static public JsStatement translateNamespace(@NotNull JetNamespace namespace, + @NotNull TranslationContext context) { + return NamespaceTranslator.translate(context, namespace); } @NotNull @@ -76,10 +78,19 @@ public final class Translation { return WhenTranslator.translateWhenExpression(expression, context); } + @NotNull + static public JsNameRef generateCorrectReference(@NotNull TranslationContext context, + @NotNull JetSimpleNameExpression expression, + @NotNull JsName referencedName) { + return (new ReferenceProvider(context, expression, referencedName)).generateCorrectReference(); + } + public static void generateAst(@NotNull JsProgram result, @NotNull BindingContext bindingContext, @NotNull Declarations declarations, @NotNull JetNamespace namespace) { JsBlock block = result.getFragmentBlock(0); TranslationContext context = TranslationContext.rootContext(result, bindingContext, declarations); - block.addStatement(Translation.namespaceTranslator(context).translateNamespace(namespace)); + block.addStatement(Translation.translateNamespace(namespace, context)); } + + } diff --git a/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java b/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java index 4ec33f7df8c..0dfd90ca38c 100644 --- a/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java @@ -26,7 +26,11 @@ public class TranslatorVisitor extends JetVisitor { @NotNull protected JsNameRef backingFieldReference(@NotNull JetProperty expression, @NotNull TranslationContext context) { - return AstUtil.thisQualifiedReference(getBackingFieldName(getPropertyName(expression), context)); + JsName backingFieldName = getBackingFieldName(getPropertyName(expression), context); + if (BindingUtils.belongsToNamespace(context.bindingContext(), expression)) { + return context.getNamespaceQualifiedReference(backingFieldName); + } + return AstUtil.thisQualifiedReference(backingFieldName); } @NotNull diff --git a/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java b/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java index b1b2fd616c4..9ebb587e83e 100644 --- a/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java +++ b/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java @@ -89,12 +89,6 @@ public class KotlinLibTest extends IncludeLibraryTest { new RhinoFunctionResultChecker("test", true)); } - @Test - public void namespacePropertyAccess() throws Exception { - runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("namespace2.js")), - new RhinoFunctionResultChecker("test", true)); - } - @Test public void isSameType() throws Exception { runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isSameType.js")), diff --git a/translator/testFiles/kotlinLib/cases/namespace2.js b/translator/testFiles/kotlinLib/cases/namespace2.js deleted file mode 100644 index 67f1f393144..00000000000 --- a/translator/testFiles/kotlinLib/cases/namespace2.js +++ /dev/null @@ -1,35 +0,0 @@ -{ - classes = function(){ - return {}; - } - (); - foo = Namespace.create(classes, {initialize:function(){ - this.$b = 0 - } - , set_b:function(tmp$0){ - this.$b = tmp$0; - } - , get_b:function(){ - return this.$b; - } - , loop:function(times){ - while (times > 0) { - var u = function(){ - return this.set_b(this.get_b() + 1); - } - ; - u(times--); - } - } - , box:function(){ - this.loop(5); - return this.get_b() === 5; - } - }); -} - - - -function test() { - return foo.box() -}