Migrated JS backend to package views and fragments.

This commit is contained in:
Evgeny Gerashchenko
2013-11-07 23:57:57 +04:00
parent aa2ff87b47
commit 601cd4ce46
16 changed files with 172 additions and 198 deletions
@@ -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();
}
@@ -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;
}
@@ -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
@@ -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<JsName> names = new NameGenerator();
@NotNull
private final Map<FqName, JsName> packageNames = Maps.newHashMap();
@NotNull
private final Generator<JsScope> scopes = new ScopeGenerator();
@NotNull
private final Generator<JsNameRef> 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<JsName>() {
@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<JsName> {
public NameGenerator() {
@@ -184,18 +229,6 @@ public final class StaticContext {
return standardClasses.getStandardObjectName(data);
}
};
Rule<JsName> namespacesShouldBeDefinedInRootScope = new Rule<JsName>() {
@Override
@Nullable
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
if (!(descriptor instanceof NamespaceDescriptor)) {
return null;
}
String name = Namer.generateNamespaceName(descriptor);
return getRootScope().declareName(name);
}
};
Rule<JsName> memberDeclarationsInsideParentsScope = new Rule<JsName>() {
@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<JsScope> generateNewScopesForNamespaceDescriptors = new Rule<JsScope>() {
Rule<JsScope> generateNewScopesForPackageDescriptors = new Rule<JsScope>() {
@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<JsNameRef> namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule<JsNameRef>() {
Rule<JsNameRef> packageLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule<JsNameRef>() {
@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<JsNameRef> constructorHaveTheSameQualifierAsTheClass = new Rule<JsNameRef>() {
@@ -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<Boolean> topLevelNamespaceHaveNoQualifier = new Rule<Boolean>() {
@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);
}
@@ -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);
@@ -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;
}
@@ -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);
}
@@ -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<JetFile> files;
private final Map<NamespaceDescriptor,NamespaceTranslator> descriptorToTranslator =
new LinkedHashMap<NamespaceDescriptor, NamespaceTranslator>();
private final Map<PackageFragmentDescriptor, NamespaceTranslator> packageFragmentToTranslator =
new LinkedHashMap<PackageFragmentDescriptor, NamespaceTranslator>();
public static List<JsStatement> translateFiles(@NotNull Collection<JetFile> files, @NotNull TranslationContext context) {
return new NamespaceDeclarationTranslator(files, context).translate();
@@ -50,51 +50,36 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
@NotNull
private List<JsStatement> translate() {
// predictable order
Map<NamespaceDescriptor, DefineInvocation> descriptorToDefineInvocation = new THashMap<NamespaceDescriptor, DefineInvocation>();
NamespaceDescriptor rootNamespaceDescriptor = null;
Map<FqName, DefineInvocation> packageFqNameToDefineInvocation = new THashMap<FqName, DefineInvocation>();
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.<JsStatement>singletonList(vars);
}
@NotNull
private NamespaceDescriptor getRootPackageDescriptor(
@NotNull Map<NamespaceDescriptor, DefineInvocation> descriptorToDefineInvocation,
@NotNull NamespaceDescriptor descriptor
) {
NamespaceDescriptor rootNamespace = descriptor;
while (DescriptorUtils.isTopLevelDeclaration(rootNamespace)) {
rootNamespace = (NamespaceDescriptor) rootNamespace.getContainingDeclaration();
private void createRootPackageDefineInvocationIfNeeded(@NotNull Map<FqName, DefineInvocation> 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) {
@@ -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<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>> definitionPlace;
NamespaceTranslator(
@NotNull final NamespaceDescriptor descriptor,
@NotNull final Map<NamespaceDescriptor, DefineInvocation> descriptorToDefineInvocation,
@NotNull final PackageFragmentDescriptor descriptor,
@NotNull final Map<FqName, DefineInvocation> packageFqNameToDefineInvocation,
@NotNull TranslationContext context
) {
super(context.newDeclaration(descriptor));
@@ -59,12 +60,12 @@ final class NamespaceTranslator extends AbstractTranslator {
@Override
@NotNull
public Trinity<List<JsPropertyInitializer>, 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<NamespaceDescriptor, DefineInvocation> descriptorToDefineInvocation
Map<FqName, DefineInvocation> 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<NamespaceDescriptor, DefineInvocation> descriptorToDefineInvocation) {
public void add(@NotNull Map<FqName, DefineInvocation> 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<NamespaceDescriptor, DefineInvocation> descriptorToDeclarationPlace) {
DefineInvocation parentDefineInvocation = descriptorToDeclarationPlace.get(parentDescriptor);
Map<FqName, DefineInvocation> 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<NamespaceDescriptor, DefineInvocation> descriptorToDefineInvocation) {
while (!addEntryIfParentExists(parentDescriptor, entry, descriptorToDefineInvocation)) {
Map<FqName, DefineInvocation> packageFqNameToDefineInvocation) {
while (!addEntryIfParentExists(parentFqName, entry, packageFqNameToDefineInvocation)) {
JsObjectLiteral members = new JsObjectLiteral(new SmartList<JsPropertyInitializer>(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();
}
}
@@ -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", "<init>"), new MapSelectImplementationIntrinsic(false));
add(pattern("java", "util", "HashSet", "<init>"), new MapSelectImplementationIntrinsic(true));
add(pattern("java.util", "HashMap", "<init>"), new MapSelectImplementationIntrinsic(false));
add(pattern("java.util", "HashSet", "<init>"), new MapSelectImplementationIntrinsic(true));
add(pattern("js", "Json", "get"), ArrayFIF.GET_INTRINSIC);
add(pattern("js", "Json", "set"), ArrayFIF.SET_INTRINSIC);
@@ -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
@@ -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
@@ -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
@@ -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;
}
}
@@ -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;
}
}
}
@@ -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