JS backend: generate ref for not public api open classes as ref to internal class pool (_c var), but not to namespace definition.

(cherry picked from commit fa3db43)
This commit is contained in:
develar
2013-08-22 19:35:55 +04:00
committed by Zalim Bashorov
parent c27fb10f5a
commit df0a218015
3 changed files with 37 additions and 8 deletions
@@ -47,7 +47,7 @@ public final class Namer {
private static final String SUPER_METHOD_NAME = "super_init";
private static final String ROOT_NAMESPACE = "_";
private static final String RECEIVER_PARAMETER_NAME = "$receiver";
private static final String CLASSES_OBJECT_NAME = "classes";
private static final String CLASSES_OBJECT_NAME = "_c";
private static final String THROW_NPE_FUN_NAME = "throwNPE";
private static final String CLASS_OBJECT_GETTER = "object$";
private static final String CLASS_OBJECT_INITIALIZER = "object_initializer$";
@@ -19,16 +19,17 @@ package org.jetbrains.k2js.translate.declaration;
import com.google.dart.compiler.backend.js.ast.*;
import com.intellij.util.SmartList;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectObjectProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.Modality;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.utils.DFS;
import org.jetbrains.k2js.translate.LabelGenerator;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
@@ -47,7 +48,7 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor
* Generates a big block where are all the classes(objects representing them) are created.
*/
public final class ClassDeclarationTranslator extends AbstractTranslator {
private final LabelGenerator localLabelGenerator = new LabelGenerator('c');
private final THashSet<String> nameClashGuard = new THashSet<String>();
@NotNull
private final THashMap<ClassDescriptor, OpenClassInfo> openClassDescriptorToItem = new THashMap<ClassDescriptor, OpenClassInfo>();
@@ -201,7 +202,28 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
});
}
@NotNull
private String createNameForClass(ClassDescriptor descriptor) {
String suggestedName = descriptor.getName().asString();
String name = suggestedName;
DeclarationDescriptor containing = descriptor;
while (!nameClashGuard.add(name)) {
containing = containing.getContainingDeclaration();
assert containing != null;
name = suggestedName + '_' + containing.getName().asString();
}
return name;
}
@Nullable
public JsNameRef getQualifiedReference(ClassDescriptor descriptor) {
if (descriptor.getModality() != Modality.FINAL) {
//noinspection ConstantConditions
return classDescriptorToQualifiedLabel.get(descriptor, null);
}
return null;
}
@Nullable
public JsPropertyInitializer translate(@NotNull JetClassOrObject declaration, TranslationContext context) {
ClassDescriptor descriptor = getClassDescriptor(context().bindingContext(), declaration);
JsExpression value;
@@ -209,7 +231,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
value = new ClassTranslator(declaration, classDescriptorToQualifiedLabel, context).translate();
}
else {
String label = localLabelGenerator.generate();
String label = createNameForClass(descriptor);
JsName name = dummyFunction.getScope().declareName(label);
JsNameRef qualifiedLabel = openClassDescriptorToQualifiedLabel.get(descriptor);
if (qualifiedLabel == null) {
@@ -227,6 +249,11 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
openClassDescriptorToItem.put(descriptor, item);
value = qualifiedLabel;
// not public api classes referenced to internal var _c
if (!descriptor.getVisibility().isPublicAPI()) {
return null;
}
}
return InitializerUtils.createPropertyInitializer(descriptor, value, context());
@@ -1,9 +1,9 @@
package foo
trait A {
public trait A {
fun foo() {}
}
trait B : A {
public trait B : A {
fun boo() {}
}
@@ -12,7 +12,6 @@ native val undefined: Any = noImpl
native class Function(vararg args: String)
val hasProp = Function("obj, prop", "return obj[prop] !== undefined") as ((Any, String)->Boolean)
val PREFIX = "Kotlin.modules.JS_TESTS.foo"
fun box(): String {
val a = object: A {}
@@ -24,6 +23,9 @@ fun box(): String {
if (!hasProp(b, "foo")) return "B hasn't foo"
if (!hasProp(b, "boo")) return "B hasn't boo"
val PREFIX = "Kotlin.modules.JS_TESTS.foo"
if (eval("$PREFIX.A") == null) return "$PREFIX.A not found"
if (eval("$PREFIX.B") == null) return "$PREFIX.B not found"
if (eval("$PREFIX.A === $PREFIX.B") as Boolean) return "A and B refer to the same object"
return "OK"