diff --git a/compiler/testData/codegen/box/coroutines/inlineSuspendFunction.kt b/compiler/testData/codegen/box/coroutines/inlineSuspendFunction.kt index afa2c2dd1da..3c7ebaef057 100644 --- a/compiler/testData/codegen/box/coroutines/inlineSuspendFunction.kt +++ b/compiler/testData/codegen/box/coroutines/inlineSuspendFunction.kt @@ -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) { x.resume(v) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt index ba090d9bc4f..a07118ba6b9 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt @@ -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, + inlineResolvedCall: ResolvedCall, 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 diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java index 96a44f98255..5b915187941 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java @@ -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()); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/FunctionTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/FunctionTranslator.java index 7039986866b..2578f4f955d 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/FunctionTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/FunctionTranslator.java @@ -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(); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java index d83ce2fc93c..301e004c11a 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java @@ -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); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/PsiUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/PsiUtils.java index c35b11ffcf5..516cb11b3dd 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/PsiUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/PsiUtils.java @@ -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) {