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 new file mode 100644 index 00000000000..9f4ca46a6f3 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/DefinitionPlace.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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 + +class DefinitionPlace( + val properties: MutableList, + private val fqName: JsExpression +) { + fun define(name: String, expression : JsExpression): JsNameRef { + properties.add(JsPropertyInitializer(JsNameRef(name), expression)) + return JsNameRef(name, fqName) + } +} \ No newline at end of file diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java index 04f776bd83d..80037c92c6b 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java @@ -31,7 +31,6 @@ import org.jetbrains.k2js.config.EcmaVersion; import org.jetbrains.k2js.config.LibrarySourcesConfig; import org.jetbrains.k2js.translate.context.generator.Generator; import org.jetbrains.k2js.translate.context.generator.Rule; -import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator; import org.jetbrains.k2js.translate.intrinsic.Intrinsics; import org.jetbrains.k2js.translate.utils.AnnotationsUtils; import org.jetbrains.k2js.translate.utils.JsAstUtils; @@ -93,9 +92,6 @@ public final class StaticContext { @NotNull private final EcmaVersion ecmaVersion; - @NotNull - private LiteralFunctionTranslator literalFunctionTranslator; - //TODO: too many parameters in constructor private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext, @NotNull Namer namer, @NotNull Intrinsics intrinsics, @@ -109,15 +105,6 @@ public final class StaticContext { this.ecmaVersion = ecmaVersion; } - public void initTranslators(TranslationContext programContext) { - literalFunctionTranslator = new LiteralFunctionTranslator(programContext); - } - - @NotNull - public LiteralFunctionTranslator getLiteralFunctionTranslator() { - return literalFunctionTranslator; - } - public boolean isEcma5() { return ecmaVersion == EcmaVersion.v5; } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java index 643a6d9a7da..85ded6b001f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java @@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.name.FqName; -import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator; import org.jetbrains.k2js.translate.intrinsic.Intrinsics; import java.util.HashMap; @@ -46,31 +45,42 @@ public class TranslationContext { private final AliasingContext aliasingContext; @Nullable private final UsageTracker usageTracker; + @Nullable + private final TranslationContext parent; + @Nullable + private final DefinitionPlace definitionPlace; @NotNull public static TranslationContext rootContext(@NotNull StaticContext staticContext, JsFunction rootFunction) { DynamicContext rootDynamicContext = DynamicContext.rootContext(rootFunction.getScope(), rootFunction.getBody()); AliasingContext rootAliasingContext = AliasingContext.getCleanContext(); - return new TranslationContext(staticContext, rootDynamicContext, rootAliasingContext, null); + return new TranslationContext(null, staticContext, rootDynamicContext, rootAliasingContext, null, null); } private final HashMap expressionToTempConstVariableCache = new HashMap(); private TranslationContext( + @Nullable TranslationContext parent, @NotNull StaticContext staticContext, @NotNull DynamicContext dynamicContext, @NotNull AliasingContext aliasingContext, - @Nullable UsageTracker usageTracker + @Nullable UsageTracker usageTracker, + @Nullable DefinitionPlace definitionPlace ) { + this.parent = parent; this.dynamicContext = dynamicContext; this.staticContext = staticContext; this.aliasingContext = aliasingContext; this.usageTracker = usageTracker; + this.definitionPlace = definitionPlace; } - private TranslationContext(@NotNull TranslationContext parent, @NotNull AliasingContext aliasingContext) { - this(parent.staticContext, parent.dynamicContext, aliasingContext, parent.usageTracker); + private TranslationContext( + @NotNull TranslationContext parent, + @NotNull AliasingContext aliasingContext + ) { + this(parent, parent.staticContext, parent.dynamicContext, aliasingContext, parent.usageTracker, null); } private TranslationContext( @@ -79,8 +89,8 @@ public class TranslationContext { @NotNull AliasingContext aliasingContext, @Nullable UsageTracker usageTracker ) { - this(parent.staticContext, DynamicContext.newContext(fun.getScope(), fun.getBody()), aliasingContext, - usageTracker == null ? parent.usageTracker : usageTracker); + this(parent, parent.staticContext, DynamicContext.newContext(fun.getScope(), fun.getBody()), aliasingContext, + usageTracker == null ? parent.usageTracker : usageTracker, null); } @Nullable @@ -97,14 +107,6 @@ public class TranslationContext { return new TranslationContext(this, fun, aliasingContext, null); } - @NotNull - private TranslationContext contextWithScope(@NotNull JsScope newScope, - @NotNull JsBlock block, - @NotNull AliasingContext aliasingContext, - @Nullable UsageTracker usageTracker) { - return new TranslationContext(staticContext, DynamicContext.newContext(newScope, block), aliasingContext, usageTracker); - } - @NotNull public TranslationContext newFunctionBody( @NotNull JsFunction fun, @@ -117,12 +119,13 @@ public class TranslationContext { @NotNull public TranslationContext innerBlock(@NotNull JsBlock block) { - return new TranslationContext(staticContext, dynamicContext.innerBlock(block), aliasingContext, usageTracker); + return new TranslationContext(this, staticContext, dynamicContext.innerBlock(block), aliasingContext, usageTracker, null); } @NotNull - public TranslationContext newDeclaration(@NotNull DeclarationDescriptor descriptor) { - return contextWithScope(getScopeForDescriptor(descriptor), getBlockForDescriptor(descriptor), aliasingContext, usageTracker); + public TranslationContext newDeclaration(@NotNull DeclarationDescriptor descriptor, @Nullable DefinitionPlace place) { + DynamicContext dynamicContext = DynamicContext.newContext(getScopeForDescriptor(descriptor), getBlockForDescriptor(descriptor)); + return new TranslationContext(this, staticContext, dynamicContext, aliasingContext, usageTracker, place); } @NotNull @@ -247,11 +250,6 @@ public class TranslationContext { return aliasingContext; } - @NotNull - public LiteralFunctionTranslator literalFunctionTranslator() { - return staticContext.getLiteralFunctionTranslator(); - } - @NotNull public JsFunction getFunctionObject(@NotNull CallableDescriptor descriptor) { return staticContext.getFunctionWithScope(descriptor); @@ -287,4 +285,12 @@ public class TranslationContext { JsExpression alias = aliasingContext.getAliasForDescriptor(effectiveDescriptor); return alias == null ? JsLiteral.THIS : alias; } + + @NotNull + public DefinitionPlace getDefinitionPlace() { + if (definitionPlace != null) return definitionPlace; + if (parent != null) return parent.getDefinitionPlace(); + + throw new AssertionError("Can not find definition place from rootContext(definitionPlace and parent is 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 813aadb347f..c3cb96f9eac 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 @@ -17,8 +17,6 @@ package org.jetbrains.k2js.translate.declaration; import com.google.dart.compiler.backend.js.ast.*; -import com.intellij.openapi.util.NotNullLazyValue; -import com.intellij.openapi.util.Trinity; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -29,8 +27,9 @@ import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeConstructor; -import org.jetbrains.k2js.translate.LabelGenerator; +import org.jetbrains.k2js.translate.context.DefinitionPlace; import org.jetbrains.k2js.translate.context.TranslationContext; +import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator; import org.jetbrains.k2js.translate.utils.JsAstUtils; @@ -39,7 +38,6 @@ import java.util.*; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.types.TypeUtils.topologicallySortSuperclassesAndRecordAllInstances; -import static org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator.createPlace; import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createClassObjectInitializer; import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor; import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter; @@ -110,7 +108,7 @@ public final class ClassTranslator extends AbstractTranslator { if (containingClass == null) { return translate(context()); } - return context().literalFunctionTranslator().translate(containingClass, context(), classDeclaration, descriptor, this); + return new LiteralFunctionTranslator(context()).translate(containingClass, context(), classDeclaration, descriptor, this); } @NotNull @@ -130,34 +128,26 @@ public final class ClassTranslator extends AbstractTranslator { private List getClassCreateInvocationArguments(@NotNull TranslationContext declarationContext) { List invocationArguments = new ArrayList(); - final List properties = new SmartList(); - final List staticProperties = new SmartList(); + List properties = new SmartList(); + List staticProperties = new SmartList(); + boolean isTopLevelDeclaration = context() == declarationContext; - final JsNameRef qualifiedReference; + + JsNameRef qualifiedReference; if (!isTopLevelDeclaration) { qualifiedReference = null; } - else if (descriptor.getKind().isSingleton() || isAnonymousObject(descriptor)) { - qualifiedReference = null; - declarationContext.literalFunctionTranslator().setDefinitionPlace( - new NotNullLazyValue, LabelGenerator, JsExpression>>() { - @Override - @NotNull - public Trinity, LabelGenerator, JsExpression> compute() { - return createPlace(properties, context().getThisObject(descriptor)); - } - }); - } else { - qualifiedReference = declarationContext.getQualifiedReference(descriptor); - declarationContext.literalFunctionTranslator().setDefinitionPlace( - new NotNullLazyValue, LabelGenerator, JsExpression>>() { - @Override - @NotNull - public Trinity, LabelGenerator, JsExpression> compute() { - return createPlace(staticProperties, qualifiedReference); - } - }); + DefinitionPlace definitionPlace; + if (descriptor.getKind().isSingleton() || isAnonymousObject(descriptor)) { + qualifiedReference = null; + definitionPlace = new DefinitionPlace(properties, context().getThisObject(descriptor)); + } + else { + qualifiedReference = declarationContext.getQualifiedReference(descriptor); + definitionPlace = new DefinitionPlace(staticProperties, qualifiedReference); + } + declarationContext = declarationContext.newDeclaration(descriptor, definitionPlace); } invocationArguments.add(getSuperclassReferences(declarationContext)); @@ -171,10 +161,6 @@ public final class ClassTranslator extends AbstractTranslator { bodyVisitor.traverseContainer(classDeclaration, declarationContext); mayBeAddEnumEntry(bodyVisitor.getEnumEntryList(), staticProperties, declarationContext); - if (isTopLevelDeclaration) { - declarationContext.literalFunctionTranslator().setDefinitionPlace(null); - } - boolean hasStaticProperties = !staticProperties.isEmpty(); if (!properties.isEmpty() || hasStaticProperties) { if (properties.isEmpty()) { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java index 9dde95a4af6..04ac7ce7200 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java @@ -48,10 +48,6 @@ public class DeclarationBodyVisitor extends TranslatorVisitor { protected final List staticResult; protected final List enumEntryList = new SmartList(); - public DeclarationBodyVisitor() { - this(new SmartList(), new SmartList()); - } - public DeclarationBodyVisitor(@NotNull List result, @NotNull List staticResult) { this.result = result; this.staticResult = staticResult; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DefineInvocation.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DefineInvocation.java index 07c00f0b22e..17428d33ec9 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DefineInvocation.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/DefineInvocation.java @@ -30,7 +30,7 @@ public class DefineInvocation { /* package */ @NotNull - static DefineInvocation createDefineInvocation( + static DefineInvocation create( @NotNull FqName packageFqName, @Nullable JsExpression initializer, @NotNull JsObjectLiteral members, diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/FileDeclaration.kt b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/FileDeclaration.kt index ed94df82a23..c5cd3253e94 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/FileDeclaration.kt +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/FileDeclaration.kt @@ -15,14 +15,11 @@ */ package org.jetbrains.k2js.translate.declaration -import com.google.dart.compiler.backend.js.ast.JsExpression -import com.google.dart.compiler.backend.js.ast.JsNameRef import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer import org.jetbrains.k2js.translate.initializer.InitializerVisitor import org.jetbrains.k2js.translate.utils.JsAstUtils import org.jetbrains.k2js.translate.context.TranslationContext import org.jetbrains.jet.lang.psi.JetClassInitializer -import com.google.dart.compiler.backend.js.ast.JsStatement import org.jetbrains.k2js.translate.general.Translation import org.jetbrains.jet.lang.psi.JetProperty import org.jetbrains.k2js.translate.initializer.InitializerUtils @@ -32,8 +29,13 @@ import com.google.dart.compiler.backend.js.ast.JsFunction import org.jetbrains.k2js.translate.utils.BindingUtils.* import org.jetbrains.k2js.translate.initializer.InitializerUtils.* import org.jetbrains.jet.lang.descriptors.PropertyDescriptor +import com.intellij.util.SmartList + +class FileDeclarationVisitor( + val context: TranslationContext, + initializers: List = SmartList() +) : DeclarationBodyVisitor(initializers, SmartList()) { -class FileDeclarationVisitor(val context: TranslationContext) : DeclarationBodyVisitor() { private val initializer = JsAstUtils.createFunctionWithEmptyBody(context.scope()) private val initializerContext = context.contextWithScope(initializer) private val initializerStatements = initializer.getBody()!!.getStatements()!! diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PackageDeclarationTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PackageDeclarationTranslator.java index 01bb598b510..8cb3bdba5fd 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PackageDeclarationTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PackageDeclarationTranslator.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.TranslationContext; @@ -30,7 +31,6 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator; import java.util.*; import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar; -import static org.jetbrains.k2js.translate.declaration.DefineInvocation.createDefineInvocation; public final class PackageDeclarationTranslator extends AbstractTranslator { private final Iterable files; @@ -53,12 +53,13 @@ public final class PackageDeclarationTranslator extends AbstractTranslator { Map packageFqNameToDefineInvocation = new THashMap(); for (JetFile file : files) { - PackageFragmentDescriptor packageFragment = context().bindingContext().get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, file); + PackageFragmentDescriptor packageFragment = + BindingContextUtils.getNotNull(context().bindingContext(), BindingContext.FILE_TO_PACKAGE_FRAGMENT, file); PackageTranslator translator = packageFragmentToTranslator.get(packageFragment); if (translator == null) { createRootPackageDefineInvocationIfNeeded(packageFqNameToDefineInvocation); - translator = new PackageTranslator(packageFragment, packageFqNameToDefineInvocation, context()); + translator = PackageTranslator.create(packageFragment, context()); packageFragmentToTranslator.put(packageFragment, translator); } @@ -78,7 +79,7 @@ public final class PackageDeclarationTranslator extends AbstractTranslator { private void createRootPackageDefineInvocationIfNeeded(@NotNull Map packageFqNameToDefineInvocation) { if (!packageFqNameToDefineInvocation.containsKey(FqName.ROOT)) { packageFqNameToDefineInvocation.put( - FqName.ROOT, createDefineInvocation(FqName.ROOT, null, new JsObjectLiteral(true), context())); + FqName.ROOT, DefineInvocation.create(FqName.ROOT, null, new JsObjectLiteral(true), context())); } } 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 355e58b6480..69b5bb60274 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 @@ -17,15 +17,14 @@ package org.jetbrains.k2js.translate.declaration; import com.google.dart.compiler.backend.js.ast.*; -import com.intellij.openapi.util.NotNullLazyValue; -import com.intellij.openapi.util.Trinity; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; -import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.psi.JetDeclaration; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.name.FqName; -import org.jetbrains.k2js.translate.LabelGenerator; +import org.jetbrains.k2js.translate.context.DefinitionPlace; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.utils.AnnotationsUtils; @@ -34,61 +33,50 @@ import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.List; import java.util.Map; -import static org.jetbrains.k2js.translate.declaration.DefineInvocation.createDefineInvocation; -import static org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator.createPlace; - final class PackageTranslator extends AbstractTranslator { + static PackageTranslator create( + @NotNull PackageFragmentDescriptor descriptor, + @NotNull TranslationContext context + ) { + SmartList properties = new SmartList(); + DefinitionPlace definitionPlace = new DefinitionPlace(properties, context.getQualifiedReference(descriptor)); + + TranslationContext newContext = context.newDeclaration(descriptor, definitionPlace); + FileDeclarationVisitor visitor = new FileDeclarationVisitor(newContext, definitionPlace.getProperties()); + return new PackageTranslator(descriptor, newContext, visitor); + } + @NotNull private final PackageFragmentDescriptor descriptor; private final FileDeclarationVisitor visitor; - private final NotNullLazyValue, LabelGenerator, JsExpression>> definitionPlace; - - PackageTranslator( - @NotNull final PackageFragmentDescriptor descriptor, - @NotNull final Map packageFqNameToDefineInvocation, - @NotNull TranslationContext context + private PackageTranslator( + @NotNull PackageFragmentDescriptor descriptor, + @NotNull TranslationContext context, + @NotNull FileDeclarationVisitor visitor ) { - super(context.newDeclaration(descriptor)); - + super(context); this.descriptor = descriptor; - - visitor = new FileDeclarationVisitor(context()); - - definitionPlace = new NotNullLazyValue, LabelGenerator, JsExpression>>() { - @Override - @NotNull - public Trinity, LabelGenerator, JsExpression> compute() { - DefineInvocation defineInvocation = packageFqNameToDefineInvocation.get(descriptor.getFqName()); - if (defineInvocation == null) { - defineInvocation = createDefinitionPlace(null, packageFqNameToDefineInvocation); - } - - return createPlace(defineInvocation.getMembers(), context().getQualifiedReference(descriptor.getFqName())); - } - }; + this.visitor = visitor; } - + public void translate(JetFile file) { - context().literalFunctionTranslator().setDefinitionPlace(definitionPlace); for (JetDeclaration declaration : file.getDeclarations()) { if (!AnnotationsUtils.isPredefinedObject(BindingUtils.getDescriptorForElement(bindingContext(), declaration))) { declaration.accept(visitor, context()); } } - context().literalFunctionTranslator().setDefinitionPlace(null); } - private DefineInvocation createDefinitionPlace( + private void createDefinitionPlace( @Nullable JsExpression initializer, Map packageFqNameToDefineInvocation ) { FqName fqName = descriptor.getFqName(); - DefineInvocation place = createDefineInvocation(fqName, initializer, new JsObjectLiteral(visitor.getResult(), true), context()); + DefineInvocation place = DefineInvocation.create(fqName, initializer, new JsObjectLiteral(visitor.getResult(), true), context()); packageFqNameToDefineInvocation.put(fqName, place); addToParent(fqName.parent(), getEntry(fqName, place), packageFqNameToDefineInvocation); - return place; } public void add(@NotNull Map packageFqNameToDefineInvocation) { @@ -137,7 +125,7 @@ final class PackageTranslator extends AbstractTranslator { Map packageFqNameToDefineInvocation) { while (!addEntryIfParentExists(parentFqName, entry, packageFqNameToDefineInvocation)) { JsObjectLiteral members = new JsObjectLiteral(new SmartList(entry), true); - DefineInvocation defineInvocation = createDefineInvocation(parentFqName, null, members, context()); + DefineInvocation defineInvocation = DefineInvocation.create(parentFqName, null, members, context()); entry = getEntry(parentFqName, defineInvocation); packageFqNameToDefineInvocation.put(parentFqName, defineInvocation); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java index 0e983c5ffba..22e27098b41 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java @@ -187,7 +187,7 @@ public final class PropertyTranslator extends AbstractTranslator { @NotNull private JsFunction generateDefaultSetterFunction(@NotNull PropertySetterDescriptor setterDescriptor) { JsFunction fun = new JsFunction(context().getScopeForDescriptor(setterDescriptor.getContainingDeclaration())); - JsParameter defaultParameter = new JsParameter(propertyAccessContext(setterDescriptor).scope().declareTemporary()); + JsParameter defaultParameter = new JsParameter(fun.getScope().declareTemporary()); fun.getParameters().add(defaultParameter); JsExpression setExpression; @@ -208,11 +208,6 @@ public final class PropertyTranslator extends AbstractTranslator { return TranslationUtils.translateFunctionAsEcma5PropertyDescriptor(function, accessorDescriptor, context()); } - @NotNull - private TranslationContext propertyAccessContext(@NotNull PropertySetterDescriptor propertySetterDescriptor) { - return context().newDeclaration(propertySetterDescriptor); - } - @NotNull private JsPropertyInitializer translateCustomAccessor(@NotNull JetPropertyAccessor expression) { FunctionTranslator translator = Translation.functionTranslator(expression, context()); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java index 10783856747..69226b6415f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java @@ -403,13 +403,13 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitFunctionLiteralExpression(@NotNull JetFunctionLiteralExpression expression, @NotNull TranslationContext context) { - return context.literalFunctionTranslator().translate(expression.getFunctionLiteral(), context); + return new LiteralFunctionTranslator(context).translate(expression.getFunctionLiteral(), context); } @Override @NotNull public JsNode visitNamedFunction(@NotNull JetNamedFunction expression, @NotNull TranslationContext context) { - JsExpression alias = context.literalFunctionTranslator().translate(expression, context); + JsExpression alias = new LiteralFunctionTranslator(context).translate(expression, context); FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression); JsName name = context.scope().declareFreshName(descriptor.getName().asString()); context.aliasingContext().registerAlias(descriptor, name.makeRef()); 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 58661a9ff72..1f347109be8 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 @@ -17,9 +17,6 @@ package org.jetbrains.k2js.translate.expression; import com.google.dart.compiler.backend.js.ast.*; -import com.intellij.openapi.util.NotNullLazyValue; -import com.intellij.openapi.util.Trinity; -import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -31,42 +28,24 @@ 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.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.context.*; import org.jetbrains.k2js.translate.declaration.ClassTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator; -import java.util.List; - import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor; import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody; import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedReceiverDescriptor; public class LiteralFunctionTranslator extends AbstractTranslator { - private final Stack, LabelGenerator, JsExpression>>> definitionPlaces = - new Stack, LabelGenerator, JsExpression>>>(); - private NotNullLazyValue, LabelGenerator, JsExpression>> definitionPlace; + private static final LabelGenerator FUNCTION_NAME_GENERATOR = new LabelGenerator('f'); + @NotNull + private final DefinitionPlace definitionPlace; + + // TODO: Maybe we need make it private and add static method `translate` public LiteralFunctionTranslator(@NotNull TranslationContext context) { super(context); - } - - public static Trinity, LabelGenerator, JsExpression> createPlace(@NotNull List list, - @NotNull JsExpression reference) { - return Trinity.create(list, new LabelGenerator('f'), reference); - } - - public void setDefinitionPlace(@Nullable NotNullLazyValue, LabelGenerator, JsExpression>> place) { - if (place == null) { - definitionPlaces.pop(); - definitionPlace = definitionPlaces.isEmpty() ? null : definitionPlaces.peek(); - } - else { - definitionPlaces.push(place); - definitionPlace = place; - } + this.definitionPlace = context.getDefinitionPlace(); } @NotNull @@ -128,16 +107,13 @@ public class LiteralFunctionTranslator extends AbstractTranslator { InnerFunctionTranslator translator = new InnerFunctionTranslator(descriptor, funContext, fun); - JsExpression result = translator.translate(createReference(fun), outerContext); + JsExpression result = translator.translate(defineFunction(fun), outerContext); addRegularParameters(descriptor, fun, funContext, receiverName); return result; } - private JsNameRef createReference(JsFunction fun) { - Trinity, LabelGenerator, JsExpression> place = definitionPlace.getValue(); - JsNameRef nameRef = new JsNameRef(place.second.generate(), place.third); - place.first.add(new JsPropertyInitializer(nameRef, fun)); - return nameRef; + private JsNameRef defineFunction(JsFunction fun) { + return definitionPlace.define(FUNCTION_NAME_GENERATOR.generate(), fun); } private static void addRegularParameters( @@ -172,6 +148,6 @@ public class LiteralFunctionTranslator extends AbstractTranslator { fun.getBody().getStatements().add(new JsReturn(classTranslator.translate(funContext))); JetClassBody body = declaration.getBody(); assert body != null; - return new InnerObjectTranslator(funContext, fun).translate(createReference(fun), usageTracker.isUsed() ? outerClassRef : null); + return new InnerObjectTranslator(funContext, fun).translate(defineFunction(fun), usageTracker.isUsed() ? outerClassRef : null); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java index 6b06f40062a..cf155167337 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java @@ -134,7 +134,6 @@ public final class Translation { statements.add(program.getStringLiteral("use strict").makeStmt()); TranslationContext context = TranslationContext.rootContext(staticContext, rootFunction); - staticContext.initTranslators(context); statements.addAll(PackageDeclarationTranslator.translateFiles(files, context)); defineModule(context, statements, config.getModuleId()); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java index b45cf636097..b3718b4765d 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java @@ -52,10 +52,13 @@ public final class ClassInitializerTranslator extends AbstractTranslator { @NotNull private final List initializerStatements = new SmartList(); - public ClassInitializerTranslator(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) { + public ClassInitializerTranslator( + @NotNull JetClassOrObject classDeclaration, + @NotNull TranslationContext context + ) { // Note: it's important we use scope for class descriptor because anonymous function used in property initializers // belong to the properties themselves - super(context.newDeclaration(getConstructor(context.bindingContext(), classDeclaration))); + super(context.newDeclaration(getConstructor(context.bindingContext(), classDeclaration), null)); this.classDeclaration = classDeclaration; }