JS: don't generate object literal for local delegated properties, generate call to getValue/setValue on each use site instead.
This commit is contained in:
+17
-3
@@ -24,14 +24,17 @@ import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsLiteral
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor
|
||||
import org.jetbrains.kotlin.js.translate.declaration.contextWithPropertyMetadataCreationIntrinsified
|
||||
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.translate.reference.buildReifiedTypeArgs
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import java.util.*
|
||||
@@ -100,9 +103,20 @@ object DefaultVariableAccessCase : VariableAccessCase() {
|
||||
|
||||
val localVariableDescriptor = resolvedCall.resultingDescriptor as? LocalVariableDescriptor
|
||||
val accessorDescriptor = if (isGetAccess()) localVariableDescriptor?.getter else localVariableDescriptor?.setter
|
||||
if (accessorDescriptor != null) {
|
||||
val funRef = JsNameRef(TranslationUtils.getAccessorFunctionName(accessorDescriptor), ref)
|
||||
return JsInvocation(funRef, *additionalArguments.toTypedArray())
|
||||
val delegatedCall = accessorDescriptor?.let { context.bindingContext()[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, it] }
|
||||
if (delegatedCall != null) {
|
||||
val delegateContext = context.contextWithPropertyMetadataCreationIntrinsified(
|
||||
delegatedCall, localVariableDescriptor!!, JsLiteral.NULL)
|
||||
val delegateContextWithArgs = if (!isGetAccess()) {
|
||||
val valueArg = delegatedCall.valueArgumentsByIndex!![2].arguments[0].getArgumentExpression()
|
||||
delegateContext.innerContextWithAliasesForExpressions(mapOf(valueArg to value!!))
|
||||
}
|
||||
else {
|
||||
delegateContext
|
||||
}
|
||||
val localVariableRef = context.getAliasForDescriptor(localVariableDescriptor) ?:
|
||||
JsAstUtils.pureFqn(context.getNameForDescriptor(localVariableDescriptor), null)
|
||||
return CallTranslator.translate(delegateContextWithArgs, delegatedCall, localVariableRef)
|
||||
}
|
||||
|
||||
return constructAccessExpression(ref)
|
||||
|
||||
+11
-14
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.js.translate.expression;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
@@ -36,7 +35,10 @@ import org.jetbrains.kotlin.js.translate.general.TranslatorVisitor;
|
||||
import org.jetbrains.kotlin.js.translate.operation.BinaryOperationTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.operation.UnaryOperationTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.reference.*;
|
||||
import org.jetbrains.kotlin.js.translate.utils.*;
|
||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.UtilsKt;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -134,6 +136,8 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
JsExpression jsReturnExpression = translateAsExpression(returned, context);
|
||||
|
||||
KotlinType returnedType = context.bindingContext().getType(returned);
|
||||
assert returnedType != null : "Resolved return expression is expected to have type: " +
|
||||
PsiUtilsKt.getTextWithLocation(jetReturnExpression);
|
||||
|
||||
if (KotlinBuiltIns.isCharOrNullableChar(returnedType) &&
|
||||
TranslationUtils.shouldBoxReturnValue((CallableDescriptor)context.getDeclarationDescriptor())) {
|
||||
@@ -203,19 +207,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
JsExpression initializer = translateInitializerForProperty(expression, context);
|
||||
|
||||
KtExpression delegateExpression = expression.getDelegateExpression();
|
||||
if (delegateExpression != null) {
|
||||
SmartList<JsPropertyInitializer> propertyInitializers = new SmartList<JsPropertyInitializer>();
|
||||
PropertyTranslatorKt.translateAccessors((VariableDescriptorWithAccessors) descriptor, propertyInitializers, context);
|
||||
JsExpression initializerValue = PropertyTranslatorKt.translateDelegateOrInitializerExpression(context, expression);
|
||||
assert initializerValue != null : "Initializer must be non-null for property with delegate";
|
||||
JsPropertyInitializer delegateInitializer = new JsPropertyInitializer(
|
||||
context.program().getStringLiteral(Namer.getDelegateName(descriptor.getName().asString())), initializerValue);
|
||||
propertyInitializers.add(delegateInitializer);
|
||||
initializer = new JsObjectLiteral(propertyInitializers, true);
|
||||
}
|
||||
|
||||
JsName name = context.getNameForDescriptor(descriptor);
|
||||
if (isVarCapturedInClosure(context.bindingContext(), descriptor)) {
|
||||
if (delegateExpression != null) {
|
||||
initializer = PropertyTranslatorKt.translateDelegateOrInitializerExpression(context, expression);
|
||||
assert initializer != null : "Initializer must be non-null for property with delegate";
|
||||
}
|
||||
else if (isVarCapturedInClosure(context.bindingContext(), descriptor)) {
|
||||
JsNameRef alias = getCapturedVarAccessor(name.makeRef());
|
||||
initializer = JsAstUtils.wrapValue(alias, initializer == null ? JsLiteral.NULL : initializer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user