Rework logic in class declaration and namespace declaration.
Adapted from https://github.com/develar/kotlin/commit/a9e0a42fb1347fa8e21c86b5a073ef8a7c873da0.
This commit is contained in:
@@ -34,7 +34,6 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.config.Config.withJsLibAdded;
|
||||
import static org.jetbrains.k2js.facade.FacadeUtils.parseString;
|
||||
import static org.jetbrains.k2js.generate.CodeGenerator.generateProgramToString;
|
||||
|
||||
@@ -93,7 +92,7 @@ public final class K2JSTranslator {
|
||||
throws TranslationException {
|
||||
JetStandardLibrary.initialize(config.getProject());
|
||||
BindingContext bindingContext = AnalyzerFacadeForJS.analyzeFilesAndCheckErrors(filesToTranslate, config);
|
||||
return Translation.generateAst(bindingContext, withJsLibAdded(filesToTranslate, config), mainCallParameters, config);
|
||||
return Translation.generateAst(bindingContext, filesToTranslate, mainCallParameters, config);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.jetbrains.k2js.translate.declaration;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
|
||||
public interface ClassAliasingMap {
|
||||
@Nullable
|
||||
JsNameRef get(JetClass declaration, JetClass referencedDeclaration);
|
||||
JsNameRef get(ClassDescriptor descriptor, ClassDescriptor referencedDescriptor);
|
||||
}
|
||||
|
||||
+62
-74
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.k2js.translate.declaration;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.SmartList;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.TLinkable;
|
||||
import gnu.trove.TLinkableAdaptor;
|
||||
@@ -26,18 +28,20 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Modality;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
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;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
|
||||
import static org.jetbrains.k2js.translate.general.Translation.translateClassDeclaration;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.message;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newBlock;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -45,43 +49,44 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.newBlock;
|
||||
* Generates a big block where are all the classes(objects representing them) are created.
|
||||
*/
|
||||
public final class ClassDeclarationTranslator extends AbstractTranslator {
|
||||
private int localNameCounter;
|
||||
private final LabelGenerator localLabelGenerator = new LabelGenerator('c');
|
||||
|
||||
@NotNull
|
||||
private final THashMap<JetClass, ListItem> openClassToItem = new THashMap<JetClass, ListItem>();
|
||||
private final THashMap<ClassDescriptor, FinalListItem> openClassDescriptorToItem = new THashMap<ClassDescriptor, FinalListItem>();
|
||||
|
||||
private final TLinkedList<ListItem> openList = new TLinkedList<ListItem>();
|
||||
private final List<ListItem> finalList = new ArrayList<ListItem>();
|
||||
private final TLinkedList<FinalListItem> openList = new TLinkedList<FinalListItem>();
|
||||
private final List<Pair<JetClassOrObject, JsInvocation>> finalList = new ArrayList<Pair<JetClassOrObject, JsInvocation>>();
|
||||
|
||||
@NotNull
|
||||
private final JsFunction dummyFunction;
|
||||
|
||||
private final JsName declarationsObject;
|
||||
private final JsVars.JsVar classesVar;
|
||||
private final JsNameRef declarationsObjectRef;
|
||||
private final JsVar classesVar;
|
||||
|
||||
public ClassDeclarationTranslator(@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
|
||||
dummyFunction = new JsFunction(context.scope());
|
||||
declarationsObject = context().scope().declareName(Namer.nameForClassesVariable());
|
||||
JsName declarationsObject = context().scope().declareName(Namer.nameForClassesVariable());
|
||||
classesVar = new JsVars.JsVar(declarationsObject);
|
||||
declarationsObjectRef = declarationsObject.makeRef();
|
||||
}
|
||||
|
||||
private final class OpenClassRefProvider implements ClassAliasingMap {
|
||||
@Override
|
||||
@Nullable
|
||||
public JsNameRef get(JetClass declaration, JetClass referencedDeclaration) {
|
||||
ListItem item = openClassToItem.get(declaration);
|
||||
public JsNameRef get(ClassDescriptor descriptor, ClassDescriptor referencedDescriptor) {
|
||||
FinalListItem item = openClassDescriptorToItem.get(descriptor);
|
||||
// class declared in library
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
addAfter(item, openClassToItem.get(referencedDeclaration));
|
||||
addAfter(item, openClassDescriptorToItem.get(referencedDescriptor));
|
||||
return item.label;
|
||||
}
|
||||
|
||||
private void addAfter(@NotNull ListItem item, @NotNull ListItem referencedItem) {
|
||||
private void addAfter(@NotNull FinalListItem item, @NotNull FinalListItem referencedItem) {
|
||||
for (TLinkable link = item.getNext(); link != null; link = link.getNext()) {
|
||||
if (link == referencedItem) {
|
||||
return;
|
||||
@@ -89,65 +94,55 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
openList.remove(referencedItem);
|
||||
openList.addBefore((ListItem) item.getNext(), referencedItem);
|
||||
openList.addBefore((FinalListItem) item.getNext(), referencedItem);
|
||||
}
|
||||
}
|
||||
|
||||
private final class FinalClassRefProvider implements ClassAliasingMap {
|
||||
@Override
|
||||
public JsNameRef get(JetClass declaration, JetClass referencedDeclaration) {
|
||||
ListItem item = openClassToItem.get(declaration);
|
||||
return item == null ? null : item.label;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ListItem extends TLinkableAdaptor {
|
||||
private static class FinalListItem extends TLinkableAdaptor {
|
||||
private final JetClass declaration;
|
||||
private final JsNameRef label;
|
||||
private final JsNameRef qualifiedLabel;
|
||||
|
||||
private JsExpression translatedDeclaration;
|
||||
|
||||
private ListItem(JetClass declaration, JsNameRef label) {
|
||||
private FinalListItem(JetClass declaration, JsNameRef label, JsNameRef qualifiedLabel) {
|
||||
this.declaration = declaration;
|
||||
this.label = label;
|
||||
this.qualifiedLabel = qualifiedLabel;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsVars getDeclarationsStatement() {
|
||||
JsVars vars = new JsVars();
|
||||
vars.add(classesVar);
|
||||
return vars;
|
||||
public JsVars.JsVar getDeclaration() {
|
||||
return classesVar;
|
||||
}
|
||||
|
||||
public void generateDeclarations() {
|
||||
JsObjectLiteral valueLiteral = new JsObjectLiteral();
|
||||
JsVars vars = new JsVars();
|
||||
List<JsPropertyInitializer> propertyInitializers = valueLiteral.getPropertyInitializers();
|
||||
List<JsVar> vars = new SmartList<JsVar>();
|
||||
List<JsPropertyInitializer> propertyInitializers = new SmartList<JsPropertyInitializer>();
|
||||
|
||||
generateOpenClassDeclarations(vars, propertyInitializers);
|
||||
generateFinalClassDeclarations(vars, propertyInitializers);
|
||||
generateFinalClassDeclarations();
|
||||
|
||||
if (vars.isEmpty()) {
|
||||
classesVar.setInitExpression(valueLiteral);
|
||||
if (!propertyInitializers.isEmpty()) {
|
||||
classesVar.setInitExpression(new JsObjectLiteral(propertyInitializers));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<JsStatement> result = new ArrayList<JsStatement>();
|
||||
result.add(vars);
|
||||
result.add(new JsReturn(valueLiteral));
|
||||
dummyFunction.setBody(newBlock(result));
|
||||
dummyFunction.setBody(new JsBlock(new JsVars(vars, true), new JsReturn(new JsObjectLiteral(propertyInitializers))));
|
||||
classesVar.setInitExpression(new JsInvocation(dummyFunction));
|
||||
}
|
||||
|
||||
private void generateOpenClassDeclarations(@NotNull JsVars vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||
private void generateOpenClassDeclarations(@NotNull List<JsVar> vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||
ClassAliasingMap classAliasingMap = new OpenClassRefProvider();
|
||||
// first pass: set up list order
|
||||
for (ListItem item : openList) {
|
||||
for (FinalListItem item : openList) {
|
||||
item.translatedDeclaration = translateClassDeclaration(item.declaration, classAliasingMap, context());
|
||||
}
|
||||
// second pass: generate
|
||||
for (ListItem item : openList) {
|
||||
for (FinalListItem item : openList) {
|
||||
JsExpression translatedDeclaration = item.translatedDeclaration;
|
||||
if (translatedDeclaration == null) {
|
||||
throw new IllegalStateException(message(item.declaration, "Could not translate class declaration)"));
|
||||
@@ -156,24 +151,31 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateFinalClassDeclarations(@NotNull JsVars vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||
ClassAliasingMap classAliasingMap = new FinalClassRefProvider();
|
||||
for (ListItem item : finalList) {
|
||||
generate(item, propertyInitializers, translateClassDeclaration(item.declaration, classAliasingMap, context()), vars);
|
||||
private void generateFinalClassDeclarations() {
|
||||
ClassAliasingMap aliasingMap = new ClassAliasingMap() {
|
||||
@Override
|
||||
public JsNameRef get(ClassDescriptor descriptor, ClassDescriptor referencedDescriptor) {
|
||||
FinalListItem item = openClassDescriptorToItem.get(descriptor);
|
||||
return item == null ? null : item.qualifiedLabel;
|
||||
}
|
||||
};
|
||||
|
||||
for (Pair<JetClassOrObject, JsInvocation> item : finalList) {
|
||||
new ClassTranslator(item.first, aliasingMap, context()).translateClassOrObjectCreation(item.second);
|
||||
}
|
||||
}
|
||||
|
||||
private static void generate(@NotNull ListItem item,
|
||||
private static void generate(@NotNull FinalListItem item,
|
||||
@NotNull List<JsPropertyInitializer> propertyInitializers,
|
||||
@NotNull JsExpression definition,
|
||||
@NotNull JsVars vars) {
|
||||
@NotNull List<JsVar> vars) {
|
||||
JsExpression value;
|
||||
if (item.label.getName() == null) {
|
||||
value = definition;
|
||||
}
|
||||
else {
|
||||
assert item.label.getName() != null;
|
||||
vars.add(new JsVars.JsVar(item.label.getName(), definition));
|
||||
vars.add(new JsVar(item.label.getName(), definition));
|
||||
value = item.label;
|
||||
}
|
||||
|
||||
@@ -181,38 +183,24 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsPropertyInitializer translateAndGetClassNameToClassObject(@NotNull JetClass declaration) {
|
||||
public JsPropertyInitializer translate(@NotNull JetClassOrObject declaration) {
|
||||
ClassDescriptor descriptor = getClassDescriptor(context().bindingContext(), declaration);
|
||||
|
||||
JsNameRef labelRef;
|
||||
String label = 'c' + Integer.toString(localNameCounter++, 36);
|
||||
boolean isFinal = descriptor.getModality() == Modality.FINAL;
|
||||
if (isFinal) {
|
||||
labelRef = new JsNameRef(label);
|
||||
}
|
||||
else {
|
||||
labelRef = dummyFunction.getScope().declareName(label).makeRef();
|
||||
}
|
||||
|
||||
ListItem item = new ListItem(declaration, labelRef);
|
||||
if (isFinal) {
|
||||
finalList.add(item);
|
||||
}
|
||||
else {
|
||||
openList.add(item);
|
||||
openClassToItem.put(declaration, item);
|
||||
}
|
||||
|
||||
JsNameRef qualifiedLabelRef = new JsNameRef(labelRef.getIdent());
|
||||
qualifiedLabelRef.setQualifier(declarationsObject.makeRef());
|
||||
JsExpression value;
|
||||
if (context().isEcma5()) {
|
||||
value = JsAstUtils.createDataDescriptor(qualifiedLabelRef);
|
||||
if (descriptor.getModality() == Modality.FINAL) {
|
||||
JsInvocation invocation = context().namer().classCreateInvocation(descriptor);
|
||||
finalList.add(new Pair<JetClassOrObject, JsInvocation>(declaration, invocation));
|
||||
value = invocation;
|
||||
}
|
||||
else {
|
||||
value = qualifiedLabelRef;
|
||||
String label = localLabelGenerator.generate();
|
||||
JsNameRef labelRef = dummyFunction.getScope().declareName(label).makeRef();
|
||||
FinalListItem item = new FinalListItem((JetClass) declaration, labelRef, new JsNameRef(labelRef.getIdent(), declarationsObjectRef));
|
||||
openList.add(item);
|
||||
openClassDescriptorToItem.put(descriptor, item);
|
||||
|
||||
value = item.qualifiedLabel;
|
||||
}
|
||||
|
||||
return new JsPropertyInitializer(context().program().getStringLiteral(descriptor.getName().getName()), value);
|
||||
return InitializerUtils.createPropertyInitializer(descriptor, value, context());
|
||||
}
|
||||
}
|
||||
|
||||
+115
-130
@@ -17,32 +17,34 @@
|
||||
package org.jetbrains.k2js.translate.declaration;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.k2js.translate.context.Namer;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.dart.compiler.util.AstUtil.newSequence;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForType;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isNotAny;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.findAncestorClass;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getContainingClass;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getPrimaryConstructorParameters;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getQualifiedReference;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getThisObject;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -50,114 +52,105 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.getThisObject;
|
||||
* Generates a definition of a single class.
|
||||
*/
|
||||
public final class ClassTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
public static JsPropertyInitializer translateAsProperty(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull TranslationContext context) {
|
||||
JsExpression classCreationExpression =
|
||||
generateClassCreationExpression(classDeclaration, context);
|
||||
JsName className = context.getNameForElement(classDeclaration);
|
||||
return new JsPropertyInitializer(className.makeRef(), classCreationExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull ClassAliasingMap aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ClassTranslator(classDeclaration, aliasingMap, context)).translateClassOrObjectCreation();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ClassTranslator(classDeclaration, null, context)).translateClassOrObjectCreation();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateObjectLiteralExpression(@NotNull JetObjectLiteralExpression objectLiteralExpression,
|
||||
@NotNull TranslationContext outerContext) {
|
||||
JetObjectDeclaration objectDeclaration = objectLiteralExpression.getObjectDeclaration();
|
||||
ClassTranslator classTranslator = new ClassTranslator(objectDeclaration, null, outerContext);
|
||||
ClassDescriptor containingClass = getContainingClass(classTranslator.descriptor);
|
||||
if (containingClass == null) {
|
||||
return classTranslator.translateClassOrObjectCreation();
|
||||
}
|
||||
return classTranslator.translateObjectLiteralWithThisAliased(containingClass, outerContext);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private final DeclarationBodyVisitor declarationBodyVisitor = new DeclarationBodyVisitor();
|
||||
|
||||
@NotNull
|
||||
private final JetClassOrObject classDeclaration;
|
||||
|
||||
@Nullable
|
||||
private TemporaryVariable aliasForContainingClassThis = null;
|
||||
|
||||
@NotNull
|
||||
private final ClassDescriptor descriptor;
|
||||
|
||||
@Nullable
|
||||
private final ClassAliasingMap aliasingMap;
|
||||
|
||||
private ClassTranslator(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull
|
||||
public static JsExpression generateClassCreation(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull ClassAliasingMap aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
return new ClassTranslator(classDeclaration, aliasingMap, context).translateClassOrObjectCreation(context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateClassCreation(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) {
|
||||
return new ClassTranslator(classDeclaration, null, context).translateClassOrObjectCreation(context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateClassCreation(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull ClassDescriptor descriptor,
|
||||
@NotNull TranslationContext context) {
|
||||
return new ClassTranslator(classDeclaration, descriptor, null, context).translateClassOrObjectCreation(context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateObjectLiteral(@NotNull JetObjectLiteralExpression objectLiteralExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
return new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), null, context).translateObjectLiteralExpression();
|
||||
}
|
||||
|
||||
ClassTranslator(@NotNull JetClassOrObject classDeclaration,
|
||||
@Nullable ClassAliasingMap aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context.newDeclaration(classDeclaration));
|
||||
this(classDeclaration, getClassDescriptor(context.bindingContext(), classDeclaration), aliasingMap, context);
|
||||
}
|
||||
|
||||
ClassTranslator(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull ClassDescriptor descriptor,
|
||||
@Nullable ClassAliasingMap aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.aliasingMap = aliasingMap;
|
||||
this.descriptor = getClassDescriptor(context.bindingContext(), classDeclaration);
|
||||
this.descriptor = descriptor;
|
||||
this.classDeclaration = classDeclaration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateClassOrObjectCreation() {
|
||||
JsInvocation jsClassDeclaration = classCreateMethodInvocation();
|
||||
if (!isObject()) {
|
||||
addSuperclassReferences(jsClassDeclaration);
|
||||
private JsExpression translateObjectLiteralExpression() {
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
if (containingClass == null) {
|
||||
return translateClassOrObjectCreation(context());
|
||||
}
|
||||
addClassOwnDeclarations(jsClassDeclaration);
|
||||
return jsClassDeclaration;
|
||||
return translateAsObjectCreationExpressionWithEnclosingThisSaved(containingClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsInvocation classCreateMethodInvocation() {
|
||||
if (isObject()) {
|
||||
return new JsInvocation(context().namer().objectCreationMethodReference());
|
||||
}
|
||||
else if (isTrait() && !context().isEcma5()) {
|
||||
return new JsInvocation(context().namer().traitCreationMethodReference());
|
||||
}
|
||||
else {
|
||||
return new JsInvocation(context().namer().classCreationMethodReference());
|
||||
}
|
||||
private JsExpression translateAsObjectCreationExpressionWithEnclosingThisSaved(@NotNull ClassDescriptor containingClass) {
|
||||
return context().literalFunctionTranslator().translate(containingClass, classDeclaration, descriptor, this);
|
||||
}
|
||||
|
||||
private boolean isObject() {
|
||||
return descriptor.getKind().equals(ClassKind.OBJECT);
|
||||
@NotNull
|
||||
public JsExpression translateClassOrObjectCreation(@NotNull TranslationContext declarationContext) {
|
||||
JsInvocation createInvocation = context().namer().classCreateInvocation(descriptor);
|
||||
translateClassOrObjectCreation(createInvocation, declarationContext);
|
||||
return createInvocation;
|
||||
}
|
||||
|
||||
public void translateClassOrObjectCreation(@NotNull JsInvocation createInvocation) {
|
||||
translateClassOrObjectCreation(createInvocation, context());
|
||||
}
|
||||
|
||||
private void translateClassOrObjectCreation(@NotNull JsInvocation createInvocation, @NotNull TranslationContext context) {
|
||||
addSuperclassReferences(createInvocation);
|
||||
addClassOwnDeclarations(createInvocation, context);
|
||||
}
|
||||
|
||||
private boolean isTrait() {
|
||||
return descriptor.getKind().equals(ClassKind.TRAIT);
|
||||
}
|
||||
|
||||
private void addClassOwnDeclarations(@NotNull JsInvocation jsClassDeclaration) {
|
||||
TranslationContext classDeclarationContext = getClassDeclarationContext();
|
||||
JsObjectLiteral properties = new JsObjectLiteral();
|
||||
private void addClassOwnDeclarations(@NotNull JsInvocation jsClassDeclaration, @NotNull TranslationContext classDeclarationContext) {
|
||||
JsObjectLiteral properties = new JsObjectLiteral(true);
|
||||
List<JsPropertyInitializer> propertyList = properties.getPropertyInitializers();
|
||||
if (!isTrait()) {
|
||||
JsFunction initializer = Translation.generateClassInitializerMethod(classDeclaration, classDeclarationContext);
|
||||
if (context().isEcma5()) {
|
||||
jsClassDeclaration.getArguments()
|
||||
.add(initializer.getName() == null ? initializer : JsAstUtils.encloseFunction(initializer));
|
||||
jsClassDeclaration.getArguments().add(initializer.getBody().getStatements().isEmpty() ? JsLiteral.NULL : initializer);
|
||||
}
|
||||
else {
|
||||
propertyList.add(InitializerUtils.generateInitializeMethod(initializer));
|
||||
propertyList.add(new JsPropertyInitializer(Namer.initializeMethodReference(), initializer));
|
||||
}
|
||||
}
|
||||
else if (context().isEcma5()) {
|
||||
jsClassDeclaration.getArguments().add(JsLiteral.NULL);
|
||||
}
|
||||
|
||||
propertyList.addAll(translatePropertiesAsConstructorParameters(classDeclarationContext));
|
||||
propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, classDeclarationContext));
|
||||
@@ -168,7 +161,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private void addSuperclassReferences(@NotNull JsInvocation jsClassDeclaration) {
|
||||
List<JsExpression> superClassReferences = getSuperclassNameReferences();
|
||||
List<JsExpression> superClassReferences = getSupertypesNameReferences();
|
||||
List<JsExpression> expressions = jsClassDeclaration.getArguments();
|
||||
if (context().isEcma5()) {
|
||||
if (superClassReferences.isEmpty()) {
|
||||
@@ -188,37 +181,49 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsExpression> getSuperclassNameReferences() {
|
||||
List<JsExpression> superclassReferences = new ArrayList<JsExpression>();
|
||||
List<ClassDescriptor> superclassDescriptors = DescriptorUtils.getSuperclassDescriptors(descriptor);
|
||||
addAncestorClass(superclassReferences, superclassDescriptors);
|
||||
addTraits(superclassReferences, superclassDescriptors);
|
||||
return superclassReferences;
|
||||
}
|
||||
|
||||
private void addTraits(@NotNull List<JsExpression> superclassReferences,
|
||||
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||
for (ClassDescriptor superClassDescriptor : superclassDescriptors) {
|
||||
assert (superClassDescriptor.getKind() == ClassKind.TRAIT) : "Only traits are expected here";
|
||||
superclassReferences.add(getClassReference(superClassDescriptor));
|
||||
private List<JsExpression> getSupertypesNameReferences() {
|
||||
Collection<? extends JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
|
||||
if (supertypes.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private void addAncestorClass(@NotNull List<JsExpression> superclassReferences,
|
||||
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||
//here we remove ancestor class from the list
|
||||
ClassDescriptor ancestorClass = findAndRemoveAncestorClass(superclassDescriptors);
|
||||
if (ancestorClass != null) {
|
||||
superclassReferences.add(getClassReference(ancestorClass));
|
||||
JsExpression base = null;
|
||||
List<JsExpression> list = null;
|
||||
for (JetType type : supertypes) {
|
||||
ClassDescriptor result = getClassDescriptorForType(type);
|
||||
if (isNotAny(result) && !AnnotationsUtils.isNativeObject(result)) {
|
||||
switch (result.getKind()) {
|
||||
case CLASS:
|
||||
base = getClassReference(result);
|
||||
break;
|
||||
case TRAIT:
|
||||
if (list == null) {
|
||||
list = new ArrayList<JsExpression>();
|
||||
}
|
||||
list.add(getClassReference(result));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("unsupported super class kind " + result.getKind().name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (list == null) {
|
||||
return base == null ? Collections.<JsExpression>emptyList() : Collections.singletonList(base);
|
||||
}
|
||||
else if (base != null) {
|
||||
list.add(0, base);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
||||
// aliasing here is needed for the declaration generation step
|
||||
if (aliasingMap != null) {
|
||||
JsNameRef name = aliasingMap.get(BindingUtils.getClassForDescriptor(bindingContext(), superClassDescriptor),
|
||||
(JetClass) classDeclaration);
|
||||
JsNameRef name = aliasingMap.get(superClassDescriptor, descriptor);
|
||||
if (name != null) {
|
||||
return name;
|
||||
}
|
||||
@@ -228,40 +233,20 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
return getQualifiedReference(context(), superClassDescriptor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ClassDescriptor findAndRemoveAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||
ClassDescriptor ancestorClass = findAncestorClass(superclassDescriptors);
|
||||
superclassDescriptors.remove(ancestorClass);
|
||||
return ancestorClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsPropertyInitializer> translatePropertiesAsConstructorParameters(@NotNull TranslationContext classDeclarationContext) {
|
||||
List<JsPropertyInitializer> result = new ArrayList<JsPropertyInitializer>();
|
||||
for (JetParameter parameter : getPrimaryConstructorParameters(classDeclaration)) {
|
||||
PropertyDescriptor descriptor =
|
||||
getPropertyDescriptorForConstructorParameter(bindingContext(), parameter);
|
||||
List<JetParameter> parameters = getPrimaryConstructorParameters(classDeclaration);
|
||||
if (parameters.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<JsPropertyInitializer> result = new SmartList<JsPropertyInitializer>();
|
||||
for (JetParameter parameter : parameters) {
|
||||
PropertyDescriptor descriptor = getPropertyDescriptorForConstructorParameter(bindingContext(), parameter);
|
||||
if (descriptor != null) {
|
||||
result.addAll(PropertyTranslator.translateAccessors(descriptor, classDeclarationContext));
|
||||
PropertyTranslator.translateAccessors(descriptor, result, classDeclarationContext);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TranslationContext getClassDeclarationContext() {
|
||||
if (aliasForContainingClassThis == null) {
|
||||
return context();
|
||||
}
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
assert containingClass != null;
|
||||
return context().innerContextWithThisAliased(containingClass, aliasForContainingClassThis.name());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateObjectLiteralWithThisAliased(@NotNull ClassDescriptor containingClass,
|
||||
@NotNull TranslationContext outerContext) {
|
||||
aliasForContainingClassThis = outerContext.declareTemporary(getThisObject(outerContext, containingClass));
|
||||
return newSequence(aliasForContainingClassThis.assignmentExpression(), translateClassOrObjectCreation());
|
||||
}
|
||||
}
|
||||
|
||||
+35
-62
@@ -18,10 +18,10 @@ package org.jetbrains.k2js.translate.declaration;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Modality;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
@@ -30,104 +30,77 @@ import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForObjectDeclaration;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPropertyInitializer>> {
|
||||
@Nullable
|
||||
private final ClassDeclarationTranslator classDeclarationTranslator;
|
||||
public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
||||
protected final List<JsPropertyInitializer> result = new SmartList<JsPropertyInitializer>();
|
||||
|
||||
public DeclarationBodyVisitor() {
|
||||
classDeclarationTranslator = null;
|
||||
}
|
||||
|
||||
public DeclarationBodyVisitor(ClassDeclarationTranslator classDeclarationTranslator) {
|
||||
this.classDeclarationTranslator = classDeclarationTranslator;
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> traverseClass(@NotNull JetClassOrObject jetClass,
|
||||
@NotNull TranslationContext context) {
|
||||
List<JsPropertyInitializer> properties = new ArrayList<JsPropertyInitializer>();
|
||||
for (JetDeclaration declaration : jetClass.getDeclarations()) {
|
||||
properties.addAll(declaration.accept(this, context));
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> traverseNamespace(@NotNull NamespaceDescriptor namespace,
|
||||
@NotNull TranslationContext context) {
|
||||
List<JsPropertyInitializer> properties = new ArrayList<JsPropertyInitializer>();
|
||||
for (JetDeclaration declaration : getDeclarationsForNamespace(context.bindingContext(), namespace)) {
|
||||
properties.addAll(declaration.accept(this, context));
|
||||
for (JetDeclaration declaration : jetClass.getDeclarations()) {
|
||||
declaration.accept(this, context);
|
||||
}
|
||||
return properties;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> visitClass(@NotNull JetClass expression, @NotNull TranslationContext context) {
|
||||
if (classDeclarationTranslator == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Collections.singletonList(classDeclarationTranslator.translateAndGetClassNameToClassObject(expression));
|
||||
public Void visitClass(@NotNull JetClass expression, @NotNull TranslationContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> visitNamedFunction(@NotNull JetNamedFunction expression,
|
||||
@NotNull TranslationContext context) {
|
||||
public Void visitNamedFunction(@NotNull JetNamedFunction expression,
|
||||
@NotNull TranslationContext context) {
|
||||
FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
|
||||
if (descriptor.getModality() == Modality.ABSTRACT) {
|
||||
return null;
|
||||
}
|
||||
|
||||
JsPropertyInitializer methodAsPropertyInitializer = Translation.functionTranslator(expression, context).translateAsMethod();
|
||||
if (context.isEcma5()) {
|
||||
FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
|
||||
JsExpression methodBodyExpression = methodAsPropertyInitializer.getValueExpr();
|
||||
methodAsPropertyInitializer.setValueExpr(JsAstUtils.createPropertyDataDescriptor(descriptor, methodBodyExpression));
|
||||
}
|
||||
return Collections.singletonList(methodAsPropertyInitializer);
|
||||
result.add(methodAsPropertyInitializer);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> visitProperty(@NotNull JetProperty expression,
|
||||
@NotNull TranslationContext context) {
|
||||
PropertyDescriptor propertyDescriptor =
|
||||
BindingUtils.getPropertyDescriptor(context.bindingContext(), expression);
|
||||
return PropertyTranslator.translateAccessors(propertyDescriptor, context);
|
||||
public Void visitProperty(@NotNull JetProperty expression, @NotNull TranslationContext context) {
|
||||
PropertyDescriptor propertyDescriptor = BindingUtils.getPropertyDescriptor(context.bindingContext(), expression);
|
||||
PropertyTranslator.translateAccessors(propertyDescriptor, expression, result, context);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> visitObjectDeclaration(@NotNull JetObjectDeclaration expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return Collections.singletonList(ClassTranslator.translateAsProperty(expression, context));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> visitObjectDeclarationName(@NotNull JetObjectDeclarationName expression,
|
||||
@NotNull TranslationContext context) {
|
||||
if (context.isEcma5()) {
|
||||
return Collections.emptyList();
|
||||
public Void visitObjectDeclarationName(@NotNull JetObjectDeclarationName expression,
|
||||
@NotNull TranslationContext context) {
|
||||
if (!context.isEcma5()) {
|
||||
PropertyTranslator
|
||||
.translateAccessors(getPropertyDescriptorForObjectDeclaration(context.bindingContext(), expression), result, context);
|
||||
}
|
||||
|
||||
PropertyDescriptor propertyDescriptor =
|
||||
getPropertyDescriptorForObjectDeclaration(context.bindingContext(), expression);
|
||||
return PropertyTranslator.translateAccessors(propertyDescriptor, context);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> visitAnonymousInitializer(@NotNull JetClassInitializer expression,
|
||||
@NotNull TranslationContext context) {
|
||||
public Void visitAnonymousInitializer(@NotNull JetClassInitializer expression, @NotNull TranslationContext context) {
|
||||
// parsed it in initializer visitor => no additional actions are needed
|
||||
return Collections.emptyList();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+72
-74
@@ -16,116 +16,114 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.declaration;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.k2js.translate.context.Namer;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getAllNonNativeNamespaceDescriptors;
|
||||
import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
||||
private final Iterable<JetFile> files;
|
||||
private final Map<NamespaceDescriptor,NamespaceTranslator> descriptorToTranslator =
|
||||
new LinkedHashMap<NamespaceDescriptor, NamespaceTranslator>();
|
||||
|
||||
public static List<JsStatement> translateFiles(@NotNull Collection<JetFile> files, @NotNull TranslationContext context) {
|
||||
Set<NamespaceDescriptor> namespaceDescriptorSet = getAllNonNativeNamespaceDescriptors(context.bindingContext(), files);
|
||||
return (new NamespaceDeclarationTranslator(Lists.newArrayList(namespaceDescriptorSet), context)).translate();
|
||||
return new NamespaceDeclarationTranslator(files, context).translate();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final ClassDeclarationTranslator classDeclarationTranslator;
|
||||
@NotNull
|
||||
private final List<NamespaceDescriptor> namespaceDescriptors;
|
||||
|
||||
private NamespaceDeclarationTranslator(@NotNull List<NamespaceDescriptor> namespaceDescriptors,
|
||||
@NotNull TranslationContext context) {
|
||||
private NamespaceDeclarationTranslator(@NotNull Iterable<JetFile> files, @NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.namespaceDescriptors = namespaceDescriptors;
|
||||
classDeclarationTranslator = new ClassDeclarationTranslator(context);
|
||||
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> translate() {
|
||||
List<JsStatement> result = new ArrayList<JsStatement>();
|
||||
result.add(classDeclarationTranslator.getDeclarationsStatement());
|
||||
namespacesDeclarations(result);
|
||||
classDeclarationTranslator.generateDeclarations();
|
||||
return result;
|
||||
}
|
||||
// predictable order
|
||||
Map<NamespaceDescriptor, List<JsExpression>> descriptorToDefineInvocation = new THashMap<NamespaceDescriptor, List<JsExpression>>();
|
||||
JsObjectLiteral rootNamespaceDefinition = null;
|
||||
|
||||
private void namespacesDeclarations(List<JsStatement> statements) {
|
||||
List<NamespaceTranslator> namespaceTranslators = getTranslatorsForNonEmptyNamespaces();
|
||||
declarationStatements(namespaceTranslators, statements);
|
||||
initializeStatements(namespaceTranslators, statements);
|
||||
}
|
||||
ClassDeclarationTranslator classDeclarationTranslator = new ClassDeclarationTranslator(context());
|
||||
for (JetFile file : files) {
|
||||
NamespaceDescriptor descriptor = context().bindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
|
||||
assert descriptor != null;
|
||||
NamespaceTranslator translator = descriptorToTranslator.get(descriptor);
|
||||
if (translator == null) {
|
||||
if (rootNamespaceDefinition == null) {
|
||||
rootNamespaceDefinition = getRootPackage(descriptorToDefineInvocation, descriptor);
|
||||
}
|
||||
translator = new NamespaceTranslator(descriptor, classDeclarationTranslator, context());
|
||||
descriptorToTranslator.put(descriptor, translator);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<NamespaceTranslator> getTranslatorsForNonEmptyNamespaces() {
|
||||
List<NamespaceTranslator> namespaceTranslators = Lists.newArrayList();
|
||||
for (NamespaceDescriptor descriptor : filterNonEmptyNamespaces(filterTopLevelAndRootNamespaces(namespaceDescriptors))) {
|
||||
namespaceTranslators.add(new NamespaceTranslator(descriptor, classDeclarationTranslator, context()));
|
||||
translator.translate(file);
|
||||
}
|
||||
return namespaceTranslators;
|
||||
}
|
||||
|
||||
private void declarationStatements(@NotNull List<NamespaceTranslator> namespaceTranslators,
|
||||
@NotNull List<JsStatement> statements) {
|
||||
JsObjectLiteral objectLiteral = new JsObjectLiteral();
|
||||
JsNameRef packageMapNameRef = context().scope().declareName("_").makeRef();
|
||||
JsExpression packageMapValue;
|
||||
if (context().isNotEcma3()) {
|
||||
packageMapValue = new JsInvocation(JsAstUtils.CREATE_OBJECT, JsLiteral.NULL, objectLiteral);
|
||||
if (rootNamespaceDefinition == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
JsVars vars = new JsVars(true);
|
||||
List<JsStatement> result;
|
||||
if (context().isEcma5()) {
|
||||
result = Collections.<JsStatement>singletonList(vars);
|
||||
}
|
||||
else {
|
||||
packageMapValue = objectLiteral;
|
||||
result = new ArrayList<JsStatement>();
|
||||
result.add(vars);
|
||||
}
|
||||
statements.add(JsAstUtils.newVar(packageMapNameRef.getName(), packageMapValue));
|
||||
|
||||
for (NamespaceTranslator translator : namespaceTranslators) {
|
||||
translator.addNamespaceDeclaration(objectLiteral.getPropertyInitializers());
|
||||
classDeclarationTranslator.generateDeclarations();
|
||||
for (NamespaceTranslator translator : descriptorToTranslator.values()) {
|
||||
translator.add(descriptorToDefineInvocation, result);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initializeStatements(@NotNull List<NamespaceTranslator> namespaceTranslators,
|
||||
@NotNull List<JsStatement> statements) {
|
||||
for (NamespaceTranslator translator : namespaceTranslators) {
|
||||
for (JsExpression expression : translator.getInitializers()) {
|
||||
statements.add(expression.makeStmt());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<NamespaceDescriptor> filterTopLevelAndRootNamespaces(@NotNull List<NamespaceDescriptor> namespaceDescriptors) {
|
||||
List<NamespaceDescriptor> result = Lists.newArrayList();
|
||||
for (NamespaceDescriptor descriptor : namespaceDescriptors) {
|
||||
if (DescriptorUtils.isTopLevelNamespace(descriptor) || DescriptorUtils.isRootNamespace(descriptor)) {
|
||||
result.add(descriptor);
|
||||
}
|
||||
}
|
||||
vars.addIfHasInitializer(context().literalFunctionTranslator().getDeclaration());
|
||||
vars.addIfHasInitializer(classDeclarationTranslator.getDeclaration());
|
||||
vars.addIfHasInitializer(getDeclaration(rootNamespaceDefinition));
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<NamespaceDescriptor> filterNonEmptyNamespaces(@NotNull List<NamespaceDescriptor> namespaceDescriptors) {
|
||||
List<NamespaceDescriptor> result = Lists.newArrayList();
|
||||
for (NamespaceDescriptor descriptor : namespaceDescriptors) {
|
||||
if (!JsDescriptorUtils.isNamespaceEmpty(descriptor, context().bindingContext())) {
|
||||
result.add(descriptor);
|
||||
}
|
||||
private JsObjectLiteral getRootPackage(Map<NamespaceDescriptor, List<JsExpression>> descriptorToDefineInvocation,
|
||||
NamespaceDescriptor descriptor) {
|
||||
NamespaceDescriptor rootNamespace = descriptor;
|
||||
while (rootNamespace.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
||||
rootNamespace = (NamespaceDescriptor) rootNamespace.getContainingDeclaration();
|
||||
}
|
||||
return result;
|
||||
|
||||
List<JsExpression> args;
|
||||
JsObjectLiteral rootNamespaceDefinition = new JsObjectLiteral(true);
|
||||
if (context().isEcma5()) {
|
||||
args = Arrays.<JsExpression>asList(JsLiteral.NULL, rootNamespaceDefinition);
|
||||
}
|
||||
else {
|
||||
args = Collections.<JsExpression>singletonList(rootNamespaceDefinition);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
packageMapValue = rootNamespaceDefinition;
|
||||
}
|
||||
return new JsVar(context().scope().declareName(Namer.getRootNamespaceName()), packageMapValue);
|
||||
}
|
||||
}
|
||||
|
||||
+138
-86
@@ -16,125 +16,177 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.declaration;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
||||
import org.jetbrains.k2js.translate.initializer.InitializerVisitor;
|
||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newObjectLiteral;
|
||||
import static org.jetbrains.k2js.translate.initializer.InitializerUtils.generateInitializerForProperty;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptor;
|
||||
|
||||
/**
|
||||
* @author Pavel.Talanov
|
||||
* <p/>
|
||||
* Genereate code for a single descriptor.
|
||||
*/
|
||||
public final class NamespaceTranslator extends AbstractTranslator {
|
||||
|
||||
final class NamespaceTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private final NamespaceDescriptor descriptor;
|
||||
@NotNull
|
||||
private final JsName namespaceName;
|
||||
@NotNull
|
||||
private final ClassDeclarationTranslator classDeclarationTranslator;
|
||||
|
||||
@NotNull
|
||||
private final List<JsExpression> initializers = new ArrayList<JsExpression>();
|
||||
private final FileDeclarationVisitor visitor;
|
||||
|
||||
/*package*/ NamespaceTranslator(@NotNull NamespaceDescriptor descriptor,
|
||||
@NotNull ClassDeclarationTranslator classDeclarationTranslator,
|
||||
@NotNull TranslationContext context) {
|
||||
NamespaceTranslator(@NotNull NamespaceDescriptor descriptor,
|
||||
@NotNull ClassDeclarationTranslator classDeclarationTranslator,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context.newDeclaration(descriptor));
|
||||
this.descriptor = descriptor;
|
||||
this.namespaceName = context.getNameForDescriptor(descriptor);
|
||||
this.classDeclarationTranslator = classDeclarationTranslator;
|
||||
|
||||
visitor = new FileDeclarationVisitor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JsExpression> getInitializers() {
|
||||
return initializers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsPropertyInitializer getDeclarationAsInitializer() {
|
||||
addNamespaceInitializer();
|
||||
return new JsPropertyInitializer(namespaceName.makeRef(), getNamespaceDeclaration());
|
||||
}
|
||||
|
||||
public void addNamespaceDeclaration(List<JsPropertyInitializer> list) {
|
||||
addNamespaceInitializer();
|
||||
|
||||
if (DescriptorUtils.isRootNamespace(descriptor)) {
|
||||
list.addAll(getFunctionsAndClasses());
|
||||
return;
|
||||
}
|
||||
|
||||
JsExpression value = getNamespaceDeclaration();
|
||||
if (context().isNotEcma3()) {
|
||||
value = JsAstUtils.createDataDescriptor(value);
|
||||
}
|
||||
|
||||
list.add(new JsPropertyInitializer(namespaceName.makeRef(), value));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsInvocation getNamespaceDeclaration() {
|
||||
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation();
|
||||
addIfNeed(getFunctionsAndClasses(), namespaceDeclaration.getArguments());
|
||||
addIfNeed(getNestedNamespaceDeclarations(), namespaceDeclaration.getArguments());
|
||||
return namespaceDeclaration;
|
||||
}
|
||||
|
||||
private void addNamespaceInitializer() {
|
||||
JsFunction initializer = Translation.generateNamespaceInitializerMethod(descriptor, context());
|
||||
if (!initializer.getBody().getStatements().isEmpty()) {
|
||||
JsNameRef call = new JsNameRef("call");
|
||||
call.setQualifier(initializer);
|
||||
JsInvocation invocation = new JsInvocation();
|
||||
invocation.setQualifier(call);
|
||||
invocation.getArguments().add(TranslationUtils.getQualifiedReference(context(), descriptor));
|
||||
initializers.add(invocation);
|
||||
public void translate(JetFile file) {
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
if (!AnnotationsUtils.isNativeObject(BindingUtils.getDescriptorForElement(bindingContext(), declaration))) {
|
||||
declaration.accept(visitor, context());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<JsPropertyInitializer> getFunctionsAndClasses() {
|
||||
return new DeclarationBodyVisitor(classDeclarationTranslator).traverseNamespace(descriptor, context());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsInvocation namespaceCreateMethodInvocation() {
|
||||
return new JsInvocation(context().namer().packageDefinitionMethodReference());
|
||||
}
|
||||
|
||||
private void addIfNeed(@NotNull List<JsPropertyInitializer> declarations, @NotNull List<JsExpression> expressions) {
|
||||
// ecma5 expects strict number of arguments, but ecma3 doesn't
|
||||
if (!declarations.isEmpty()) {
|
||||
expressions.add(newObjectLiteral(declarations));
|
||||
public void add(@NotNull Map<NamespaceDescriptor, List<JsExpression>> descriptorToDefineInvocation,
|
||||
@NotNull List<JsStatement> initializers) {
|
||||
JsExpression initializer;
|
||||
if (visitor.initializerStatements.isEmpty()) {
|
||||
initializer = null;
|
||||
}
|
||||
else if (context().isNotEcma3()) {
|
||||
expressions.add(JsLiteral.NULL);
|
||||
else {
|
||||
initializer = visitor.initializer;
|
||||
if (!context().isEcma5()) {
|
||||
initializers.add(new JsInvocation(new JsNameRef("call", initializer),
|
||||
TranslationUtils.getQualifiedReference(context(), descriptor)).makeStmt());
|
||||
}
|
||||
}
|
||||
|
||||
List<JsExpression> defineInvocation = descriptorToDefineInvocation.get(descriptor);
|
||||
if (defineInvocation == null) {
|
||||
defineInvocation = createDefineInvocation(initializer, new JsObjectLiteral(visitor.getResult(), true));
|
||||
descriptorToDefineInvocation.put(descriptor, defineInvocation);
|
||||
addToParent((NamespaceDescriptor) descriptor.getContainingDeclaration(), getEntry(descriptor, defineInvocation),
|
||||
descriptorToDefineInvocation);
|
||||
}
|
||||
else {
|
||||
if (context().isEcma5() && initializer != null) {
|
||||
assert defineInvocation.get(0) == JsLiteral.NULL;
|
||||
defineInvocation.set(0, initializer);
|
||||
}
|
||||
((JsObjectLiteral) defineInvocation.get(context().isEcma5() ? 1 : 0)).getPropertyInitializers().addAll(visitor.getResult());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsPropertyInitializer> getNestedNamespaceDeclarations() {
|
||||
List<JsPropertyInitializer> result = Lists.newArrayList();
|
||||
List<NamespaceDescriptor> nestedNamespaces = JsDescriptorUtils.getNestedNamespaces(descriptor, context().bindingContext());
|
||||
for (NamespaceDescriptor nestedNamespace : nestedNamespaces) {
|
||||
NamespaceTranslator nestedNamespaceTranslator = new NamespaceTranslator(nestedNamespace, classDeclarationTranslator, context());
|
||||
result.add(nestedNamespaceTranslator.getDeclarationAsInitializer());
|
||||
|
||||
initializers.addAll(nestedNamespaceTranslator.getInitializers());
|
||||
private List<JsExpression> createDefineInvocation(@Nullable JsExpression initializer, @NotNull JsObjectLiteral members) {
|
||||
if (context().isEcma5()) {
|
||||
return Arrays.asList(initializer == null ? JsLiteral.NULL : initializer, members);
|
||||
}
|
||||
else {
|
||||
return Collections.<JsExpression>singletonList(members);
|
||||
}
|
||||
}
|
||||
|
||||
private JsPropertyInitializer getEntry(@NotNull NamespaceDescriptor descriptor, List<JsExpression> defineInvocation) {
|
||||
return new JsPropertyInitializer(context().getNameForDescriptor(descriptor).makeRef(),
|
||||
new JsInvocation(context().namer().packageDefinitionMethodReference(), defineInvocation));
|
||||
}
|
||||
|
||||
private boolean addEntryIfParentExists(NamespaceDescriptor parentDescriptor,
|
||||
JsPropertyInitializer entry,
|
||||
Map<NamespaceDescriptor, List<JsExpression>> descriptorToDeclarationPlace) {
|
||||
List<JsExpression> parentDefineInvocation = descriptorToDeclarationPlace.get(parentDescriptor);
|
||||
if (parentDefineInvocation != null) {
|
||||
((JsObjectLiteral) parentDefineInvocation.get(context().isEcma5() ? 1 : 0)).getPropertyInitializers().add(entry);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addToParent(NamespaceDescriptor parentDescriptor,
|
||||
JsPropertyInitializer entry,
|
||||
Map<NamespaceDescriptor, List<JsExpression>> descriptorToDefineInvocation) {
|
||||
while (!addEntryIfParentExists(parentDescriptor, entry, descriptorToDefineInvocation)) {
|
||||
List<JsExpression> defineInvocation =
|
||||
createDefineInvocation(null, new JsObjectLiteral(new SmartList<JsPropertyInitializer>(entry), true));
|
||||
entry = getEntry(parentDescriptor, defineInvocation);
|
||||
|
||||
descriptorToDefineInvocation.put(parentDescriptor, defineInvocation);
|
||||
parentDescriptor = (NamespaceDescriptor) parentDescriptor.getContainingDeclaration();
|
||||
}
|
||||
}
|
||||
|
||||
private class FileDeclarationVisitor extends DeclarationBodyVisitor {
|
||||
private final JsFunction initializer;
|
||||
private final TranslationContext initializerContext;
|
||||
private final List<JsStatement> initializerStatements;
|
||||
private final InitializerVisitor initializerVisitor;
|
||||
|
||||
private FileDeclarationVisitor() {
|
||||
initializer = JsAstUtils.createFunctionWithEmptyBody(context().scope());
|
||||
initializerContext = context().contextWithScope(initializer);
|
||||
initializerStatements = initializer.getBody().getStatements();
|
||||
initializerVisitor = new InitializerVisitor(initializerStatements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitClass(@NotNull JetClass expression, @NotNull TranslationContext context) {
|
||||
JsPropertyInitializer value = classDeclarationTranslator.translate(expression);
|
||||
result.add(value);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration, @NotNull TranslationContext context) {
|
||||
InitializerUtils.generate(declaration, initializerStatements, result, context);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitProperty(@NotNull JetProperty property, @NotNull TranslationContext context) {
|
||||
super.visitProperty(property, context);
|
||||
JetExpression initializer = property.getInitializer();
|
||||
if (initializer != null) {
|
||||
JsExpression value = Translation.translateAsExpression(initializer, initializerContext);
|
||||
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(context.bindingContext(), property);
|
||||
if (value instanceof JsLiteral) {
|
||||
result.add(new JsPropertyInitializer(context.getNameForDescriptor(propertyDescriptor).makeRef(),
|
||||
context().isEcma5() ? JsAstUtils
|
||||
.createPropertyDataDescriptor(propertyDescriptor, value) : value));
|
||||
}
|
||||
else {
|
||||
initializerStatements.add(generateInitializerForProperty(context, propertyDescriptor, value));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitAnonymousInitializer(@NotNull JetClassInitializer expression, @NotNull TranslationContext context) {
|
||||
expression.accept(initializerVisitor, initializerContext);
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@NotNull
|
||||
public JsNode visitObjectLiteralExpression(@NotNull JetObjectLiteralExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return ClassTranslator.generateObjectLiteralExpression(expression, context);
|
||||
return ClassTranslator.generateObjectLiteral(expression, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -387,7 +387,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
JetObjectDeclarationName objectDeclarationName = getObjectDeclarationName(expression);
|
||||
DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(), objectDeclarationName);
|
||||
JsName propertyName = context.getNameForDescriptor(descriptor);
|
||||
JsExpression value = ClassTranslator.generateClassCreationExpression(expression, context);
|
||||
JsExpression value = ClassTranslator.generateClassCreation(expression, context);
|
||||
return newVar(propertyName, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.google.dart.compiler.backend.js.ast.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.k2js.config.Config;
|
||||
@@ -29,6 +28,7 @@ import org.jetbrains.k2js.facade.exceptions.MainFunctionNotFoundException;
|
||||
import org.jetbrains.k2js.facade.exceptions.TranslationException;
|
||||
import org.jetbrains.k2js.facade.exceptions.TranslationInternalException;
|
||||
import org.jetbrains.k2js.facade.exceptions.UnsupportedFeatureException;
|
||||
import org.jetbrains.k2js.translate.context.Namer;
|
||||
import org.jetbrains.k2js.translate.context.StaticContext;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.declaration.ClassAliasingMap;
|
||||
@@ -39,12 +39,10 @@ import org.jetbrains.k2js.translate.expression.FunctionTranslator;
|
||||
import org.jetbrains.k2js.translate.expression.PatternTranslator;
|
||||
import org.jetbrains.k2js.translate.expression.WhenTranslator;
|
||||
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
||||
import org.jetbrains.k2js.translate.initializer.NamespaceInitializerTranslator;
|
||||
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
||||
import org.jetbrains.k2js.translate.test.JSTestGenerator;
|
||||
import org.jetbrains.k2js.translate.test.JSTester;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
import org.jetbrains.k2js.translate.utils.dangerous.DangerousData;
|
||||
import org.jetbrains.k2js.translate.utils.dangerous.DangerousTranslator;
|
||||
|
||||
@@ -75,7 +73,7 @@ public final class Translation {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JsStatement> translateFiles(@NotNull Collection<JetFile> files, @NotNull TranslationContext context) {
|
||||
private static List<JsStatement> translateFiles(@NotNull Collection<JetFile> files, @NotNull TranslationContext context) {
|
||||
return NamespaceDeclarationTranslator.translateFiles(files, context);
|
||||
}
|
||||
|
||||
@@ -83,7 +81,7 @@ public final class Translation {
|
||||
public static JsExpression translateClassDeclaration(@NotNull JetClass classDeclaration,
|
||||
@NotNull ClassAliasingMap classAliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
return ClassTranslator.generateClassCreationExpression(classDeclaration, classAliasingMap, context);
|
||||
return ClassTranslator.generateClassCreation(classDeclaration, classAliasingMap, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -136,13 +134,6 @@ public final class Translation {
|
||||
return classInitializerTranslator.generateInitializeMethod();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsFunction generateNamespaceInitializerMethod(@NotNull NamespaceDescriptor namespace,
|
||||
@NotNull TranslationContext context) {
|
||||
final NamespaceInitializerTranslator namespaceInitializerTranslator = new NamespaceInitializerTranslator(namespace, context);
|
||||
return namespaceInitializerTranslator.generateInitializeMethod();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsProgram generateAst(@NotNull BindingContext bindingContext,
|
||||
@NotNull Collection<JetFile> files, @NotNull MainCallParameters mainCallParameters,
|
||||
@@ -174,8 +165,9 @@ public final class Translation {
|
||||
statements.add(program.getStringLiteral("use strict").makeStmt());
|
||||
|
||||
TranslationContext context = TranslationContext.rootContext(staticContext);
|
||||
staticContext.getLiteralFunctionTranslator().setRootContext(context);
|
||||
statements.addAll(translateFiles(files, context));
|
||||
TranslationUtils.defineModule(context, statements, config.getModuleId());
|
||||
defineModule(context, statements, config.getModuleId());
|
||||
|
||||
if (mainCallParameters.shouldBeGenerated()) {
|
||||
JsStatement statement = generateCallToMain(context, files, mainCallParameters.arguments());
|
||||
@@ -187,6 +179,14 @@ public final class Translation {
|
||||
return context.program();
|
||||
}
|
||||
|
||||
private static void defineModule(@NotNull TranslationContext context, @NotNull List<JsStatement> statements, @NotNull String moduleId) {
|
||||
JsName rootNamespaceName = context.scope().findName(Namer.getRootNamespaceName());
|
||||
if (rootNamespaceName != null) {
|
||||
statements.add(new JsInvocation(context.namer().kotlin("defineModule"), context.program().getStringLiteral(moduleId),
|
||||
rootNamespaceName.makeRef()).makeStmt());
|
||||
}
|
||||
}
|
||||
|
||||
private static void mayBeGenerateTests(@NotNull Collection<JetFile> files, @NotNull Config config,
|
||||
@NotNull JsBlock rootBlock, @NotNull TranslationContext context) {
|
||||
JSTester tester = config.getTester();
|
||||
|
||||
Reference in New Issue
Block a user