JS backend: refactoring -- prepare to fix KT-2696
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.k2js.config.EcmaVersion;
|
|||||||
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||||
import org.jetbrains.k2js.translate.context.generator.Generator;
|
import org.jetbrains.k2js.translate.context.generator.Generator;
|
||||||
import org.jetbrains.k2js.translate.context.generator.Rule;
|
import org.jetbrains.k2js.translate.context.generator.Rule;
|
||||||
|
import org.jetbrains.k2js.translate.declaration.ClassDeclarationTranslator;
|
||||||
import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator;
|
import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator;
|
||||||
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||||
@@ -89,7 +90,9 @@ public final class StaticContext {
|
|||||||
private final EcmaVersion ecmaVersion;
|
private final EcmaVersion ecmaVersion;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final LiteralFunctionTranslator literalFunctionTranslator = new LiteralFunctionTranslator();
|
private LiteralFunctionTranslator literalFunctionTranslator;
|
||||||
|
@NotNull
|
||||||
|
private ClassDeclarationTranslator classDeclarationTranslator;
|
||||||
|
|
||||||
//TODO: too many parameters in constructor
|
//TODO: too many parameters in constructor
|
||||||
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
||||||
@@ -104,11 +107,21 @@ public final class StaticContext {
|
|||||||
this.ecmaVersion = ecmaVersion;
|
this.ecmaVersion = ecmaVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initTranslators(TranslationContext programContext) {
|
||||||
|
literalFunctionTranslator = new LiteralFunctionTranslator(programContext);
|
||||||
|
classDeclarationTranslator = new ClassDeclarationTranslator(programContext);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public LiteralFunctionTranslator getLiteralFunctionTranslator() {
|
public LiteralFunctionTranslator getLiteralFunctionTranslator() {
|
||||||
return literalFunctionTranslator;
|
return literalFunctionTranslator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ClassDeclarationTranslator getClassDeclarationTranslator() {
|
||||||
|
return classDeclarationTranslator;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEcma5() {
|
public boolean isEcma5() {
|
||||||
return ecmaVersion == EcmaVersion.v5;
|
return ecmaVersion == EcmaVersion.v5;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
|||||||
import org.jetbrains.jet.lang.descriptors.Named;
|
import org.jetbrains.jet.lang.descriptors.Named;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.k2js.translate.declaration.ClassDeclarationTranslator;
|
||||||
import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator;
|
import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator;
|
||||||
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||||
|
|
||||||
@@ -87,6 +88,7 @@ public class TranslationContext {
|
|||||||
usageTracker == null ? parent.usageTracker : usageTracker);
|
usageTracker == null ? parent.usageTracker : usageTracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public UsageTracker usageTracker() {
|
public UsageTracker usageTracker() {
|
||||||
return usageTracker;
|
return usageTracker;
|
||||||
}
|
}
|
||||||
@@ -240,6 +242,11 @@ public class TranslationContext {
|
|||||||
return staticContext.getLiteralFunctionTranslator();
|
return staticContext.getLiteralFunctionTranslator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ClassDeclarationTranslator classDeclarationTranslator() {
|
||||||
|
return staticContext.getClassDeclarationTranslator();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsFunction getFunctionObject(@NotNull CallableDescriptor descriptor) {
|
public JsFunction getFunctionObject(@NotNull CallableDescriptor descriptor) {
|
||||||
return staticContext.getFunctionWithScope(descriptor);
|
return staticContext.getFunctionWithScope(descriptor);
|
||||||
@@ -249,6 +256,7 @@ public class TranslationContext {
|
|||||||
dynamicContext.jsBlock().getStatements().add(statement);
|
dynamicContext.jsBlock().getStatements().add(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public JsExpression getAliasForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
public JsExpression getAliasForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
if (usageTracker != null) {
|
if (usageTracker != null) {
|
||||||
usageTracker.triggerUsed(descriptor);
|
usageTracker.triggerUsed(descriptor);
|
||||||
|
|||||||
+54
-45
@@ -17,9 +17,9 @@
|
|||||||
package org.jetbrains.k2js.translate.declaration;
|
package org.jetbrains.k2js.translate.declaration;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import com.intellij.openapi.util.Pair;
|
|
||||||
import com.intellij.util.SmartList;
|
import com.intellij.util.SmartList;
|
||||||
import gnu.trove.THashMap;
|
import gnu.trove.THashMap;
|
||||||
|
import gnu.trove.TObjectObjectProcedure;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
@@ -34,7 +34,10 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
|||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
|
import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
|
||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForType;
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForType;
|
||||||
@@ -50,11 +53,27 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
private final THashMap<ClassDescriptor, OpenClassInfo> openClassDescriptorToItem = new THashMap<ClassDescriptor, OpenClassInfo>();
|
private final THashMap<ClassDescriptor, OpenClassInfo> openClassDescriptorToItem = new THashMap<ClassDescriptor, OpenClassInfo>();
|
||||||
|
|
||||||
private final LinkedList<OpenClassInfo> openList = new LinkedList<OpenClassInfo>();
|
private final LinkedList<OpenClassInfo> openList = new LinkedList<OpenClassInfo>();
|
||||||
private final List<Pair<JetClassOrObject, JsInvocation>> finalList = new ArrayList<Pair<JetClassOrObject, JsInvocation>>();
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final ClassDescriptorToLabel classDescriptorToLabel = new ClassDescriptorToLabel();
|
private final ClassDescriptorToLabel classDescriptorToLabel = new ClassDescriptorToLabel();
|
||||||
|
|
||||||
|
private final THashMap<ClassDescriptor, JsNameRef> openClassDescriptorToQualifiedLabel = new THashMap<ClassDescriptor, JsNameRef>();
|
||||||
|
|
||||||
|
private final ClassAliasingMap classDescriptorToQualifiedLabel = new ClassAliasingMap() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JsNameRef get(ClassDescriptor descriptor, ClassDescriptor referencedDescriptor) {
|
||||||
|
JsNameRef ref = openClassDescriptorToQualifiedLabel.get(descriptor);
|
||||||
|
if (ref != null) {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
// will be resolved later
|
||||||
|
ref = new JsNameRef("<unresolved class>");
|
||||||
|
openClassDescriptorToQualifiedLabel.put(descriptor, ref);
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsFunction dummyFunction;
|
private final JsFunction dummyFunction;
|
||||||
|
|
||||||
@@ -71,8 +90,8 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class ClassDescriptorToLabel implements ClassAliasingMap {
|
private final class ClassDescriptorToLabel implements ClassAliasingMap {
|
||||||
@Override
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@Override
|
||||||
public JsNameRef get(ClassDescriptor descriptor, ClassDescriptor referencedDescriptor) {
|
public JsNameRef get(ClassDescriptor descriptor, ClassDescriptor referencedDescriptor) {
|
||||||
OpenClassInfo item = openClassDescriptorToItem.get(descriptor);
|
OpenClassInfo item = openClassDescriptorToItem.get(descriptor);
|
||||||
// class declared in library
|
// class declared in library
|
||||||
@@ -88,13 +107,11 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
private final ClassDescriptor descriptor;
|
private final ClassDescriptor descriptor;
|
||||||
private final JetClass declaration;
|
private final JetClass declaration;
|
||||||
private final JsNameRef label;
|
private final JsNameRef label;
|
||||||
private final JsNameRef qualifiedLabel;
|
|
||||||
|
|
||||||
private OpenClassInfo(JetClass declaration, ClassDescriptor descriptor, JsNameRef label, JsNameRef qualifiedLabel) {
|
private OpenClassInfo(JetClass declaration, ClassDescriptor descriptor, JsNameRef label) {
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
this.declaration = declaration;
|
this.declaration = declaration;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.qualifiedLabel = qualifiedLabel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +125,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
List<JsPropertyInitializer> propertyInitializers = new SmartList<JsPropertyInitializer>();
|
List<JsPropertyInitializer> propertyInitializers = new SmartList<JsPropertyInitializer>();
|
||||||
|
|
||||||
generateOpenClassDeclarations(vars, propertyInitializers);
|
generateOpenClassDeclarations(vars, propertyInitializers);
|
||||||
generateFinalClassDeclarations();
|
fixUnresolvedClassReferences();
|
||||||
|
|
||||||
if (vars.isEmpty()) {
|
if (vars.isEmpty()) {
|
||||||
if (!propertyInitializers.isEmpty()) {
|
if (!propertyInitializers.isEmpty()) {
|
||||||
@@ -154,59 +171,51 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
OpenClassInfo item = it.next();
|
OpenClassInfo item = it.next();
|
||||||
JsExpression translatedDeclaration =
|
JsExpression translatedDeclaration =
|
||||||
new ClassTranslator(item.declaration, item.descriptor, classDescriptorToLabel, context()).translate();
|
new ClassTranslator(item.declaration, item.descriptor, classDescriptorToLabel, context()).translate();
|
||||||
generate(item, propertyInitializers, translatedDeclaration, vars);
|
vars.add(new JsVar(item.label.getName(), translatedDeclaration));
|
||||||
|
propertyInitializers.add(new JsPropertyInitializer(item.label, item.label));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateFinalClassDeclarations() {
|
private void fixUnresolvedClassReferences() {
|
||||||
ClassAliasingMap aliasingMap = new ClassAliasingMap() {
|
openClassDescriptorToQualifiedLabel.forEachEntry(new TObjectObjectProcedure<ClassDescriptor, JsNameRef>() {
|
||||||
@Override
|
@Override
|
||||||
public JsNameRef get(ClassDescriptor descriptor, ClassDescriptor referencedDescriptor) {
|
public boolean execute(ClassDescriptor descriptor, JsNameRef ref) {
|
||||||
OpenClassInfo item = openClassDescriptorToItem.get(descriptor);
|
if (ref.getName() == null) {
|
||||||
return item == null ? null : item.qualifiedLabel;
|
// from library
|
||||||
|
ref.resolve(context().getNameForDescriptor(descriptor));
|
||||||
|
ref.setQualifier(context().getQualifierForDescriptor(descriptor));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
for (Pair<JetClassOrObject, JsInvocation> item : finalList) {
|
|
||||||
new ClassTranslator(item.first, aliasingMap, context()).translate(item.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void generate(@NotNull OpenClassInfo item,
|
|
||||||
@NotNull List<JsPropertyInitializer> propertyInitializers,
|
|
||||||
@NotNull JsExpression definition,
|
|
||||||
@NotNull List<JsVar> vars) {
|
|
||||||
JsExpression value;
|
|
||||||
if (item.label.getName() == null) {
|
|
||||||
value = definition;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert item.label.getName() != null;
|
|
||||||
vars.add(new JsVar(item.label.getName(), definition));
|
|
||||||
value = item.label;
|
|
||||||
}
|
|
||||||
|
|
||||||
propertyInitializers.add(new JsPropertyInitializer(item.label, value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsPropertyInitializer translate(@NotNull JetClassOrObject declaration) {
|
public JsPropertyInitializer translate(@NotNull JetClassOrObject declaration, TranslationContext context) {
|
||||||
ClassDescriptor descriptor = getClassDescriptor(context().bindingContext(), declaration);
|
ClassDescriptor descriptor = getClassDescriptor(context().bindingContext(), declaration);
|
||||||
JsExpression value;
|
JsExpression value;
|
||||||
if (descriptor.getModality() == Modality.FINAL) {
|
if (descriptor.getModality() == Modality.FINAL) {
|
||||||
JsInvocation invocation = context().namer().classCreateInvocation(descriptor);
|
value = new ClassTranslator(declaration, classDescriptorToQualifiedLabel, context).translate();
|
||||||
finalList.add(new Pair<JetClassOrObject, JsInvocation>(declaration, invocation));
|
|
||||||
value = invocation;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String label = localLabelGenerator.generate();
|
String label = localLabelGenerator.generate();
|
||||||
JsNameRef labelRef = dummyFunction.getScope().declareName(label).makeRef();
|
JsName name = dummyFunction.getScope().declareName(label);
|
||||||
OpenClassInfo item = new OpenClassInfo((JetClass) declaration, descriptor, labelRef,
|
JsNameRef qualifiedLabel = openClassDescriptorToQualifiedLabel.get(descriptor);
|
||||||
new JsNameRef(labelRef.getIdent(), declarationsObjectRef));
|
if (qualifiedLabel == null) {
|
||||||
|
qualifiedLabel = new JsNameRef(name);
|
||||||
|
openClassDescriptorToQualifiedLabel.put(descriptor, qualifiedLabel);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qualifiedLabel.resolve(name);
|
||||||
|
}
|
||||||
|
qualifiedLabel.setQualifier(declarationsObjectRef);
|
||||||
|
|
||||||
|
OpenClassInfo item = new OpenClassInfo((JetClass) declaration, descriptor, name.makeRef());
|
||||||
|
|
||||||
openList.add(item);
|
openList.add(item);
|
||||||
openClassDescriptorToItem.put(descriptor, item);
|
openClassDescriptorToItem.put(descriptor, item);
|
||||||
|
|
||||||
value = item.qualifiedLabel;
|
value = qualifiedLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return InitializerUtils.createPropertyInitializer(descriptor, value, context());
|
return InitializerUtils.createPropertyInitializer(descriptor, value, context());
|
||||||
|
|||||||
-11
@@ -129,17 +129,6 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitObjectDeclarationName(@NotNull JetObjectDeclarationName expression,
|
|
||||||
@NotNull TranslationContext context) {
|
|
||||||
if (!context.isEcma5()) {
|
|
||||||
PropertyTranslator
|
|
||||||
.translateAccessors(getPropertyDescriptorForObjectDeclaration(context.bindingContext(), expression), result, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void 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
|
// parsed it in initializer visitor => no additional actions are needed
|
||||||
|
|||||||
+3
-4
@@ -53,7 +53,6 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
|||||||
Map<NamespaceDescriptor, List<JsExpression>> descriptorToDefineInvocation = new THashMap<NamespaceDescriptor, List<JsExpression>>();
|
Map<NamespaceDescriptor, List<JsExpression>> descriptorToDefineInvocation = new THashMap<NamespaceDescriptor, List<JsExpression>>();
|
||||||
JsObjectLiteral rootNamespaceDefinition = null;
|
JsObjectLiteral rootNamespaceDefinition = null;
|
||||||
|
|
||||||
ClassDeclarationTranslator classDeclarationTranslator = new ClassDeclarationTranslator(context());
|
|
||||||
for (JetFile file : files) {
|
for (JetFile file : files) {
|
||||||
NamespaceDescriptor descriptor = context().bindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
|
NamespaceDescriptor descriptor = context().bindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
|
||||||
assert descriptor != null;
|
assert descriptor != null;
|
||||||
@@ -62,7 +61,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
|||||||
if (rootNamespaceDefinition == null) {
|
if (rootNamespaceDefinition == null) {
|
||||||
rootNamespaceDefinition = getRootPackage(descriptorToDefineInvocation, descriptor);
|
rootNamespaceDefinition = getRootPackage(descriptorToDefineInvocation, descriptor);
|
||||||
}
|
}
|
||||||
translator = new NamespaceTranslator(descriptor, classDeclarationTranslator, descriptorToDefineInvocation, context());
|
translator = new NamespaceTranslator(descriptor, descriptorToDefineInvocation, context());
|
||||||
descriptorToTranslator.put(descriptor, translator);
|
descriptorToTranslator.put(descriptor, translator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,12 +82,12 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
|||||||
result.add(vars);
|
result.add(vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
classDeclarationTranslator.generateDeclarations();
|
context().classDeclarationTranslator().generateDeclarations();
|
||||||
for (NamespaceTranslator translator : descriptorToTranslator.values()) {
|
for (NamespaceTranslator translator : descriptorToTranslator.values()) {
|
||||||
translator.add(descriptorToDefineInvocation, result);
|
translator.add(descriptorToDefineInvocation, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.addIfHasInitializer(classDeclarationTranslator.getDeclaration());
|
vars.addIfHasInitializer(context().classDeclarationTranslator().getDeclaration());
|
||||||
vars.addIfHasInitializer(getDeclaration(rootNamespaceDefinition));
|
vars.addIfHasInitializer(getDeclaration(rootNamespaceDefinition));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-9
@@ -49,21 +49,19 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescrip
|
|||||||
final class NamespaceTranslator extends AbstractTranslator {
|
final class NamespaceTranslator extends AbstractTranslator {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final NamespaceDescriptor descriptor;
|
private final NamespaceDescriptor descriptor;
|
||||||
@NotNull
|
|
||||||
private final ClassDeclarationTranslator classDeclarationTranslator;
|
|
||||||
|
|
||||||
private final FileDeclarationVisitor visitor;
|
private final FileDeclarationVisitor visitor;
|
||||||
|
|
||||||
private final NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>> definitionPlace;
|
private final NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>> definitionPlace;
|
||||||
|
|
||||||
NamespaceTranslator(@NotNull final NamespaceDescriptor descriptor,
|
NamespaceTranslator(
|
||||||
@NotNull ClassDeclarationTranslator classDeclarationTranslator,
|
@NotNull final NamespaceDescriptor descriptor,
|
||||||
@NotNull final Map<NamespaceDescriptor, List<JsExpression>> descriptorToDefineInvocation,
|
@NotNull final Map<NamespaceDescriptor, List<JsExpression>> descriptorToDefineInvocation,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context
|
||||||
|
) {
|
||||||
super(context.newDeclaration(descriptor));
|
super(context.newDeclaration(descriptor));
|
||||||
|
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
this.classDeclarationTranslator = classDeclarationTranslator;
|
|
||||||
|
|
||||||
visitor = new FileDeclarationVisitor();
|
visitor = new FileDeclarationVisitor();
|
||||||
|
|
||||||
@@ -186,9 +184,8 @@ final class NamespaceTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitClass(@NotNull JetClass expression, @NotNull TranslationContext context) {
|
public Void visitClass(@NotNull JetClass declaration, @NotNull TranslationContext context) {
|
||||||
JsPropertyInitializer value = classDeclarationTranslator.translate(expression);
|
result.add(context.classDeclarationTranslator().translate(declaration, context));
|
||||||
result.add(value);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -36,6 +36,7 @@ import org.jetbrains.k2js.translate.context.Namer;
|
|||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.context.UsageTracker;
|
import org.jetbrains.k2js.translate.context.UsageTracker;
|
||||||
import org.jetbrains.k2js.translate.declaration.ClassTranslator;
|
import org.jetbrains.k2js.translate.declaration.ClassTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -43,16 +44,13 @@ import java.util.List;
|
|||||||
import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody;
|
import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody;
|
||||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedReceiverDescriptor;
|
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedReceiverDescriptor;
|
||||||
|
|
||||||
public class LiteralFunctionTranslator {
|
public class LiteralFunctionTranslator extends AbstractTranslator {
|
||||||
private TranslationContext rootContext;
|
|
||||||
|
|
||||||
private final Stack<NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>> definitionPlaces =
|
private final Stack<NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>> definitionPlaces =
|
||||||
new Stack<NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>>();
|
new Stack<NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>>>();
|
||||||
private NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>> definitionPlace;
|
private NotNullLazyValue<Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression>> definitionPlace;
|
||||||
|
|
||||||
public void setRootContext(@NotNull TranslationContext rootContext) {
|
public LiteralFunctionTranslator(@NotNull TranslationContext context) {
|
||||||
assert this.rootContext == null;
|
super(context);
|
||||||
this.rootContext = rootContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression> createPlace(@NotNull List<JsPropertyInitializer> list,
|
public static Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression> createPlace(@NotNull List<JsPropertyInitializer> list,
|
||||||
@@ -120,7 +118,7 @@ public class LiteralFunctionTranslator {
|
|||||||
UsageTracker usageTracker = funContext.usageTracker();
|
UsageTracker usageTracker = funContext.usageTracker();
|
||||||
assert usageTracker != null;
|
assert usageTracker != null;
|
||||||
if (usageTracker.isUsed()) {
|
if (usageTracker.isUsed()) {
|
||||||
return new JsInvocation(rootContext.namer().kotlin("assignOwner"), fun, JsLiteral.THIS);
|
return new JsInvocation(context().namer().kotlin("assignOwner"), fun, JsLiteral.THIS);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fun.setName(null);
|
fun.setName(null);
|
||||||
@@ -138,7 +136,7 @@ public class LiteralFunctionTranslator {
|
|||||||
private JsNameRef createReference(JsFunction fun) {
|
private JsNameRef createReference(JsFunction fun) {
|
||||||
Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression> place = definitionPlace.getValue();
|
Trinity<List<JsPropertyInitializer>, LabelGenerator, JsExpression> place = definitionPlace.getValue();
|
||||||
JsNameRef nameRef = new JsNameRef(place.second.generate(), place.third);
|
JsNameRef nameRef = new JsNameRef(place.second.generate(), place.third);
|
||||||
place.first.add(new JsPropertyInitializer(nameRef, InitializerUtils.toDataDescriptor(fun, rootContext)));
|
place.first.add(new JsPropertyInitializer(nameRef, InitializerUtils.toDataDescriptor(fun, context())));
|
||||||
return nameRef;
|
return nameRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,18 +151,20 @@ public class LiteralFunctionTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JsFunction createFunction() {
|
private JsFunction createFunction() {
|
||||||
return new JsFunction(rootContext.scope(), new JsBlock());
|
return new JsFunction(context().scope(), new JsBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsExpression translate(@NotNull ClassDescriptor outerClass,
|
public JsExpression translate(
|
||||||
|
@NotNull ClassDescriptor outerClass,
|
||||||
@NotNull JetClassOrObject declaration,
|
@NotNull JetClassOrObject declaration,
|
||||||
@NotNull ClassDescriptor descriptor,
|
@NotNull ClassDescriptor descriptor,
|
||||||
@NotNull ClassTranslator classTranslator) {
|
@NotNull ClassTranslator classTranslator
|
||||||
|
) {
|
||||||
JsFunction fun = createFunction();
|
JsFunction fun = createFunction();
|
||||||
JsNameRef outerClassRef = fun.getScope().declareName(Namer.OUTER_CLASS_NAME).makeRef();
|
JsNameRef outerClassRef = fun.getScope().declareName(Namer.OUTER_CLASS_NAME).makeRef();
|
||||||
UsageTracker usageTracker = new UsageTracker(descriptor, null, outerClass);
|
UsageTracker usageTracker = new UsageTracker(descriptor, null, outerClass);
|
||||||
TranslationContext funContext = rootContext.newFunctionBody(fun, rootContext.aliasingContext().inner(outerClass, outerClassRef),
|
TranslationContext funContext = context().newFunctionBody(fun, context().aliasingContext().inner(outerClass, outerClassRef),
|
||||||
usageTracker);
|
usageTracker);
|
||||||
|
|
||||||
fun.getBody().getStatements().add(new JsReturn(classTranslator.translate(funContext)));
|
fun.getBody().getStatements().add(new JsReturn(classTranslator.translate(funContext)));
|
||||||
JetClassBody body = declaration.getBody();
|
JetClassBody body = declaration.getBody();
|
||||||
|
|||||||
@@ -67,11 +67,6 @@ public final class Translation {
|
|||||||
return FunctionTranslator.newInstance(function, context);
|
return FunctionTranslator.newInstance(function, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static List<JsStatement> translateFiles(@NotNull Collection<JetFile> files, @NotNull TranslationContext context) {
|
|
||||||
return NamespaceDeclarationTranslator.translateFiles(files, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static PatternTranslator patternTranslator(@NotNull TranslationContext context) {
|
public static PatternTranslator patternTranslator(@NotNull TranslationContext context) {
|
||||||
return PatternTranslator.newInstance(context);
|
return PatternTranslator.newInstance(context);
|
||||||
@@ -134,7 +129,6 @@ public final class Translation {
|
|||||||
private static JsProgram doGenerateAst(@NotNull BindingContext bindingContext, @NotNull Collection<JetFile> files,
|
private static JsProgram doGenerateAst(@NotNull BindingContext bindingContext, @NotNull Collection<JetFile> files,
|
||||||
@NotNull MainCallParameters mainCallParameters,
|
@NotNull MainCallParameters mainCallParameters,
|
||||||
@NotNull Config config) throws MainFunctionNotFoundException {
|
@NotNull Config config) throws MainFunctionNotFoundException {
|
||||||
//TODO: move some of the code somewhere
|
|
||||||
StaticContext staticContext = StaticContext.generateStaticContext(bindingContext, config.getTarget());
|
StaticContext staticContext = StaticContext.generateStaticContext(bindingContext, config.getTarget());
|
||||||
JsProgram program = staticContext.getProgram();
|
JsProgram program = staticContext.getProgram();
|
||||||
JsBlock block = program.getGlobalBlock();
|
JsBlock block = program.getGlobalBlock();
|
||||||
@@ -145,8 +139,8 @@ public final class Translation {
|
|||||||
statements.add(program.getStringLiteral("use strict").makeStmt());
|
statements.add(program.getStringLiteral("use strict").makeStmt());
|
||||||
|
|
||||||
TranslationContext context = TranslationContext.rootContext(staticContext, rootFunction);
|
TranslationContext context = TranslationContext.rootContext(staticContext, rootFunction);
|
||||||
staticContext.getLiteralFunctionTranslator().setRootContext(context);
|
staticContext.initTranslators(context);
|
||||||
statements.addAll(translateFiles(files, context));
|
statements.addAll(NamespaceDeclarationTranslator.translateFiles(files, context));
|
||||||
defineModule(context, statements, config.getModuleId());
|
defineModule(context, statements, config.getModuleId());
|
||||||
|
|
||||||
if (mainCallParameters.shouldBeGenerated()) {
|
if (mainCallParameters.shouldBeGenerated()) {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public final class BindingUtils {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context,
|
public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context,
|
||||||
@NotNull JetClassOrObject declaration) {
|
@NotNull JetClassOrObject declaration) {
|
||||||
return getDescriptorForExpression(context, declaration, ClassDescriptor.class);
|
return BindingContextUtils.getNotNull(context, BindingContext.CLASS, declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -232,12 +232,6 @@ public final class BindingUtils {
|
|||||||
return BindingContextUtils.getNotNull(context, BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, rangeExpression);
|
return BindingContextUtils.getNotNull(context, BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, rangeExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static PropertyDescriptor getPropertyDescriptorForObjectDeclaration(@NotNull BindingContext context,
|
|
||||||
@NotNull JetObjectDeclarationName name) {
|
|
||||||
return BindingContextUtils.getNotNull(context, BindingContext.OBJECT_DECLARATION, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JetType getTypeForExpression(@NotNull BindingContext context,
|
public static JetType getTypeForExpression(@NotNull BindingContext context,
|
||||||
@NotNull JetExpression expression) {
|
@NotNull JetExpression expression) {
|
||||||
|
|||||||
Reference in New Issue
Block a user