From 819a3a95b3749099d2d543b0ee2d4443b35f71bd Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 14 Dec 2017 17:41:49 +0100 Subject: [PATCH] Add support for contract feature in inliner --- .../kotlin/codegen/inline/FieldRemapper.kt | 7 +- .../kotlin/codegen/inline/MethodInliner.kt | 169 ++++++++++-------- .../boxInline/contracts/complexInitializer.kt | 28 +++ ...mplexInitializerWithStackTransformation.kt | 27 +++ .../definiteLongValInitialization.kt | 24 +++ .../definiteNestedValInitialization.kt | 27 +++ .../contracts/definiteValInitialization.kt | 25 +++ .../boxInline/contracts/nonLocalReturn.kt | 25 +++ .../contracts/nonLocalReturnWithCycle.kt | 39 ++++ .../contracts/propertyInitialization.kt | 30 ++++ ...valInitializationAndUsageInNestedLambda.kt | 29 +++ .../IrBlackBoxInlineCodegenTestGenerated.java | 63 +++++++ ...otlinAgainstInlineKotlinTestGenerated.java | 63 +++++++ .../BlackBoxInlineCodegenTestGenerated.java | 63 +++++++ ...otlinAgainstInlineKotlinTestGenerated.java | 63 +++++++ 15 files changed, 610 insertions(+), 72 deletions(-) create mode 100644 compiler/testData/codegen/boxInline/contracts/complexInitializer.kt create mode 100644 compiler/testData/codegen/boxInline/contracts/complexInitializerWithStackTransformation.kt create mode 100644 compiler/testData/codegen/boxInline/contracts/definiteLongValInitialization.kt create mode 100644 compiler/testData/codegen/boxInline/contracts/definiteNestedValInitialization.kt create mode 100644 compiler/testData/codegen/boxInline/contracts/definiteValInitialization.kt create mode 100644 compiler/testData/codegen/boxInline/contracts/nonLocalReturn.kt create mode 100644 compiler/testData/codegen/boxInline/contracts/nonLocalReturnWithCycle.kt create mode 100644 compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt create mode 100644 compiler/testData/codegen/boxInline/contracts/valInitializationAndUsageInNestedLambda.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt index 9a911f4d0af..3f557cd7993 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt @@ -68,7 +68,7 @@ open class FieldRemapper( val insnNode = capturedFieldAccess[currentInstruction] as FieldInsnNode if (canProcess(insnNode.owner, insnNode.name, true)) { - insnNode.name = CAPTURED_FIELD_FOLD_PREFIX + getFieldNameForFolding(insnNode) + insnNode.name = Companion.foldName(getFieldNameForFolding(insnNode)) insnNode.opcode = Opcodes.GETSTATIC node.remove(InsnSequence(capturedFieldAccess[0], insnNode)) @@ -95,4 +95,9 @@ open class FieldRemapper( open fun getFieldForInline(node: FieldInsnNode, prefix: StackValue?): StackValue? = MethodInliner.findCapturedField(node, this).remapValue + + companion object { + fun foldName(fieldName: String) = + CAPTURED_FIELD_FOLD_PREFIX + fieldName + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index 472ac7e531a..77bed77e8dc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.optimization.ApiVersionCallsPreprocessingMet import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful +import org.jetbrains.kotlin.codegen.optimization.fixStack.peek import org.jetbrains.kotlin.codegen.optimization.fixStack.top import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartSet @@ -410,85 +411,111 @@ class MethodInliner( val frame = sources[instructions.indexOf(cur)] if (frame != null) { - if (ReifiedTypeInliner.isNeedClassReificationMarker(cur)) { - awaitClassReification = true - } - else if (cur is MethodInsnNode) { - if (isFinallyStart(cur)) { - //TODO deep index calc could be more precise - currentFinallyDeep = getConstant(cur.previous) - } + when { + ReifiedTypeInliner.isNeedClassReificationMarker(cur) -> awaitClassReification = true - val owner = cur.owner - val name = cur.name - //TODO check closure - val argTypes = Type.getArgumentTypes(cur.desc) - val paramCount = argTypes.size + 1//non static - val firstParameterIndex = frame.stackSize - paramCount - if (isInvokeOnLambda(owner, name) /*&& methodInsnNode.owner.equals(INLINE_RUNTIME)*/) { - val sourceValue = frame.getStack(firstParameterIndex) - val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, true, instructions, sources, toDelete) - invokeCalls.add(InvokeCall(lambdaInfo, currentFinallyDeep)) - } - else if (isSamWrapperConstructorCall(owner, name)) { - transformations.add(SamWrapperTransformationInfo(owner, inliningContext, isAlreadyRegenerated(owner))) - } - else if (isAnonymousConstructorCall(owner, name)) { - val lambdaMapping = HashMap() - - var offset = 0 - var capturesAnonymousObjectThatMustBeRegenerated = false - for (i in 0 until paramCount) { - val sourceValue = frame.getStack(firstParameterIndex + i) - val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, false, instructions, sources, toDelete - ) - if (lambdaInfo != null) { - lambdaMapping.put(offset, lambdaInfo) - } - else if (i < argTypes.size && isAnonymousClassThatMustBeRegenerated(argTypes[i])) { - capturesAnonymousObjectThatMustBeRegenerated = true - } - - offset += if (i == 0) 1 else argTypes[i - 1].size + cur is MethodInsnNode -> { + if (isFinallyStart(cur)) { + //TODO deep index calc could be more precise + currentFinallyDeep = getConstant(cur.previous) } - transformations.add( - buildConstructorInvocation( - owner, cur.desc, lambdaMapping, awaitClassReification, capturesAnonymousObjectThatMustBeRegenerated + val owner = cur.owner + val name = cur.name + //TODO check closure + val argTypes = Type.getArgumentTypes(cur.desc) + val paramCount = argTypes.size + 1//non static + val firstParameterIndex = frame.stackSize - paramCount + if (isInvokeOnLambda(owner, name) /*&& methodInsnNode.owner.equals(INLINE_RUNTIME)*/) { + val sourceValue = frame.getStack(firstParameterIndex) + val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, true, instructions, sources, toDelete) + invokeCalls.add(InvokeCall(lambdaInfo, currentFinallyDeep)) + } + else if (isSamWrapperConstructorCall(owner, name)) { + transformations.add(SamWrapperTransformationInfo(owner, inliningContext, isAlreadyRegenerated(owner))) + } + else if (isAnonymousConstructorCall(owner, name)) { + val lambdaMapping = HashMap() + + var offset = 0 + var capturesAnonymousObjectThatMustBeRegenerated = false + for (i in 0 until paramCount) { + val sourceValue = frame.getStack(firstParameterIndex + i) + val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, false, instructions, sources, toDelete ) - ) - awaitClassReification = false + if (lambdaInfo != null) { + lambdaMapping.put(offset, lambdaInfo) + } + else if (i < argTypes.size && isAnonymousClassThatMustBeRegenerated(argTypes[i])) { + capturesAnonymousObjectThatMustBeRegenerated = true + } + + offset += if (i == 0) 1 else argTypes[i - 1].size + } + + transformations.add( + buildConstructorInvocation( + owner, cur.desc, lambdaMapping, awaitClassReification, capturesAnonymousObjectThatMustBeRegenerated + ) + ) + awaitClassReification = false + } + else if (inliningContext.isInliningLambda && ReifiedTypeInliner.isOperationReifiedMarker(cur)) { + val reificationArgument = cur.reificationArgument + val parameterName = reificationArgument!!.parameterName + result.reifiedTypeParametersUsages.addUsedReifiedParameter(parameterName) + } } - else if (inliningContext.isInliningLambda && ReifiedTypeInliner.isOperationReifiedMarker(cur)) { - val reificationArgument = cur.reificationArgument - val parameterName = reificationArgument!!.parameterName - result.reifiedTypeParametersUsages.addUsedReifiedParameter(parameterName) + + cur.opcode == Opcodes.GETSTATIC -> { + val fieldInsnNode = cur as FieldInsnNode? + val className = fieldInsnNode!!.owner + if (isAnonymousSingletonLoad(className, fieldInsnNode.name)) { + transformations.add( + AnonymousObjectTransformationInfo( + className, awaitClassReification, isAlreadyRegenerated(className), true, + inliningContext.nameGenerator + ) + ) + awaitClassReification = false + } + else if (isWhenMappingAccess(className, fieldInsnNode.name)) { + transformations.add( + WhenMappingTransformationInfo( + className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode + ) + ) + } } - } - else if (cur.opcode == Opcodes.GETSTATIC) { - val fieldInsnNode = cur as FieldInsnNode? - val className = fieldInsnNode!!.owner - if (isAnonymousSingletonLoad(className, fieldInsnNode.name)) { - transformations.add( - AnonymousObjectTransformationInfo( - className, awaitClassReification, isAlreadyRegenerated(className), true, - inliningContext.nameGenerator - ) - ) - awaitClassReification = false - } - else if (isWhenMappingAccess(className, fieldInsnNode.name)) { - transformations.add( - WhenMappingTransformationInfo( - className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode - ) - ) - } - } - else if (cur.opcode == Opcodes.POP) { - getLambdaIfExistsAndMarkInstructions(frame.top()!!, true, instructions, sources, toDelete)?.let { + + cur.opcode == Opcodes.POP -> getLambdaIfExistsAndMarkInstructions(frame.top()!!, true, instructions, sources, toDelete)?.let { toDelete.add(cur) } + + cur.opcode == Opcodes.PUTFIELD -> { + //Recognize next contract's pattern in inline lambda + // ALOAD 0 + // SOME_VALUE + // PUTFIELD $capturedField + // and transform it to + // SOME_VALUE + // PUTSTATIC $$$$capturedField + val fieldInsn = cur as FieldInsnNode + if (isCapturedFieldName(fieldInsn.name) && + nodeRemapper is InlinedLambdaRemapper && + nodeRemapper.originalLambdaInternalName == fieldInsn.owner) { + val stackTransformations = mutableSetOf() + val lambdaInfo = getLambdaIfExistsAndMarkInstructions(frame.peek(1)!!, false, instructions, sources, stackTransformations) + if (lambdaInfo != null && stackTransformations.all { it is VarInsnNode }) { + assert(lambdaInfo.lambdaClassType.internalName == nodeRemapper.originalLambdaInternalName) { + "Wrong bytecode template for contract template: ${lambdaInfo.lambdaClassType.internalName} != ${nodeRemapper.originalLambdaInternalName}" + } + fieldInsn.name = FieldRemapper.foldName(fieldInsn.name) + fieldInsn.opcode = Opcodes.PUTSTATIC + toDelete.addAll(stackTransformations) + } + } + } } } else { diff --git a/compiler/testData/codegen/boxInline/contracts/complexInitializer.kt b/compiler/testData/codegen/boxInline/contracts/complexInitializer.kt new file mode 100644 index 00000000000..f9f97f6fa42 --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/complexInitializer.kt @@ -0,0 +1,28 @@ +// !LANGUAGE: +CallsInPlaceEffect +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + +// FILE: 2.kt + +import test.* + +fun cond() = true +fun test(s: String) = s + +fun box(): String { + val x: String + myrun { + x = if (cond()) test("OK") else test("fail") + } + return x +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/contracts/complexInitializerWithStackTransformation.kt b/compiler/testData/codegen/boxInline/contracts/complexInitializerWithStackTransformation.kt new file mode 100644 index 00000000000..b27aaad5281 --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/complexInitializerWithStackTransformation.kt @@ -0,0 +1,27 @@ +// !LANGUAGE: +CallsInPlaceEffect +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + +// FILE: 2.kt + +import test.* + +fun test(s: String) = s + +fun box(): String { + val x: String + myrun { + x = try { test("OK") } catch (e: Exception) { test("fail") } + } + return x +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/contracts/definiteLongValInitialization.kt b/compiler/testData/codegen/boxInline/contracts/definiteLongValInitialization.kt new file mode 100644 index 00000000000..7a53af05a9f --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/definiteLongValInitialization.kt @@ -0,0 +1,24 @@ +// !LANGUAGE: +CallsInPlaceEffect +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + +// FILE: 2.kt +import test.* + +fun box(): String { + val x: Long + myrun { + x = 42L + } + return if (x.inc() == 43L) "OK" else "Fail: ${x.inc()}" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/contracts/definiteNestedValInitialization.kt b/compiler/testData/codegen/boxInline/contracts/definiteNestedValInitialization.kt new file mode 100644 index 00000000000..aa3955f2eb2 --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/definiteNestedValInitialization.kt @@ -0,0 +1,27 @@ +// !LANGUAGE: +CallsInPlaceEffect +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + + +// FILE: 2.kt +import test.* + +fun box(): String { + val x: Int + myrun { + myrun { + x = 42 + } + } + return if (x.inc() == 43) "OK" else "Fail: ${x.inc()}" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/contracts/definiteValInitialization.kt b/compiler/testData/codegen/boxInline/contracts/definiteValInitialization.kt new file mode 100644 index 00000000000..ec47b128aae --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/definiteValInitialization.kt @@ -0,0 +1,25 @@ +// !LANGUAGE: +CallsInPlaceEffect +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + + +// FILE: 2.kt +import test.* + +fun box(): String { + val x: Int + myrun { + x = 42 + } + return if (x.inc() == 43) "OK" else "Fail: ${x.inc()}" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/contracts/nonLocalReturn.kt b/compiler/testData/codegen/boxInline/contracts/nonLocalReturn.kt new file mode 100644 index 00000000000..b4c12b943bd --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/nonLocalReturn.kt @@ -0,0 +1,25 @@ +// !LANGUAGE: +CallsInPlaceEffect +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + +// FILE: 2.kt +import test.* + +fun box(): String { + val x: Long + myrun { + x = 42L + if (x == 42L) return "OK" + } + return "fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/contracts/nonLocalReturnWithCycle.kt b/compiler/testData/codegen/boxInline/contracts/nonLocalReturnWithCycle.kt new file mode 100644 index 00000000000..62f1bf7ab88 --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/nonLocalReturnWithCycle.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: +CallsInPlaceEffect +// WITH_RUNTIME +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + +// FILE: 2.kt +import test.* + +fun test(xs: List): String { + var result = "" + + myrun L@ { + for (x in xs) { + val y: String + myrun { + y = x + if (y.length > 1) return@L + } + result += y + } + } + + return result +} + + +fun box(): String { + return test(listOf("O", "K", "fail")) +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt b/compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt new file mode 100644 index 00000000000..c8216a5d0f7 --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt @@ -0,0 +1,30 @@ +// !LANGUAGE: +CallsInPlaceEffect +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + +// FILE: 2.kt + +import test.* + +class A { + val z: String + init { + myrun { + z = "OK" + } + } +} + +fun box(): String { + return A().z +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/contracts/valInitializationAndUsageInNestedLambda.kt b/compiler/testData/codegen/boxInline/contracts/valInitializationAndUsageInNestedLambda.kt new file mode 100644 index 00000000000..d7f18f91f4d --- /dev/null +++ b/compiler/testData/codegen/boxInline/contracts/valInitializationAndUsageInNestedLambda.kt @@ -0,0 +1,29 @@ +// !LANGUAGE: +CallsInPlaceEffect +// FILE: 1.kt +package test + +import kotlin.internal.contracts.* + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +public inline fun myrun(block: () -> R): R { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + + +// FILE: 2.kt +// NO_CHECK_LAMBDA_INLINING +import test.* + +fun box(): String { + val x: Int + val res = myrun { + x = 42 + { + x + }() + } + return if (res == 42 && x.inc() == 43) "OK" else "Fail: ${x.inc()}" +} \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index f0d2987c613..e7ddf18c6a1 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -1017,6 +1017,69 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli } } + @TestMetadata("compiler/testData/codegen/boxInline/contracts") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Contracts extends AbstractIrBlackBoxInlineCodegenTest { + public void testAllFilesPresentInContracts() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/contracts"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("complexInitializer.kt") + public void testComplexInitializer() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/complexInitializer.kt"); + doTest(fileName); + } + + @TestMetadata("complexInitializerWithStackTransformation.kt") + public void testComplexInitializerWithStackTransformation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/complexInitializerWithStackTransformation.kt"); + doTest(fileName); + } + + @TestMetadata("definiteLongValInitialization.kt") + public void testDefiniteLongValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteLongValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("definiteNestedValInitialization.kt") + public void testDefiniteNestedValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteNestedValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("definiteValInitialization.kt") + public void testDefiniteValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("nonLocalReturn.kt") + public void testNonLocalReturn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/nonLocalReturn.kt"); + doTest(fileName); + } + + @TestMetadata("nonLocalReturnWithCycle.kt") + public void testNonLocalReturnWithCycle() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/nonLocalReturnWithCycle.kt"); + doTest(fileName); + } + + @TestMetadata("propertyInitialization.kt") + public void testPropertyInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("valInitializationAndUsageInNestedLambda.kt") + public void testValInitializationAndUsageInNestedLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/valInitializationAndUsageInNestedLambda.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/defaultValues") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index c8accabf5e9..863fca86718 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1017,6 +1017,69 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC } } + @TestMetadata("compiler/testData/codegen/boxInline/contracts") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Contracts extends AbstractIrCompileKotlinAgainstInlineKotlinTest { + public void testAllFilesPresentInContracts() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/contracts"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("complexInitializer.kt") + public void testComplexInitializer() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/complexInitializer.kt"); + doTest(fileName); + } + + @TestMetadata("complexInitializerWithStackTransformation.kt") + public void testComplexInitializerWithStackTransformation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/complexInitializerWithStackTransformation.kt"); + doTest(fileName); + } + + @TestMetadata("definiteLongValInitialization.kt") + public void testDefiniteLongValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteLongValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("definiteNestedValInitialization.kt") + public void testDefiniteNestedValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteNestedValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("definiteValInitialization.kt") + public void testDefiniteValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("nonLocalReturn.kt") + public void testNonLocalReturn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/nonLocalReturn.kt"); + doTest(fileName); + } + + @TestMetadata("nonLocalReturnWithCycle.kt") + public void testNonLocalReturnWithCycle() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/nonLocalReturnWithCycle.kt"); + doTest(fileName); + } + + @TestMetadata("propertyInitialization.kt") + public void testPropertyInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("valInitializationAndUsageInNestedLambda.kt") + public void testValInitializationAndUsageInNestedLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/valInitializationAndUsageInNestedLambda.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/defaultValues") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index 81f5dbbbb09..7a88104d6e7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -1017,6 +1017,69 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo } } + @TestMetadata("compiler/testData/codegen/boxInline/contracts") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Contracts extends AbstractBlackBoxInlineCodegenTest { + public void testAllFilesPresentInContracts() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/contracts"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("complexInitializer.kt") + public void testComplexInitializer() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/complexInitializer.kt"); + doTest(fileName); + } + + @TestMetadata("complexInitializerWithStackTransformation.kt") + public void testComplexInitializerWithStackTransformation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/complexInitializerWithStackTransformation.kt"); + doTest(fileName); + } + + @TestMetadata("definiteLongValInitialization.kt") + public void testDefiniteLongValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteLongValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("definiteNestedValInitialization.kt") + public void testDefiniteNestedValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteNestedValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("definiteValInitialization.kt") + public void testDefiniteValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("nonLocalReturn.kt") + public void testNonLocalReturn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/nonLocalReturn.kt"); + doTest(fileName); + } + + @TestMetadata("nonLocalReturnWithCycle.kt") + public void testNonLocalReturnWithCycle() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/nonLocalReturnWithCycle.kt"); + doTest(fileName); + } + + @TestMetadata("propertyInitialization.kt") + public void testPropertyInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("valInitializationAndUsageInNestedLambda.kt") + public void testValInitializationAndUsageInNestedLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/valInitializationAndUsageInNestedLambda.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/defaultValues") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index c6b5e957bd8..892c5274ebb 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1017,6 +1017,69 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi } } + @TestMetadata("compiler/testData/codegen/boxInline/contracts") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Contracts extends AbstractCompileKotlinAgainstInlineKotlinTest { + public void testAllFilesPresentInContracts() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/contracts"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("complexInitializer.kt") + public void testComplexInitializer() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/complexInitializer.kt"); + doTest(fileName); + } + + @TestMetadata("complexInitializerWithStackTransformation.kt") + public void testComplexInitializerWithStackTransformation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/complexInitializerWithStackTransformation.kt"); + doTest(fileName); + } + + @TestMetadata("definiteLongValInitialization.kt") + public void testDefiniteLongValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteLongValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("definiteNestedValInitialization.kt") + public void testDefiniteNestedValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteNestedValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("definiteValInitialization.kt") + public void testDefiniteValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/definiteValInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("nonLocalReturn.kt") + public void testNonLocalReturn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/nonLocalReturn.kt"); + doTest(fileName); + } + + @TestMetadata("nonLocalReturnWithCycle.kt") + public void testNonLocalReturnWithCycle() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/nonLocalReturnWithCycle.kt"); + doTest(fileName); + } + + @TestMetadata("propertyInitialization.kt") + public void testPropertyInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/propertyInitialization.kt"); + doTest(fileName); + } + + @TestMetadata("valInitializationAndUsageInNestedLambda.kt") + public void testValInitializationAndUsageInNestedLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/contracts/valInitializationAndUsageInNestedLambda.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/defaultValues") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)