JS: always create aliases for function parameters

This is required to make translateAndAliasParameters
behaviour a little more clear.
Also, fix destructuring declaration translator to use parameter aliases
from TranslationContext, when possible.
This commit is contained in:
Alexey Andreev
2017-03-31 15:35:51 +03:00
parent 524dd122e7
commit 88cf37951b
9 changed files with 29 additions and 32 deletions
@@ -98,7 +98,7 @@ abstract class AbstractDeclarationVisitor : TranslatorVisitor<Unit>() {
context: TranslationContext
): JsExpression {
val function = context.getFunctionObject(descriptor)
val innerContext = context.newDeclaration(descriptor).translateAndAliasParameters(descriptor, function.parameters, false)
val innerContext = context.newDeclaration(descriptor).translateAndAliasParameters(descriptor, function.parameters)
if (descriptor.isSuspend) {
if (descriptor.requiresStateMachineTransformation(context)) {
@@ -219,7 +219,7 @@ class ClassTranslator private constructor(
context.addDeclarationStatement(constructorInitializer.makeStmt())
context = context.contextWithScope(constructorInitializer)
context.translateAndAliasParameters(constructorDescriptor, constructorInitializer.parameters, false)
context.translateAndAliasParameters(constructorDescriptor, constructorInitializer.parameters)
.translateFunction(constructor, constructorInitializer)
// Translate super/this call
@@ -115,7 +115,7 @@ class DeclarationBodyVisitor(
val caller = JsFunction(context.getScopeForDescriptor(containingClass), JsBlock(), "")
val callerContext = context
.newDeclaration(descriptor)
.translateAndAliasParameters(descriptor, caller.parameters, true)
.translateAndAliasParameters(descriptor, caller.parameters)
.innerBlock(caller.body)
val callbackName = JsScope.declareTemporaryName("callback" + Namer.DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX)
@@ -240,7 +240,7 @@ private class PropertyTranslator(
private fun translateCustomAccessor(expression: KtPropertyAccessor): JsPropertyInitializer {
val descriptor = BindingUtils.getFunctionDescriptor(bindingContext(), expression)
val function = JsFunction(context().getScopeForDescriptor(descriptor), JsBlock(), descriptor.toString())
context().translateAndAliasParameters(descriptor, function.parameters, false).translateFunction(expression, function)
context().translateAndAliasParameters(descriptor, function.parameters).translateFunction(expression, function)
return translateFunctionAsEcma5PropertyDescriptor(function, descriptor, context())
}
@@ -16,15 +16,14 @@
package org.jetbrains.kotlin.js.translate.expression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.kotlin.js.backend.ast.JsName;
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
import org.jetbrains.kotlin.js.backend.ast.JsVars;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
@@ -50,39 +49,29 @@ public class DestructuringDeclarationTranslator extends AbstractTranslator {
@NotNull
public static JsVars translate(
@NotNull KtDestructuringDeclaration multiDeclaration,
@NotNull JsName multiObjectName,
@Nullable JsExpression initializer,
@NotNull JsExpression multiObjectExpr,
@NotNull TranslationContext context
) {
return new DestructuringDeclarationTranslator(multiDeclaration, multiObjectName, initializer, context).translate();
return new DestructuringDeclarationTranslator(multiDeclaration, multiObjectExpr, context).translate();
}
@NotNull
private final KtDestructuringDeclaration multiDeclaration;
@NotNull
private final JsName multiObjectName;
@Nullable
private final JsExpression initializer;
private final JsExpression multiObjectExpr;
private DestructuringDeclarationTranslator(
@NotNull KtDestructuringDeclaration multiDeclaration,
@NotNull JsName multiObjectName,
@Nullable JsExpression initializer,
@NotNull JsExpression multiObjectExpr,
@NotNull TranslationContext context
) {
super(context);
this.multiDeclaration = multiDeclaration;
this.multiObjectName = multiObjectName;
this.initializer = initializer;
this.multiObjectExpr = multiObjectExpr;
}
private JsVars translate() {
if (initializer != null) {
context().getCurrentBlock().getStatements().add(JsAstUtils.newVar(multiObjectName, initializer));
}
List<JsVars.JsVar> jsVars = new ArrayList<>();
JsNameRef multiObjNameRef = multiObjectName.makeRef();
for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) {
VariableDescriptor descriptor = BindingContextUtils.getNotNull(context().bindingContext(), BindingContext.VARIABLE, entry);
// Do not call `componentX` for destructuring entry called _
@@ -90,7 +79,7 @@ public class DestructuringDeclarationTranslator extends AbstractTranslator {
ResolvedCall<FunctionDescriptor> entryInitCall = context().bindingContext().get(BindingContext.COMPONENT_RESOLVED_CALL, entry);
assert entryInitCall != null : "Entry init call must be not null";
JsExpression entryInitializer = CallTranslator.translate(context(), entryInitCall, multiObjNameRef);
JsExpression entryInitializer = CallTranslator.translate(context(), entryInitCall, multiObjectExpr);
FunctionDescriptor candidateDescriptor = entryInitCall.getCandidateDescriptor();
if (CallExpressionTranslator.shouldBeInlined(candidateDescriptor, context())) {
setInlineCallMetadata(entryInitializer, entry, entryInitCall, context());
@@ -113,7 +113,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
KtExpression jetInitializer = multiDeclaration.getInitializer();
assert jetInitializer != null : "Initializer for multi declaration must be not null";
JsExpression initializer = Translation.translateAsExpression(jetInitializer, context);
return DestructuringDeclarationTranslator.translate(multiDeclaration, JsScope.declareTemporary(), initializer, context);
JsName parameterName = JsScope.declareTemporary();
context.addStatementToCurrentBlock(JsAstUtils.newVar(parameterName, initializer));
return DestructuringDeclarationTranslator.translate(multiDeclaration, JsAstUtils.pureFqn(parameterName, null), context);
}
@Override
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsFunction
import org.jetbrains.kotlin.js.backend.ast.JsParameter
import org.jetbrains.kotlin.js.backend.ast.JsScope
import org.jetbrains.kotlin.js.backend.ast.metadata.descriptor
import org.jetbrains.kotlin.js.backend.ast.metadata.functionDescriptor
import org.jetbrains.kotlin.js.backend.ast.metadata.hasDefaultValue
import org.jetbrains.kotlin.js.translate.context.Namer
@@ -39,8 +40,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
fun TranslationContext.translateAndAliasParameters(
descriptor: FunctionDescriptor,
targetList: MutableList<JsParameter>,
aliasValueParams: Boolean
targetList: MutableList<JsParameter>
): TranslationContext {
val aliases = mutableMapOf<DeclarationDescriptor, JsExpression>()
@@ -64,7 +64,7 @@ fun TranslationContext.translateAndAliasParameters(
for (valueParameter in descriptor.valueParameters) {
val name = getNameForDescriptor(valueParameter)
val tmpName = if (aliasValueParams) JsScope.declareTemporaryName(name.ident) else name
val tmpName = JsScope.declareTemporaryName(name.ident).also { it.descriptor = valueParameter }
aliases[valueParameter] = JsAstUtils.pureFqn(tmpName, null)
targetList += JsParameter(tmpName).apply { hasDefaultValue = valueParameter.hasDefaultValue() }
}
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.context.getNameForCapturedDescriptor
import org.jetbrains.kotlin.js.translate.context.hasCapturedExceptContaining
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getFunctionDescriptor
import org.jetbrains.kotlin.js.translate.utils.FunctionBodyTranslator.setDefaultValueForArguments
import org.jetbrains.kotlin.js.translate.utils.FunctionBodyTranslator.translateFunctionBody
@@ -47,7 +48,7 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
val functionContext = invokingContext
.newFunctionBodyWithUsageTracker(lambda, descriptor)
.translateAndAliasParameters(descriptor, lambda.parameters, false)
.translateAndAliasParameters(descriptor, lambda.parameters)
descriptor.valueParameters.forEach {
if (it is ValueParameterDescriptorImpl.WithDestructuringDeclaration) {
@@ -100,8 +101,8 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
(DescriptorToSourceUtils.descriptorToDeclaration(this) as? KtParameter)?.destructuringDeclaration
?: error("Destructuring declaration for descriptor $this not found")
val jsParameter = JsParameter(context.getNameForDescriptor(this))
return DestructuringDeclarationTranslator.translate(destructuringDeclaration, jsParameter.name, null, context)
val parameterRef = ReferenceTranslator.translateAsValueReference(this, context)
return DestructuringDeclarationTranslator.translate(destructuringDeclaration, parameterRef, context)
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.general.Translation
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.*
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
@@ -116,8 +117,12 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
newVar(parameterName, itemValue)
}
else {
val innerBlockContext = context.innerBlock(block)
if (itemValue != null) {
innerBlockContext.addStatementToCurrentBlock(JsAstUtils.newVar(parameterName, itemValue))
}
DestructuringDeclarationTranslator.translate(
destructuringParameter, parameterName, itemValue, context.innerBlock(block))
destructuringParameter, JsAstUtils.pureFqn(parameterName, null), innerBlockContext)
}
block.statements += currentVarInit
block.statements += if (realBody is JsBlock) realBody.statements else listOfNotNull(realBody)