From 02da9b42c171438b3ae921ea49bef6d9f6ca6294 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Mon, 19 Mar 2012 15:44:02 +0400 Subject: [PATCH] Support for simple cases when a namespace creates classes from other namespaces. --- .../test/semantics/MultiNamespaceTest.java | 15 +++++- .../k2js/test/semantics/NamespaceTest.java | 5 ++ .../k2js/translate/context/StaticContext.java | 39 +++++++++----- .../translate/context/TranslationContext.java | 4 +- .../NamespaceDeclarationTranslator.java | 18 +++++-- .../declaration/NamespaceTranslator.java | 26 ++++++--- .../QualifiedExpressionTranslator.java | 38 ++++++++++--- .../k2js/translate/utils/DescriptorUtils.java | 51 +++++++++--------- .../utils/NamespaceSortingUtils.java | 54 ------------------- .../cases/createClassFromOtherNamespace/a.kt | 5 ++ .../cases/createClassFromOtherNamespace/b.kt | 5 ++ .../cases/subnamespacesWithClashingNames/a.kt | 3 ++ .../cases/subnamespacesWithClashingNames/b.kt | 3 ++ .../a.kt | 5 ++ .../b.kt | 3 ++ .../classCreatedInDeeplyNestedNamespace.kt | 7 +++ 16 files changed, 164 insertions(+), 117 deletions(-) delete mode 100644 js/js.translator/src/org/jetbrains/k2js/translate/utils/NamespaceSortingUtils.java create mode 100644 js/js.translator/testFiles/multiNamespace/cases/createClassFromOtherNamespace/a.kt create mode 100644 js/js.translator/testFiles/multiNamespace/cases/createClassFromOtherNamespace/b.kt create mode 100644 js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNames/a.kt create mode 100644 js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNames/b.kt create mode 100644 js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNamesUsingImport/a.kt create mode 100644 js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNamesUsingImport/b.kt create mode 100644 js/js.translator/testFiles/namespace/cases/classCreatedInDeeplyNestedNamespace.kt diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/MultiNamespaceTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/MultiNamespaceTest.java index 2f9c3239cb3..826211e1932 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/MultiNamespaceTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/MultiNamespaceTest.java @@ -40,9 +40,20 @@ public class MultiNamespaceTest extends MultipleFilesTranslationTest { checkFooBoxIsTrue("namespaceVariableVisibleFromOtherNamespace"); } - public void testNestedNamespaceFunctionCalledFromOtherNamespace() throws Exception { - checkFooBoxIsTrue("nestedNamespaceFunctionCalledFromOtherNamespace"); + runMultiFileTest("nestedNamespaceFunctionCalledFromOtherNamespace", "a.foo", "box", true); + } + + public void testSubnamespacesWithClashingNames() throws Exception { + runMultiFileTest("subnamespacesWithClashingNames", "a.foo", "box", true); + } + + public void testSubnamespacesWithClashingNamesUsingImport() throws Exception { + runMultiFileTest("subnamespacesWithClashingNamesUsingImport", "a.foo", "box", true); + } + + public void testCreateClassFromOtherNamespace() throws Exception { + runMultiFileTest("createClassFromOtherNamespace", "a.foo", "box", true); } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NamespaceTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NamespaceTest.java index 4aec71a5c93..68939abe4df 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NamespaceTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NamespaceTest.java @@ -37,4 +37,9 @@ public final class NamespaceTest extends SingleFileTranslationTest { public void testDeeplyNestedNamespaceFunctionCalled() throws Exception { runFunctionOutputTest("deeplyNestedNamespaceFunctionCalled.kt", "foo1.foo2.foo3.foo5.foo6.foo7.foo8", "box", true); } + + + public void testClassCreatedInDeeplyNestedNamespace() throws Exception { + runFunctionOutputTest("classCreatedInDeeplyNestedNamespace.kt", "foo1.foo2.foo3.foo5.foo6.foo7.foo8", "box", true); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java index 1602554cc5e..3f78b937f7f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java @@ -27,6 +27,7 @@ import org.jetbrains.k2js.translate.context.generator.Generator; import org.jetbrains.k2js.translate.context.generator.Rule; import org.jetbrains.k2js.translate.intrinsic.Intrinsics; import org.jetbrains.k2js.translate.utils.AnnotationsUtils; +import org.jetbrains.k2js.translate.utils.DescriptorUtils; import org.jetbrains.k2js.translate.utils.JsAstUtils; import org.jetbrains.k2js.translate.utils.PredefinedAnnotation; @@ -51,7 +52,7 @@ public final class StaticContext { NamingScope scope = NamingScope.rootScope(jsRootScope); Intrinsics intrinsics = Intrinsics.standardLibraryIntrinsics(library); StandardClasses standardClasses = - StandardClasses.bindImplementations(namer.getKotlinScope()); + StandardClasses.bindImplementations(namer.getKotlinScope()); return new StaticContext(program, bindingContext, aliaser, namer, intrinsics, standardClasses, scope); } @@ -174,7 +175,7 @@ public final class StaticContext { if (!(descriptor instanceof NamespaceDescriptor)) { return null; } - String nameForNamespace = getNameForNamespace((NamespaceDescriptor) descriptor); + String nameForNamespace = getNameForNamespace((NamespaceDescriptor)descriptor); return getRootScope().declareUnobfuscatableName(nameForNamespace); } }; @@ -204,7 +205,7 @@ public final class StaticContext { return null; } boolean isGetter = descriptor instanceof PropertyGetterDescriptor; - String propertyName = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty().getName(); + String propertyName = ((PropertyAccessorDescriptor)descriptor).getCorrespondingProperty().getName(); String accessorName = Namer.getNameForAccessor(propertyName, isGetter); NamingScope enclosingScope = getEnclosingScope(descriptor); return enclosingScope.declareObfuscatableName(accessorName); @@ -245,12 +246,11 @@ public final class StaticContext { if (!descriptor.getName().equals("toString")) { return null; } - if (((FunctionDescriptor) descriptor).getValueParameters().isEmpty()) { + if (((FunctionDescriptor)descriptor).getValueParameters().isEmpty()) { return getEnclosingScope(descriptor).declareUnobfuscatableName("toString"); } return null; } - }; Rule overridingDescriptorsReferToOriginalName = new Rule() { @@ -260,7 +260,7 @@ public final class StaticContext { if (!(descriptor instanceof FunctionDescriptor)) { return null; } - FunctionDescriptor overriddenDescriptor = getOverriddenDescriptor((FunctionDescriptor) descriptor); + FunctionDescriptor overriddenDescriptor = getOverriddenDescriptor((FunctionDescriptor)descriptor); if (overriddenDescriptor == null) { return null; } @@ -295,7 +295,7 @@ public final class StaticContext { if (!(descriptor instanceof ClassDescriptor)) { return null; } - if (getSuperclass((ClassDescriptor) descriptor) == null) { + if (getSuperclass((ClassDescriptor)descriptor) == null) { return getRootScope().innerScope("Scope for class " + descriptor.getName()); } return null; @@ -307,7 +307,7 @@ public final class StaticContext { if (!(descriptor instanceof ClassDescriptor)) { return null; } - ClassDescriptor superclass = getSuperclass((ClassDescriptor) descriptor); + ClassDescriptor superclass = getSuperclass((ClassDescriptor)descriptor); if (superclass == null) { return null; } @@ -354,7 +354,7 @@ public final class StaticContext { @Nullable public JsNameRef getQualifierForDescriptor(@NotNull DeclarationDescriptor descriptor) { - if (qualifierIsNull.get(descriptor) != null) { + if (qualifierIsNull.get(descriptor.getOriginal()) != null) { return null; } return qualifiers.get(descriptor.getOriginal()); @@ -362,7 +362,7 @@ public final class StaticContext { private final class QualifierGenerator extends Generator { public QualifierGenerator() { - Rule namespacesHaveNoQualifiers = new Rule() { + Rule standardObjectsHaveKotlinQualifier = new Rule() { @Override public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) { if (!standardClasses.isStandardObject(descriptor)) { @@ -379,7 +379,9 @@ public final class StaticContext { return null; } JsName containingDeclarationName = getNameForDescriptor(containingDeclaration); - return containingDeclarationName.makeRef(); + JsNameRef qualifier = containingDeclarationName.makeRef(); + qualifier.setQualifier(getQualifierForDescriptor(containingDeclaration)); + return qualifier; } }; Rule constructorHaveTheSameQualifierAsTheClass = new Rule() { @@ -405,7 +407,7 @@ public final class StaticContext { }; addRule(libraryObjectsHaveKotlinQualifier); addRule(constructorHaveTheSameQualifierAsTheClass); - addRule(namespacesHaveNoQualifiers); + addRule(standardObjectsHaveKotlinQualifier); addRule(namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier); } } @@ -441,6 +443,19 @@ public final class StaticContext { return true; } }; + Rule topLevelNamespaceHaveNoQualifier = new Rule() { + @Override + public Boolean apply(@NotNull DeclarationDescriptor descriptor) { + if (!(descriptor instanceof NamespaceDescriptor)) { + return null; + } + if (DescriptorUtils.isTopLevelNamespace((NamespaceDescriptor)descriptor)) { + return true; + } + return null; + } + }; + addRule(topLevelNamespaceHaveNoQualifier); addRule(propertiesHaveNoQualifiers); addRule(variableAsFunctionsHaveNoQualifiers); addRule(nativeObjectsHaveNoQualifiers); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java index d55d61bb2c7..e463e7a5020 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java @@ -76,7 +76,7 @@ public final class TranslationContext { @NotNull public JsBlock getBlockForDescriptor(@NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof CallableDescriptor) { - return getFunctionObject((CallableDescriptor) descriptor).getBody(); + return getFunctionObject((CallableDescriptor)descriptor).getBody(); } else { return new JsBlock(); @@ -111,7 +111,7 @@ public final class TranslationContext { @Nullable public JsNameRef getQualifierForDescriptor(@NotNull DeclarationDescriptor descriptor) { - return staticContext.getQualifierForDescriptor(descriptor.getOriginal()); + return staticContext.getQualifierForDescriptor(descriptor); } @NotNull 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 8cdc45f6f25..f1c97c667db 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 @@ -31,7 +31,6 @@ import java.util.Set; import static org.jetbrains.k2js.translate.utils.BindingUtils.getAllNonNativeNamespaceDescriptors; import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getAllClassesDefinedInNamespace; -import static org.jetbrains.k2js.translate.utils.NamespaceSortingUtils.sortNamespacesUsingQualificationOrder; /** * @author Pavel Talanov @@ -51,7 +50,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { private NamespaceDeclarationTranslator(@NotNull List namespaceDescriptors, @NotNull TranslationContext context) { super(context); - this.namespaceDescriptors = sortNamespacesUsingQualificationOrder(namespaceDescriptors); + this.namespaceDescriptors = namespaceDescriptors; this.classDeclarationTranslator = new ClassDeclarationTranslator(getAllClasses(), context); } @@ -91,7 +90,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { @NotNull private List getTranslatorsForNonEmptyNamespaces() { List namespaceTranslators = Lists.newArrayList(); - for (NamespaceDescriptor descriptor : namespaceDescriptors) { + for (NamespaceDescriptor descriptor : filterTopLevelNamespaces(namespaceDescriptors)) { if (!DescriptorUtils.isNamespaceEmpty(descriptor)) { namespaceTranslators.add(new NamespaceTranslator(descriptor, classDeclarationTranslator, context())); } @@ -103,7 +102,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { private static List declarationStatements(@NotNull List namespaceTranslators) { List result = Lists.newArrayList(); for (NamespaceTranslator translator : namespaceTranslators) { - result.add(translator.getDeclarationStatement()); + result.add(translator.getDeclarationAsVar()); } return result; } @@ -116,4 +115,15 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { } return result; } + + @NotNull + private static List filterTopLevelNamespaces(@NotNull List namespaceDescriptors) { + List result = Lists.newArrayList(); + for (NamespaceDescriptor descriptor : namespaceDescriptors) { + if (DescriptorUtils.isTopLevelNamespace(descriptor)) { + result.add(descriptor); + } + } + return result; + } } 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 201a0b79c01..94795cf193e 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 @@ -64,25 +64,35 @@ public final class NamespaceTranslator extends AbstractTranslator { } @NotNull - private JsInvocation namespaceCreateMethodInvocation() { - return AstUtil.newInvocation(context().namer().namespaceCreationMethodReference()); + public JsStatement getDeclarationAsVar() { + return newVar(namespaceName, getNamespaceDeclaration()); } @NotNull - public JsStatement getDeclarationStatement() { + public JsPropertyInitializer getDeclarationAsInitializer() { + return new JsPropertyInitializer(namespaceName.makeRef(), getNamespaceDeclaration()); + } + + @NotNull + private JsInvocation getNamespaceDeclaration() { JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation(); namespaceDeclaration.getArguments().add(translateNamespaceMemberDeclarations()); namespaceDeclaration.getArguments().add(getClassesAndNestedNamespaces()); - return newVar(namespaceName, namespaceDeclaration); + return namespaceDeclaration; + } + + @NotNull + private JsInvocation namespaceCreateMethodInvocation() { + return AstUtil.newInvocation(context().namer().namespaceCreationMethodReference()); } @NotNull private JsObjectLiteral getClassesAndNestedNamespaces() { JsObjectLiteral classesAndNestedNamespaces = new JsObjectLiteral(); classesAndNestedNamespaces.getPropertyInitializers() - .addAll(getClassesDefined()); + .addAll(getClassesDefined()); classesAndNestedNamespaces.getPropertyInitializers() - .addAll(getNestedNamespaceDeclarations()); + .addAll(getNestedNamespaceDeclarations()); return classesAndNestedNamespaces; } @@ -96,8 +106,8 @@ public final class NamespaceTranslator extends AbstractTranslator { List result = Lists.newArrayList(); List nestedNamespaces = DescriptorUtils.getNestedNamespaces(descriptor); for (NamespaceDescriptor nestedNamespace : nestedNamespaces) { - JsName nameForDescriptor = context().getNameForDescriptor(nestedNamespace); - result.add(new JsPropertyInitializer(nameForDescriptor.makeRef(), nameForDescriptor.makeRef())); + NamespaceTranslator nestedNamespaceTranslator = new NamespaceTranslator(nestedNamespace, classDeclarationTranslator, context()); + result.add(nestedNamespaceTranslator.getDeclarationAsInitializer()); } return result; } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java index 65e0609b5cb..a4d4e4972b5 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java @@ -18,13 +18,14 @@ package org.jetbrains.k2js.translate.reference; import com.google.dart.compiler.backend.js.ast.JsExpression; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetCallExpression; -import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.psi.JetQualifiedExpression; -import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.k2js.translate.context.TranslationContext; import static org.jetbrains.k2js.translate.general.Translation.translateAsExpression; +import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression; import static org.jetbrains.k2js.translate.utils.PsiUtils.getNotNullSimpleNameSelector; import static org.jetbrains.k2js.translate.utils.PsiUtils.getSelector; @@ -58,7 +59,7 @@ public final class QualifiedExpressionTranslator { } @NotNull - private static JsExpression dispatchToCorrectTranslator(@NotNull JsExpression receiver, + private static JsExpression dispatchToCorrectTranslator(@Nullable JsExpression receiver, @NotNull JetExpression selector, @NotNull CallType callType, @NotNull TranslationContext context) { @@ -76,10 +77,31 @@ public final class QualifiedExpressionTranslator { throw new AssertionError("Unexpected qualified expression: " + selector.getText()); } - //TODO: if has duplications - @NotNull + @Nullable private static JsExpression translateReceiver(@NotNull JetQualifiedExpression expression, @NotNull TranslationContext context) { - return translateAsExpression(expression.getReceiverExpression(), context); + JetExpression receiverExpression = expression.getReceiverExpression(); + if (isFullQualifierForExpression(receiverExpression, context)) { + return null; + } + return translateAsExpression(receiverExpression, context); + } + + //TODO: prove correctness + private static boolean isFullQualifierForExpression(@Nullable JetExpression receiverExpression, @NotNull TranslationContext context) { + if (receiverExpression == null) { + return false; + } + if (receiverExpression instanceof JetReferenceExpression) { + DeclarationDescriptor descriptorForReferenceExpression = + getDescriptorForReferenceExpression(context.bindingContext(), (JetReferenceExpression)receiverExpression); + if (descriptorForReferenceExpression instanceof NamespaceDescriptor) { + return true; + } + } + if (receiverExpression instanceof JetQualifiedExpression) { + return isFullQualifierForExpression(((JetQualifiedExpression)receiverExpression).getSelectorExpression(), context); + } + return false; } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java index f47adab3ed9..8f67d12c6c8 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java @@ -66,8 +66,8 @@ public final class DescriptorUtils { @NotNull String name) { Set functionDescriptors = scope.getFunctions(name); assert functionDescriptors.size() == 1 : - "In scope " + scope + " supposed to be exactly one " + name + " function.\n" + - "Found: " + functionDescriptors.size(); + "In scope " + scope + " supposed to be exactly one " + name + " function.\n" + + "Found: " + functionDescriptors.size(); //noinspection LoopStatementThatDoesntLoop for (FunctionDescriptor descriptor : functionDescriptors) { return descriptor; @@ -84,7 +84,7 @@ public final class DescriptorUtils { Set variables = scope.getProperties(name); assert variables.size() == 1 : "Actual size: " + variables.size(); VariableDescriptor variable = variables.iterator().next(); - PropertyDescriptor descriptor = (PropertyDescriptor) variable; + PropertyDescriptor descriptor = (PropertyDescriptor)variable; assert descriptor != null : "Must have a descriptor."; return descriptor; } @@ -120,15 +120,15 @@ public final class DescriptorUtils { @NotNull public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) { DeclarationDescriptor superClassDescriptor = - type.getConstructor().getDeclarationDescriptor(); + type.getConstructor().getDeclarationDescriptor(); assert superClassDescriptor instanceof ClassDescriptor - : "Superclass descriptor of a type should be of type ClassDescriptor"; - return (ClassDescriptor) superClassDescriptor; + : "Superclass descriptor of a type should be of type ClassDescriptor"; + return (ClassDescriptor)superClassDescriptor; } @NotNull public static VariableDescriptor getVariableDescriptorForVariableAsFunction - (@NotNull VariableAsFunctionDescriptor descriptor) { + (@NotNull VariableAsFunctionDescriptor descriptor) { VariableDescriptor functionVariable = descriptor.getVariableDescriptor(); assert functionVariable != null; return functionVariable; @@ -171,9 +171,9 @@ public final class DescriptorUtils { @NotNull public static DeclarationDescriptor getDeclarationDescriptorForReceiver - (@NotNull ReceiverDescriptor receiverParameter) { + (@NotNull ReceiverDescriptor receiverParameter) { DeclarationDescriptor declarationDescriptor = - receiverParameter.getType().getConstructor().getDeclarationDescriptor(); + receiverParameter.getType().getConstructor().getDeclarationDescriptor(); //TODO: WHY assert? assert declarationDescriptor != null; return declarationDescriptor.getOriginal(); @@ -194,7 +194,7 @@ public final class DescriptorUtils { DeclarationDescriptor containing = descriptor.getContainingDeclaration(); while (containing != null) { if (containing instanceof ClassDescriptor) { - return (ClassDescriptor) containing; + return (ClassDescriptor)containing; } containing = containing.getContainingDeclaration(); } @@ -206,7 +206,7 @@ public final class DescriptorUtils { List classDescriptors = Lists.newArrayList(); for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespaceDescriptor)) { if (descriptor instanceof ClassDescriptor) { - classDescriptors.add((ClassDescriptor) descriptor); + classDescriptors.add((ClassDescriptor)descriptor); } } return classDescriptors; @@ -217,7 +217,7 @@ public final class DescriptorUtils { List result = Lists.newArrayList(); for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespaceDescriptor)) { if (descriptor instanceof NamespaceDescriptor) { - result.add((NamespaceDescriptor) descriptor); + result.add((NamespaceDescriptor)descriptor); } } return result; @@ -235,21 +235,18 @@ public final class DescriptorUtils { } } - //TODO:? -// @NotNull -// public static FunctionDescriptor getOverriddenOrThis(@NotNull FunctionDescriptor functionDescriptor) { -// FunctionDescriptor overriddenDescriptor = getOverriddenDescriptor(functionDescriptor); -// if (overriddenDescriptor != null) { -// return overriddenDescriptor; -// } -// else { -// return functionDescriptor; -// } -// } + public static boolean isTopLevelNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { + NamespaceDescriptorParent containingDeclaration = namespaceDescriptor.getContainingDeclaration(); + boolean containedInModule = !(containingDeclaration instanceof NamespaceDescriptor); + if (containedInModule) { + return true; + } + //TODO + return containingDeclaration.getName().equals(""); + } @NotNull - public static List getContainedDescriptorsWhichAreNotPredefined - (@NotNull NamespaceDescriptor namespace) { + public static List getContainedDescriptorsWhichAreNotPredefined(@NotNull NamespaceDescriptor namespace) { List result = Lists.newArrayList(); for (DeclarationDescriptor descriptor : namespace.getMemberScope().getAllDescriptors()) { if (!AnnotationsUtils.isPredefinedObject(descriptor)) { @@ -264,7 +261,7 @@ public final class DescriptorUtils { List containedDescriptors = getContainedDescriptorsWhichAreNotPredefined(namespace); for (DeclarationDescriptor descriptor : containedDescriptors) { if (descriptor instanceof NamespaceDescriptor) { - if (!isNamespaceEmpty((NamespaceDescriptor) descriptor)) { + if (!isNamespaceEmpty((NamespaceDescriptor)descriptor)) { return false; } } @@ -282,7 +279,7 @@ public final class DescriptorUtils { while (!current.getName().equals("")) { result.add(current); if (current.getContainingDeclaration() instanceof NamespaceDescriptor) { - current = (NamespaceDescriptor) current.getContainingDeclaration(); + current = (NamespaceDescriptor)current.getContainingDeclaration(); assert current != null; } else { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/NamespaceSortingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/NamespaceSortingUtils.java deleted file mode 100644 index e9d4290f551..00000000000 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/NamespaceSortingUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2010-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.k2js.translate.utils; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorParent; - -import java.util.List; - -/** - * @author Pavel Talanov - */ -public final class NamespaceSortingUtils { - - private NamespaceSortingUtils() { - } - - @NotNull - public static List sortNamespacesUsingQualificationOrder - (@NotNull List namespaceDescriptors) { - PartiallyOrderedSet namespaceDescriptorPartiallyOrderedSet - = new PartiallyOrderedSet(namespaceDescriptors, qualificationOrder()); - return namespaceDescriptorPartiallyOrderedSet.partiallySortedElements(); - } - - @NotNull - private static PartiallyOrderedSet.Order qualificationOrder() { - return new PartiallyOrderedSet.Order() { - @Override - public boolean firstDependsOnSecond(@NotNull NamespaceDescriptor first, @NotNull NamespaceDescriptor second) { - NamespaceDescriptorParent containingDeclaration = first.getContainingDeclaration(); - if (containingDeclaration == null) { - return false; - } - return containingDeclaration.equals(second); - } - }; - } -} diff --git a/js/js.translator/testFiles/multiNamespace/cases/createClassFromOtherNamespace/a.kt b/js/js.translator/testFiles/multiNamespace/cases/createClassFromOtherNamespace/a.kt new file mode 100644 index 00000000000..303119efbd7 --- /dev/null +++ b/js/js.translator/testFiles/multiNamespace/cases/createClassFromOtherNamespace/a.kt @@ -0,0 +1,5 @@ +package a.foo + +import b.foo.* + +fun box() = (A().tadada(A())) \ No newline at end of file diff --git a/js/js.translator/testFiles/multiNamespace/cases/createClassFromOtherNamespace/b.kt b/js/js.translator/testFiles/multiNamespace/cases/createClassFromOtherNamespace/b.kt new file mode 100644 index 00000000000..a73ba23e674 --- /dev/null +++ b/js/js.translator/testFiles/multiNamespace/cases/createClassFromOtherNamespace/b.kt @@ -0,0 +1,5 @@ +package b.foo + +class A() { + fun tadada(a : A) = true +} \ No newline at end of file diff --git a/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNames/a.kt b/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNames/a.kt new file mode 100644 index 00000000000..881ec5f37a7 --- /dev/null +++ b/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNames/a.kt @@ -0,0 +1,3 @@ +package a.foo + +fun box() = (b.foo.f() == 1) \ No newline at end of file diff --git a/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNames/b.kt b/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNames/b.kt new file mode 100644 index 00000000000..4fd5b6b8ebb --- /dev/null +++ b/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNames/b.kt @@ -0,0 +1,3 @@ +package b.foo + +fun f() = 1 \ No newline at end of file diff --git a/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNamesUsingImport/a.kt b/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNamesUsingImport/a.kt new file mode 100644 index 00000000000..9e1d632af04 --- /dev/null +++ b/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNamesUsingImport/a.kt @@ -0,0 +1,5 @@ +package a.foo + +import b.foo.f + +fun box() = (f() == 1) \ No newline at end of file diff --git a/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNamesUsingImport/b.kt b/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNamesUsingImport/b.kt new file mode 100644 index 00000000000..4fd5b6b8ebb --- /dev/null +++ b/js/js.translator/testFiles/multiNamespace/cases/subnamespacesWithClashingNamesUsingImport/b.kt @@ -0,0 +1,3 @@ +package b.foo + +fun f() = 1 \ No newline at end of file diff --git a/js/js.translator/testFiles/namespace/cases/classCreatedInDeeplyNestedNamespace.kt b/js/js.translator/testFiles/namespace/cases/classCreatedInDeeplyNestedNamespace.kt new file mode 100644 index 00000000000..47d68ea3b2c --- /dev/null +++ b/js/js.translator/testFiles/namespace/cases/classCreatedInDeeplyNestedNamespace.kt @@ -0,0 +1,7 @@ +package foo1.foo2.foo3.foo5.foo6.foo7.foo8 + +fun box() = A().doBox() + +class A() { + fun doBox() = true +} \ No newline at end of file