[JS BE] Support contracts in JS Fix KT-27946
This commit is contained in:
@@ -198,10 +198,14 @@ public class BindingContextUtils {
|
|||||||
return expression instanceof KtReferenceExpression;
|
return expression instanceof KtReferenceExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isVarCapturedInClosure(BindingContext bindingContext, DeclarationDescriptor descriptor) {
|
public static boolean isCapturedInClosure(BindingContext bindingContext, DeclarationDescriptor descriptor) {
|
||||||
if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false;
|
if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false;
|
||||||
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
||||||
return bindingContext.get(CAPTURED_IN_CLOSURE, variableDescriptor) != null && variableDescriptor.isVar();
|
return bindingContext.get(CAPTURED_IN_CLOSURE, variableDescriptor) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isVarCapturedInClosure(BindingContext bindingContext, DeclarationDescriptor descriptor) {
|
||||||
|
return isCapturedInClosure(bindingContext, descriptor) && ((VariableDescriptor) descriptor).isVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+1
-1
@@ -86,7 +86,7 @@ internal fun VariableDescriptor.variableKind(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun hasNoWritersInClosures(
|
fun hasNoWritersInClosures(
|
||||||
variableContainingDeclaration: DeclarationDescriptor,
|
variableContainingDeclaration: DeclarationDescriptor,
|
||||||
writers: Set<AssignedVariablesSearcher.Writer>,
|
writers: Set<AssignedVariablesSearcher.Writer>,
|
||||||
bindingContext: BindingContext
|
bindingContext: BindingContext
|
||||||
|
|||||||
+4
-5
@@ -16,23 +16,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.translate.callTranslator
|
package org.jetbrains.kotlin.js.translate.callTranslator
|
||||||
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
|
||||||
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.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||||
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.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.reference.buildReifiedTypeArgs
|
import org.jetbrains.kotlin.js.translate.reference.buildReifiedTypeArgs
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||||
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.BindingContext
|
||||||
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.*
|
||||||
|
|
||||||
@@ -87,7 +86,7 @@ object DefaultVariableAccessCase : VariableAccessCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
|
val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
|
||||||
val ref = if (isVarCapturedInClosure(context.bindingContext(), callableDescriptor)) {
|
val ref = if (context.isBoxedLocalCapturedInClosure(callableDescriptor)) {
|
||||||
getCapturedVarAccessor(functionRef)
|
getCapturedVarAccessor(functionRef)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
+23
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.config.LanguageFeature;
|
|||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
|
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||||
@@ -41,6 +42,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
|||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind;
|
import org.jetbrains.kotlin.serialization.js.ModuleKind;
|
||||||
|
import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -50,6 +52,8 @@ import static org.jetbrains.kotlin.js.translate.context.UsageTrackerKt.getNameFo
|
|||||||
import static org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isNativeObject;
|
import static org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isNativeObject;
|
||||||
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getDescriptorForElement;
|
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getDescriptorForElement;
|
||||||
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn;
|
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn;
|
||||||
|
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isCapturedInClosure;
|
||||||
|
import static org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueKindUtilsKt.hasNoWritersInClosures;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All the info about the state of the translation process.
|
* All the info about the state of the translation process.
|
||||||
@@ -793,6 +797,25 @@ public class TranslationContext {
|
|||||||
return staticContext.getDeferredCallSites().containsKey(classDescriptor);
|
return staticContext.getDeferredCallSites().containsKey(classDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isValWithWriterInDifferentScope(VariableDescriptor descriptor) {
|
||||||
|
//TODO: Simplify this code once KT-17694 is fixed
|
||||||
|
if (!(descriptor instanceof LocalVariableDescriptor)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PreliminaryDeclarationVisitor preliminaryVisitor =
|
||||||
|
PreliminaryDeclarationVisitor.Companion.getVisitorByVariable(descriptor, bindingContext());
|
||||||
|
return (preliminaryVisitor == null ||
|
||||||
|
!hasNoWritersInClosures(descriptor.getContainingDeclaration(), preliminaryVisitor.writers(descriptor), bindingContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBoxedLocalCapturedInClosure(CallableDescriptor descriptor) {
|
||||||
|
if (isCapturedInClosure(bindingContext(), descriptor)) {
|
||||||
|
VariableDescriptor localVariable = (VariableDescriptor) descriptor;
|
||||||
|
return localVariable.isVar() || isValWithWriterInDifferentScope(localVariable);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void deferConstructorCall(@NotNull ClassConstructorDescriptor constructor, @NotNull List<JsExpression> invocationArgs) {
|
public void deferConstructorCall(@NotNull ClassConstructorDescriptor constructor, @NotNull List<JsExpression> invocationArgs) {
|
||||||
ClassDescriptor classDescriptor = constructor.getContainingDeclaration();
|
ClassDescriptor classDescriptor = constructor.getContainingDeclaration();
|
||||||
List<DeferredCallSite> callSites = staticContext.getDeferredCallSites().get(classDescriptor);
|
List<DeferredCallSite> callSites = staticContext.getDeferredCallSites().get(classDescriptor);
|
||||||
|
|||||||
+1
-2
@@ -74,7 +74,6 @@ import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*;
|
|||||||
import static org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getReceiverParameterForDeclaration;
|
import static org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getReceiverParameterForDeclaration;
|
||||||
import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.translateInitializerForProperty;
|
import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.translateInitializerForProperty;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
|
|
||||||
import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt.getResolvedCallWithAssert;
|
import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt.getResolvedCallWithAssert;
|
||||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getAnnotationClass;
|
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getAnnotationClass;
|
||||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression;
|
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression;
|
||||||
@@ -244,7 +243,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
initializer = PropertyTranslatorKt.translateDelegateOrInitializerExpression(context, expression);
|
initializer = PropertyTranslatorKt.translateDelegateOrInitializerExpression(context, expression);
|
||||||
assert initializer != null : "Initializer must be non-null for property with delegate";
|
assert initializer != null : "Initializer must be non-null for property with delegate";
|
||||||
}
|
}
|
||||||
else if (isVarCapturedInClosure(context.bindingContext(), descriptor)) {
|
else if (context.isBoxedLocalCapturedInClosure(descriptor)) {
|
||||||
JsNameRef alias = getCapturedVarAccessor(name.makeRef());
|
JsNameRef alias = getCapturedVarAccessor(name.makeRef());
|
||||||
initializer = JsAstUtils.wrapValue(alias, initializer == null ? new JsNullLiteral() : initializer);
|
initializer = JsAstUtils.wrapValue(alias, initializer == null ? new JsNullLiteral() : initializer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user