JS: coroutines: fix inlining of suspend functions
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_REFLECT
|
||||
// CHECK_NOT_CALLED: suspendInline_die06n$
|
||||
// CHECK_NOT_CALLED: suspendInline_nesahw$
|
||||
// CHECK_NOT_CALLED: suspendInline_grpnnl$
|
||||
class Controller {
|
||||
fun withValue(v: String, x: Continuation<String>) {
|
||||
x.resume(v)
|
||||
|
||||
+22
-8
@@ -27,9 +27,12 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation
|
||||
import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator
|
||||
import org.jetbrains.kotlin.js.translate.reference.CallExpressionTranslator
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.setInlineCallMetadata
|
||||
import org.jetbrains.kotlin.psi.Call.CallType
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
@@ -96,32 +99,43 @@ private fun translateCall(context: TranslationContext,
|
||||
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||
assert(explicitReceivers.extensionReceiver == null) { "VariableAsFunctionResolvedCall must have one receiver" }
|
||||
val variableCall = resolvedCall.variableCall
|
||||
if (variableCall.expectedReceivers()) {
|
||||
|
||||
return if (variableCall.expectedReceivers()) {
|
||||
val newReceiver = CallTranslator.translateGet(context, variableCall, explicitReceivers.extensionOrDispatchReceiver)
|
||||
return translateFunctionCall(context, resolvedCall.functionCall, ExplicitReceivers(newReceiver))
|
||||
translateFunctionCall(context, resolvedCall.functionCall, resolvedCall.variableCall, ExplicitReceivers(newReceiver))
|
||||
} else {
|
||||
val dispatchReceiver = CallTranslator.translateGet(context, variableCall, null)
|
||||
if (explicitReceivers.extensionOrDispatchReceiver == null)
|
||||
return translateFunctionCall(context, resolvedCall.functionCall, ExplicitReceivers(dispatchReceiver))
|
||||
else
|
||||
return translateFunctionCall(context, resolvedCall.functionCall, ExplicitReceivers(dispatchReceiver, explicitReceivers.extensionOrDispatchReceiver))
|
||||
if (explicitReceivers.extensionOrDispatchReceiver == null) {
|
||||
translateFunctionCall(context, resolvedCall.functionCall, resolvedCall.variableCall, ExplicitReceivers(dispatchReceiver))
|
||||
}
|
||||
else {
|
||||
translateFunctionCall(context, resolvedCall.functionCall, resolvedCall.variableCall,
|
||||
ExplicitReceivers(dispatchReceiver, explicitReceivers.extensionOrDispatchReceiver))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val call = resolvedCall.call
|
||||
if (call.callType == CallType.INVOKE && !isInvokeCallOnVariable(call)) {
|
||||
val explicitReceiversForInvoke = computeExplicitReceiversForInvoke(context, resolvedCall, explicitReceivers)
|
||||
return translateFunctionCall(context, resolvedCall, explicitReceiversForInvoke)
|
||||
return translateFunctionCall(context, resolvedCall, resolvedCall, explicitReceiversForInvoke)
|
||||
}
|
||||
|
||||
return translateFunctionCall(context, resolvedCall, explicitReceivers)
|
||||
return translateFunctionCall(context, resolvedCall, resolvedCall, explicitReceivers)
|
||||
}
|
||||
|
||||
private fun translateFunctionCall(context: TranslationContext,
|
||||
resolvedCall: ResolvedCall<out FunctionDescriptor>,
|
||||
inlineResolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||
explicitReceivers: ExplicitReceivers
|
||||
): JsExpression {
|
||||
val callExpression = context.getCallInfo(resolvedCall, explicitReceivers).translateFunctionCall()
|
||||
|
||||
if (CallExpressionTranslator.shouldBeInlined(inlineResolvedCall.resultingDescriptor, context)) {
|
||||
setInlineCallMetadata(callExpression, resolvedCall.call.callElement as KtExpression,
|
||||
inlineResolvedCall.resultingDescriptor, context)
|
||||
}
|
||||
|
||||
if (resolvedCall.resultingDescriptor.isSuspend && resolvedCall.resultingDescriptor.initialSignatureDescriptor != null) {
|
||||
context.currentBlock.statements += JsAstUtils.asSyntheticStatement((callExpression as JsInvocation).apply {
|
||||
isSuspend = true
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ public class DestructuringDeclarationTranslator extends AbstractTranslator {
|
||||
assert entryInitCall != null : "Entry init call must be not null";
|
||||
JsExpression entryInitializer = CallTranslator.translate(context(), entryInitCall, multiObjNameRef);
|
||||
FunctionDescriptor candidateDescriptor = entryInitCall.getCandidateDescriptor();
|
||||
if (CallExpressionTranslator.shouldBeInlined(candidateDescriptor)) {
|
||||
if (CallExpressionTranslator.shouldBeInlined(candidateDescriptor, context())) {
|
||||
setInlineCallMetadata(entryInitializer, entry, entryInitCall, context());
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.js.translate.context.AliasingContext;
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
|
||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody;
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression;
|
||||
@@ -107,7 +106,7 @@ public final class FunctionTranslator extends AbstractTranslator {
|
||||
public JsExpression translateAsMethod() {
|
||||
translateAsMethodWithoutMetadata();
|
||||
|
||||
if (shouldBeInlined(descriptor) && DescriptorUtilsKt.isEffectivelyPublicApi(descriptor)) {
|
||||
if (shouldBeInlined(descriptor, context()) && DescriptorUtilsKt.isEffectivelyPublicApi(descriptor)) {
|
||||
InlineMetadata metadata = InlineMetadata.compose(functionObject, descriptor);
|
||||
return metadata.getFunctionWithMetadata();
|
||||
}
|
||||
|
||||
+2
-11
@@ -36,8 +36,6 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.js.resolve.diagnostics.JsCallChecker.isJsCall;
|
||||
import static org.jetbrains.kotlin.js.translate.utils.InlineUtils.setInlineCallMetadata;
|
||||
import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.getFunctionDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator.getConstant;
|
||||
|
||||
public final class CallExpressionTranslator extends AbstractCallExpressionTranslator {
|
||||
@@ -55,19 +53,12 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl
|
||||
return (new CallExpressionTranslator(expression, receiver, context)).translateJsCode();
|
||||
}
|
||||
|
||||
JsExpression callExpression = (new CallExpressionTranslator(expression, receiver, context)).translate();
|
||||
|
||||
if (shouldBeInlined(expression, context)) {
|
||||
setInlineCallMetadata(callExpression, expression, resolvedCall, context);
|
||||
}
|
||||
|
||||
return callExpression;
|
||||
return (new CallExpressionTranslator(expression, receiver, context)).translate();
|
||||
}
|
||||
|
||||
public static boolean shouldBeInlined(@NotNull KtCallExpression expression, @NotNull TranslationContext context) {
|
||||
public static boolean shouldBeInlined(@NotNull CallableDescriptor descriptor, @NotNull TranslationContext context) {
|
||||
if (context.getConfig().getConfiguration().getBoolean(CommonConfigurationKeys.DISABLE_INLINE)) return false;
|
||||
|
||||
CallableDescriptor descriptor = getFunctionDescriptor(expression, context);
|
||||
return shouldBeInlined(descriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@ import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.lexer.KtToken;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall;
|
||||
|
||||
@@ -99,7 +97,7 @@ public final class PsiUtils {
|
||||
return isInOperation(binaryExpression) || isNotInOperation(binaryExpression);
|
||||
}
|
||||
|
||||
public static boolean isNotInOperation(@NotNull KtBinaryExpression binaryExpression) {
|
||||
private static boolean isNotInOperation(@NotNull KtBinaryExpression binaryExpression) {
|
||||
return (binaryExpression.getOperationToken() == KtTokens.NOT_IN);
|
||||
}
|
||||
|
||||
@@ -126,17 +124,6 @@ public final class PsiUtils {
|
||||
return rangeExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CallableDescriptor getFunctionDescriptor(
|
||||
@NotNull KtCallExpression expression,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(expression, context.bindingContext());
|
||||
assert resolvedCall != null;
|
||||
|
||||
return getFunctionDescriptor(resolvedCall);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CallableDescriptor getFunctionDescriptor(ResolvedCall<?> resolvedCall) {
|
||||
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
||||
|
||||
Reference in New Issue
Block a user