Additional logic in static context related to modules. Hacky fix for nameclashes when inheriting descriptors.
Adapted from https://github.com/develar/kotlin/commit/d3521123a6e4d551b30743b68b6bb23b9678553b.
This commit is contained in:
@@ -42,7 +42,7 @@ public class LibrarySourcesConfig extends Config {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static final Key<String> EXTERNAL_MODULE_NAME = new Key<String>("externalModule");
|
public static final Key<String> EXTERNAL_MODULE_NAME = new Key<String>("externalModule");
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final String UNKNOWN_EXTERNAL_MODULE_NAME = "<unknown>";
|
public static final String UNKNOWN_EXTERNAL_MODULE_NAME = "<unknown>";
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jet.asJava.JetLightClass");
|
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jet.asJava.JetLightClass");
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ package org.jetbrains.k2js.translate.context;
|
|||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
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.DescriptorUtils;
|
||||||
import org.jetbrains.k2js.config.EcmaVersion;
|
import org.jetbrains.k2js.config.EcmaVersion;
|
||||||
|
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||||
import org.jetbrains.k2js.translate.context.generator.Generator;
|
import org.jetbrains.k2js.translate.context.generator.Generator;
|
||||||
import org.jetbrains.k2js.translate.context.generator.Rule;
|
import org.jetbrains.k2js.translate.context.generator.Rule;
|
||||||
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||||
@@ -46,11 +50,10 @@ public final class StaticContext {
|
|||||||
|
|
||||||
public static StaticContext generateStaticContext(@NotNull BindingContext bindingContext, @NotNull EcmaVersion ecmaVersion) {
|
public static StaticContext generateStaticContext(@NotNull BindingContext bindingContext, @NotNull EcmaVersion ecmaVersion) {
|
||||||
JsProgram program = new JsProgram("main");
|
JsProgram program = new JsProgram("main");
|
||||||
JsRootScope rootScope = program.getRootScope();
|
Namer namer = Namer.newInstance(program.getRootScope());
|
||||||
Namer namer = Namer.newInstance(rootScope);
|
|
||||||
Intrinsics intrinsics = new Intrinsics();
|
Intrinsics intrinsics = new Intrinsics();
|
||||||
StandardClasses standardClasses = StandardClasses.bindImplementations(namer.getKotlinScope());
|
StandardClasses standardClasses = StandardClasses.bindImplementations(namer.getKotlinScope());
|
||||||
return new StaticContext(program, bindingContext, namer, intrinsics, standardClasses, rootScope, ecmaVersion);
|
return new StaticContext(program, bindingContext, namer, intrinsics, standardClasses, program.getRootScope(), ecmaVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -133,9 +136,9 @@ public final class StaticContext {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
public JsScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
JsScope namingScope = scopes.get(descriptor.getOriginal());
|
JsScope scope = scopes.get(descriptor.getOriginal());
|
||||||
assert namingScope != null : "Must have a scope for descriptor";
|
assert scope != null : "Must have a scope for descriptor";
|
||||||
return namingScope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -189,11 +192,8 @@ public final class StaticContext {
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
JsScope namingScope = getEnclosingScope(descriptor);
|
JsScope scope = getEnclosingScope(descriptor);
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
return scope.declareFreshName(descriptor.getName().getName());
|
||||||
return namingScope.declareName(descriptor.getName().getName());
|
|
||||||
}
|
|
||||||
return namingScope.declareFreshName(descriptor.getName().getName());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Rule<JsName> constructorHasTheSameNameAsTheClass = new Rule<JsName>() {
|
Rule<JsName> constructorHasTheSameNameAsTheClass = new Rule<JsName>() {
|
||||||
@@ -213,9 +213,14 @@ public final class StaticContext {
|
|||||||
if (!(descriptor instanceof PropertyAccessorDescriptor)) {
|
if (!(descriptor instanceof PropertyAccessorDescriptor)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
|
|
||||||
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) descriptor;
|
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) descriptor;
|
||||||
String propertyName = accessorDescriptor.getCorrespondingProperty().getName().getName();
|
String propertyName = accessorDescriptor.getCorrespondingProperty().getName().getName();
|
||||||
|
if (accessorDescriptor.getCorrespondingProperty().isObjectDeclaration()) {
|
||||||
|
return declareName(descriptor, propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
|
||||||
String accessorName = Namer.getNameForAccessor(propertyName, isGetter,
|
String accessorName = Namer.getNameForAccessor(propertyName, isGetter,
|
||||||
!accessorDescriptor.getReceiverParameter().exists() && isEcma5());
|
!accessorDescriptor.getReceiverParameter().exists() && isEcma5());
|
||||||
return declareName(descriptor, accessorName);
|
return declareName(descriptor, accessorName);
|
||||||
@@ -279,7 +284,11 @@ public final class StaticContext {
|
|||||||
if (overriddenDescriptor == null) {
|
if (overriddenDescriptor == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getNameForDescriptor(overriddenDescriptor);
|
|
||||||
|
JsScope scope = getEnclosingScope(descriptor);
|
||||||
|
JsName result = getNameForDescriptor(overriddenDescriptor);
|
||||||
|
scope.declareName(result.getIdent());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
addRule(namesForStandardClasses);
|
addRule(namesForStandardClasses);
|
||||||
@@ -300,7 +309,6 @@ public final class StaticContext {
|
|||||||
return getScopeForDescriptor(containingDeclaration.getOriginal());
|
return getScopeForDescriptor(containingDeclaration.getOriginal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final class ScopeGenerator extends Generator<JsScope> {
|
private final class ScopeGenerator extends Generator<JsScope> {
|
||||||
|
|
||||||
public ScopeGenerator() {
|
public ScopeGenerator() {
|
||||||
@@ -353,11 +361,11 @@ public final class StaticContext {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JsScope enclosingScope = getEnclosingScope(descriptor);
|
JsScope enclosingScope = getEnclosingScope(descriptor);
|
||||||
|
|
||||||
JsFunction correspondingFunction = JsAstUtils.createFunctionWithEmptyBody(enclosingScope);
|
JsFunction correspondingFunction = JsAstUtils.createFunctionWithEmptyBody(enclosingScope);
|
||||||
JsScope newScope = correspondingFunction.getScope();
|
assert (!scopeToFunction.containsKey(correspondingFunction.getScope())) : "Scope to function value overridden for " + descriptor;
|
||||||
assert (!scopeToFunction.containsKey(newScope)) : "Scope to function value overridden for " + descriptor;
|
scopeToFunction.put(correspondingFunction.getScope(), correspondingFunction);
|
||||||
scopeToFunction.put(newScope, correspondingFunction);
|
return correspondingFunction.getScope();
|
||||||
return newScope;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
addRule(createFunctionObjectsForCallableDescriptors);
|
addRule(createFunctionObjectsForCallableDescriptors);
|
||||||
@@ -387,17 +395,54 @@ public final class StaticContext {
|
|||||||
return namer.kotlinObject();
|
return namer.kotlinObject();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//TODO: review and refactor
|
||||||
Rule<JsNameRef> namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule<JsNameRef>() {
|
Rule<JsNameRef> namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule<JsNameRef>() {
|
||||||
@Override
|
@Override
|
||||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
|
DeclarationDescriptor containingDescriptor = getContainingDeclaration(descriptor);
|
||||||
if (!(containingDeclaration instanceof NamespaceDescriptor)) {
|
if (!(containingDescriptor instanceof NamespaceDescriptor)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JsName containingDeclarationName = getNameForDescriptor(containingDeclaration);
|
|
||||||
JsNameRef qualifier = containingDeclarationName.makeRef();
|
final JsNameRef result = new JsNameRef(getNameForDescriptor(containingDescriptor));
|
||||||
qualifier.setQualifier(getQualifierForDescriptor(containingDeclaration));
|
if (DescriptorUtils.isRootNamespace((NamespaceDescriptor) containingDescriptor)) {
|
||||||
return qualifier;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
else if (result == qualifier && result.getIdent().equals("kotlin")) {
|
||||||
|
// todo WebDemoExamples2Test#testBuilder, package "kotlin" from kotlin/js/js.libraries/src/stdlib/JUMaps.kt must be inlined
|
||||||
|
return qualifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qualifier.getQualifier() == null) {
|
||||||
|
qualifier.setQualifier(new JsNameRef(Namer.getRootNamespaceName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Rule<JsNameRef> constructorHaveTheSameQualifierAsTheClass = new Rule<JsNameRef>() {
|
Rule<JsNameRef> constructorHaveTheSameQualifierAsTheClass = new Rule<JsNameRef>() {
|
||||||
@@ -412,7 +457,6 @@ public final class StaticContext {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
Rule<JsNameRef> libraryObjectsHaveKotlinQualifier = new Rule<JsNameRef>() {
|
Rule<JsNameRef> libraryObjectsHaveKotlinQualifier = new Rule<JsNameRef>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
if (isLibraryObject(descriptor)) {
|
if (isLibraryObject(descriptor)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user