Fix wrong state-machine generation if inner object is retransformed

during inlining.
 #KT-29492 Fixed
This commit is contained in:
Ilmir Usmanov
2019-03-12 17:49:31 +03:00
parent 7b97c2a42a
commit 1c2b8e6fad
19 changed files with 481 additions and 55 deletions
@@ -276,7 +276,8 @@ class AnonymousObjectTransformer(
InlineCallSiteInfo(
transformationInfo.oldClassName,
sourceNode.name,
if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc
if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc,
inliningContext.callSiteInfo.isInlineOrInsideInline
), null
)
@@ -16,4 +16,4 @@
package org.jetbrains.kotlin.codegen.inline
class InlineCallSiteInfo(val ownerClassName: String, val functionName: String?, val functionDesc: String?)
class InlineCallSiteInfo(val ownerClassName: String, val functionName: String?, val functionDesc: String?, val isInlineOrInsideInline: Boolean)
@@ -121,7 +121,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
val signature = codegen.state.typeMapper.mapSignatureSkipGeneric(context.functionDescriptor, context.contextKind)
return InlineCallSiteInfo(
parentCodegen.className, signature.asmMethod.name, signature.asmMethod.descriptor
parentCodegen.className, signature.asmMethod.name, signature.asmMethod.descriptor, compilationContextFunctionDescriptor.isInlineOrInsideInline()
)
}
@@ -472,4 +472,8 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
}
}
}
}
private fun DeclarationDescriptor.isInlineOrInsideInline(): Boolean =
if (this is FunctionDescriptor && isInline) true
else containingDeclaration?.isInlineOrInsideInline() == true
@@ -34,6 +34,9 @@ class CoroutineTransformer(
private val state = inliningContext.state
fun shouldTransform(node: MethodNode): Boolean {
// Never generate state-machine for objects, which are going to be retransformed
// See innerObjectRetransformation.kt
if (inliningContext.callSiteInfo.isInlineOrInsideInline) return false
if (isContinuationNotLambda()) return false
val crossinlineParam = crossinlineLambda() ?: return false
if (inliningContext.isInliningLambda && !inliningContext.isContinuation) return false