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 fec36249258..199c9b85aad 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 @@ -35,6 +35,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator; import org.jetbrains.k2js.translate.utils.AnnotationsUtils; +import org.jetbrains.k2js.translate.utils.JsAstUtils; import java.util.ArrayList; import java.util.Collection; @@ -200,14 +201,14 @@ public final class ClassTranslator extends AbstractTranslator { } else { if (qualifiedReference != null) { - // about "prototype" -- see http://code.google.com/p/jsdoc-toolkit/wiki/TagLends - invocationArguments.add(new JsDocComment("lends", new JsNameRef("prototype", qualifiedReference))); + // about "prototype" - see http://code.google.com/p/jsdoc-toolkit/wiki/TagLends + invocationArguments.add(new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, new JsNameRef("prototype", qualifiedReference))); } invocationArguments.add(new JsObjectLiteral(properties, true)); } } if (hasStaticProperties) { - invocationArguments.add(new JsDocComment("lends", qualifiedReference)); + invocationArguments.add(new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, qualifiedReference)); invocationArguments.add(new JsObjectLiteral(staticProperties, true)); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java index ede69fc2074..3ca18f22a1e 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java @@ -19,6 +19,7 @@ package org.jetbrains.k2js.translate.declaration; import com.google.dart.compiler.backend.js.ast.*; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -31,6 +32,7 @@ import org.jetbrains.k2js.translate.utils.JsAstUtils; import java.util.*; import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar; +import static org.jetbrains.k2js.translate.utils.TranslationUtils.getQualifiedReference; public final class NamespaceDeclarationTranslator extends AbstractTranslator { private final Iterable files; @@ -99,23 +101,33 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { rootNamespace = (NamespaceDescriptor) rootNamespace.getContainingDeclaration(); } - List args; JsObjectLiteral rootNamespaceDefinition = new JsObjectLiteral(true); - if (context().isEcma5()) { - args = Arrays.asList(JsLiteral.NULL, rootNamespaceDefinition); + descriptorToDefineInvocation.put(rootNamespace, createDefineInvocation(rootNamespace, null, rootNamespaceDefinition, context())); + return rootNamespaceDefinition; + } + + static List createDefineInvocation( + @NotNull NamespaceDescriptor descriptor, + @Nullable JsExpression initializer, + @NotNull JsObjectLiteral members, + @NotNull TranslationContext context + ) { + if (context.isEcma5()) { + return Arrays.asList(initializer == null ? JsLiteral.NULL : initializer, + new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, getQualifiedReference(context, descriptor)), + members); } else { - args = Collections.singletonList(rootNamespaceDefinition); + return Collections.singletonList(members); } - - descriptorToDefineInvocation.put(rootNamespace, args); - return rootNamespaceDefinition; } private JsVar getDeclaration(@NotNull JsObjectLiteral rootNamespaceDefinition) { JsExpression packageMapValue; if (context().isEcma5()) { - packageMapValue = new JsInvocation(JsAstUtils.CREATE_OBJECT, JsLiteral.NULL, rootNamespaceDefinition); + packageMapValue = new JsInvocation(JsAstUtils.CREATE_OBJECT, JsLiteral.NULL, + new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, Namer.getRootNamespaceName()), + rootNamespaceDefinition); } else { packageMapValue = rootNamespaceDefinition; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java index 1e179e579d6..1bb384775c2 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java @@ -35,8 +35,6 @@ import org.jetbrains.k2js.translate.utils.AnnotationsUtils; import org.jetbrains.k2js.translate.utils.BindingUtils; import org.jetbrains.k2js.translate.utils.JsAstUtils; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -130,18 +128,11 @@ final class NamespaceTranslator extends AbstractTranslator { } private List getListFromPlace(List defineInvocation) { - return ((JsObjectLiteral) defineInvocation.get(context().isEcma5() ? 1 : 0)).getPropertyInitializers(); + return ((JsObjectLiteral) defineInvocation.get(context().isEcma5() ? 2 : 0)).getPropertyInitializers(); } private List createDefineInvocation(@Nullable JsExpression initializer, @NotNull JsObjectLiteral members) { - if (context().isEcma5()) { - return Arrays.asList(initializer == null ? JsLiteral.NULL : initializer, - new JsDocComment("lends", getQualifiedReference(context(), descriptor)), - members); - } - else { - return Collections.singletonList(members); - } + return NamespaceDeclarationTranslator.createDefineInvocation(descriptor, initializer, members, context()); } private JsPropertyInitializer getEntry(@NotNull NamespaceDescriptor descriptor, List defineInvocation) { @@ -154,7 +145,7 @@ final class NamespaceTranslator extends AbstractTranslator { Map> descriptorToDeclarationPlace) { List parentDefineInvocation = descriptorToDeclarationPlace.get(parentDescriptor); if (parentDefineInvocation != null) { - ((JsObjectLiteral) parentDefineInvocation.get(context().isEcma5() ? 1 : 0)).getPropertyInitializers().add(entry); + getListFromPlace(parentDefineInvocation).add(entry); return true; } return false; 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 07301c58929..d5f7cfaf29a 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 @@ -19,9 +19,7 @@ package org.jetbrains.k2js.translate.initializer; import com.google.dart.compiler.backend.js.ast.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.Named; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.psi.JetProperty; @@ -72,16 +70,16 @@ public final class InitializerUtils { ) { ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration); JsExpression value = ClassTranslator.generateObjectLiteral(declaration, descriptor, context); - initializers.add(create(descriptor, value, context)); + initializers.add(create(descriptor, !(descriptor.getContainingDeclaration() instanceof NamespaceDescriptor), value, context)); } - public static JsStatement create(Named named, JsExpression value, TranslationContext context) { + private static JsStatement create(DeclarationDescriptor descriptor, boolean enumerable, JsExpression value, TranslationContext context) { JsExpression expression; if (context.isEcma5()) { - expression = JsAstUtils.defineProperty(named.getName().asString(), JsAstUtils.createDataDescriptor(value), context); + expression = JsAstUtils.defineProperty(descriptor.getName().asString(), JsAstUtils.createDataDescriptor(value, false, enumerable), context); } else { - expression = assignment(new JsNameRef(named.getName().asString(), JsLiteral.THIS), value); + expression = assignment(new JsNameRef(descriptor.getName().asString(), JsLiteral.THIS), value); } return expression.makeStmt(); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java index 9f95c9a0759..c199fabaf3b 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java @@ -101,8 +101,8 @@ public final class AnnotationsUtils { } ClassDescriptor containingClass = getContainingClass(descriptor); return containingClass != null && - (getAnnotationByName(containingClass, ENUMERABLE) != null || - (containingClass.getKind().equals(ClassKind.OBJECT) && containingClass.getName().isSpecial())); + ((containingClass.getKind().equals(ClassKind.OBJECT) && containingClass.getName().isSpecial()) || + getAnnotationByName(containingClass, ENUMERABLE) != null); } public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java index 77b1a3ca736..bfb7a2e40c3 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java @@ -39,6 +39,8 @@ public final class JsAstUtils { private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(new JsNameRef("writable"), JsLiteral.TRUE); private static final JsPropertyInitializer ENUMERABLE = new JsPropertyInitializer(new JsNameRef("enumerable"), JsLiteral.TRUE); + public static final String LENDS_JS_DOC_TAG = "lends"; + static { JsNameRef globalObjectReference = new JsNameRef("Object"); DEFINE_PROPERTY.setQualifier(globalObjectReference); @@ -228,20 +230,18 @@ public final class JsAstUtils { } @NotNull - public static JsInvocation defineProperty(@NotNull String name, + public static JsInvocation defineProperty( + @NotNull String name, @NotNull JsObjectLiteral value, - @NotNull TranslationContext context) { - JsInvocation invocation = new JsInvocation(DEFINE_PROPERTY); - invocation.getArguments().add(JsLiteral.THIS); - invocation.getArguments().add(context.program().getStringLiteral(name)); - invocation.getArguments().add(value); - return invocation; + @NotNull TranslationContext context + ) { + return new JsInvocation(DEFINE_PROPERTY, JsLiteral.THIS, context.program().getStringLiteral(name), value); } @NotNull public static JsStatement defineSimpleProperty(@NotNull String name, @NotNull JsExpression value, @NotNull TranslationContext context) { if (context.isEcma5()) { - return defineProperty(name, createDataDescriptor(value, false), context).makeStmt(); + return defineProperty(name, createDataDescriptor(value, false, false), context).makeStmt(); } else { return assignment(new JsNameRef(name, JsLiteral.THIS), value).makeStmt(); } @@ -250,41 +250,41 @@ public final class JsAstUtils { @NotNull public static JsObjectLiteral createPropertyDataDescriptor(@NotNull FunctionDescriptor descriptor, @NotNull JsExpression value) { - return createPropertyDataDescriptor(descriptor.getModality().isOverridable(), descriptor, value); + return createPropertyDataDescriptor(descriptor, descriptor.getModality().isOverridable(), value); } @NotNull public static JsObjectLiteral createDataDescriptor(@NotNull JsExpression value) { - return createDataDescriptor(value, false); + return createDataDescriptor(value, false, false); } @NotNull - public static JsObjectLiteral createDataDescriptor(@NotNull JsExpression value, boolean writable) { + public static JsObjectLiteral createDataDescriptor(@NotNull JsExpression value, boolean writable, boolean enumerable) { JsObjectLiteral dataDescriptor = new JsObjectLiteral(); dataDescriptor.getPropertyInitializers().add(new JsPropertyInitializer(VALUE, value)); if (writable) { dataDescriptor.getPropertyInitializers().add(WRITABLE); } - return dataDescriptor; - } - - @NotNull - public static JsObjectLiteral createPropertyDataDescriptor(@NotNull PropertyDescriptor descriptor, - @NotNull JsExpression value) { - return createPropertyDataDescriptor(descriptor.isVar() || descriptor.getModality() == Modality.OPEN, descriptor, value); - } - - @NotNull - private static JsObjectLiteral createPropertyDataDescriptor(boolean writable, - @NotNull DeclarationDescriptor descriptor, - @NotNull JsExpression value) { - JsObjectLiteral dataDescriptor = createDataDescriptor(value, writable); - if (AnnotationsUtils.isEnumerable(descriptor)) { + if (enumerable) { dataDescriptor.getPropertyInitializers().add(ENUMERABLE); } return dataDescriptor; } + @NotNull + public static JsObjectLiteral createPropertyDataDescriptor(@NotNull PropertyDescriptor descriptor, @NotNull JsExpression value) { + return createPropertyDataDescriptor(descriptor, descriptor.isVar() || descriptor.getModality() == Modality.OPEN, value); + } + + @NotNull + private static JsObjectLiteral createPropertyDataDescriptor( + @NotNull DeclarationDescriptor descriptor, + boolean writable, + @NotNull JsExpression value + ) { + return createDataDescriptor(value, writable, AnnotationsUtils.isEnumerable(descriptor)); + } + @NotNull public static JsFunction createPackage(@NotNull List to, @NotNull JsScope scope) { JsFunction packageBlockFunction = createFunctionWithEmptyBody(scope); 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 06319675683..3be7316cae6 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 @@ -64,7 +64,7 @@ public final class TranslationUtils { @NotNull private static JsPropertyInitializer translateExtensionFunctionAsEcma5DataDescriptor(@NotNull JsFunction function, @NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context) { - JsObjectLiteral meta = createDataDescriptor(function, descriptor.getModality().isOverridable()); + JsObjectLiteral meta = createDataDescriptor(function, descriptor.getModality().isOverridable(), false); return new JsPropertyInitializer(context.getNameForDescriptor(descriptor).makeRef(), meta); }