JS: fix translation of safe calls if suspend functions. See KT-15892

This commit is contained in:
Alexey Andreev
2017-01-23 13:13:32 +03:00
parent 2adaaf5e9f
commit bf55744e64
9 changed files with 39 additions and 52 deletions
@@ -16,13 +16,13 @@
package org.jetbrains.kotlin.js.translate.callTranslator
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.js.backend.ast.JsBlock
import org.jetbrains.kotlin.js.backend.ast.JsConditional
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsLiteral
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
@@ -41,7 +41,7 @@ interface CallInfo {
val dispatchReceiver: JsExpression?
val extensionReceiver: JsExpression?
fun constructSafeCallIsNeeded(result: JsExpression): JsExpression
fun constructSafeCallIfNeeded(result: JsExpression): JsExpression
}
abstract class AbstractCallInfo : CallInfo {
@@ -162,7 +162,7 @@ private fun TranslationContext.createCallInfo(
val notNullConditionalForSafeCall: JsConditional? = notNullConditional
override fun constructSafeCallIsNeeded(result: JsExpression): JsExpression {
override fun constructSafeCallIfNeeded(result: JsExpression): JsExpression {
if (notNullConditionalForSafeCall == null) {
return result
} else {
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsInvocation
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
import org.jetbrains.kotlin.js.backend.ast.metadata.coroutineResult
@@ -90,9 +89,10 @@ private fun ResolvedCall<out CallableDescriptor>.expectedReceivers(): Boolean {
return this.explicitReceiverKind != NO_EXPLICIT_RECEIVER
}
private fun translateCall(context: TranslationContext,
resolvedCall: ResolvedCall<out FunctionDescriptor>,
explicitReceivers: ExplicitReceivers
private fun translateCall(
context: TranslationContext,
resolvedCall: ResolvedCall<out FunctionDescriptor>,
explicitReceivers: ExplicitReceivers
): JsExpression {
if (resolvedCall is VariableAsFunctionResolvedCall) {
assert(explicitReceivers.extensionReceiver == null) { "VariableAsFunctionResolvedCall must have one receiver" }
@@ -138,7 +138,7 @@ private fun translateFunctionCall(
}
if (resolvedCall.resultingDescriptor.isSuspend && context.isInStateMachine) {
context.currentBlock.statements += JsAstUtils.asSyntheticStatement((callExpression as JsInvocation).apply { isSuspend = true })
context.currentBlock.statements += JsAstUtils.asSyntheticStatement(callExpression.apply { isSuspend = true })
val coroutineRef = TranslationUtils.translateContinuationArgument(context, resolvedCall)
return context.defineTemporary(JsNameRef("\$\$coroutineResult\$\$", coroutineRef).apply {
sideEffects = SideEffectKind.DEPENDS_ON_STATE
@@ -213,7 +213,7 @@ abstract class CallCase<in I : CallInfo> {
callInfo.bothReceivers()
}
return callInfo.constructSafeCallIsNeeded(result)
return callInfo.constructSafeCallIfNeeded(result)
}
}
@@ -235,7 +235,7 @@ interface DelegateIntrinsic<in I : CallInfo> {
}
if (result != null) {
return callInfo.constructSafeCallIsNeeded(result)
return callInfo.constructSafeCallIfNeeded(result)
} else {
return null
}