[JVM_IR] Support basic fake var generation for IR inliner
#KT-58778
This commit is contained in:
+33
-3
@@ -79,6 +79,12 @@ public class FirLightTreeLocalVariableTestGenerated extends AbstractFirLightTree
|
|||||||
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithLambdaParameter.kt")
|
||||||
|
public void testLambdaWithLambdaParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/lambdaWithLambdaParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localFun.kt")
|
@TestMetadata("localFun.kt")
|
||||||
public void testLocalFun() throws Exception {
|
public void testLocalFun() throws Exception {
|
||||||
@@ -170,9 +176,15 @@ public class FirLightTreeLocalVariableTestGenerated extends AbstractFirLightTree
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("tryFinally6.kt")
|
@TestMetadata("tryFinally6_1.kt")
|
||||||
public void testTryFinally6() throws Exception {
|
public void testTryFinally6_1() throws Exception {
|
||||||
runTest("compiler/testData/debug/localVariables/tryFinally6.kt");
|
runTest("compiler/testData/debug/localVariables/tryFinally6_1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally6_2.kt")
|
||||||
|
public void testTryFinally6_2() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally6_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -394,6 +406,24 @@ public class FirLightTreeLocalVariableTestGenerated extends AbstractFirLightTree
|
|||||||
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedInsideSuspendUnintercepted.kt")
|
||||||
|
public void testNestedInsideSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedInsideSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUnintercepted.kt")
|
||||||
|
public void testNestedSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUninterceptedWithDeepLambdaCall.kt")
|
||||||
|
public void testNestedSuspendUninterceptedWithDeepLambdaCall() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUninterceptedWithDeepLambdaCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
|
|||||||
+33
-3
@@ -79,6 +79,12 @@ public class FirPsiLocalVariableTestGenerated extends AbstractFirPsiLocalVariabl
|
|||||||
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithLambdaParameter.kt")
|
||||||
|
public void testLambdaWithLambdaParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/lambdaWithLambdaParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localFun.kt")
|
@TestMetadata("localFun.kt")
|
||||||
public void testLocalFun() throws Exception {
|
public void testLocalFun() throws Exception {
|
||||||
@@ -170,9 +176,15 @@ public class FirPsiLocalVariableTestGenerated extends AbstractFirPsiLocalVariabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("tryFinally6.kt")
|
@TestMetadata("tryFinally6_1.kt")
|
||||||
public void testTryFinally6() throws Exception {
|
public void testTryFinally6_1() throws Exception {
|
||||||
runTest("compiler/testData/debug/localVariables/tryFinally6.kt");
|
runTest("compiler/testData/debug/localVariables/tryFinally6_1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally6_2.kt")
|
||||||
|
public void testTryFinally6_2() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally6_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -394,6 +406,24 @@ public class FirPsiLocalVariableTestGenerated extends AbstractFirPsiLocalVariabl
|
|||||||
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedInsideSuspendUnintercepted.kt")
|
||||||
|
public void testNestedInsideSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedInsideSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUnintercepted.kt")
|
||||||
|
public void testNestedSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUninterceptedWithDeepLambdaCall.kt")
|
||||||
|
public void testNestedSuspendUninterceptedWithDeepLambdaCall() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUninterceptedWithDeepLambdaCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
|
|||||||
+39
-1
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.backend.common.ir
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
||||||
import org.jetbrains.kotlin.backend.common.lower.inline.INLINED_FUNCTION_ARGUMENTS
|
import org.jetbrains.kotlin.backend.common.lower.inline.INLINED_FUNCTION_ARGUMENTS
|
||||||
import org.jetbrains.kotlin.backend.common.lower.inline.INLINED_FUNCTION_DEFAULT_ARGUMENTS
|
import org.jetbrains.kotlin.backend.common.lower.inline.INLINED_FUNCTION_DEFAULT_ARGUMENTS
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.inline.isAdaptedFunctionReference
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||||
@@ -16,7 +18,10 @@ import org.jetbrains.kotlin.ir.builders.irComposite
|
|||||||
import org.jetbrains.kotlin.ir.builders.irTemporary
|
import org.jetbrains.kotlin.ir.builders.irTemporary
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
||||||
@@ -175,3 +180,36 @@ fun IrInlinedFunctionBlock.putStatementsInFrontOfInlinedFunction(statements: Lis
|
|||||||
this.statements.addAll(if (insertAfter == -1) 0 else insertAfter + 1, statements)
|
this.statements.addAll(if (insertAfter == -1) 0 else insertAfter + 1, statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun List<IrInlinedFunctionBlock>.extractDeclarationWhereGivenElementWasInlined(inlinedElement: IrElement): IrDeclaration? {
|
||||||
|
val originalInlinedElement = ((inlinedElement as? IrAttributeContainer)?.attributeOwnerId ?: inlinedElement)
|
||||||
|
for (block in this.filter { it.isFunctionInlining() }) {
|
||||||
|
block.inlineCall.getAllArgumentsWithIr().forEach {
|
||||||
|
// pretty messed up thing, this is needed to get the original expression that was inlined
|
||||||
|
// it was changed a couple of times after all lowerings, so we must get `attributeOwnerId` to ensure that this is original
|
||||||
|
val actualArg = if (it.second == null) {
|
||||||
|
val blockWithClass = it.first.defaultValue?.expression?.attributeOwnerId as? IrBlock
|
||||||
|
blockWithClass?.statements?.firstOrNull() as? IrClass
|
||||||
|
} else {
|
||||||
|
it.second
|
||||||
|
}
|
||||||
|
|
||||||
|
val originalActualArg = actualArg?.attributeOwnerId as? IrExpression
|
||||||
|
val extractedAnonymousFunction = if (originalActualArg?.isAdaptedFunctionReference() == true) {
|
||||||
|
(originalActualArg as IrBlock).statements.last() as IrFunctionReference
|
||||||
|
} else {
|
||||||
|
originalActualArg
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extractedAnonymousFunction?.attributeOwnerId == originalInlinedElement) {
|
||||||
|
return block.inlineDeclaration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val IrVariable.isTmpForInline: Boolean
|
||||||
|
get() = this.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_PARAMETER ||
|
||||||
|
this.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_EXTENSION_RECEIVER
|
||||||
|
|||||||
+14
-30
@@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
package org.jetbrains.kotlin.backend.jvm.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.extractDeclarationWhereGivenElementWasInlined
|
||||||
import org.jetbrains.kotlin.ir.util.inlineDeclaration
|
import org.jetbrains.kotlin.ir.util.inlineDeclaration
|
||||||
import org.jetbrains.kotlin.ir.util.isFunctionInlining
|
import org.jetbrains.kotlin.ir.util.isFunctionInlining
|
||||||
import org.jetbrains.kotlin.ir.util.isLambdaInlining
|
import org.jetbrains.kotlin.ir.util.isLambdaInlining
|
||||||
import org.jetbrains.kotlin.backend.common.lower.inline.isAdaptedFunctionReference
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.fileParentBeforeInline
|
import org.jetbrains.kotlin.backend.jvm.ir.fileParentBeforeInline
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
|
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
|
||||||
@@ -17,9 +17,18 @@ import org.jetbrains.kotlin.codegen.inline.SourceMapCopier
|
|||||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper
|
import org.jetbrains.kotlin.codegen.inline.SourceMapper
|
||||||
import org.jetbrains.kotlin.codegen.inline.SourcePosition
|
import org.jetbrains.kotlin.codegen.inline.SourcePosition
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrCallableReference
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrInlinedFunctionBlock
|
||||||
|
import org.jetbrains.kotlin.ir.util.fileEntry
|
||||||
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
|
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.util.statements
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
|
|
||||||
@@ -190,32 +199,7 @@ class LineNumberMapper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getDeclarationWhereGivenElementWasInlined(inlinedElement: IrElement): IrDeclaration? {
|
private fun getDeclarationWhereGivenElementWasInlined(inlinedElement: IrElement): IrDeclaration? {
|
||||||
val originalInlinedElement = ((inlinedElement as? IrAttributeContainer)?.attributeOwnerId ?: inlinedElement)
|
return smapStack.map { it.inlinedBlock }.extractDeclarationWhereGivenElementWasInlined(inlinedElement)
|
||||||
for (block in smapStack.map { it.inlinedBlock }.filter { it.isFunctionInlining() }) {
|
|
||||||
block.inlineCall.getAllArgumentsWithIr().forEach {
|
|
||||||
// pretty messed up thing, this is needed to get the original expression that was inlined
|
|
||||||
// it was changed a couple of times after all lowerings, so we must get `attributeOwnerId` to ensure that this is original
|
|
||||||
val actualArg = if (it.second == null) {
|
|
||||||
val blockWithClass = it.first.defaultValue?.expression?.attributeOwnerId as? IrBlock
|
|
||||||
blockWithClass?.statements?.firstOrNull() as? IrClass
|
|
||||||
} else {
|
|
||||||
it.second
|
|
||||||
}
|
|
||||||
|
|
||||||
val originalActualArg = actualArg?.attributeOwnerId as? IrExpression
|
|
||||||
val extractedAnonymousFunction = if (originalActualArg?.isAdaptedFunctionReference() == true) {
|
|
||||||
(originalActualArg as IrBlock).statements.last() as IrFunctionReference
|
|
||||||
} else {
|
|
||||||
originalActualArg
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extractedAnonymousFunction?.attributeOwnerId == originalInlinedElement) {
|
|
||||||
return block.inlineDeclaration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrInlinedFunctionBlock.isInvokeOnDefaultArg(): Boolean {
|
private fun IrInlinedFunctionBlock.isInvokeOnDefaultArg(): Boolean {
|
||||||
|
|||||||
+117
-48
@@ -12,9 +12,11 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
|||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
|
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
|
||||||
import org.jetbrains.kotlin.backend.jvm.irInlinerIsEnabled
|
import org.jetbrains.kotlin.backend.jvm.irInlinerIsEnabled
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX
|
import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX
|
||||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.createTmpVariable
|
import org.jetbrains.kotlin.ir.builders.createTmpVariable
|
||||||
import org.jetbrains.kotlin.ir.builders.irInt
|
import org.jetbrains.kotlin.ir.builders.irInt
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -42,11 +44,21 @@ internal val fakeInliningLocalVariablesAfterInlineLowering = makeIrFilePhase<Jvm
|
|||||||
)
|
)
|
||||||
|
|
||||||
// TODO extract common code with FakeInliningLocalVariablesLowering
|
// TODO extract common code with FakeInliningLocalVariablesLowering
|
||||||
internal class FakeInliningLocalVariablesAfterInlineLowering(val context: JvmBackendContext) : IrElementVisitor<Unit, IrDeclaration?>, FileLoweringPass {
|
internal class FakeInliningLocalVariablesAfterInlineLowering(
|
||||||
|
val context: JvmBackendContext
|
||||||
|
) : IrElementVisitor<Unit, IrDeclaration?>, FileLoweringPass {
|
||||||
private val inlinedStack = mutableListOf<IrInlinedFunctionBlock>()
|
private val inlinedStack = mutableListOf<IrInlinedFunctionBlock>()
|
||||||
|
|
||||||
|
private fun IrInlinedFunctionBlock.insertInStackAndProcess(data: IrDeclaration?) {
|
||||||
|
inlinedStack += this
|
||||||
|
super.visitBlock(this, data)
|
||||||
|
inlinedStack.removeLast()
|
||||||
|
}
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.accept(this, null)
|
irFile.accept(this, null)
|
||||||
|
irFile.acceptVoid(FunctionParametersProcessor())
|
||||||
|
irFile.accept(LocalVariablesProcessor(), LocalVariablesProcessor.Data(processingOriginalDeclarations = false))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitElement(element: IrElement, data: IrDeclaration?) {
|
override fun visitElement(element: IrElement, data: IrDeclaration?) {
|
||||||
@@ -63,63 +75,120 @@ internal class FakeInliningLocalVariablesAfterInlineLowering(val context: JvmBac
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleInlineFunction(expression: IrInlinedFunctionBlock, data: IrDeclaration?) {
|
private fun handleInlineFunction(expression: IrInlinedFunctionBlock, data: IrDeclaration?) {
|
||||||
|
expression.insertInStackAndProcess(data)
|
||||||
|
|
||||||
val declaration = expression.inlineDeclaration
|
val declaration = expression.inlineDeclaration
|
||||||
|
|
||||||
inlinedStack += expression
|
|
||||||
super.visitBlock(expression, data)
|
|
||||||
inlinedStack.removeLast()
|
|
||||||
|
|
||||||
if (declaration is IrFunction && declaration.isInline && !declaration.origin.isSynthetic && declaration.body != null && !declaration.isInlineOnly()) {
|
if (declaration is IrFunction && declaration.isInline && !declaration.origin.isSynthetic && declaration.body != null && !declaration.isInlineOnly()) {
|
||||||
val currentFunctionName = context.defaultMethodSignatureMapper.mapFunctionName(declaration)
|
val currentFunctionName = context.defaultMethodSignatureMapper.mapFunctionName(declaration)
|
||||||
val localName = "${JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION}$currentFunctionName"
|
val localName = "${JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION}$currentFunctionName"
|
||||||
//declaration.addFakeLocalVariable(localName)
|
expression.addFakeLocalVariable(localName, data!!)
|
||||||
with(context.createIrBuilder(data!!.symbol)) {
|
|
||||||
val tmpVar =
|
|
||||||
scope.createTmpVariable(irInt(0), localName.removeSuffix(FOR_INLINE_SUFFIX), origin = IrDeclarationOrigin.DEFINED)
|
|
||||||
// TODO maybe add in front of inline block
|
|
||||||
expression.putStatementsInFrontOfInlinedFunction(listOf(tmpVar))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expression.processLocalDeclarations()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
private fun handleInlineLambda(expression: IrInlinedFunctionBlock, data: IrDeclaration?) {
|
private fun handleInlineLambda(expression: IrInlinedFunctionBlock, data: IrDeclaration?) {
|
||||||
// TODO
|
expression.insertInStackAndProcess(data)
|
||||||
|
|
||||||
|
// `inlinedElement` here can be either `IrFunctionExpression` or `IrFunctionReference`, so cast must be safe
|
||||||
|
val argument = expression.inlinedElement as IrAttributeContainer
|
||||||
|
val callee = inlinedStack.extractDeclarationWhereGivenElementWasInlined(argument) as? IrFunction ?: return
|
||||||
|
|
||||||
|
val argumentToFunctionName = context.defaultMethodSignatureMapper.mapFunctionName(callee)
|
||||||
|
val lambdaReferenceName = context.getLocalClassType(argument)!!.internalName.substringAfterLast("/")
|
||||||
|
val localName = "${JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT}-$argumentToFunctionName-$lambdaReferenceName"
|
||||||
|
expression.addFakeLocalVariable(localName, data!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrInlinedFunctionBlock.processLocalDeclarations() {
|
private fun IrInlinedFunctionBlock.addFakeLocalVariable(localName: String, container: IrDeclaration) {
|
||||||
this.getAdditionalStatementsFromInlinedBlock().forEach {
|
with(context.createIrBuilder(container.symbol)) {
|
||||||
if (it is IrVariable && it.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE) {
|
val tmpVar = scope.createTmpVariable(
|
||||||
val varName = it.name.asString().substringAfterLast("_")
|
irInt(0), localName.removeSuffix(FOR_INLINE_SUFFIX), origin = IrDeclarationOrigin.DEFINED
|
||||||
it.name = Name.identifier((if (varName == SpecialNames.THIS.asString()) "this_" else varName) + INLINE_FUN_VAR_SUFFIX)
|
)
|
||||||
it.origin = IrDeclarationOrigin.DEFINED
|
this@addFakeLocalVariable.putStatementsInFrontOfInlinedFunction(listOf(tmpVar))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getOriginalStatementsFromInlinedBlock().forEach {
|
|
||||||
it.acceptVoid(object : IrElementVisitorVoid {
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariable(declaration: IrVariable) {
|
|
||||||
val varName = declaration.name.asString()
|
|
||||||
declaration.name = when {
|
|
||||||
varName == SpecialNames.THIS.asString() -> {
|
|
||||||
Name.identifier("this_$INLINE_FUN_VAR_SUFFIX")
|
|
||||||
}
|
|
||||||
|
|
||||||
!varName.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) -> {
|
|
||||||
Name.identifier(varName + INLINE_FUN_VAR_SUFFIX)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> declaration.name
|
|
||||||
}
|
|
||||||
super.visitVariable(declaration)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class LocalVariablesProcessor : IrElementVisitor<Unit, LocalVariablesProcessor.Data> {
|
||||||
|
data class Data(val processingOriginalDeclarations: Boolean)
|
||||||
|
|
||||||
|
private val inlinedStack = mutableListOf<IrInlinedFunctionBlock>()
|
||||||
|
|
||||||
|
private inline fun IrInlinedFunctionBlock.insertInStackAndProcess(block: IrInlinedFunctionBlock.() -> Unit) {
|
||||||
|
inlinedStack += this
|
||||||
|
block()
|
||||||
|
inlinedStack.removeLast()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitElement(element: IrElement, data: Data) {
|
||||||
|
element.acceptChildren(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBlock(expression: IrBlock, data: Data) {
|
||||||
|
if (expression !is IrInlinedFunctionBlock) {
|
||||||
|
return super.visitBlock(expression, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expression.isLambdaInlining()) {
|
||||||
|
val argument = expression.inlinedElement as IrAttributeContainer
|
||||||
|
val callee = inlinedStack.extractDeclarationWhereGivenElementWasInlined(argument)
|
||||||
|
if (callee == null || callee != inlinedStack.lastOrNull()) return
|
||||||
|
}
|
||||||
|
|
||||||
|
super.visitBlock(expression, data)
|
||||||
|
|
||||||
|
expression.insertInStackAndProcess {
|
||||||
|
getOriginalStatementsFromInlinedBlock().forEach {
|
||||||
|
it.accept(this@LocalVariablesProcessor, data.copy(processingOriginalDeclarations = true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitVariable(declaration: IrVariable, data: Data) {
|
||||||
|
if (!data.processingOriginalDeclarations) return super.visitVariable(declaration, data)
|
||||||
|
|
||||||
|
val varName = declaration.name.asString()
|
||||||
|
val varSuffix = when {
|
||||||
|
inlinedStack.size == 1 && !varName.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) -> INLINE_FUN_VAR_SUFFIX
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
val newName = when {
|
||||||
|
varSuffix.isNotEmpty() && varName == SpecialNames.THIS.asStringStripSpecialMarkers() -> "this_"
|
||||||
|
else -> varName
|
||||||
|
}
|
||||||
|
declaration.name = Name.identifier(newName + varSuffix)
|
||||||
|
super.visitVariable(declaration, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FunctionParametersProcessor : IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBlock(expression: IrBlock) {
|
||||||
|
if (expression !is IrInlinedFunctionBlock) {
|
||||||
|
return super.visitBlock(expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
super.visitBlock(expression)
|
||||||
|
expression.getAdditionalStatementsFromInlinedBlock().forEach {
|
||||||
|
it.processFunctionParameter(expression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrStatement.processFunctionParameter(inlinedBlock: IrInlinedFunctionBlock) {
|
||||||
|
if (this !is IrVariable || !this.isTmpForInline) return
|
||||||
|
|
||||||
|
val varName = this.name.asString().substringAfterLast("_")
|
||||||
|
val varNewName = when {
|
||||||
|
this.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_EXTENSION_RECEIVER -> {
|
||||||
|
val functionName = (inlinedBlock.inlineDeclaration as? IrDeclarationWithName)?.name
|
||||||
|
functionName?.let { name -> "\$this$$name" } ?: AsmUtil.RECEIVER_PARAMETER_NAME
|
||||||
|
}
|
||||||
|
varName == SpecialNames.THIS.asStringStripSpecialMarkers() -> "this_"
|
||||||
|
else -> varName
|
||||||
|
}
|
||||||
|
this.name = Name.identifier(varNewName + INLINE_FUN_VAR_SUFFIX)
|
||||||
|
this.origin = IrDeclarationOrigin.DEFINED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
// IGNORE_INLINER: IR
|
||||||
|
// FILE: test.kt
|
||||||
|
class Foo {
|
||||||
|
var bar = ""
|
||||||
|
|
||||||
|
inline fun inlineCall(action: (complete: () -> Unit) -> Unit) {
|
||||||
|
action {
|
||||||
|
bar += "K"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start() {
|
||||||
|
inlineCall {
|
||||||
|
bar += "O"
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() {
|
||||||
|
val foo = Foo()
|
||||||
|
foo.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:21 box:
|
||||||
|
// test.kt:3 <init>:
|
||||||
|
// test.kt:4 <init>:
|
||||||
|
// EXPECTATIONS JVM_IR
|
||||||
|
// test.kt:3 <init>:
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:21 box:
|
||||||
|
// test.kt:22 box: foo:Foo=Foo
|
||||||
|
// test.kt:13 start:
|
||||||
|
// test.kt:7 start: this_$iv:Foo=Foo, $i$f$inlineCall:int=0:int
|
||||||
|
// test.kt:14 start: this_$iv:Foo=Foo, $i$f$inlineCall:int=0:int, it:kotlin.jvm.functions.Function0=Foo$inlineCall$1, $i$a$-inlineCall-Foo$start$1:int=0:int
|
||||||
|
// test.kt:15 start: this_$iv:Foo=Foo, $i$f$inlineCall:int=0:int, it:kotlin.jvm.functions.Function0=Foo$inlineCall$1, $i$a$-inlineCall-Foo$start$1:int=0:int
|
||||||
|
// test.kt:8 invoke:
|
||||||
|
// test.kt:4 getBar:
|
||||||
|
// test.kt:8 invoke:
|
||||||
|
// test.kt:4 setBar: <set-?>:java.lang.String="OK":java.lang.String
|
||||||
|
// test.kt:9 invoke:
|
||||||
|
// test.kt:15 start: this_$iv:Foo=Foo, $i$f$inlineCall:int=0:int, it:kotlin.jvm.functions.Function0=Foo$inlineCall$1, $i$a$-inlineCall-Foo$start$1:int=0:int
|
||||||
|
// test.kt:16 start: this_$iv:Foo=Foo, $i$f$inlineCall:int=0:int, it:kotlin.jvm.functions.Function0=Foo$inlineCall$1, $i$a$-inlineCall-Foo$start$1:int=0:int
|
||||||
|
// test.kt:7 start: this_$iv:Foo=Foo, $i$f$inlineCall:int=0:int
|
||||||
|
// test.kt:10 start: this_$iv:Foo=Foo, $i$f$inlineCall:int=0:int
|
||||||
|
// test.kt:17 start:
|
||||||
|
// test.kt:23 box: foo:Foo=Foo
|
||||||
|
|
||||||
|
// EXPECTATIONS JS_IR
|
||||||
|
// test.kt:21 box:
|
||||||
|
// test.kt:4 <init>:
|
||||||
|
// test.kt:3 <init>:
|
||||||
|
// test.kt:22 box: foo=Foo
|
||||||
|
// test.kt:14 start:
|
||||||
|
// test.kt:8 start:
|
||||||
|
// test.kt:17 start:
|
||||||
|
// test.kt:23 box: foo=Foo
|
||||||
+30
-29
@@ -1,3 +1,4 @@
|
|||||||
|
// IGNORE_INLINER: IR
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
|
|
||||||
@@ -29,43 +30,43 @@ suspend fun box() {
|
|||||||
// FIXME(JS_IR): KT-54657
|
// FIXME(JS_IR): KT-54657
|
||||||
|
|
||||||
// EXPECTATIONS JVM JVM_IR
|
// EXPECTATIONS JVM JVM_IR
|
||||||
// test.kt:25 box:
|
// test.kt:26 box:
|
||||||
// test.kt:26 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
// test.kt:27 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
// test.kt:19 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
// test.kt:20 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
||||||
// EXPECTATIONS JVM
|
// EXPECTATIONS JVM
|
||||||
// test.kt:19 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
// test.kt:20 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
||||||
// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
|
||||||
// EXPECTATIONS JVM JVM_IR
|
|
||||||
// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
|
||||||
// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
||||||
// test.kt:6 getValue:
|
// EXPECTATIONS JVM JVM_IR
|
||||||
// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
||||||
// test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
// test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
||||||
// test.kt:20 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
// test.kt:7 getValue:
|
||||||
// test.kt:21 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$suspendBar$2$iv:int=0:int
|
// test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
||||||
|
// test.kt:17 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $this$extensionFun$iv$iv:AtomicInt=AtomicInt, $i$f$extensionFun:int=0:int
|
||||||
// EXPECTATIONS ClassicFrontend JVM JVM_IR
|
// test.kt:21 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
||||||
// test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$suspendBar$2$iv:int=0:int
|
// test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$suspendBar$2$iv:int=0:int
|
||||||
|
|
||||||
|
// EXPECTATIONS ClassicFrontend JVM JVM_IR
|
||||||
|
// test.kt:23 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$suspendBar$2$iv:int=0:int
|
||||||
|
|
||||||
// EXPECTATIONS ClassicFrontend FIR JVM JVM_IR
|
// EXPECTATIONS ClassicFrontend FIR JVM JVM_IR
|
||||||
// test.kt:20 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
// test.kt:21 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
||||||
// test.kt:23 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
// test.kt:24 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$suspendBar:int=0:int
|
||||||
// test.kt:26 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
|
||||||
// test.kt:27 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
// test.kt:27 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
// test.kt:28 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
|
||||||
// EXPECTATIONS JS_IR
|
// EXPECTATIONS JS_IR
|
||||||
// test.kt:19 doResume:
|
// test.kt:20 doResume:
|
||||||
// test.kt:10 <init properties test.kt>:
|
|
||||||
// test.kt:8 atomic: i=0:number
|
|
||||||
// test.kt:6 <init>: value=0:number
|
|
||||||
// test.kt:6 <init>: value=0:number
|
|
||||||
// test.kt:11 <init properties test.kt>:
|
// test.kt:11 <init properties test.kt>:
|
||||||
// test.kt:10 <get-state>$accessor$1gle43a:
|
// test.kt:9 atomic: i=0:number
|
||||||
// test.kt:10 <get-state>:
|
// test.kt:7 <init>: value=0:number
|
||||||
// test.kt:14 doResume:
|
// test.kt:7 <init>: value=0:number
|
||||||
// test.kt:11 <get-a>$accessor$1gle43a:
|
// test.kt:12 <init properties test.kt>:
|
||||||
// test.kt:11 <get-a>:
|
// test.kt:11 <get-state>$accessor$1gle43a:
|
||||||
// test.kt:37 doResume:
|
// test.kt:11 <get-state>:
|
||||||
// test.kt:37 doResume:
|
// test.kt:15 doResume:
|
||||||
// test.kt:26 doResume:
|
// test.kt:12 <get-a>$accessor$1gle43a:
|
||||||
// test.kt:27 doResume: a=Unit
|
// test.kt:12 <get-a>:
|
||||||
|
// test.kt:38 doResume:
|
||||||
|
// test.kt:38 doResume:
|
||||||
|
// test.kt:27 doResume:
|
||||||
|
// test.kt:28 doResume: a=Unit
|
||||||
|
|||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
// IGNORE_INLINER: IR
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
import kotlin.coroutines.intrinsics.*
|
||||||
|
|
||||||
|
fun id(obj: Any) = obj
|
||||||
|
|
||||||
|
public suspend inline fun foo() {
|
||||||
|
suspendCoroutineUninterceptedOrReturn<Any?> { ucont ->
|
||||||
|
bar {
|
||||||
|
val b = 2
|
||||||
|
id(b)
|
||||||
|
}
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public inline fun bar(block: () -> Unit) {
|
||||||
|
val c = 1
|
||||||
|
id(c)
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
|
||||||
|
public suspend inline fun baz() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun box() {
|
||||||
|
val a = baz()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:29 box:
|
||||||
|
// test.kt:30 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
// test.kt:26 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int
|
||||||
|
// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int
|
||||||
|
// test.kt:20 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int
|
||||||
|
// test.kt:21 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int
|
||||||
|
// test.kt:7 id: obj:java.lang.Object=java.lang.Integer
|
||||||
|
// test.kt:21 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int
|
||||||
|
// test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int
|
||||||
|
// test.kt:12 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int, $i$a$-bar-TestKt$foo$2$1$iv$iv:int=0:int
|
||||||
|
// test.kt:13 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int, $i$a$-bar-TestKt$foo$2$1$iv$iv:int=0:int, b$iv$iv:int=2:int
|
||||||
|
// test.kt:7 id: obj:java.lang.Object=java.lang.Integer
|
||||||
|
// test.kt:13 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int, $i$a$-bar-TestKt$foo$2$1$iv$iv:int=0:int, b$iv$iv:int=2:int
|
||||||
|
// EXPECTATIONS JVM_IR
|
||||||
|
// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int, $i$a$-bar-TestKt$foo$2$1$iv$iv:int=0:int, b$iv$iv:int=2:int
|
||||||
|
// EXPECTATIONS JVM
|
||||||
|
// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int, $i$a$-bar-TestKt$foo$2$1$iv$iv:int=0:int
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int
|
||||||
|
// test.kt:23 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int, $i$f$bar:int=0:int, c$iv$iv$iv:int=1:int
|
||||||
|
// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int
|
||||||
|
// EXPECTATIONS ClassicFrontend JVM JVM_IR
|
||||||
|
// test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv:int=0:int
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:17 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:27 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int
|
||||||
|
// test.kt:30 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
// test.kt:31 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
|
||||||
|
// EXPECTATIONS JS_IR
|
||||||
|
// test.kt:20 doResume:
|
||||||
|
// test.kt:21 doResume: c=1:number
|
||||||
|
// test.kt:7 id: obj=1:number
|
||||||
|
// test.kt:12 doResume: c=1:number
|
||||||
|
// test.kt:13 doResume: c=1:number, b=2:number
|
||||||
|
// test.kt:7 id: obj=2:number
|
||||||
|
// test.kt:38 doResume: c=1:number, b=2:number
|
||||||
|
// test.kt:38 doResume: c=1:number, b=2:number
|
||||||
|
// test.kt:30 doResume: c=1:number, b=2:number
|
||||||
|
// test.kt:31 doResume: c=1:number, b=2:number, a=Unit
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// IGNORE_INLINER: IR
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
import kotlin.coroutines.intrinsics.*
|
||||||
|
|
||||||
|
private suspend inline fun foo() {
|
||||||
|
suspendCoroutineUninterceptedOrReturn<Any?> { ucont ->
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend inline fun bar() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend inline fun baz() {
|
||||||
|
bar()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun box() {
|
||||||
|
val a = baz()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:21 box:
|
||||||
|
// test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
// test.kt:18 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int
|
||||||
|
// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int
|
||||||
|
// test.kt:8 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:9 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int
|
||||||
|
// EXPECTATIONS ClassicFrontend JVM JVM_IR
|
||||||
|
// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:8 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int
|
||||||
|
// test.kt:19 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int
|
||||||
|
// test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
// test.kt:23 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
|
||||||
|
// EXPECTATIONS JS_IR
|
||||||
|
// test.kt:31 doResume:
|
||||||
|
// test.kt:31 doResume:
|
||||||
|
// test.kt:22 doResume:
|
||||||
|
// test.kt:23 doResume: a=Unit
|
||||||
Vendored
+107
@@ -0,0 +1,107 @@
|
|||||||
|
// IGNORE_INLINER: IR
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
import kotlin.coroutines.intrinsics.*
|
||||||
|
|
||||||
|
fun id(obj: Any) = obj
|
||||||
|
|
||||||
|
private suspend inline fun foo(crossinline block: () -> Unit) {
|
||||||
|
val a = 1
|
||||||
|
id(a)
|
||||||
|
suspendCoroutineUninterceptedOrReturn<Any?> { ucont ->
|
||||||
|
val b = 2
|
||||||
|
id(b)
|
||||||
|
block()
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend inline fun bar(crossinline block: () -> Unit) {
|
||||||
|
val c = 3
|
||||||
|
id(c)
|
||||||
|
foo(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend inline fun baz(crossinline block: () -> Unit) {
|
||||||
|
val d = 4
|
||||||
|
id(d)
|
||||||
|
bar(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun box() {
|
||||||
|
val result = baz() {
|
||||||
|
val e = 5
|
||||||
|
id(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:32 box:
|
||||||
|
// test.kt:33 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
// test.kt:27 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int
|
||||||
|
// test.kt:28 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, d$iv:int=4:int
|
||||||
|
// test.kt:7 id: obj:java.lang.Object=java.lang.Integer
|
||||||
|
// test.kt:28 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, d$iv:int=4:int
|
||||||
|
// test.kt:29 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int
|
||||||
|
// test.kt:21 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int
|
||||||
|
// test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, c$iv$iv:int=3:int
|
||||||
|
// test.kt:7 id: obj:java.lang.Object=java.lang.Integer
|
||||||
|
// test.kt:22 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, c$iv$iv:int=3:int
|
||||||
|
// test.kt:23 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int
|
||||||
|
// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, a$iv$iv$iv:int=1:int
|
||||||
|
// test.kt:7 id: obj:java.lang.Object=java.lang.Integer
|
||||||
|
// test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, a$iv$iv$iv:int=1:int
|
||||||
|
// test.kt:12 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:13 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int
|
||||||
|
// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int
|
||||||
|
// test.kt:7 id: obj:java.lang.Object=java.lang.Integer
|
||||||
|
// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int
|
||||||
|
// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int
|
||||||
|
// test.kt:34 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int, $i$a$-baz-TestKt$box$result$1:int=0:int
|
||||||
|
// test.kt:35 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int, $i$a$-baz-TestKt$box$result$1:int=0:int, e:int=5:int
|
||||||
|
// test.kt:7 id: obj:java.lang.Object=java.lang.Integer
|
||||||
|
// test.kt:35 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int, $i$a$-baz-TestKt$box$result$1:int=0:int, e:int=5:int
|
||||||
|
// EXPECTATIONS JVM_IR
|
||||||
|
// test.kt:36 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int, $i$a$-baz-TestKt$box$result$1:int=0:int, e:int=5:int
|
||||||
|
// EXPECTATIONS JVM
|
||||||
|
// test.kt:36 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int, $i$a$-baz-TestKt$box$result$1:int=0:int
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int
|
||||||
|
// test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int
|
||||||
|
// EXPECTATIONS ClassicFrontend JVM_IR
|
||||||
|
// test.kt:17 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int, b$iv$iv$iv:int=2:int
|
||||||
|
// EXPECTATIONS FIR JVM_IR
|
||||||
|
// test.kt:12 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// EXPECTATIONS JVM
|
||||||
|
// test.kt:17 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int, $i$a$-suspendCoroutineUninterceptedOrReturn-TestKt$foo$2$iv$iv$iv:int=0:int
|
||||||
|
// EXPECTATIONS ClassicFrontend JVM JVM_IR
|
||||||
|
// test.kt:12 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:18 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int, $i$f$foo:int=0:int
|
||||||
|
// test.kt:24 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int, $i$f$bar:int=0:int
|
||||||
|
// test.kt:30 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$baz:int=0:int
|
||||||
|
// test.kt:33 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
// test.kt:37 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null
|
||||||
|
|
||||||
|
// EXPECTATIONS JS_IR
|
||||||
|
// test.kt:27 doResume:
|
||||||
|
// test.kt:28 doResume:
|
||||||
|
// test.kt:7 id: obj=4:number
|
||||||
|
// test.kt:21 doResume:
|
||||||
|
// test.kt:22 doResume:
|
||||||
|
// test.kt:7 id: obj=3:number
|
||||||
|
// test.kt:10 doResume:
|
||||||
|
// test.kt:11 doResume:
|
||||||
|
// test.kt:7 id: obj=1:number
|
||||||
|
// test.kt:13 doResume:
|
||||||
|
// test.kt:14 doResume: b=2:number
|
||||||
|
// test.kt:7 id: obj=2:number
|
||||||
|
// test.kt:34 doResume: b=2:number
|
||||||
|
// test.kt:35 doResume: b=2:number, e=5:number
|
||||||
|
// test.kt:7 id: obj=5:number
|
||||||
|
// test.kt:44 doResume: b=2:number, e=5:number
|
||||||
|
// test.kt:44 doResume: b=2:number, e=5:number
|
||||||
|
// test.kt:33 doResume: b=2:number, e=5:number
|
||||||
|
// test.kt:37 doResume: b=2:number, e=5:number, result=Unit
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// JVM backend has `a` visible in the `compute` finally block. It shouldn't be.
|
// IGNORE_INLINER: IR
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
// IGNORE_INLINER: IR
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
inline fun g(block: () -> Unit) {
|
||||||
|
try {
|
||||||
|
val gLocal = "gLocal"
|
||||||
|
block()
|
||||||
|
} finally {
|
||||||
|
val g = "g"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var x: String? = null
|
||||||
|
|
||||||
|
fun compute(): String {
|
||||||
|
try {
|
||||||
|
g {
|
||||||
|
for (b in listOf("b")) {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
x = "OK"
|
||||||
|
}
|
||||||
|
return "FAIL"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() {
|
||||||
|
val result = compute()
|
||||||
|
val localX = x
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTATIONS JVM JVM_IR
|
||||||
|
// test.kt:30 box:
|
||||||
|
// test.kt:17 compute:
|
||||||
|
// test.kt:18 compute:
|
||||||
|
// test.kt:6 compute: $i$f$g:int=0:int
|
||||||
|
// test.kt:7 compute: $i$f$g:int=0:int
|
||||||
|
// test.kt:8 compute: $i$f$g:int=0:int, gLocal$iv:java.lang.String="gLocal":java.lang.String
|
||||||
|
// test.kt:19 compute: $i$f$g:int=0:int, gLocal$iv:java.lang.String="gLocal":java.lang.String, $i$a$-g-TestKt$compute$1:int=0:int
|
||||||
|
// test.kt:20 compute: $i$f$g:int=0:int, gLocal$iv:java.lang.String="gLocal":java.lang.String, $i$a$-g-TestKt$compute$1:int=0:int, b:java.lang.String="b":java.lang.String
|
||||||
|
// test.kt:10 compute:
|
||||||
|
// test.kt:24 compute:
|
||||||
|
// test.kt:30 box:
|
||||||
|
// test.kt:31 box: result:java.lang.String="b":java.lang.String
|
||||||
|
// test.kt:32 box: result:java.lang.String="b":java.lang.String, localX:java.lang.String="OK":java.lang.String
|
||||||
|
|
||||||
|
// EXPECTATIONS JS_IR
|
||||||
|
// test.kt:30 box:
|
||||||
|
// test.kt:7 compute:
|
||||||
|
// test.kt:19 compute: gLocal="gLocal":kotlin.String
|
||||||
|
// test.kt:19 compute: gLocal="gLocal":kotlin.String
|
||||||
|
// test.kt:19 compute: gLocal="gLocal":kotlin.String
|
||||||
|
// test.kt:19 compute: gLocal="gLocal":kotlin.String
|
||||||
|
// test.kt:20 compute: gLocal="gLocal":kotlin.String, b="b":kotlin.String
|
||||||
|
// test.kt:10 compute: gLocal="gLocal":kotlin.String, b="b":kotlin.String
|
||||||
|
// test.kt:24 compute: gLocal="gLocal":kotlin.String, b="b":kotlin.String, g="g":kotlin.String
|
||||||
+485
@@ -0,0 +1,485 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.test.runners.codegen;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.test.generators.GenerateCompilerTestsKt}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("compiler/testData/debug/localVariables")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class IrLocalVariableBytecodeInlinerTestGenerated extends AbstractIrLocalVariableBytecodeInlinerTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInLocalVariables() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/debug/localVariables"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("assignment.kt")
|
||||||
|
public void testAssignment() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/assignment.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("catchClause.kt")
|
||||||
|
public void testCatchClause() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/catchClause.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("copyFunction.kt")
|
||||||
|
public void testCopyFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/copyFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("directInvoke.kt")
|
||||||
|
public void testDirectInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/directInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("doWhile.kt")
|
||||||
|
public void testDoWhile() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/doWhile.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("emptyFun.kt")
|
||||||
|
public void testEmptyFun() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/emptyFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("forLoopMultiline.kt")
|
||||||
|
public void testForLoopMultiline() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/forLoopMultiline.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineProperty.kt")
|
||||||
|
public void testInlineProperty() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/inlineProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("jvmOverloads.kt")
|
||||||
|
public void testJvmOverloads() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithLambdaParameter.kt")
|
||||||
|
public void testLambdaWithLambdaParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/lambdaWithLambdaParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localFun.kt")
|
||||||
|
public void testLocalFun() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/localFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localFunUnused.kt")
|
||||||
|
public void testLocalFunUnused() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/localFunUnused.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally.kt")
|
||||||
|
public void testTryFinally() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally10.kt")
|
||||||
|
public void testTryFinally10() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally10.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally11.kt")
|
||||||
|
public void testTryFinally11() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally11.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally12.kt")
|
||||||
|
public void testTryFinally12() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally12.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally13.kt")
|
||||||
|
public void testTryFinally13() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally13.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally14.kt")
|
||||||
|
public void testTryFinally14() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally14.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally15.kt")
|
||||||
|
public void testTryFinally15() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally15.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally16.kt")
|
||||||
|
public void testTryFinally16() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally16.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally17.kt")
|
||||||
|
public void testTryFinally17() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally17.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally2.kt")
|
||||||
|
public void testTryFinally2() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally3.kt")
|
||||||
|
public void testTryFinally3() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally4.kt")
|
||||||
|
public void testTryFinally4() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally4.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally5.kt")
|
||||||
|
public void testTryFinally5() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally5.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally6_1.kt")
|
||||||
|
public void testTryFinally6_1() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally6_1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally6_2.kt")
|
||||||
|
public void testTryFinally6_2() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally6_2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally7.kt")
|
||||||
|
public void testTryFinally7() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally7.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally8.kt")
|
||||||
|
public void testTryFinally8() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally8.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally9.kt")
|
||||||
|
public void testTryFinally9() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally9.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("underscoreNames.kt")
|
||||||
|
public void testUnderscoreNames() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/underscoreNames.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/debug/localVariables/constructors")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Constructors {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInConstructors() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/debug/localVariables/constructors"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleConstructors.kt")
|
||||||
|
public void testMultipleConstructors() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/constructors/multipleConstructors.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("property.kt")
|
||||||
|
public void testProperty() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/constructors/property.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/debug/localVariables/destructuring")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Destructuring {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInDestructuring() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/debug/localVariables/destructuring"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("assignment.kt")
|
||||||
|
public void testAssignment() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/assignment.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("assignmentCustomComponentNs.kt")
|
||||||
|
public void testAssignmentCustomComponentNs() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/assignmentCustomComponentNs.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("assignmentCustomComponentNsMultiline.kt")
|
||||||
|
public void testAssignmentCustomComponentNsMultiline() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/assignmentCustomComponentNsMultiline.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("assignmentMultiline.kt")
|
||||||
|
public void testAssignmentMultiline() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/assignmentMultiline.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("assignmentUnderscoreNames.kt")
|
||||||
|
public void testAssignmentUnderscoreNames() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/assignmentUnderscoreNames.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("assignmentUnderscoreNamesMultiline.kt")
|
||||||
|
public void testAssignmentUnderscoreNamesMultiline() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/assignmentUnderscoreNamesMultiline.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("forLoop.kt")
|
||||||
|
public void testForLoop() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/forLoop.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("forLoopMultiline.kt")
|
||||||
|
public void testForLoopMultiline() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/forLoopMultiline.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambda.kt")
|
||||||
|
public void testLambda() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/lambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaCustomComponentNs.kt")
|
||||||
|
public void testLambdaCustomComponentNs() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/lambdaCustomComponentNs.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaCustomComponentNsMultiline.kt")
|
||||||
|
public void testLambdaCustomComponentNsMultiline() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/lambdaCustomComponentNsMultiline.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaMultiline.kt")
|
||||||
|
public void testLambdaMultiline() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/lambdaMultiline.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaMultipleDestructs.kt")
|
||||||
|
public void testLambdaMultipleDestructs() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/destructuring/lambdaMultipleDestructs.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/debug/localVariables/receiverMangling")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class ReceiverMangling {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInReceiverMangling() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/debug/localVariables/receiverMangling"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("capturedThisField.kt")
|
||||||
|
public void testCapturedThisField() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/receiverMangling/capturedThisField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("labeledThisParameterLabel.kt")
|
||||||
|
public void testLabeledThisParameterLabel() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/receiverMangling/labeledThisParameterLabel.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithExtensionReceiver.kt")
|
||||||
|
public void testLambdaWithExtensionReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/receiverMangling/lambdaWithExtensionReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("receiverParameter.kt")
|
||||||
|
public void testReceiverParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/receiverMangling/receiverParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/receiverMangling/simple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("simpleCapturedReceiver.kt")
|
||||||
|
public void testSimpleCapturedReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/receiverMangling/simpleCapturedReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("simpleCapturedReceiverWithLabel.kt")
|
||||||
|
public void testSimpleCapturedReceiverWithLabel() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/receiverMangling/simpleCapturedReceiverWithLabel.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("simpleCapturedReceiverWithParenthesis.kt")
|
||||||
|
public void testSimpleCapturedReceiverWithParenthesis() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/receiverMangling/simpleCapturedReceiverWithParenthesis.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/debug/localVariables/suspend")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Suspend {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSuspend() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/debug/localVariables/suspend"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineLocalsStateMachineTransform.kt")
|
||||||
|
public void testInlineLocalsStateMachineTransform() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/inlineLocalsStateMachineTransform.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localsStateMachineTransform.kt")
|
||||||
|
public void testLocalsStateMachineTransform() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mergeLvt.kt")
|
||||||
|
public void testMergeLvt() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedInsideSuspendUnintercepted.kt")
|
||||||
|
public void testNestedInsideSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedInsideSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUnintercepted.kt")
|
||||||
|
public void testNestedSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUninterceptedWithDeepLambdaCall.kt")
|
||||||
|
public void testNestedSuspendUninterceptedWithDeepLambdaCall() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUninterceptedWithDeepLambdaCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/simple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("underscoreNames.kt")
|
||||||
|
public void testUnderscoreNames() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/underscoreNames.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/debug/localVariables/suspend/completion")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Completion {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInCompletion() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/debug/localVariables/suspend/completion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonStaticSimple.kt")
|
||||||
|
public void testNonStaticSimple() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/completion/nonStaticSimple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonStaticStateMachine.kt")
|
||||||
|
public void testNonStaticStateMachine() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/completion/nonStaticStateMachine.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("staticSimple.kt")
|
||||||
|
public void testStaticSimple() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/completion/staticSimple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("staticSimpleReceiver.kt")
|
||||||
|
public void testStaticSimpleReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/completion/staticSimpleReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("staticStateMachine.kt")
|
||||||
|
public void testStaticStateMachine() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/completion/staticStateMachine.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("staticStateMachineReceiver.kt")
|
||||||
|
public void testStaticStateMachineReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/completion/staticStateMachineReceiver.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+34
-4
@@ -19,7 +19,7 @@ import java.util.regex.Pattern;
|
|||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("compiler/testData/debug/localVariables")
|
@TestMetadata("compiler/testData/debug/localVariables")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest {
|
public class IrLocalVariableIrInlinerTestGenerated extends AbstractIrLocalVariableIrInlinerTest {
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInLocalVariables() throws Exception {
|
public void testAllFilesPresentInLocalVariables() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/debug/localVariables"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/debug/localVariables"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
@@ -79,6 +79,12 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest {
|
|||||||
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithLambdaParameter.kt")
|
||||||
|
public void testLambdaWithLambdaParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/lambdaWithLambdaParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localFun.kt")
|
@TestMetadata("localFun.kt")
|
||||||
public void testLocalFun() throws Exception {
|
public void testLocalFun() throws Exception {
|
||||||
@@ -170,9 +176,15 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("tryFinally6.kt")
|
@TestMetadata("tryFinally6_1.kt")
|
||||||
public void testTryFinally6() throws Exception {
|
public void testTryFinally6_1() throws Exception {
|
||||||
runTest("compiler/testData/debug/localVariables/tryFinally6.kt");
|
runTest("compiler/testData/debug/localVariables/tryFinally6_1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally6_2.kt")
|
||||||
|
public void testTryFinally6_2() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally6_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -394,6 +406,24 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest {
|
|||||||
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedInsideSuspendUnintercepted.kt")
|
||||||
|
public void testNestedInsideSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedInsideSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUnintercepted.kt")
|
||||||
|
public void testNestedSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUninterceptedWithDeepLambdaCall.kt")
|
||||||
|
public void testNestedSuspendUninterceptedWithDeepLambdaCall() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUninterceptedWithDeepLambdaCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
+33
-3
@@ -79,6 +79,12 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest {
|
|||||||
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
runTest("compiler/testData/debug/localVariables/jvmOverloads.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithLambdaParameter.kt")
|
||||||
|
public void testLambdaWithLambdaParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/lambdaWithLambdaParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localFun.kt")
|
@TestMetadata("localFun.kt")
|
||||||
public void testLocalFun() throws Exception {
|
public void testLocalFun() throws Exception {
|
||||||
@@ -170,9 +176,15 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("tryFinally6.kt")
|
@TestMetadata("tryFinally6_1.kt")
|
||||||
public void testTryFinally6() throws Exception {
|
public void testTryFinally6_1() throws Exception {
|
||||||
runTest("compiler/testData/debug/localVariables/tryFinally6.kt");
|
runTest("compiler/testData/debug/localVariables/tryFinally6_1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally6_2.kt")
|
||||||
|
public void testTryFinally6_2() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally6_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -394,6 +406,24 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest {
|
|||||||
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedInsideSuspendUnintercepted.kt")
|
||||||
|
public void testNestedInsideSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedInsideSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUnintercepted.kt")
|
||||||
|
public void testNestedSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUninterceptedWithDeepLambdaCall.kt")
|
||||||
|
public void testNestedSuspendUninterceptedWithDeepLambdaCall() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUninterceptedWithDeepLambdaCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
|
|||||||
+9
-1
@@ -6,13 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.test.runners.codegen
|
package org.jetbrains.kotlin.test.runners.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.Constructor
|
import org.jetbrains.kotlin.test.Constructor
|
||||||
|
import org.jetbrains.kotlin.test.FirParser
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
|
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
|
||||||
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
|
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
|
||||||
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||||
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
|
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
|
||||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
import org.jetbrains.kotlin.test.FirParser
|
|
||||||
import org.jetbrains.kotlin.test.directives.configureFirParser
|
import org.jetbrains.kotlin.test.directives.configureFirParser
|
||||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
|
||||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
|
||||||
@@ -42,6 +42,14 @@ open class AbstractIrLocalVariableTest : AbstractLocalVariableTestBase<ClassicFr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class AbstractIrLocalVariableBytecodeInlinerTest : AbstractIrLocalVariableTest()
|
||||||
|
open class AbstractIrLocalVariableIrInlinerTest : AbstractIrLocalVariableTest() {
|
||||||
|
override fun configure(builder: TestConfigurationBuilder) {
|
||||||
|
super.configure(builder)
|
||||||
|
builder.useIrInliner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open class AbstractLocalVariableTest : AbstractLocalVariableTestBase<ClassicFrontendOutputArtifact, ClassicBackendInput>(
|
open class AbstractLocalVariableTest : AbstractLocalVariableTestBase<ClassicFrontendOutputArtifact, ClassicBackendInput>(
|
||||||
FrontendKinds.ClassicFrontend,
|
FrontendKinds.ClassicFrontend,
|
||||||
TargetBackend.JVM
|
TargetBackend.JVM
|
||||||
|
|||||||
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.test.runners.codegen
|
|||||||
import org.jetbrains.kotlin.test.Constructor
|
import org.jetbrains.kotlin.test.Constructor
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
||||||
|
import org.jetbrains.kotlin.test.backend.BlackBoxInlinerCodegenSuppressor
|
||||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.REQUIRES_SEPARATE_PROCESS
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.REQUIRES_SEPARATE_PROCESS
|
||||||
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.REPORT_ONLY_EXPLICITLY_DEFINED_DEBUG_INFO
|
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.REPORT_ONLY_EXPLICITLY_DEFINED_DEBUG_INFO
|
||||||
@@ -29,7 +30,7 @@ abstract class AbstractLocalVariableTestBase<R : ResultingArtifact.FrontendOutpu
|
|||||||
|
|
||||||
configureCommonHandlersForLocalVariableTest()
|
configureCommonHandlersForLocalVariableTest()
|
||||||
|
|
||||||
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
|
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor, ::BlackBoxInlinerCodegenSuppressor)
|
||||||
|
|
||||||
defaultDirectives {
|
defaultDirectives {
|
||||||
+REPORT_ONLY_EXPLICITLY_DEFINED_DEBUG_INFO
|
+REPORT_ONLY_EXPLICITLY_DEFINED_DEBUG_INFO
|
||||||
|
|||||||
+5
-1
@@ -103,7 +103,11 @@ fun generateJUnit5CompilerTests(args: Array<String>) {
|
|||||||
model("debug/localVariables")
|
model("debug/localVariables")
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractIrLocalVariableTest> {
|
testClass<AbstractIrLocalVariableBytecodeInlinerTest> {
|
||||||
|
model("debug/localVariables")
|
||||||
|
}
|
||||||
|
|
||||||
|
testClass<AbstractIrLocalVariableIrInlinerTest> {
|
||||||
model("debug/localVariables")
|
model("debug/localVariables")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-3
@@ -79,6 +79,12 @@ public class IrJsLocalVariableTestGenerated extends AbstractIrJsLocalVariableTes
|
|||||||
runTest("compiler/testData/debug/localVariables/jsCode.kt");
|
runTest("compiler/testData/debug/localVariables/jsCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithLambdaParameter.kt")
|
||||||
|
public void testLambdaWithLambdaParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/lambdaWithLambdaParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("localFun.kt")
|
@TestMetadata("localFun.kt")
|
||||||
public void testLocalFun() throws Exception {
|
public void testLocalFun() throws Exception {
|
||||||
@@ -170,9 +176,15 @@ public class IrJsLocalVariableTestGenerated extends AbstractIrJsLocalVariableTes
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("tryFinally6.kt")
|
@TestMetadata("tryFinally6_1.kt")
|
||||||
public void testTryFinally6() throws Exception {
|
public void testTryFinally6_1() throws Exception {
|
||||||
runTest("compiler/testData/debug/localVariables/tryFinally6.kt");
|
runTest("compiler/testData/debug/localVariables/tryFinally6_1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("tryFinally6_2.kt")
|
||||||
|
public void testTryFinally6_2() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/tryFinally6_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -394,6 +406,24 @@ public class IrJsLocalVariableTestGenerated extends AbstractIrJsLocalVariableTes
|
|||||||
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
runTest("compiler/testData/debug/localVariables/suspend/mergeLvt.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedInsideSuspendUnintercepted.kt")
|
||||||
|
public void testNestedInsideSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedInsideSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUnintercepted.kt")
|
||||||
|
public void testNestedSuspendUnintercepted() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUnintercepted.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nestedSuspendUninterceptedWithDeepLambdaCall.kt")
|
||||||
|
public void testNestedSuspendUninterceptedWithDeepLambdaCall() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/localVariables/suspend/nestedSuspendUninterceptedWithDeepLambdaCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user