diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/RegressionMergeEcmaTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/RegressionMergeEcmaTest.java index d83c7a92769..7b8c8962067 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/RegressionMergeEcmaTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/RegressionMergeEcmaTest.java @@ -55,9 +55,8 @@ public class RegressionMergeEcmaTest extends SingleFileTranslationTest { checkFooBoxIsOk(); } - //TODO - public void TestRootPackageValInit() throws Exception { - checkFooBoxIsOk(); + public void testRootPackageValInit() throws Exception { + runFunctionOutputTest(DEFAULT_ECMA_VERSIONS, getTestName(true) + ".kt", "_", "box", "OK"); } public void testIsClassSupport() throws Exception { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java index bec1d782a2e..8fed189d5d0 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java @@ -159,6 +159,8 @@ public final class Namer { @NotNull private final JsExpression definePackage; @NotNull + private final JsExpression defineRootPackage; + @NotNull private final JsName objectName; @NotNull private final JsName enumEntriesName; @@ -172,6 +174,7 @@ public final class Namer { traitName = kotlinScope.declareName(TRAIT_OBJECT_NAME); definePackage = kotlin("definePackage"); + defineRootPackage = kotlin("defineRootPackage"); className = kotlinScope.declareName(CLASS_OBJECT_NAME); enumEntriesName = kotlinScope.declareName(ENUM_ENTRIES_NAME); @@ -200,6 +203,11 @@ public final class Namer { return definePackage; } + @NotNull + public JsExpression rootPackageDefinitionMethodReference() { + return defineRootPackage; + } + @NotNull public JsExpression objectCreationMethodReference() { return kotlin(objectName); 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 82ee5fc5668..f57ac34285e 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 @@ -52,15 +52,15 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { private List translate() { // predictable order Map> descriptorToDefineInvocation = new THashMap>(); - JsObjectLiteral rootNamespaceDefinition = null; + NamespaceDescriptor rootNamespaceDescriptor = null; for (JetFile file : files) { NamespaceDescriptor descriptor = context().bindingContext().get(BindingContext.FILE_TO_NAMESPACE, file); assert descriptor != null; NamespaceTranslator translator = descriptorToTranslator.get(descriptor); if (translator == null) { - if (rootNamespaceDefinition == null) { - rootNamespaceDefinition = getRootPackage(descriptorToDefineInvocation, descriptor); + if (rootNamespaceDescriptor == null) { + rootNamespaceDescriptor = getRootPackageDescriptor(descriptorToDefineInvocation, descriptor); } translator = new NamespaceTranslator(descriptor, descriptorToDefineInvocation, context()); descriptorToTranslator.put(descriptor, translator); @@ -69,7 +69,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { translator.translate(file); } - if (rootNamespaceDefinition == null) { + if (rootNamespaceDescriptor == null) { return Collections.emptyList(); } @@ -89,20 +89,22 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { } vars.addIfHasInitializer(context().classDeclarationTranslator().getDeclaration()); - vars.addIfHasInitializer(getDeclaration(rootNamespaceDefinition)); + vars.addIfHasInitializer(getRootPackageDeclaration(descriptorToDefineInvocation.get(rootNamespaceDescriptor))); return result; } - private JsObjectLiteral getRootPackage(Map> descriptorToDefineInvocation, - NamespaceDescriptor descriptor) { + @NotNull + private NamespaceDescriptor getRootPackageDescriptor( + @NotNull Map> descriptorToDefineInvocation, + @NotNull NamespaceDescriptor descriptor + ) { NamespaceDescriptor rootNamespace = descriptor; while (DescriptorUtils.isTopLevelDeclaration(rootNamespace)) { rootNamespace = (NamespaceDescriptor) rootNamespace.getContainingDeclaration(); } - JsObjectLiteral rootNamespaceDefinition = new JsObjectLiteral(true); - descriptorToDefineInvocation.put(rootNamespace, createDefineInvocation(rootNamespace, null, rootNamespaceDefinition, context())); - return rootNamespaceDefinition; + descriptorToDefineInvocation.put(rootNamespace, createDefineInvocation(rootNamespace, null, new JsObjectLiteral(true), context())); + return rootNamespace; } static List createDefineInvocation( @@ -121,16 +123,8 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { } } - private JsVar getDeclaration(@NotNull JsObjectLiteral rootNamespaceDefinition) { - JsExpression packageMapValue; - if (context().isEcma5()) { - packageMapValue = new JsInvocation(JsAstUtils.CREATE_OBJECT, JsLiteral.NULL, - new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, Namer.getRootNamespaceName()), - rootNamespaceDefinition); - } - else { - packageMapValue = rootNamespaceDefinition; - } - return new JsVar(context().scope().declareName(Namer.getRootNamespaceName()), packageMapValue); + private JsVar getRootPackageDeclaration(@NotNull List defineInvocation) { + JsExpression rootPackageVar = new JsInvocation(context().namer().rootPackageDefinitionMethodReference(), defineInvocation); + return new JsVar(context().scope().declareName(Namer.getRootNamespaceName()), rootPackageVar); } } 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 bdd5f16ea6b..61ffd692982 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 @@ -197,14 +197,7 @@ final class NamespaceTranslator extends AbstractTranslator { if (initializer != null) { JsExpression value = Translation.translateAsExpression(initializer, initializerContext); PropertyDescriptor propertyDescriptor = getPropertyDescriptor(context.bindingContext(), property); - if (value instanceof JsLiteral) { - result.add(new JsPropertyInitializer(context.getNameForDescriptor(propertyDescriptor).makeRef(), - context().isEcma5() ? JsAstUtils - .createPropertyDataDescriptor(propertyDescriptor, value) : value)); - } - else { - initializerStatements.add(generateInitializerForProperty(context, propertyDescriptor, value)); - } + initializerStatements.add(generateInitializerForProperty(context, propertyDescriptor, value)); } JsStatement delegate = generateInitializerForDelegate(context, property); diff --git a/js/js.translator/testFiles/kotlin_lib_ecma5.js b/js/js.translator/testFiles/kotlin_lib_ecma5.js index 2e8c79fe121..f54c3ba39c3 100644 --- a/js/js.translator/testFiles/kotlin_lib_ecma5.js +++ b/js/js.translator/testFiles/kotlin_lib_ecma5.js @@ -244,11 +244,22 @@ var KotlinNew = {}; } }; + KotlinNew.defineRootPackage = function (initializer, members) { + var definition = Object.create(null, members === null ? undefined : members); + + if (initializer === null) { + definition.$initializer = emptyFunction; + } else { + definition.$initializer = initializer; + } + return definition; + }; + KotlinNew.defineModule = function (id, module) { if (id in Kotlin.modules) { - throw Kotlin.$new(Kotlin.IllegalArgumentException)(); + throw new Kotlin.IllegalArgumentException(); } - + module.$initializer.call(module); Object.defineProperty(Kotlin.modules, id, {value: module}); }; @@ -310,6 +321,10 @@ var Kotlin = Object.create(null); return KotlinNew.definePackage(initializer, members); }; + Kotlin.defineRootPackage = function (initializer, members) { + return KotlinNew.defineRootPackage(initializer, members); + }; + Kotlin.defineModule = function (id, module) { KotlinNew.defineModule(id, module); };