JS backend: ensure enumerability for object literal properties.
Namespace lends annotation improved (root). (cherry picked from commit 246c001)
This commit is contained in:
@@ -35,6 +35,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -200,14 +201,14 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
}
|
||||
else {
|
||||
if (qualifiedReference != null) {
|
||||
// about "prototype" -- see http://code.google.com/p/jsdoc-toolkit/wiki/TagLends
|
||||
invocationArguments.add(new JsDocComment("lends", new JsNameRef("prototype", qualifiedReference)));
|
||||
// about "prototype" - see http://code.google.com/p/jsdoc-toolkit/wiki/TagLends
|
||||
invocationArguments.add(new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, new JsNameRef("prototype", qualifiedReference)));
|
||||
}
|
||||
invocationArguments.add(new JsObjectLiteral(properties, true));
|
||||
}
|
||||
}
|
||||
if (hasStaticProperties) {
|
||||
invocationArguments.add(new JsDocComment("lends", qualifiedReference));
|
||||
invocationArguments.add(new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, qualifiedReference));
|
||||
invocationArguments.add(new JsObjectLiteral(staticProperties, true));
|
||||
}
|
||||
}
|
||||
|
||||
+20
-8
@@ -19,6 +19,7 @@ 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.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
@@ -31,6 +32,7 @@ import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import java.util.*;
|
||||
|
||||
import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getQualifiedReference;
|
||||
|
||||
public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
||||
private final Iterable<JetFile> files;
|
||||
@@ -99,23 +101,33 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
||||
rootNamespace = (NamespaceDescriptor) rootNamespace.getContainingDeclaration();
|
||||
}
|
||||
|
||||
List<JsExpression> args;
|
||||
JsObjectLiteral rootNamespaceDefinition = new JsObjectLiteral(true);
|
||||
if (context().isEcma5()) {
|
||||
args = Arrays.<JsExpression>asList(JsLiteral.NULL, rootNamespaceDefinition);
|
||||
descriptorToDefineInvocation.put(rootNamespace, createDefineInvocation(rootNamespace, null, rootNamespaceDefinition, context()));
|
||||
return rootNamespaceDefinition;
|
||||
}
|
||||
|
||||
static List<JsExpression> createDefineInvocation(
|
||||
@NotNull NamespaceDescriptor descriptor,
|
||||
@Nullable JsExpression initializer,
|
||||
@NotNull JsObjectLiteral members,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
if (context.isEcma5()) {
|
||||
return Arrays.asList(initializer == null ? JsLiteral.NULL : initializer,
|
||||
new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, getQualifiedReference(context, descriptor)),
|
||||
members);
|
||||
}
|
||||
else {
|
||||
args = Collections.<JsExpression>singletonList(rootNamespaceDefinition);
|
||||
return Collections.<JsExpression>singletonList(members);
|
||||
}
|
||||
|
||||
descriptorToDefineInvocation.put(rootNamespace, args);
|
||||
return rootNamespaceDefinition;
|
||||
}
|
||||
|
||||
private JsVar getDeclaration(@NotNull JsObjectLiteral rootNamespaceDefinition) {
|
||||
JsExpression packageMapValue;
|
||||
if (context().isEcma5()) {
|
||||
packageMapValue = new JsInvocation(JsAstUtils.CREATE_OBJECT, JsLiteral.NULL, rootNamespaceDefinition);
|
||||
packageMapValue = new JsInvocation(JsAstUtils.CREATE_OBJECT, JsLiteral.NULL,
|
||||
new JsDocComment(JsAstUtils.LENDS_JS_DOC_TAG, Namer.getRootNamespaceName()),
|
||||
rootNamespaceDefinition);
|
||||
}
|
||||
else {
|
||||
packageMapValue = rootNamespaceDefinition;
|
||||
|
||||
+3
-12
@@ -35,8 +35,6 @@ import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -130,18 +128,11 @@ final class NamespaceTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private List<JsPropertyInitializer> getListFromPlace(List<JsExpression> defineInvocation) {
|
||||
return ((JsObjectLiteral) defineInvocation.get(context().isEcma5() ? 1 : 0)).getPropertyInitializers();
|
||||
return ((JsObjectLiteral) defineInvocation.get(context().isEcma5() ? 2 : 0)).getPropertyInitializers();
|
||||
}
|
||||
|
||||
private List<JsExpression> createDefineInvocation(@Nullable JsExpression initializer, @NotNull JsObjectLiteral members) {
|
||||
if (context().isEcma5()) {
|
||||
return Arrays.asList(initializer == null ? JsLiteral.NULL : initializer,
|
||||
new JsDocComment("lends", getQualifiedReference(context(), descriptor)),
|
||||
members);
|
||||
}
|
||||
else {
|
||||
return Collections.<JsExpression>singletonList(members);
|
||||
}
|
||||
return NamespaceDeclarationTranslator.createDefineInvocation(descriptor, initializer, members, context());
|
||||
}
|
||||
|
||||
private JsPropertyInitializer getEntry(@NotNull NamespaceDescriptor descriptor, List<JsExpression> defineInvocation) {
|
||||
@@ -154,7 +145,7 @@ final class NamespaceTranslator extends AbstractTranslator {
|
||||
Map<NamespaceDescriptor, List<JsExpression>> descriptorToDeclarationPlace) {
|
||||
List<JsExpression> parentDefineInvocation = descriptorToDeclarationPlace.get(parentDescriptor);
|
||||
if (parentDefineInvocation != null) {
|
||||
((JsObjectLiteral) parentDefineInvocation.get(context().isEcma5() ? 1 : 0)).getPropertyInitializers().add(entry);
|
||||
getListFromPlace(parentDefineInvocation).add(entry);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -19,9 +19,7 @@ package org.jetbrains.k2js.translate.initializer;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Named;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
@@ -72,16 +70,16 @@ public final class InitializerUtils {
|
||||
) {
|
||||
ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration);
|
||||
JsExpression value = ClassTranslator.generateObjectLiteral(declaration, descriptor, context);
|
||||
initializers.add(create(descriptor, value, context));
|
||||
initializers.add(create(descriptor, !(descriptor.getContainingDeclaration() instanceof NamespaceDescriptor), value, context));
|
||||
}
|
||||
|
||||
public static JsStatement create(Named named, JsExpression value, TranslationContext context) {
|
||||
private static JsStatement create(DeclarationDescriptor descriptor, boolean enumerable, JsExpression value, TranslationContext context) {
|
||||
JsExpression expression;
|
||||
if (context.isEcma5()) {
|
||||
expression = JsAstUtils.defineProperty(named.getName().asString(), JsAstUtils.createDataDescriptor(value), context);
|
||||
expression = JsAstUtils.defineProperty(descriptor.getName().asString(), JsAstUtils.createDataDescriptor(value, false, enumerable), context);
|
||||
}
|
||||
else {
|
||||
expression = assignment(new JsNameRef(named.getName().asString(), JsLiteral.THIS), value);
|
||||
expression = assignment(new JsNameRef(descriptor.getName().asString(), JsLiteral.THIS), value);
|
||||
}
|
||||
return expression.makeStmt();
|
||||
}
|
||||
|
||||
@@ -101,8 +101,8 @@ public final class AnnotationsUtils {
|
||||
}
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
return containingClass != null &&
|
||||
(getAnnotationByName(containingClass, ENUMERABLE) != null ||
|
||||
(containingClass.getKind().equals(ClassKind.OBJECT) && containingClass.getName().isSpecial()));
|
||||
((containingClass.getKind().equals(ClassKind.OBJECT) && containingClass.getName().isSpecial()) ||
|
||||
getAnnotationByName(containingClass, ENUMERABLE) != null);
|
||||
}
|
||||
|
||||
public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) {
|
||||
|
||||
@@ -39,6 +39,8 @@ public final class JsAstUtils {
|
||||
private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(new JsNameRef("writable"), JsLiteral.TRUE);
|
||||
private static final JsPropertyInitializer ENUMERABLE = new JsPropertyInitializer(new JsNameRef("enumerable"), JsLiteral.TRUE);
|
||||
|
||||
public static final String LENDS_JS_DOC_TAG = "lends";
|
||||
|
||||
static {
|
||||
JsNameRef globalObjectReference = new JsNameRef("Object");
|
||||
DEFINE_PROPERTY.setQualifier(globalObjectReference);
|
||||
@@ -228,20 +230,18 @@ public final class JsAstUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsInvocation defineProperty(@NotNull String name,
|
||||
public static JsInvocation defineProperty(
|
||||
@NotNull String name,
|
||||
@NotNull JsObjectLiteral value,
|
||||
@NotNull TranslationContext context) {
|
||||
JsInvocation invocation = new JsInvocation(DEFINE_PROPERTY);
|
||||
invocation.getArguments().add(JsLiteral.THIS);
|
||||
invocation.getArguments().add(context.program().getStringLiteral(name));
|
||||
invocation.getArguments().add(value);
|
||||
return invocation;
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
return new JsInvocation(DEFINE_PROPERTY, JsLiteral.THIS, context.program().getStringLiteral(name), value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsStatement defineSimpleProperty(@NotNull String name, @NotNull JsExpression value, @NotNull TranslationContext context) {
|
||||
if (context.isEcma5()) {
|
||||
return defineProperty(name, createDataDescriptor(value, false), context).makeStmt();
|
||||
return defineProperty(name, createDataDescriptor(value, false, false), context).makeStmt();
|
||||
} else {
|
||||
return assignment(new JsNameRef(name, JsLiteral.THIS), value).makeStmt();
|
||||
}
|
||||
@@ -250,41 +250,41 @@ public final class JsAstUtils {
|
||||
@NotNull
|
||||
public static JsObjectLiteral createPropertyDataDescriptor(@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull JsExpression value) {
|
||||
return createPropertyDataDescriptor(descriptor.getModality().isOverridable(), descriptor, value);
|
||||
return createPropertyDataDescriptor(descriptor, descriptor.getModality().isOverridable(), value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsObjectLiteral createDataDescriptor(@NotNull JsExpression value) {
|
||||
return createDataDescriptor(value, false);
|
||||
return createDataDescriptor(value, false, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsObjectLiteral createDataDescriptor(@NotNull JsExpression value, boolean writable) {
|
||||
public static JsObjectLiteral createDataDescriptor(@NotNull JsExpression value, boolean writable, boolean enumerable) {
|
||||
JsObjectLiteral dataDescriptor = new JsObjectLiteral();
|
||||
dataDescriptor.getPropertyInitializers().add(new JsPropertyInitializer(VALUE, value));
|
||||
if (writable) {
|
||||
dataDescriptor.getPropertyInitializers().add(WRITABLE);
|
||||
}
|
||||
return dataDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsObjectLiteral createPropertyDataDescriptor(@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull JsExpression value) {
|
||||
return createPropertyDataDescriptor(descriptor.isVar() || descriptor.getModality() == Modality.OPEN, descriptor, value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsObjectLiteral createPropertyDataDescriptor(boolean writable,
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull JsExpression value) {
|
||||
JsObjectLiteral dataDescriptor = createDataDescriptor(value, writable);
|
||||
if (AnnotationsUtils.isEnumerable(descriptor)) {
|
||||
if (enumerable) {
|
||||
dataDescriptor.getPropertyInitializers().add(ENUMERABLE);
|
||||
}
|
||||
return dataDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsObjectLiteral createPropertyDataDescriptor(@NotNull PropertyDescriptor descriptor, @NotNull JsExpression value) {
|
||||
return createPropertyDataDescriptor(descriptor, descriptor.isVar() || descriptor.getModality() == Modality.OPEN, value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsObjectLiteral createPropertyDataDescriptor(
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
boolean writable,
|
||||
@NotNull JsExpression value
|
||||
) {
|
||||
return createDataDescriptor(value, writable, AnnotationsUtils.isEnumerable(descriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsFunction createPackage(@NotNull List<JsStatement> to, @NotNull JsScope scope) {
|
||||
JsFunction packageBlockFunction = createFunctionWithEmptyBody(scope);
|
||||
|
||||
@@ -64,7 +64,7 @@ public final class TranslationUtils {
|
||||
@NotNull
|
||||
private static JsPropertyInitializer translateExtensionFunctionAsEcma5DataDescriptor(@NotNull JsFunction function,
|
||||
@NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context) {
|
||||
JsObjectLiteral meta = createDataDescriptor(function, descriptor.getModality().isOverridable());
|
||||
JsObjectLiteral meta = createDataDescriptor(function, descriptor.getModality().isOverridable(), false);
|
||||
return new JsPropertyInitializer(context.getNameForDescriptor(descriptor).makeRef(), meta);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user