JS backend: use name of containing declaration when naming local and literal functions.

This commit is contained in:
Zalim Bashorov
2014-01-17 23:08:34 +04:00
parent 1e9defaad3
commit 0af1ae360f
6 changed files with 48 additions and 21 deletions
@@ -5,6 +5,7 @@
package com.google.dart.compiler.backend.js.ast;
import com.google.dart.compiler.common.Symbol;
import org.jetbrains.annotations.NotNull;
/**
* An abstract base class for named JavaScript objects.
@@ -25,6 +26,7 @@ public class JsName implements Symbol {
return ident;
}
@NotNull
public JsNameRef makeRef() {
return new JsNameRef(this);
}
@@ -19,13 +19,16 @@ package org.jetbrains.k2js.translate.context
import com.google.dart.compiler.backend.js.ast.JsExpression
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer
import com.google.dart.compiler.backend.js.ast.JsNameRef
import com.google.dart.compiler.backend.js.ast.JsScope
class DefinitionPlace(
val properties: MutableList<JsPropertyInitializer>,
private val fqName: JsExpression
private val scope: JsScope,
private val fqName: JsExpression,
val properties: MutableList<JsPropertyInitializer>
) {
fun define(name: String, expression : JsExpression): JsNameRef {
properties.add(JsPropertyInitializer(JsNameRef(name), expression))
fun define(suggestedName: String, expression : JsExpression): JsNameRef {
val name = scope.declareFreshName(suggestedName)
properties.add(JsPropertyInitializer(name.makeRef(), expression))
return JsNameRef(name, fqName)
}
}
@@ -26,8 +26,6 @@ import java.util.List;
import java.util.Map;
public class Generator<V> {
@NotNull
private final Map<DeclarationDescriptor, V> values = Maps.newHashMap();
@NotNull
@@ -50,13 +48,12 @@ public class Generator<V> {
@Nullable
private V generate(@NotNull DeclarationDescriptor descriptor) {
V result = null;
for (Rule<V> rule : rules) {
result = rule.apply(descriptor);
V result = rule.apply(descriptor);
if (result != null) {
return result;
}
}
return result;
return null;
}
}
@@ -138,14 +138,15 @@ public final class ClassTranslator extends AbstractTranslator {
qualifiedReference = null;
}
else {
JsScope scope = context().getScopeForDescriptor(descriptor);
DefinitionPlace definitionPlace;
if (descriptor.getKind().isSingleton() || isAnonymousObject(descriptor)) {
qualifiedReference = null;
definitionPlace = new DefinitionPlace(properties, context().getThisObject(descriptor));
definitionPlace = new DefinitionPlace(scope, context().getThisObject(descriptor), properties);
}
else {
qualifiedReference = declarationContext.getQualifiedReference(descriptor);
definitionPlace = new DefinitionPlace(staticProperties, qualifiedReference);
definitionPlace = new DefinitionPlace(scope, qualifiedReference, staticProperties);
}
declarationContext = declarationContext.newDeclaration(descriptor, definitionPlace);
}
@@ -38,8 +38,11 @@ final class PackageTranslator extends AbstractTranslator {
@NotNull PackageFragmentDescriptor descriptor,
@NotNull TranslationContext context
) {
JsScope scope = context.getScopeForDescriptor(descriptor);
JsNameRef reference = context.getQualifiedReference(descriptor);
SmartList<JsPropertyInitializer> properties = new SmartList<JsPropertyInitializer>();
DefinitionPlace definitionPlace = new DefinitionPlace(properties, context.getQualifiedReference(descriptor));
DefinitionPlace definitionPlace = new DefinitionPlace(scope, reference, properties);
TranslationContext newContext = context.newDeclaration(descriptor, definitionPlace);
FileDeclarationVisitor visitor = new FileDeclarationVisitor(newContext, definitionPlace.getProperties());
@@ -20,16 +20,16 @@ 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.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetClassBody;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.k2js.translate.LabelGenerator;
import org.jetbrains.k2js.translate.context.*;
import org.jetbrains.k2js.translate.context.AliasingContext;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.context.UsageTracker;
import org.jetbrains.k2js.translate.declaration.ClassTranslator;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
@@ -41,7 +41,6 @@ import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translat
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedReceiverDescriptor;
public class LiteralFunctionTranslator extends AbstractTranslator {
private static final LabelGenerator FUNCTION_NAME_GENERATOR = new LabelGenerator('f');
private static final String CAPTURED_VALUE_FIELD = "v";
private final JetDeclarationWithBody declaration;
@@ -118,7 +117,7 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
}
}
else {
JsNameRef funReference = context().define(FUNCTION_NAME_GENERATOR.generate(), jsFunction);
JsNameRef funReference = context().define(getSuggestedName(functionContext, descriptor), jsFunction);
InnerFunctionTranslator innerTranslator = new InnerFunctionTranslator(descriptor, functionContext, jsFunction, tempRef);
result = innerTranslator.translate(funReference, context());
@@ -193,6 +192,28 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
FunctionTranslator.addParameters(fun.getParameters(), descriptor, funContext);
}
private static String getSuggestedName(TranslationContext context, DeclarationDescriptor descriptor) {
String suggestedName = "";
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration != null &&
!(containingDeclaration instanceof ClassOrPackageFragmentDescriptor) &&
!(containingDeclaration instanceof AnonymousFunctionDescriptor)) {
suggestedName = context.getNameForDescriptor(containingDeclaration).getIdent();
}
if (!suggestedName.isEmpty() && !suggestedName.endsWith("$")) {
suggestedName += "$";
}
if (descriptor.getName().isSpecial()) {
suggestedName += "f";
}
else {
suggestedName += context.getNameForDescriptor(descriptor).getIdent();
}
return suggestedName;
}
@NotNull
public static JsVars translateLocalNamedFunction(@NotNull JetDeclarationWithBody declaration, @NotNull TranslationContext outerContext) {
return new LiteralFunctionTranslator(declaration, outerContext).translateLocalNamedFunction();
@@ -223,7 +244,7 @@ public class LiteralFunctionTranslator extends AbstractTranslator {
JetClassBody body = declaration.getBody();
assert body != null;
JsNameRef define = funContext.define(FUNCTION_NAME_GENERATOR.generate(), fun);
JsNameRef define = funContext.define(getSuggestedName(funContext, descriptor), fun);
return new InnerObjectTranslator(funContext, fun).translate(define, usageTracker.isUsed() ? outerClassRef : null);
}
}