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:
Pavel V. Talanov
2012-08-07 15:05:26 +04:00
parent 0a92843245
commit 5b2469227e
2 changed files with 70 additions and 26 deletions
@@ -42,7 +42,7 @@ public class LibrarySourcesConfig extends Config {
@NotNull
public static final Key<String> EXTERNAL_MODULE_NAME = new Key<String>("externalModule");
@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");
@@ -18,12 +18,16 @@ package org.jetbrains.k2js.translate.context;
import com.google.common.collect.Maps;
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.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.k2js.config.EcmaVersion;
import org.jetbrains.k2js.config.LibrarySourcesConfig;
import org.jetbrains.k2js.translate.context.generator.Generator;
import org.jetbrains.k2js.translate.context.generator.Rule;
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) {
JsProgram program = new JsProgram("main");
JsRootScope rootScope = program.getRootScope();
Namer namer = Namer.newInstance(rootScope);
Namer namer = Namer.newInstance(program.getRootScope());
Intrinsics intrinsics = new Intrinsics();
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
@@ -133,9 +136,9 @@ public final class StaticContext {
@NotNull
public JsScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
JsScope namingScope = scopes.get(descriptor.getOriginal());
assert namingScope != null : "Must have a scope for descriptor";
return namingScope;
JsScope scope = scopes.get(descriptor.getOriginal());
assert scope != null : "Must have a scope for descriptor";
return scope;
}
@NotNull
@@ -189,11 +192,8 @@ public final class StaticContext {
@Override
@Nullable
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
JsScope namingScope = getEnclosingScope(descriptor);
if (descriptor instanceof ClassDescriptor) {
return namingScope.declareName(descriptor.getName().getName());
}
return namingScope.declareFreshName(descriptor.getName().getName());
JsScope scope = getEnclosingScope(descriptor);
return scope.declareFreshName(descriptor.getName().getName());
}
};
Rule<JsName> constructorHasTheSameNameAsTheClass = new Rule<JsName>() {
@@ -213,9 +213,14 @@ public final class StaticContext {
if (!(descriptor instanceof PropertyAccessorDescriptor)) {
return null;
}
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) descriptor;
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,
!accessorDescriptor.getReceiverParameter().exists() && isEcma5());
return declareName(descriptor, accessorName);
@@ -279,7 +284,11 @@ public final class StaticContext {
if (overriddenDescriptor == null) {
return null;
}
return getNameForDescriptor(overriddenDescriptor);
JsScope scope = getEnclosingScope(descriptor);
JsName result = getNameForDescriptor(overriddenDescriptor);
scope.declareName(result.getIdent());
return result;
}
};
addRule(namesForStandardClasses);
@@ -300,7 +309,6 @@ public final class StaticContext {
return getScopeForDescriptor(containingDeclaration.getOriginal());
}
private final class ScopeGenerator extends Generator<JsScope> {
public ScopeGenerator() {
@@ -353,11 +361,11 @@ public final class StaticContext {
return null;
}
JsScope enclosingScope = getEnclosingScope(descriptor);
JsFunction correspondingFunction = JsAstUtils.createFunctionWithEmptyBody(enclosingScope);
JsScope newScope = correspondingFunction.getScope();
assert (!scopeToFunction.containsKey(newScope)) : "Scope to function value overridden for " + descriptor;
scopeToFunction.put(newScope, correspondingFunction);
return newScope;
assert (!scopeToFunction.containsKey(correspondingFunction.getScope())) : "Scope to function value overridden for " + descriptor;
scopeToFunction.put(correspondingFunction.getScope(), correspondingFunction);
return correspondingFunction.getScope();
}
};
addRule(createFunctionObjectsForCallableDescriptors);
@@ -387,17 +395,54 @@ public final class StaticContext {
return namer.kotlinObject();
}
};
//TODO: review and refactor
Rule<JsNameRef> namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule<JsNameRef>() {
@Override
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
if (!(containingDeclaration instanceof NamespaceDescriptor)) {
DeclarationDescriptor containingDescriptor = getContainingDeclaration(descriptor);
if (!(containingDescriptor instanceof NamespaceDescriptor)) {
return null;
}
JsName containingDeclarationName = getNameForDescriptor(containingDeclaration);
JsNameRef qualifier = containingDeclarationName.makeRef();
qualifier.setQualifier(getQualifierForDescriptor(containingDeclaration));
return qualifier;
final JsNameRef result = new JsNameRef(getNameForDescriptor(containingDescriptor));
if (DescriptorUtils.isRootNamespace((NamespaceDescriptor) containingDescriptor)) {
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>() {
@@ -412,7 +457,6 @@ public final class StaticContext {
}
};
Rule<JsNameRef> libraryObjectsHaveKotlinQualifier = new Rule<JsNameRef>() {
@Override
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
if (isLibraryObject(descriptor)) {