Reformat coroutineContext related code
This commit is contained in:
+9
-9
@@ -37,9 +37,9 @@ val SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME = Name.identifier("suspendCor
|
|||||||
fun FunctionDescriptor.isBuiltInIntercepted(): Boolean {
|
fun FunctionDescriptor.isBuiltInIntercepted(): Boolean {
|
||||||
if (name != INTERCEPTED_NAME) return false
|
if (name != INTERCEPTED_NAME) return false
|
||||||
val original =
|
val original =
|
||||||
module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope
|
module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope
|
||||||
.getContributedFunctions(INTERCEPTED_NAME, NoLookupLocation.FROM_BACKEND)
|
.getContributedFunctions(INTERCEPTED_NAME, NoLookupLocation.FROM_BACKEND)
|
||||||
.singleOrNull() as CallableDescriptor
|
.singleOrNull() as CallableDescriptor
|
||||||
return DescriptorEquivalenceForOverrides.areEquivalent(original, this)
|
return DescriptorEquivalenceForOverrides.areEquivalent(original, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,14 +49,14 @@ fun FunctionDescriptor.isBuiltInSuspendCoroutineOrReturn(): Boolean {
|
|||||||
val originalDeclaration = getBuiltInSuspendCoroutineOrReturn() ?: return false
|
val originalDeclaration = getBuiltInSuspendCoroutineOrReturn() ?: return false
|
||||||
|
|
||||||
return DescriptorEquivalenceForOverrides.areEquivalent(
|
return DescriptorEquivalenceForOverrides.areEquivalent(
|
||||||
originalDeclaration, this
|
originalDeclaration, this
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FunctionDescriptor.getBuiltInSuspendCoroutineOrReturn() =
|
fun FunctionDescriptor.getBuiltInSuspendCoroutineOrReturn() =
|
||||||
module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope
|
module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope
|
||||||
.getContributedFunctions(SUSPEND_COROUTINE_OR_RETURN_NAME, NoLookupLocation.FROM_BACKEND)
|
.getContributedFunctions(SUSPEND_COROUTINE_OR_RETURN_NAME, NoLookupLocation.FROM_BACKEND)
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun FunctionDescriptor.isBuiltInCoroutineContext(): Boolean {
|
fun FunctionDescriptor.isBuiltInCoroutineContext(): Boolean {
|
||||||
val fqNameSafe = (this as? PropertyGetterDescriptor)?.correspondingProperty?.fqNameSafe
|
val fqNameSafe = (this as? PropertyGetterDescriptor)?.correspondingProperty?.fqNameSafe
|
||||||
@@ -66,7 +66,7 @@ fun FunctionDescriptor.isBuiltInCoroutineContext(): Boolean {
|
|||||||
fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(): Boolean {
|
fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(): Boolean {
|
||||||
if (name != SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME) return false
|
if (name != SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME) return false
|
||||||
val original = module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope
|
val original = module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope
|
||||||
.getContributedFunctions(SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME, NoLookupLocation.FROM_BACKEND)
|
.getContributedFunctions(SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME, NoLookupLocation.FROM_BACKEND)
|
||||||
.singleOrNull() as CallableDescriptor
|
.singleOrNull() as CallableDescriptor
|
||||||
return DescriptorEquivalenceForOverrides.areEquivalent(original, this)
|
return DescriptorEquivalenceForOverrides.areEquivalent(original, this)
|
||||||
}
|
}
|
||||||
|
|||||||
+133
-129
@@ -59,13 +59,14 @@ const val EXCEPTION_FIELD_NAME = "exception"
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME =
|
val COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME =
|
||||||
DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("jvm")).child(Name.identifier("internal"))
|
DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("jvm")).child(Name.identifier("internal"))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val CONTINUATION_ASM_TYPE = DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType()
|
val CONTINUATION_ASM_TYPE = DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType()
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val COROUTINE_CONTEXT_ASM_TYPE = DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineContext")).topLevelClassAsmType()
|
val COROUTINE_CONTEXT_ASM_TYPE =
|
||||||
|
DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineContext")).topLevelClassAsmType()
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val COROUTINE_IMPL_ASM_TYPE = COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineImpl")).topLevelClassAsmType()
|
val COROUTINE_IMPL_ASM_TYPE = COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineImpl")).topLevelClassAsmType()
|
||||||
@@ -74,7 +75,7 @@ private val COROUTINES_INTRINSICS_FILE_FACADE_INTERNAL_NAME =
|
|||||||
DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME.child(Name.identifier("IntrinsicsKt")).topLevelClassAsmType()
|
DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME.child(Name.identifier("IntrinsicsKt")).topLevelClassAsmType()
|
||||||
|
|
||||||
private val INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME =
|
private val INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME =
|
||||||
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineIntrinsics")).topLevelClassInternalName()
|
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineIntrinsics")).topLevelClassInternalName()
|
||||||
|
|
||||||
private val NORMALIZE_CONTINUATION_METHOD_NAME = "normalizeContinuation"
|
private val NORMALIZE_CONTINUATION_METHOD_NAME = "normalizeContinuation"
|
||||||
private val GET_CONTEXT_METHOD_NAME = "getContext"
|
private val GET_CONTEXT_METHOD_NAME = "getContext"
|
||||||
@@ -94,41 +95,42 @@ val INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME = object : FunctionDescriptor.UserD
|
|||||||
// So this function returns resolved call with descriptor looking like `fun <V> await(f: CompletableFuture<V>, machine: Continuation<V>): Unit`
|
// So this function returns resolved call with descriptor looking like `fun <V> await(f: CompletableFuture<V>, machine: Continuation<V>): Unit`
|
||||||
// and fake `this` expression that used as argument for second parameter
|
// and fake `this` expression that used as argument for second parameter
|
||||||
fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
||||||
project: Project,
|
project: Project,
|
||||||
bindingContext: BindingContext
|
bindingContext: BindingContext
|
||||||
): ResolvedCallWithRealDescriptor? {
|
): ResolvedCallWithRealDescriptor? {
|
||||||
if (this is VariableAsFunctionResolvedCall) {
|
if (this is VariableAsFunctionResolvedCall) {
|
||||||
val replacedFunctionCall =
|
val replacedFunctionCall =
|
||||||
functionCall.replaceSuspensionFunctionWithRealDescriptor(project, bindingContext)
|
functionCall.replaceSuspensionFunctionWithRealDescriptor(project, bindingContext)
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return replacedFunctionCall.copy(
|
return replacedFunctionCall.copy(
|
||||||
VariableAsFunctionResolvedCallImpl(
|
VariableAsFunctionResolvedCallImpl(
|
||||||
replacedFunctionCall.resolvedCall as MutableResolvedCall<FunctionDescriptor>,
|
replacedFunctionCall.resolvedCall as MutableResolvedCall<FunctionDescriptor>,
|
||||||
variableCall.asMutableResolvedCall(bindingContext)
|
variableCall.asMutableResolvedCall(bindingContext)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val function = candidateDescriptor as? FunctionDescriptor ?: return null
|
val function = candidateDescriptor as? FunctionDescriptor ?: return null
|
||||||
if (!function.isSuspend || function.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) != null) return null
|
if (!function.isSuspend || function.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) != null) return null
|
||||||
|
|
||||||
val newCandidateDescriptor =
|
val newCandidateDescriptor =
|
||||||
when (function) {
|
when (function) {
|
||||||
is FunctionImportedFromObject ->
|
is FunctionImportedFromObject ->
|
||||||
getOrCreateJvmSuspendFunctionView(function.callableFromObject, bindingContext).asImportedFromObject()
|
getOrCreateJvmSuspendFunctionView(function.callableFromObject, bindingContext).asImportedFromObject()
|
||||||
is SimpleFunctionDescriptor ->
|
is SimpleFunctionDescriptor ->
|
||||||
getOrCreateJvmSuspendFunctionView(function, bindingContext)
|
getOrCreateJvmSuspendFunctionView(function, bindingContext)
|
||||||
else ->
|
else ->
|
||||||
throw AssertionError("Unexpected suspend function descriptor: $function")
|
throw AssertionError("Unexpected suspend function descriptor: $function")
|
||||||
}
|
}
|
||||||
|
|
||||||
val newCall = ResolvedCallImpl(
|
val newCall = ResolvedCallImpl(
|
||||||
call,
|
call,
|
||||||
newCandidateDescriptor,
|
newCandidateDescriptor,
|
||||||
dispatchReceiver, extensionReceiver, explicitReceiverKind,
|
dispatchReceiver, extensionReceiver, explicitReceiverKind,
|
||||||
null, DelegatingBindingTrace(BindingTraceContext().bindingContext, "Temporary trace for unwrapped suspension function"),
|
null, DelegatingBindingTrace(BindingTraceContext().bindingContext, "Temporary trace for unwrapped suspension function"),
|
||||||
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY))
|
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
|
||||||
|
)
|
||||||
|
|
||||||
this.valueArguments.forEach {
|
this.valueArguments.forEach {
|
||||||
newCall.recordValueArgument(newCandidateDescriptor.valueParameters[it.key.index], it.value)
|
newCall.recordValueArgument(newCandidateDescriptor.valueParameters[it.key.index], it.value)
|
||||||
@@ -138,15 +140,17 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
|||||||
val arguments = psiFactory.createCallArguments("(this)").arguments.single()
|
val arguments = psiFactory.createCallArguments("(this)").arguments.single()
|
||||||
val thisExpression = arguments.getArgumentExpression()!!
|
val thisExpression = arguments.getArgumentExpression()!!
|
||||||
newCall.recordValueArgument(
|
newCall.recordValueArgument(
|
||||||
newCandidateDescriptor.valueParameters.last(),
|
newCandidateDescriptor.valueParameters.last(),
|
||||||
ExpressionValueArgument(arguments))
|
ExpressionValueArgument(arguments)
|
||||||
|
)
|
||||||
|
|
||||||
val newTypeArguments = newCandidateDescriptor.typeParameters.map {
|
val newTypeArguments = newCandidateDescriptor.typeParameters.map {
|
||||||
Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection())
|
Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection())
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
newCall.setResultingSubstitutor(
|
newCall.setResultingSubstitutor(
|
||||||
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor())
|
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor()
|
||||||
|
)
|
||||||
|
|
||||||
return ResolvedCallWithRealDescriptor(newCall, thisExpression)
|
return ResolvedCallWithRealDescriptor(newCall, thisExpression)
|
||||||
}
|
}
|
||||||
@@ -161,19 +165,19 @@ private fun ResolvedCall<VariableDescriptor>.asMutableResolvedCall(bindingContex
|
|||||||
|
|
||||||
private fun NewResolvedCallImpl<VariableDescriptor>.asDummyOldResolvedCall(bindingContext: BindingContext): ResolvedCallImpl<VariableDescriptor> {
|
private fun NewResolvedCallImpl<VariableDescriptor>.asDummyOldResolvedCall(bindingContext: BindingContext): ResolvedCallImpl<VariableDescriptor> {
|
||||||
return ResolvedCallImpl(
|
return ResolvedCallImpl(
|
||||||
call,
|
call,
|
||||||
candidateDescriptor,
|
candidateDescriptor,
|
||||||
dispatchReceiver, extensionReceiver, explicitReceiverKind,
|
dispatchReceiver, extensionReceiver, explicitReceiverKind,
|
||||||
null, DelegatingBindingTrace(bindingContext, "Trace for old call"),
|
null, DelegatingBindingTrace(bindingContext, "Trace for old call"),
|
||||||
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
|
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ResolvedCall<*>.isSuspendNoInlineCall() =
|
fun ResolvedCall<*>.isSuspendNoInlineCall() =
|
||||||
resultingDescriptor.safeAs<FunctionDescriptor>()
|
resultingDescriptor.safeAs<FunctionDescriptor>()
|
||||||
?.let {
|
?.let {
|
||||||
it.isSuspend && (!it.isInline || it.isBuiltInSuspendCoroutineOrReturnInJvm() || it.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm())
|
it.isSuspend && (!it.isInline || it.isBuiltInSuspendCoroutineOrReturnInJvm() || it.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm())
|
||||||
} == true
|
} == true
|
||||||
|
|
||||||
fun CallableDescriptor.isSuspendFunctionNotSuspensionView(): Boolean {
|
fun CallableDescriptor.isSuspendFunctionNotSuspensionView(): Boolean {
|
||||||
if (this !is FunctionDescriptor) return false
|
if (this !is FunctionDescriptor) return false
|
||||||
@@ -193,14 +197,14 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(function: D, bind
|
|||||||
bindingContext?.get(CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW, function)?.let { return it as D }
|
bindingContext?.get(CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW, function)?.let { return it as D }
|
||||||
|
|
||||||
val continuationParameter = ValueParameterDescriptorImpl(
|
val continuationParameter = ValueParameterDescriptorImpl(
|
||||||
function, null, function.valueParameters.size, Annotations.EMPTY, Name.identifier("continuation"),
|
function, null, function.valueParameters.size, Annotations.EMPTY, Name.identifier("continuation"),
|
||||||
// Add j.l.Object to invoke(), because that is the type of parameters we have in FunctionN+1
|
// Add j.l.Object to invoke(), because that is the type of parameters we have in FunctionN+1
|
||||||
if (function.containingDeclaration.safeAs<ClassDescriptor>()?.defaultType?.isBuiltinFunctionalType == true)
|
if (function.containingDeclaration.safeAs<ClassDescriptor>()?.defaultType?.isBuiltinFunctionalType == true)
|
||||||
function.builtIns.nullableAnyType
|
function.builtIns.nullableAnyType
|
||||||
else
|
else
|
||||||
function.getContinuationParameterTypeOfSuspendFunction(),
|
function.getContinuationParameterTypeOfSuspendFunction(),
|
||||||
/* declaresDefaultValue = */ false, /* isCrossinline = */ false,
|
/* declaresDefaultValue = */ false, /* isCrossinline = */ false,
|
||||||
/* isNoinline = */ false, /* varargElementType = */ null, SourceElement.NO_SOURCE
|
/* isNoinline = */ false, /* varargElementType = */ null, SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
|
|
||||||
return function.createCustomCopy {
|
return function.createCustomCopy {
|
||||||
@@ -213,18 +217,18 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(function: D, bind
|
|||||||
}
|
}
|
||||||
|
|
||||||
typealias FunctionDescriptorCopyBuilderToFunctionDescriptorCopyBuilder =
|
typealias FunctionDescriptorCopyBuilderToFunctionDescriptorCopyBuilder =
|
||||||
FunctionDescriptor.CopyBuilder<out FunctionDescriptor>.(FunctionDescriptor)
|
FunctionDescriptor.CopyBuilder<out FunctionDescriptor>.(FunctionDescriptor)
|
||||||
-> FunctionDescriptor.CopyBuilder<out FunctionDescriptor>
|
-> FunctionDescriptor.CopyBuilder<out FunctionDescriptor>
|
||||||
|
|
||||||
fun <D : FunctionDescriptor> D.createCustomCopy(
|
fun <D : FunctionDescriptor> D.createCustomCopy(
|
||||||
copySettings: FunctionDescriptorCopyBuilderToFunctionDescriptorCopyBuilder
|
copySettings: FunctionDescriptorCopyBuilderToFunctionDescriptorCopyBuilder
|
||||||
): D {
|
): D {
|
||||||
|
|
||||||
val newOriginal =
|
val newOriginal =
|
||||||
if (original !== this)
|
if (original !== this)
|
||||||
original.createCustomCopy(copySettings)
|
original.createCustomCopy(copySettings)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|
||||||
val result = newCopyBuilder().copySettings(this).setOriginal(newOriginal).build()!!
|
val result = newCopyBuilder().copySettings(this).setOriginal(newOriginal).build()!!
|
||||||
|
|
||||||
@@ -235,52 +239,52 @@ fun <D : FunctionDescriptor> D.createCustomCopy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FunctionDescriptor.getContinuationParameterTypeOfSuspendFunction() =
|
private fun FunctionDescriptor.getContinuationParameterTypeOfSuspendFunction() =
|
||||||
module.getContinuationOfTypeOrAny(returnType!!)
|
module.getContinuationOfTypeOrAny(returnType!!)
|
||||||
|
|
||||||
fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType) =
|
fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType) =
|
||||||
module.findContinuationClassDescriptorOrNull(NoLookupLocation.FROM_BACKEND)?.defaultType?.let {
|
module.findContinuationClassDescriptorOrNull(NoLookupLocation.FROM_BACKEND)?.defaultType?.let {
|
||||||
KotlinTypeFactory.simpleType(
|
KotlinTypeFactory.simpleType(
|
||||||
it,
|
it,
|
||||||
arguments = listOf(kotlinType.asTypeProjection())
|
arguments = listOf(kotlinType.asTypeProjection())
|
||||||
)
|
)
|
||||||
} ?: module.builtIns.nullableAnyType
|
} ?: module.builtIns.nullableAnyType
|
||||||
|
|
||||||
fun FunctionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm() =
|
fun FunctionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm() =
|
||||||
getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineOrReturn() == true
|
getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineOrReturn() == true
|
||||||
|
|
||||||
fun createMethodNodeForSuspendCoroutineOrReturn(
|
fun createMethodNodeForSuspendCoroutineOrReturn(
|
||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor,
|
||||||
typeMapper: KotlinTypeMapper
|
typeMapper: KotlinTypeMapper
|
||||||
): MethodNode {
|
): MethodNode {
|
||||||
assert(functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm()) {
|
assert(functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm()) {
|
||||||
"functionDescriptor must be kotlin.coroutines.intrinsics.suspendOrReturn"
|
"functionDescriptor must be kotlin.coroutines.intrinsics.suspendOrReturn"
|
||||||
}
|
}
|
||||||
|
|
||||||
val node =
|
val node =
|
||||||
MethodNode(
|
MethodNode(
|
||||||
Opcodes.ASM5,
|
Opcodes.ASM5,
|
||||||
Opcodes.ACC_STATIC,
|
Opcodes.ACC_STATIC,
|
||||||
"fake",
|
"fake",
|
||||||
typeMapper.mapAsmMethod(functionDescriptor).descriptor, null, null
|
typeMapper.mapAsmMethod(functionDescriptor).descriptor, null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
node.visitVarInsn(Opcodes.ALOAD, 0)
|
node.visitVarInsn(Opcodes.ALOAD, 0)
|
||||||
node.visitVarInsn(Opcodes.ALOAD, 1)
|
node.visitVarInsn(Opcodes.ALOAD, 1)
|
||||||
|
|
||||||
node.visitMethodInsn(
|
node.visitMethodInsn(
|
||||||
Opcodes.INVOKESTATIC,
|
Opcodes.INVOKESTATIC,
|
||||||
INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME,
|
INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME,
|
||||||
NORMALIZE_CONTINUATION_METHOD_NAME,
|
NORMALIZE_CONTINUATION_METHOD_NAME,
|
||||||
Type.getMethodDescriptor(CONTINUATION_ASM_TYPE, CONTINUATION_ASM_TYPE),
|
Type.getMethodDescriptor(CONTINUATION_ASM_TYPE, CONTINUATION_ASM_TYPE),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
node.visitMethodInsn(
|
node.visitMethodInsn(
|
||||||
Opcodes.INVOKEINTERFACE,
|
Opcodes.INVOKEINTERFACE,
|
||||||
typeMapper.mapType(functionDescriptor.valueParameters[0]).internalName,
|
typeMapper.mapType(functionDescriptor.valueParameters[0]).internalName,
|
||||||
OperatorNameConventions.INVOKE.identifier,
|
OperatorNameConventions.INVOKE.identifier,
|
||||||
"(${AsmTypes.OBJECT_TYPE})${AsmTypes.OBJECT_TYPE}",
|
"(${AsmTypes.OBJECT_TYPE})${AsmTypes.OBJECT_TYPE}",
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
node.visitInsn(Opcodes.ARETURN)
|
node.visitInsn(Opcodes.ARETURN)
|
||||||
node.visitMaxs(2, 2)
|
node.visitMaxs(2, 2)
|
||||||
@@ -289,32 +293,32 @@ fun createMethodNodeForSuspendCoroutineOrReturn(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm() =
|
fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm() =
|
||||||
getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineUninterceptedOrReturn() == true
|
getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineUninterceptedOrReturn() == true
|
||||||
|
|
||||||
fun createMethodNodeForIntercepted(
|
fun createMethodNodeForIntercepted(
|
||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor,
|
||||||
typeMapper: KotlinTypeMapper
|
typeMapper: KotlinTypeMapper
|
||||||
): MethodNode {
|
): MethodNode {
|
||||||
assert(functionDescriptor.isBuiltInIntercepted()) {
|
assert(functionDescriptor.isBuiltInIntercepted()) {
|
||||||
"functionDescriptor must be kotlin.coroutines.intrinsics.intercepted"
|
"functionDescriptor must be kotlin.coroutines.intrinsics.intercepted"
|
||||||
}
|
}
|
||||||
|
|
||||||
val node =
|
val node =
|
||||||
MethodNode(
|
MethodNode(
|
||||||
Opcodes.ASM5,
|
Opcodes.ASM5,
|
||||||
Opcodes.ACC_STATIC,
|
Opcodes.ACC_STATIC,
|
||||||
"fake",
|
"fake",
|
||||||
typeMapper.mapAsmMethod(functionDescriptor).descriptor, null, null
|
typeMapper.mapAsmMethod(functionDescriptor).descriptor, null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
node.visitVarInsn(Opcodes.ALOAD, 0)
|
node.visitVarInsn(Opcodes.ALOAD, 0)
|
||||||
|
|
||||||
node.visitMethodInsn(
|
node.visitMethodInsn(
|
||||||
Opcodes.INVOKESTATIC,
|
Opcodes.INVOKESTATIC,
|
||||||
INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME,
|
INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME,
|
||||||
NORMALIZE_CONTINUATION_METHOD_NAME,
|
NORMALIZE_CONTINUATION_METHOD_NAME,
|
||||||
Type.getMethodDescriptor(CONTINUATION_ASM_TYPE, CONTINUATION_ASM_TYPE),
|
Type.getMethodDescriptor(CONTINUATION_ASM_TYPE, CONTINUATION_ASM_TYPE),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
node.visitInsn(Opcodes.ARETURN)
|
node.visitInsn(Opcodes.ARETURN)
|
||||||
node.visitMaxs(1, 1)
|
node.visitMaxs(1, 1)
|
||||||
@@ -328,22 +332,22 @@ fun createMethodNodeForCoroutineContext(functionDescriptor: FunctionDescriptor):
|
|||||||
}
|
}
|
||||||
|
|
||||||
val node =
|
val node =
|
||||||
MethodNode(
|
MethodNode(
|
||||||
Opcodes.ASM5,
|
Opcodes.ASM5,
|
||||||
Opcodes.ACC_STATIC,
|
Opcodes.ACC_STATIC,
|
||||||
"fake",
|
"fake",
|
||||||
Type.getMethodDescriptor(COROUTINE_CONTEXT_ASM_TYPE, CONTINUATION_ASM_TYPE),
|
Type.getMethodDescriptor(COROUTINE_CONTEXT_ASM_TYPE, CONTINUATION_ASM_TYPE),
|
||||||
null, null
|
null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
node.visitVarInsn(Opcodes.ALOAD, 0)
|
node.visitVarInsn(Opcodes.ALOAD, 0)
|
||||||
|
|
||||||
node.visitMethodInsn(
|
node.visitMethodInsn(
|
||||||
Opcodes.INVOKEINTERFACE,
|
Opcodes.INVOKEINTERFACE,
|
||||||
CONTINUATION_ASM_TYPE.internalName,
|
CONTINUATION_ASM_TYPE.internalName,
|
||||||
GET_CONTEXT_METHOD_NAME,
|
GET_CONTEXT_METHOD_NAME,
|
||||||
Type.getMethodDescriptor(COROUTINE_CONTEXT_ASM_TYPE),
|
Type.getMethodDescriptor(COROUTINE_CONTEXT_ASM_TYPE),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
node.visitInsn(Opcodes.ARETURN)
|
node.visitInsn(Opcodes.ARETURN)
|
||||||
node.visitMaxs(1, 1)
|
node.visitMaxs(1, 1)
|
||||||
@@ -353,30 +357,30 @@ fun createMethodNodeForCoroutineContext(functionDescriptor: FunctionDescriptor):
|
|||||||
|
|
||||||
|
|
||||||
fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn(
|
fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn(
|
||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor,
|
||||||
typeMapper: KotlinTypeMapper
|
typeMapper: KotlinTypeMapper
|
||||||
): MethodNode {
|
): MethodNode {
|
||||||
assert(functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) {
|
assert(functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) {
|
||||||
"functionDescriptor must be kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn"
|
"functionDescriptor must be kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn"
|
||||||
}
|
}
|
||||||
|
|
||||||
val node =
|
val node =
|
||||||
MethodNode(
|
MethodNode(
|
||||||
Opcodes.ASM5,
|
Opcodes.ASM5,
|
||||||
Opcodes.ACC_STATIC,
|
Opcodes.ACC_STATIC,
|
||||||
"fake",
|
"fake",
|
||||||
typeMapper.mapAsmMethod(functionDescriptor).descriptor, null, null
|
typeMapper.mapAsmMethod(functionDescriptor).descriptor, null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
node.visitVarInsn(Opcodes.ALOAD, 0)
|
node.visitVarInsn(Opcodes.ALOAD, 0)
|
||||||
node.visitVarInsn(Opcodes.ALOAD, 1)
|
node.visitVarInsn(Opcodes.ALOAD, 1)
|
||||||
|
|
||||||
node.visitMethodInsn(
|
node.visitMethodInsn(
|
||||||
Opcodes.INVOKEINTERFACE,
|
Opcodes.INVOKEINTERFACE,
|
||||||
typeMapper.mapType(functionDescriptor.valueParameters[0]).internalName,
|
typeMapper.mapType(functionDescriptor.valueParameters[0]).internalName,
|
||||||
OperatorNameConventions.INVOKE.identifier,
|
OperatorNameConventions.INVOKE.identifier,
|
||||||
"(${AsmTypes.OBJECT_TYPE})${AsmTypes.OBJECT_TYPE}",
|
"(${AsmTypes.OBJECT_TYPE})${AsmTypes.OBJECT_TYPE}",
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
node.visitInsn(Opcodes.ARETURN)
|
node.visitInsn(Opcodes.ARETURN)
|
||||||
node.visitMaxs(2, 2)
|
node.visitMaxs(2, 2)
|
||||||
@@ -386,21 +390,21 @@ fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn(
|
|||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <D : CallableDescriptor?> D.unwrapInitialDescriptorForSuspendFunction(): D =
|
fun <D : CallableDescriptor?> D.unwrapInitialDescriptorForSuspendFunction(): D =
|
||||||
this.safeAs<SimpleFunctionDescriptor>()?.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) as D ?: this
|
this.safeAs<SimpleFunctionDescriptor>()?.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) as D ?: this
|
||||||
|
|
||||||
|
|
||||||
fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext): FunctionDescriptor =
|
fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext): FunctionDescriptor =
|
||||||
if (isSuspend)
|
if (isSuspend)
|
||||||
getOrCreateJvmSuspendFunctionView(unwrapInitialDescriptorForSuspendFunction().original, bindingContext)
|
getOrCreateJvmSuspendFunctionView(unwrapInitialDescriptorForSuspendFunction().original, bindingContext)
|
||||||
else
|
else
|
||||||
this
|
this
|
||||||
|
|
||||||
fun InstructionAdapter.loadCoroutineSuspendedMarker() {
|
fun InstructionAdapter.loadCoroutineSuspendedMarker() {
|
||||||
invokestatic(
|
invokestatic(
|
||||||
COROUTINES_INTRINSICS_FILE_FACADE_INTERNAL_NAME.internalName,
|
COROUTINES_INTRINSICS_FILE_FACADE_INTERNAL_NAME.internalName,
|
||||||
"get$COROUTINE_SUSPENDED_NAME",
|
"get$COROUTINE_SUSPENDED_NAME",
|
||||||
Type.getMethodDescriptor(AsmTypes.OBJECT_TYPE),
|
Type.getMethodDescriptor(AsmTypes.OBJECT_TYPE),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,12 +415,12 @@ fun InstructionAdapter.invokeDoResumeWithUnit(thisName: String) {
|
|||||||
aconst(null)
|
aconst(null)
|
||||||
|
|
||||||
invokevirtual(
|
invokevirtual(
|
||||||
thisName,
|
thisName,
|
||||||
DO_RESUME_METHOD_NAME,
|
DO_RESUME_METHOD_NAME,
|
||||||
Type.getMethodDescriptor(AsmTypes.OBJECT_TYPE, AsmTypes.OBJECT_TYPE, AsmTypes.JAVA_THROWABLE_TYPE),
|
Type.getMethodDescriptor(AsmTypes.OBJECT_TYPE, AsmTypes.OBJECT_TYPE, AsmTypes.JAVA_THROWABLE_TYPE),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Method.getImplForOpenMethod(ownerInternalName: String) =
|
fun Method.getImplForOpenMethod(ownerInternalName: String) =
|
||||||
Method("$name\$suspendImpl", returnType, arrayOf(Type.getObjectType(ownerInternalName)) + argumentTypes)
|
Method("$name\$suspendImpl", returnType, arrayOf(Type.getObjectType(ownerInternalName)) + argumentTypes)
|
||||||
|
|||||||
@@ -42,21 +42,20 @@ import org.jetbrains.kotlin.resolve.source.getPsi
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
fun generateDelegateCall(
|
fun generateDelegateCall(
|
||||||
classDescriptor: ClassDescriptor,
|
classDescriptor: ClassDescriptor,
|
||||||
fromDescriptor: FunctionDescriptor,
|
fromDescriptor: FunctionDescriptor,
|
||||||
toDescriptor: FunctionDescriptor,
|
toDescriptor: FunctionDescriptor,
|
||||||
thisObject: JsExpression,
|
thisObject: JsExpression,
|
||||||
context: TranslationContext,
|
context: TranslationContext,
|
||||||
detectDefaultParameters: Boolean,
|
detectDefaultParameters: Boolean,
|
||||||
source: PsiElement?
|
source: PsiElement?
|
||||||
): JsStatement {
|
): JsStatement {
|
||||||
fun FunctionDescriptor.getNameForFunctionWithPossibleDefaultParam() =
|
fun FunctionDescriptor.getNameForFunctionWithPossibleDefaultParam() =
|
||||||
if (detectDefaultParameters && hasOrInheritsParametersWithDefaultValue()) {
|
if (detectDefaultParameters && hasOrInheritsParametersWithDefaultValue()) {
|
||||||
context.scope().declareName(context.getNameForDescriptor(this).ident + Namer.DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX)
|
context.scope().declareName(context.getNameForDescriptor(this).ident + Namer.DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX)
|
||||||
}
|
} else {
|
||||||
else {
|
context.getNameForDescriptor(this)
|
||||||
context.getNameForDescriptor(this)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val overriddenMemberFunctionName = toDescriptor.getNameForFunctionWithPossibleDefaultParam()
|
val overriddenMemberFunctionName = toDescriptor.getNameForFunctionWithPossibleDefaultParam()
|
||||||
val overriddenMemberFunctionRef = JsNameRef(overriddenMemberFunctionName, thisObject)
|
val overriddenMemberFunctionRef = JsNameRef(overriddenMemberFunctionName, thisObject)
|
||||||
@@ -80,8 +79,7 @@ fun generateDelegateCall(
|
|||||||
val intrinsic = context.intrinsics().getFunctionIntrinsic(toDescriptor)
|
val intrinsic = context.intrinsics().getFunctionIntrinsic(toDescriptor)
|
||||||
val invocation = if (intrinsic.exists() && intrinsic is FunctionIntrinsicWithReceiverComputed) {
|
val invocation = if (intrinsic.exists() && intrinsic is FunctionIntrinsicWithReceiverComputed) {
|
||||||
intrinsic.apply(thisObject, args, context)
|
intrinsic.apply(thisObject, args, context)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
JsInvocation(overriddenMemberFunctionRef, args)
|
JsInvocation(overriddenMemberFunctionRef, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +128,8 @@ fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpr
|
|||||||
|
|
||||||
context.usageTracker()?.used(classifierDescriptor)
|
context.usageTracker()?.used(classifierDescriptor)
|
||||||
|
|
||||||
context.captureTypeIfNeedAndGetCapturedName(classifierDescriptor) ?:
|
context.captureTypeIfNeedAndGetCapturedName(classifierDescriptor)
|
||||||
context.getNameForDescriptor(classifierDescriptor).makeRef()
|
?: context.getNameForDescriptor(classifierDescriptor).makeRef()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw IllegalStateException("Can't get reference for $type")
|
throw IllegalStateException("Can't get reference for $type")
|
||||||
@@ -140,9 +138,9 @@ fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpr
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun TranslationContext.addFunctionToPrototype(
|
fun TranslationContext.addFunctionToPrototype(
|
||||||
classDescriptor: ClassDescriptor,
|
classDescriptor: ClassDescriptor,
|
||||||
descriptor: FunctionDescriptor,
|
descriptor: FunctionDescriptor,
|
||||||
function: JsExpression
|
function: JsExpression
|
||||||
): JsStatement {
|
): JsStatement {
|
||||||
val prototypeRef = JsAstUtils.prototypeOf(getInnerReference(classDescriptor))
|
val prototypeRef = JsAstUtils.prototypeOf(getInnerReference(classDescriptor))
|
||||||
val functionRef = JsNameRef(getNameForDescriptor(descriptor), prototypeRef)
|
val functionRef = JsNameRef(getNameForDescriptor(descriptor), prototypeRef)
|
||||||
@@ -150,9 +148,9 @@ fun TranslationContext.addFunctionToPrototype(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun TranslationContext.addAccessorsToPrototype(
|
fun TranslationContext.addAccessorsToPrototype(
|
||||||
containingClass: ClassDescriptor,
|
containingClass: ClassDescriptor,
|
||||||
propertyDescriptor: PropertyDescriptor,
|
propertyDescriptor: PropertyDescriptor,
|
||||||
literal: JsObjectLiteral
|
literal: JsObjectLiteral
|
||||||
) {
|
) {
|
||||||
val prototypeRef = JsAstUtils.prototypeOf(getInnerReference(containingClass))
|
val prototypeRef = JsAstUtils.prototypeOf(getInnerReference(containingClass))
|
||||||
val propertyName = getNameForDescriptor(propertyDescriptor)
|
val propertyName = getNameForDescriptor(propertyDescriptor)
|
||||||
@@ -161,31 +159,31 @@ fun TranslationContext.addAccessorsToPrototype(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun JsFunction.fillCoroutineMetadata(
|
fun JsFunction.fillCoroutineMetadata(
|
||||||
context: TranslationContext,
|
context: TranslationContext,
|
||||||
descriptor: FunctionDescriptor,
|
descriptor: FunctionDescriptor,
|
||||||
hasController: Boolean
|
hasController: Boolean
|
||||||
) {
|
) {
|
||||||
val suspendPropertyDescriptor = context.currentModule.getPackage(DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME)
|
val suspendPropertyDescriptor = context.currentModule.getPackage(DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME)
|
||||||
.memberScope
|
.memberScope
|
||||||
.getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND).first()
|
.getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND).first()
|
||||||
|
|
||||||
val coroutineBaseClassRef = ReferenceTranslator.translateAsTypeReference(TranslationUtils.getCoroutineBaseClass(context), context)
|
val coroutineBaseClassRef = ReferenceTranslator.translateAsTypeReference(TranslationUtils.getCoroutineBaseClass(context), context)
|
||||||
|
|
||||||
fun getCoroutinePropertyName(id: String) =
|
fun getCoroutinePropertyName(id: String) =
|
||||||
context.getNameForDescriptor(TranslationUtils.getCoroutineProperty(context, id))
|
context.getNameForDescriptor(TranslationUtils.getCoroutineProperty(context, id))
|
||||||
|
|
||||||
coroutineMetadata = CoroutineMetadata(
|
coroutineMetadata = CoroutineMetadata(
|
||||||
doResumeName = context.getNameForDescriptor(TranslationUtils.getCoroutineDoResumeFunction(context)),
|
doResumeName = context.getNameForDescriptor(TranslationUtils.getCoroutineDoResumeFunction(context)),
|
||||||
suspendObjectRef = ReferenceTranslator.translateAsValueReference(suspendPropertyDescriptor, context),
|
suspendObjectRef = ReferenceTranslator.translateAsValueReference(suspendPropertyDescriptor, context),
|
||||||
baseClassRef = coroutineBaseClassRef,
|
baseClassRef = coroutineBaseClassRef,
|
||||||
stateName = getCoroutinePropertyName("state"),
|
stateName = getCoroutinePropertyName("state"),
|
||||||
exceptionStateName = getCoroutinePropertyName("exceptionState"),
|
exceptionStateName = getCoroutinePropertyName("exceptionState"),
|
||||||
finallyPathName = getCoroutinePropertyName("finallyPath"),
|
finallyPathName = getCoroutinePropertyName("finallyPath"),
|
||||||
resultName = getCoroutinePropertyName("result"),
|
resultName = getCoroutinePropertyName("result"),
|
||||||
exceptionName = getCoroutinePropertyName("exception"),
|
exceptionName = getCoroutinePropertyName("exception"),
|
||||||
hasController = hasController,
|
hasController = hasController,
|
||||||
hasReceiver = descriptor.dispatchReceiverParameter != null,
|
hasReceiver = descriptor.dispatchReceiverParameter != null,
|
||||||
psiElement = descriptor.source.getPsi()
|
psiElement = descriptor.source.getPsi()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +203,7 @@ val PsiElement.finalElement: PsiElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun TranslationContext.addFunctionButNotExport(descriptor: FunctionDescriptor, expression: JsExpression): JsName =
|
fun TranslationContext.addFunctionButNotExport(descriptor: FunctionDescriptor, expression: JsExpression): JsName =
|
||||||
addFunctionButNotExport(getInnerNameForDescriptor(descriptor), expression)
|
addFunctionButNotExport(getInnerNameForDescriptor(descriptor), expression)
|
||||||
|
|
||||||
fun TranslationContext.addFunctionButNotExport(name: JsName, expression: JsExpression): JsName {
|
fun TranslationContext.addFunctionButNotExport(name: JsName, expression: JsExpression): JsName {
|
||||||
when (expression) {
|
when (expression) {
|
||||||
|
|||||||
Reference in New Issue
Block a user