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:
@@ -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$";
|
||||
|
||||
+31
-4
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user