Migrated JS backend to package views and fragments.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+22
-37
@@ -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) {
|
||||
|
||||
+30
-26
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
+9
-16
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user