From 0af1ae360f479a92b526040767c71c589c0b3e25 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Fri, 17 Jan 2014 23:08:34 +0400 Subject: [PATCH] JS backend: use name of containing declaration when naming local and literal functions. --- .../dart/compiler/backend/js/ast/JsName.java | 2 + .../k2js/translate/context/DefinitionPlace.kt | 11 ++++-- .../context/generator/Generator.java | 7 +--- .../declaration/ClassTranslator.java | 5 ++- .../declaration/PackageTranslator.java | 5 ++- .../expression/LiteralFunctionTranslator.java | 39 ++++++++++++++----- 6 files changed, 48 insertions(+), 21 deletions(-) diff --git a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/JsName.java b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/JsName.java index 44da16f6610..fb881814f9a 100644 --- a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/JsName.java +++ b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/JsName.java @@ -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); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/DefinitionPlace.kt b/js/js.translator/src/org/jetbrains/k2js/translate/context/DefinitionPlace.kt index 9f4ca46a6f3..223ba6ab093 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/DefinitionPlace.kt +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/DefinitionPlace.kt @@ -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, - private val fqName: JsExpression + private val scope: JsScope, + private val fqName: JsExpression, + val properties: MutableList ) { - 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) } } \ No newline at end of file diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/generator/Generator.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/generator/Generator.java index 452e681fb1e..8ef2233ad65 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/generator/Generator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/generator/Generator.java @@ -26,8 +26,6 @@ import java.util.List; import java.util.Map; public class Generator { - - @NotNull private final Map values = Maps.newHashMap(); @NotNull @@ -50,13 +48,12 @@ public class Generator { @Nullable private V generate(@NotNull DeclarationDescriptor descriptor) { - V result = null; for (Rule rule : rules) { - result = rule.apply(descriptor); + V result = rule.apply(descriptor); if (result != null) { return result; } } - return result; + return null; } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java index b775875a57e..3426d1bbb80 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java @@ -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); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PackageTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PackageTranslator.java index 69b5bb60274..56dc5a97d68 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PackageTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PackageTranslator.java @@ -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 properties = new SmartList(); - 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()); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/LiteralFunctionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/LiteralFunctionTranslator.java index e090c257daf..cbf575ce3e9 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/LiteralFunctionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/LiteralFunctionTranslator.java @@ -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); } }