JS: change how coroutine start intrinsic gets detected

This commit is contained in:
Alexey Andreev
2016-12-16 00:19:04 +03:00
committed by Stanislav Erokhin
parent 3af0840512
commit bba5c16653
@@ -18,8 +18,9 @@ package org.jetbrains.kotlin.js.translate.callTranslator
import com.google.dart.compiler.backend.js.ast.* import com.google.dart.compiler.backend.js.ast.*
import com.google.dart.compiler.backend.js.ast.metadata.* import com.google.dart.compiler.backend.js.ast.metadata.*
import org.jetbrains.kotlin.backend.common.getBuiltInSuspendWithCurrentContinuation import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.context.TranslationContext
@@ -31,14 +32,14 @@ import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
import org.jetbrains.kotlin.js.translate.utils.setInlineCallMetadata import org.jetbrains.kotlin.js.translate.utils.setInlineCallMetadata
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.Call.CallType import org.jetbrains.kotlin.psi.Call.CallType
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.DescriptorEquivalenceForOverrides
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.* import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.inline.InlineStrategy import org.jetbrains.kotlin.resolve.inline.InlineStrategy
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -131,8 +132,7 @@ private fun translateFunctionCall(
explicitReceivers: ExplicitReceivers explicitReceivers: ExplicitReceivers
): JsExpression { ): JsExpression {
val descriptorToCall = resolvedCall.resultingDescriptor val descriptorToCall = resolvedCall.resultingDescriptor
if (descriptorToCall is FunctionDescriptor && DescriptorEquivalenceForOverrides.areEquivalent( if (descriptorToCall is FunctionDescriptor && descriptorToCall.isSuspendCoroutineOrReturn()) {
descriptorToCall.getBuiltInSuspendWithCurrentContinuation(), descriptorToCall.original)) {
return translateCallWithContinuation(context, resolvedCall) return translateCallWithContinuation(context, resolvedCall)
} }
@@ -157,6 +157,14 @@ private fun translateFunctionCall(
return callExpression return callExpression
} }
private val SUSPEND_COROUTINE_OR_RETURN = Name.identifier("suspendCoroutineOrReturn")
private val COROUTINE_INTRINSICS = KotlinBuiltIns.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineIntrinsics"))
private fun FunctionDescriptor.isSuspendCoroutineOrReturn(): Boolean {
val containingClass = containingDeclaration as? ClassDescriptor ?: return false
return containingClass.fqNameSafe == COROUTINE_INTRINSICS && name == SUSPEND_COROUTINE_OR_RETURN
}
private fun translateCallWithContinuation(context: TranslationContext, resolvedCall: ResolvedCall<out FunctionDescriptor>): JsExpression { private fun translateCallWithContinuation(context: TranslationContext, resolvedCall: ResolvedCall<out FunctionDescriptor>): JsExpression {
val arguments = CallArgumentTranslator.translate(resolvedCall, null, context) val arguments = CallArgumentTranslator.translate(resolvedCall, null, context)
val coroutineArgument = TranslationUtils.getEnclosingContinuationParameter(context) val coroutineArgument = TranslationUtils.getEnclosingContinuationParameter(context)
@@ -180,7 +188,7 @@ fun computeExplicitReceiversForInvoke(
val dispatchReceiver = resolvedCall.dispatchReceiver val dispatchReceiver = resolvedCall.dispatchReceiver
val extensionReceiver = resolvedCall.extensionReceiver val extensionReceiver = resolvedCall.extensionReceiver
if (dispatchReceiver != null && extensionReceiver != null && resolvedCall.explicitReceiverKind == ExplicitReceiverKind.BOTH_RECEIVERS) { if (dispatchReceiver != null && extensionReceiver != null && resolvedCall.explicitReceiverKind == BOTH_RECEIVERS) {
assert(explicitReceivers.extensionOrDispatchReceiver != null) { assert(explicitReceivers.extensionOrDispatchReceiver != null) {
"No explicit receiver for 'invoke' resolved call with both receivers: $callElement, text: ${callElement.text}" + "No explicit receiver for 'invoke' resolved call with both receivers: $callElement, text: ${callElement.text}" +
"Dispatch receiver: $dispatchReceiver Extension receiver: $extensionReceiver" "Dispatch receiver: $dispatchReceiver Extension receiver: $extensionReceiver"