From 601cd4ce46db6def9ed1154d196cb43a7e70d440 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 7 Nov 2013 23:57:57 +0400 Subject: [PATCH] Migrated JS backend to package views and fragments. --- .../lang/descriptors/NamespaceDescriptor.java | 30 ----- .../jet/lang/resolve/DescriptorUtils.java | 4 - .../k2js/translate/context/Namer.java | 12 +- .../k2js/translate/context/StaticContext.java | 122 ++++++++++-------- .../translate/context/TranslationContext.java | 11 ++ .../k2js/translate/context/UsageTracker.java | 4 +- .../declaration/DefineInvocation.java | 6 +- .../NamespaceDeclarationTranslator.java | 59 ++++----- .../declaration/NamespaceTranslator.java | 56 ++++---- .../functions/factories/TopLevelFIF.java | 4 +- .../functions/patterns/PatternBuilder.java | 25 ++-- .../operation/CompareToInstrinsic.java | 2 +- .../intrinsic/operation/EqualsIntrinsic.java | 2 +- .../QualifiedExpressionTranslator.java | 4 +- .../k2js/translate/utils/JsAstUtils.java | 15 +++ .../translate/utils/JsDescriptorUtils.java | 14 +- 16 files changed, 172 insertions(+), 198 deletions(-) delete mode 100644 core/descriptors/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java deleted file mode 100644 index acafe0b5a51..00000000000 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2010-2013 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.jet.lang.descriptors; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.resolve.name.FqName; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; - -@Deprecated -public interface NamespaceDescriptor extends ClassOrNamespaceDescriptor { - @NotNull - JetScope getMemberScope(); - - @NotNull - FqName getFqName(); -} diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index e2701723725..b300ade1ff7 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -213,10 +213,6 @@ public class DescriptorUtils { return false; } - public static boolean isRootNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { - return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor; - } - public static boolean isFunctionLiteral(@NotNull FunctionDescriptor descriptor) { return descriptor instanceof AnonymousFunctionDescriptor; } 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 1b6dcc22b0d..9d2c0f77326 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 @@ -20,9 +20,8 @@ import com.google.dart.compiler.backend.js.ast.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.JetLanguage; import static org.jetbrains.jet.lang.descriptors.ClassKind.TRAIT; @@ -258,13 +257,8 @@ public final class Namer { } @NotNull - static String generateNamespaceName(@NotNull DeclarationDescriptor descriptor) { - if (DescriptorUtils.isRootNamespace((NamespaceDescriptor) descriptor)) { - return getRootNamespaceName(); - } - else { - return descriptor.getName().asString(); - } + static String generateNamespaceName(@NotNull FqName packageFqName) { + return packageFqName.isRoot() ? getRootNamespaceName() : packageFqName.shortName().asString(); } @NotNull 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 2b75f8a686f..9c22a2da29e 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 @@ -18,14 +18,15 @@ package org.jetbrains.k2js.translate.context; import com.google.common.collect.Maps; import com.google.dart.compiler.backend.js.ast.*; +import com.intellij.openapi.util.Factory; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.k2js.config.EcmaVersion; import org.jetbrains.k2js.config.LibrarySourcesConfig; import org.jetbrains.k2js.translate.context.generator.Generator; @@ -78,6 +79,8 @@ public final class StaticContext { @NotNull private final Generator names = new NameGenerator(); @NotNull + private final Map packageNames = Maps.newHashMap(); + @NotNull private final Generator scopes = new ScopeGenerator(); @NotNull private final Generator qualifiers = new QualifierGenerator(); @@ -161,9 +164,18 @@ public final class StaticContext { @NotNull public JsNameRef getQualifiedReference(@NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof PackageViewDescriptor) { + return getQualifiedReference(((PackageViewDescriptor) descriptor).getFqName()); + } return new JsNameRef(getNameForDescriptor(descriptor), getQualifierForDescriptor(descriptor)); } + @NotNull + public JsNameRef getQualifiedReference(@NotNull FqName packageFqName) { + return new JsNameRef(getNameForPackage(packageFqName), + packageFqName.isRoot() ? null : getQualifierForParentPackage(packageFqName.parent())); + } + @NotNull public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) { JsName name = names.get(descriptor.getOriginal()); @@ -171,6 +183,39 @@ public final class StaticContext { return name; } + @NotNull + public JsName getNameForPackage(@NotNull final FqName packageFqName) { + return ContainerUtil.getOrCreate(packageNames, packageFqName, new Factory() { + @Override + public JsName create() { + String name = Namer.generateNamespaceName(packageFqName); + return getRootScope().declareName(name); + } + }); + } + + @NotNull + private JsNameRef getQualifierForParentPackage(@NotNull FqName packageFqName) { + JsNameRef result = null; + JsNameRef qualifier = null; + + for (FqName pathElement : ContainerUtil.reverse(packageFqName.path())) { + JsNameRef ref = getNameForPackage(pathElement).makeRef(); + + if (qualifier == null) { + result = ref; + } + else { + qualifier.setQualifier(ref); + } + + qualifier = ref; + } + + assert result != null : "didn't iterate: " + packageFqName; + return result; + } + private final class NameGenerator extends Generator { public NameGenerator() { @@ -184,18 +229,6 @@ public final class StaticContext { return standardClasses.getStandardObjectName(data); } }; - Rule namespacesShouldBeDefinedInRootScope = new Rule() { - @Override - @Nullable - public JsName apply(@NotNull DeclarationDescriptor descriptor) { - if (!(descriptor instanceof NamespaceDescriptor)) { - return null; - } - - String name = Namer.generateNamespaceName(descriptor); - return getRootScope().declareName(name); - } - }; Rule memberDeclarationsInsideParentsScope = new Rule() { @Override @Nullable @@ -328,7 +361,6 @@ public final class StaticContext { addRule(constructorHasTheSameNameAsTheClass); addRule(propertyOrPropertyAccessor); addRule(predefinedObjectsHasUnobfuscatableNames); - addRule(namespacesShouldBeDefinedInRootScope); addRule(overridingDescriptorsReferToOriginalName); addRule(memberDeclarationsInsideParentsScope); } @@ -374,10 +406,10 @@ public final class StaticContext { return getScopeForDescriptor(superclass).innerScope("Scope for class " + descriptor.getName()); } }; - Rule generateNewScopesForNamespaceDescriptors = new Rule() { + Rule generateNewScopesForPackageDescriptors = new Rule() { @Override public JsScope apply(@NotNull DeclarationDescriptor descriptor) { - if (!(descriptor instanceof NamespaceDescriptor)) { + if (!(descriptor instanceof PackageFragmentDescriptor)) { return null; } return getRootScope().innerScope("Namespace " + descriptor.getName()); @@ -408,7 +440,7 @@ public final class StaticContext { addRule(createFunctionObjectsForCallableDescriptors); addRule(generateNewScopesForClassesWithNoAncestors); addRule(generateInnerScopesForDerivedClasses); - addRule(generateNewScopesForNamespaceDescriptors); + addRule(generateNewScopesForPackageDescriptors); addRule(generateInnerScopesForMembers); } } @@ -433,49 +465,41 @@ public final class StaticContext { } }; //TODO: review and refactor - Rule namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule() { + Rule packageLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule() { @Override public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) { DeclarationDescriptor containingDescriptor = getContainingDeclaration(descriptor); - if (!(containingDescriptor instanceof NamespaceDescriptor)) { + if (!(containingDescriptor instanceof PackageFragmentDescriptor)) { return null; } - JsNameRef result = new JsNameRef(getNameForDescriptor(containingDescriptor)); - if (DescriptorUtils.isRootNamespace((NamespaceDescriptor) containingDescriptor)) { + JsNameRef result = getQualifierForParentPackage(((PackageFragmentDescriptor) containingDescriptor).getFqName()); + + String moduleName = getExternalModuleName(descriptor); + if (moduleName == null) { return result; } - JsNameRef qualifier = result; - while ((containingDescriptor = getContainingDeclaration(containingDescriptor)) instanceof NamespaceDescriptor && - !DescriptorUtils.isRootNamespace((NamespaceDescriptor) containingDescriptor)) { - JsNameRef ref = getNameForDescriptor(containingDescriptor).makeRef(); - qualifier.setQualifier(ref); - qualifier = ref; + if (LibrarySourcesConfig.UNKNOWN_EXTERNAL_MODULE_NAME.equals(moduleName)) { + return null; } + JsAstUtils.replaceRootReference( + result, new JsArrayAccess(namer.kotlin("modules"), program.getStringLiteral(moduleName))); + return result; + } + + private String getExternalModuleName(DeclarationDescriptor descriptor) { PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); if (element == null && descriptor instanceof PropertyAccessorDescriptor) { element = BindingContextUtils.descriptorToDeclaration(bindingContext, ((PropertyAccessorDescriptor) descriptor) .getCorrespondingProperty()); } - if (element != null) { - PsiFile file = element.getContainingFile(); - String moduleName = file.getUserData(LibrarySourcesConfig.EXTERNAL_MODULE_NAME); - if (LibrarySourcesConfig.UNKNOWN_EXTERNAL_MODULE_NAME.equals(moduleName)) { - return null; - } - else if (moduleName != null) { - qualifier.setQualifier(new JsArrayAccess(namer.kotlin("modules"), program.getStringLiteral(moduleName))); - } + if (element == null) { + return null; } - - if (qualifier.getQualifier() == null) { - qualifier.setQualifier(new JsNameRef(Namer.getRootNamespaceName())); - } - - return result; + return element.getContainingFile().getUserData(LibrarySourcesConfig.EXTERNAL_MODULE_NAME); } }; Rule constructorHaveTheSameQualifierAsTheClass = new Rule() { @@ -501,7 +525,7 @@ public final class StaticContext { addRule(libraryObjectsHaveKotlinQualifier); addRule(constructorHaveTheSameQualifierAsTheClass); addRule(standardObjectsHaveKotlinQualifier); - addRule(namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier); + addRule(packageLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier); } } @@ -527,16 +551,6 @@ public final class StaticContext { return true; } }; - Rule topLevelNamespaceHaveNoQualifier = new Rule() { - @Override - public Boolean apply(@NotNull DeclarationDescriptor descriptor) { - if (descriptor instanceof NamespaceDescriptor && DescriptorUtils.isRootNamespace((NamespaceDescriptor) descriptor)) { - return true; - } - return null; - } - }; - addRule(topLevelNamespaceHaveNoQualifier); addRule(propertiesHaveNoQualifiers); 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 9428a35d459..643a6d9a7da 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 @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator; import org.jetbrains.k2js.translate.intrinsic.Intrinsics; @@ -170,6 +171,11 @@ public class TranslationContext { return staticContext.getNameForDescriptor(descriptor); } + @NotNull + public JsName getNameForPackage(@NotNull FqName fqName) { + return staticContext.getNameForPackage(fqName); + } + @NotNull public JsName declarePropertyOrPropertyAccessorName(@NotNull DeclarationDescriptor descriptor, @NotNull String name, boolean fresh) { return staticContext.declarePropertyOrPropertyAccessorName(descriptor, name, fresh); @@ -180,6 +186,11 @@ public class TranslationContext { return staticContext.getQualifiedReference(descriptor); } + @NotNull + public JsNameRef getQualifiedReference(@NotNull FqName packageFqName) { + return staticContext.getQualifiedReference(packageFqName); + } + @Nullable public JsNameRef getQualifierForDescriptor(@NotNull DeclarationDescriptor descriptor) { return staticContext.getQualifierForDescriptor(descriptor); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/UsageTracker.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/UsageTracker.java index d6cf44c34a9..2389d4af1f0 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/UsageTracker.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/UsageTracker.java @@ -165,13 +165,13 @@ public final class UsageTracker { return false; } - // differs from DescriptorUtils - fails if reach NamespaceDescriptor + // differs from DescriptorUtils - fails if reach PackageFragmentDescriptor private static boolean isAncestor( @NotNull DeclarationDescriptor ancestor, @NotNull DeclarationDescriptor declarationDescriptor ) { DeclarationDescriptor descriptor = declarationDescriptor.getContainingDeclaration(); - while (descriptor != null && !(descriptor instanceof NamespaceDescriptor)) { + while (descriptor != null && !(descriptor instanceof PackageFragmentDescriptor)) { if (ancestor == descriptor) { return true; } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DefineInvocation.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DefineInvocation.java index 6fbf09056d8..07c00f0b22e 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DefineInvocation.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DefineInvocation.java @@ -19,7 +19,7 @@ package org.jetbrains.k2js.translate.declaration; import com.google.dart.compiler.backend.js.ast.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.utils.JsAstUtils; @@ -31,13 +31,13 @@ public class DefineInvocation { /* package */ @NotNull static DefineInvocation createDefineInvocation( - @NotNull NamespaceDescriptor descriptor, + @NotNull FqName packageFqName, @Nullable JsExpression initializer, @NotNull JsObjectLiteral members, @NotNull TranslationContext context ) { return new DefineInvocation(initializer == null ? JsLiteral.NULL : initializer, - new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, context.getQualifiedReference(descriptor)), + new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, context.getQualifiedReference(packageFqName)), members); } 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 4b04351caf0..429d6d3bda8 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,10 +19,10 @@ 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.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; @@ -34,8 +34,8 @@ import static org.jetbrains.k2js.translate.declaration.DefineInvocation.createDe public final class NamespaceDeclarationTranslator extends AbstractTranslator { private final Iterable files; - private final Map descriptorToTranslator = - new LinkedHashMap(); + private final Map packageFragmentToTranslator = + new LinkedHashMap(); public static List translateFiles(@NotNull Collection files, @NotNull TranslationContext context) { return new NamespaceDeclarationTranslator(files, context).translate(); @@ -50,51 +50,36 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator { @NotNull private List translate() { // predictable order - Map descriptorToDefineInvocation = new THashMap(); - NamespaceDescriptor rootNamespaceDescriptor = null; + Map packageFqNameToDefineInvocation = new THashMap(); for (JetFile file : files) { - // TODO 1 - //NamespaceDescriptor descriptor = context().bindingContext().get(BindingContext.FILE_TO_NAMESPACE, file); - //assert descriptor != null; - //NamespaceTranslator translator = descriptorToTranslator.get(descriptor); - //if (translator == null) { - // if (rootNamespaceDescriptor == null) { - // rootNamespaceDescriptor = getRootPackageDescriptor(descriptorToDefineInvocation, descriptor); - // } - // translator = new NamespaceTranslator(descriptor, descriptorToDefineInvocation, context()); - // descriptorToTranslator.put(descriptor, translator); - //} - // - //translator.translate(file); + PackageFragmentDescriptor packageFragment = context().bindingContext().get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, file); + + NamespaceTranslator translator = packageFragmentToTranslator.get(packageFragment); + if (translator == null) { + createRootPackageDefineInvocationIfNeeded(packageFqNameToDefineInvocation); + translator = new NamespaceTranslator(packageFragment, packageFqNameToDefineInvocation, context()); + packageFragmentToTranslator.put(packageFragment, translator); + } + + translator.translate(file); } - if (rootNamespaceDescriptor == null) { - return Collections.emptyList(); - } - - for (NamespaceTranslator translator : descriptorToTranslator.values()) { - translator.add(descriptorToDefineInvocation); + for (NamespaceTranslator translator : packageFragmentToTranslator.values()) { + translator.add(packageFqNameToDefineInvocation); } JsVars vars = new JsVars(true); - vars.addIfHasInitializer(getRootPackageDeclaration(descriptorToDefineInvocation.get(rootNamespaceDescriptor))); + vars.addIfHasInitializer(getRootPackageDeclaration(packageFqNameToDefineInvocation.get(FqName.ROOT))); return Collections.singletonList(vars); } - @NotNull - private NamespaceDescriptor getRootPackageDescriptor( - @NotNull Map descriptorToDefineInvocation, - @NotNull NamespaceDescriptor descriptor - ) { - NamespaceDescriptor rootNamespace = descriptor; - while (DescriptorUtils.isTopLevelDeclaration(rootNamespace)) { - rootNamespace = (NamespaceDescriptor) rootNamespace.getContainingDeclaration(); + private void createRootPackageDefineInvocationIfNeeded(@NotNull Map packageFqNameToDefineInvocation) { + if (!packageFqNameToDefineInvocation.containsKey(FqName.ROOT)) { + packageFqNameToDefineInvocation.put( + FqName.ROOT, createDefineInvocation(FqName.ROOT, null, new JsObjectLiteral(true), context())); } - - descriptorToDefineInvocation.put(rootNamespace, createDefineInvocation(rootNamespace, null, new JsObjectLiteral(true), context())); - return rootNamespace; } private JsVar getRootPackageDeclaration(@NotNull DefineInvocation defineInvocation) { 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 29010665758..031b89ed9a4 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 @@ -22,8 +22,9 @@ import com.intellij.openapi.util.Trinity; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.k2js.translate.LabelGenerator; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; @@ -38,15 +39,15 @@ import static org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator. final class NamespaceTranslator extends AbstractTranslator { @NotNull - private final NamespaceDescriptor descriptor; + private final PackageFragmentDescriptor descriptor; private final FileDeclarationVisitor visitor; private final NotNullLazyValue, LabelGenerator, JsExpression>> definitionPlace; NamespaceTranslator( - @NotNull final NamespaceDescriptor descriptor, - @NotNull final Map descriptorToDefineInvocation, + @NotNull final PackageFragmentDescriptor descriptor, + @NotNull final Map packageFqNameToDefineInvocation, @NotNull TranslationContext context ) { super(context.newDeclaration(descriptor)); @@ -59,12 +60,12 @@ final class NamespaceTranslator extends AbstractTranslator { @Override @NotNull public Trinity, LabelGenerator, JsExpression> compute() { - DefineInvocation defineInvocation = descriptorToDefineInvocation.get(descriptor); + DefineInvocation defineInvocation = packageFqNameToDefineInvocation.get(descriptor.getFqName()); if (defineInvocation == null) { - defineInvocation = createDefinitionPlace(null, descriptorToDefineInvocation); + defineInvocation = createDefinitionPlace(null, packageFqNameToDefineInvocation); } - return createPlace(defineInvocation.getMembers(), context().getQualifiedReference(descriptor)); + return createPlace(defineInvocation.getMembers(), context().getQualifiedReference(descriptor.getFqName())); } }; } @@ -81,21 +82,22 @@ final class NamespaceTranslator extends AbstractTranslator { private DefineInvocation createDefinitionPlace( @Nullable JsExpression initializer, - Map descriptorToDefineInvocation + Map packageFqNameToDefineInvocation ) { - DefineInvocation place = createDefineInvocation(descriptor, initializer, new JsObjectLiteral(visitor.getResult(), true), context()); - descriptorToDefineInvocation.put(descriptor, place); - addToParent((NamespaceDescriptor) descriptor.getContainingDeclaration(), getEntry(descriptor, place), descriptorToDefineInvocation); + FqName fqName = descriptor.getFqName(); + DefineInvocation place = createDefineInvocation(fqName, initializer, new JsObjectLiteral(visitor.getResult(), true), context()); + packageFqNameToDefineInvocation.put(fqName, place); + addToParent(fqName.parent(), getEntry(fqName, place), packageFqNameToDefineInvocation); return place; } - public void add(@NotNull Map descriptorToDefineInvocation) { + public void add(@NotNull Map packageFqNameToDefineInvocation) { JsExpression initializer = visitor.computeInitializer(); - DefineInvocation defineInvocation = descriptorToDefineInvocation.get(descriptor); + DefineInvocation defineInvocation = packageFqNameToDefineInvocation.get(descriptor.getFqName()); if (defineInvocation == null) { if (initializer != null || !visitor.getResult().isEmpty()) { - createDefinitionPlace(initializer, descriptorToDefineInvocation); + createDefinitionPlace(initializer, packageFqNameToDefineInvocation); } } else { @@ -112,15 +114,17 @@ final class NamespaceTranslator extends AbstractTranslator { } } - private JsPropertyInitializer getEntry(@NotNull NamespaceDescriptor descriptor, DefineInvocation defineInvocation) { - return new JsPropertyInitializer(context().getNameForDescriptor(descriptor).makeRef(), + private JsPropertyInitializer getEntry(@NotNull FqName fqName, DefineInvocation defineInvocation) { + return new JsPropertyInitializer(context().getNameForPackage(fqName).makeRef(), new JsInvocation(context().namer().packageDefinitionMethodReference(), defineInvocation.asList())); } - private boolean addEntryIfParentExists(NamespaceDescriptor parentDescriptor, + private static boolean addEntryIfParentExists( + FqName parentFqName, JsPropertyInitializer entry, - Map descriptorToDeclarationPlace) { - DefineInvocation parentDefineInvocation = descriptorToDeclarationPlace.get(parentDescriptor); + Map packageFqNameToDeclarationPlace + ) { + DefineInvocation parentDefineInvocation = packageFqNameToDeclarationPlace.get(parentFqName); if (parentDefineInvocation != null) { parentDefineInvocation.getMembers().add(entry); return true; @@ -128,16 +132,16 @@ final class NamespaceTranslator extends AbstractTranslator { return false; } - private void addToParent(NamespaceDescriptor parentDescriptor, + private void addToParent(@NotNull FqName parentFqName, JsPropertyInitializer entry, - Map descriptorToDefineInvocation) { - while (!addEntryIfParentExists(parentDescriptor, entry, descriptorToDefineInvocation)) { + Map packageFqNameToDefineInvocation) { + while (!addEntryIfParentExists(parentFqName, entry, packageFqNameToDefineInvocation)) { JsObjectLiteral members = new JsObjectLiteral(new SmartList(entry), true); - DefineInvocation defineInvocation = createDefineInvocation(parentDescriptor, null, members, context()); - entry = getEntry(parentDescriptor, defineInvocation); + DefineInvocation defineInvocation = createDefineInvocation(parentFqName, null, members, context()); + entry = getEntry(parentFqName, defineInvocation); - descriptorToDefineInvocation.put(parentDescriptor, defineInvocation); - parentDescriptor = (NamespaceDescriptor) parentDescriptor.getContainingDeclaration(); + packageFqNameToDefineInvocation.put(parentFqName, defineInvocation); + parentFqName = parentFqName.parent(); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/TopLevelFIF.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/TopLevelFIF.java index 765da6737c2..52d3fec6db5 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/TopLevelFIF.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/TopLevelFIF.java @@ -179,8 +179,8 @@ public final class TopLevelFIF extends CompositeFIF { add(pattern("jet", "Map", "get").checkOverridden(), NATIVE_MAP_GET); add(pattern("js", "set").receiverExists(), NATIVE_MAP_SET); - add(pattern("java", "util", "HashMap", ""), new MapSelectImplementationIntrinsic(false)); - add(pattern("java", "util", "HashSet", ""), new MapSelectImplementationIntrinsic(true)); + add(pattern("java.util", "HashMap", ""), new MapSelectImplementationIntrinsic(false)); + add(pattern("java.util", "HashSet", ""), new MapSelectImplementationIntrinsic(true)); add(pattern("js", "Json", "get"), ArrayFIF.GET_INTRINSIC); add(pattern("js", "Json", "set"), ArrayFIF.SET_INTRINSIC); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/PatternBuilder.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/PatternBuilder.java index 8f1dfa78a18..5d54328a198 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/PatternBuilder.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/PatternBuilder.java @@ -18,10 +18,7 @@ package org.jetbrains.k2js.translate.intrinsic.functions.patterns; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.CallableDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.OverridingUtil; import org.jetbrains.jet.lang.resolve.name.Name; @@ -127,11 +124,6 @@ public final class PatternBuilder { return new DescriptorPredicateImpl(names); } - private static boolean isRootNamespace(DeclarationDescriptor declarationDescriptor) { - return declarationDescriptor instanceof NamespaceDescriptor && DescriptorUtils.isRootNamespace( - (NamespaceDescriptor) declarationDescriptor); - } - public static class DescriptorPredicateImpl implements DescriptorPredicate { private final String[] names; @@ -156,20 +148,21 @@ public final class PatternBuilder { private boolean matches(@NotNull CallableDescriptor callable) { DeclarationDescriptor descriptor = callable; int nameIndex = names.length - 1; - do { + while (true) { if (nameIndex == -1) { - return isRootNamespace(descriptor); - } - else if (isRootNamespace(descriptor)) { return false; } - if (!descriptor.getName().asString().equals(names[nameIndex--])) { + if (!descriptor.getName().asString().equals(names[nameIndex])) { return false; } + + nameIndex--; + descriptor = descriptor.getContainingDeclaration(); + if (descriptor instanceof PackageFragmentDescriptor) { + return nameIndex == 0 && names[0].equals(((PackageFragmentDescriptor) descriptor).getFqName().asString()); + } } - while ((descriptor = descriptor.getContainingDeclaration()) != null); - return true; } @Override diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/operation/CompareToInstrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/operation/CompareToInstrinsic.java index 27ed9105df9..565b53feba1 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/operation/CompareToInstrinsic.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/operation/CompareToInstrinsic.java @@ -38,7 +38,7 @@ public final class CompareToInstrinsic implements BinaryOperationIntrinsic { } FunctionDescriptor functionDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression); assert functionDescriptor != null; - return JsDescriptorUtils.isStandardDeclaration(functionDescriptor); + return JsDescriptorUtils.isBuiltin(functionDescriptor); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/operation/EqualsIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/operation/EqualsIntrinsic.java index 512a2807138..bc881b55e96 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/operation/EqualsIntrinsic.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/operation/EqualsIntrinsic.java @@ -48,7 +48,7 @@ public final class EqualsIntrinsic implements BinaryOperationIntrinsic { } FunctionDescriptor functionDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression); assert functionDescriptor != null; - return JsDescriptorUtils.isStandardDeclaration(functionDescriptor); + return JsDescriptorUtils.isBuiltin(functionDescriptor); } @Override 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 dea475ff59a..ba21b48177b 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 @@ -20,7 +20,7 @@ import com.google.dart.compiler.backend.js.ast.JsExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.utils.ErrorReportingUtils; @@ -112,7 +112,7 @@ public final class QualifiedExpressionTranslator { if (receiverExpression instanceof JetReferenceExpression) { DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression(context.bindingContext(), (JetReferenceExpression)receiverExpression); - if (descriptorForReferenceExpression instanceof NamespaceDescriptor) { + if (descriptorForReferenceExpression instanceof PackageViewDescriptor) { return true; } } 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 02340bb085b..846a2b21dad 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 @@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.Modality; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.TranslationContext; import java.util.Arrays; @@ -244,4 +245,18 @@ public final class JsAstUtils { public static JsObjectLiteral wrapValue(@NotNull JsExpression label, @NotNull JsExpression value) { return new JsObjectLiteral(Collections.singletonList(new JsPropertyInitializer(label, value))); } + + public static void replaceRootReference(@NotNull JsNameRef fullQualifier, @NotNull JsExpression newQualifier) { + JsNameRef qualifier = fullQualifier; + while (true) { + JsExpression parent = qualifier.getQualifier(); + assert parent instanceof JsNameRef : "unexpected qualifier: " + parent + ", original: " + fullQualifier; + if (((JsNameRef) parent).getQualifier() == null) { + assert Namer.getRootNamespaceName().equals(((JsNameRef) parent).getIdent()); + qualifier.setQualifier(newQualifier); + return; + } + qualifier = (JsNameRef) parent; + } + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java index 7876c88f4ab..1ddf7ad03fd 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java @@ -163,17 +163,9 @@ public final class JsDescriptorUtils { !propertyDescriptor.getModality().isOverridable(); } - public static boolean isStandardDeclaration(@NotNull DeclarationDescriptor descriptor) { - NamespaceDescriptor namespace = getContainingNamespace(descriptor); - if (namespace == null) { - return false; - } - return namespace.equals(KotlinBuiltIns.getInstance().getBuiltInsScope().getContainingDeclaration()); - } - - @Nullable - public static NamespaceDescriptor getContainingNamespace(@NotNull DeclarationDescriptor descriptor) { - return DescriptorUtils.getParentOfType(descriptor, NamespaceDescriptor.class); + public static boolean isBuiltin(@NotNull DeclarationDescriptor descriptor) { + PackageFragmentDescriptor containingPackageFragment = DescriptorUtils.getParentOfType(descriptor, PackageFragmentDescriptor.class); + return containingPackageFragment == KotlinBuiltIns.getInstance().getBuiltInsPackageFragment(); } @Nullable