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.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
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
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor
|
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.reference.ReferenceTranslator
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||||
import org.jetbrains.kotlin.js.translate.reference.buildReifiedTypeArgs
|
import org.jetbrains.kotlin.js.translate.reference.buildReifiedTypeArgs
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
||||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
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.BindingContextUtils.isVarCapturedInClosure
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -100,9 +103,20 @@ object DefaultVariableAccessCase : VariableAccessCase() {
|
|||||||
|
|
||||||
val localVariableDescriptor = resolvedCall.resultingDescriptor as? LocalVariableDescriptor
|
val localVariableDescriptor = resolvedCall.resultingDescriptor as? LocalVariableDescriptor
|
||||||
val accessorDescriptor = if (isGetAccess()) localVariableDescriptor?.getter else localVariableDescriptor?.setter
|
val accessorDescriptor = if (isGetAccess()) localVariableDescriptor?.getter else localVariableDescriptor?.setter
|
||||||
if (accessorDescriptor != null) {
|
val delegatedCall = accessorDescriptor?.let { context.bindingContext()[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, it] }
|
||||||
val funRef = JsNameRef(TranslationUtils.getAccessorFunctionName(accessorDescriptor), ref)
|
if (delegatedCall != null) {
|
||||||
return JsInvocation(funRef, *additionalArguments.toTypedArray())
|
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)
|
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.PsiElement;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import com.intellij.util.SmartList;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
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.BinaryOperationTranslator;
|
||||||
import org.jetbrains.kotlin.js.translate.operation.UnaryOperationTranslator;
|
import org.jetbrains.kotlin.js.translate.operation.UnaryOperationTranslator;
|
||||||
import org.jetbrains.kotlin.js.translate.reference.*;
|
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.*;
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -134,6 +136,8 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
JsExpression jsReturnExpression = translateAsExpression(returned, context);
|
JsExpression jsReturnExpression = translateAsExpression(returned, context);
|
||||||
|
|
||||||
KotlinType returnedType = context.bindingContext().getType(returned);
|
KotlinType returnedType = context.bindingContext().getType(returned);
|
||||||
|
assert returnedType != null : "Resolved return expression is expected to have type: " +
|
||||||
|
PsiUtilsKt.getTextWithLocation(jetReturnExpression);
|
||||||
|
|
||||||
if (KotlinBuiltIns.isCharOrNullableChar(returnedType) &&
|
if (KotlinBuiltIns.isCharOrNullableChar(returnedType) &&
|
||||||
TranslationUtils.shouldBoxReturnValue((CallableDescriptor)context.getDeclarationDescriptor())) {
|
TranslationUtils.shouldBoxReturnValue((CallableDescriptor)context.getDeclarationDescriptor())) {
|
||||||
@@ -203,19 +207,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
JsExpression initializer = translateInitializerForProperty(expression, context);
|
JsExpression initializer = translateInitializerForProperty(expression, context);
|
||||||
|
|
||||||
KtExpression delegateExpression = expression.getDelegateExpression();
|
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);
|
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());
|
JsNameRef alias = getCapturedVarAccessor(name.makeRef());
|
||||||
initializer = JsAstUtils.wrapValue(alias, initializer == null ? JsLiteral.NULL : initializer);
|
initializer = JsAstUtils.wrapValue(alias, initializer == null ? JsLiteral.NULL : initializer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user