From 7025a4f933137b8b42d4567738cc33f6664685b8 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Mon, 13 Apr 2015 11:57:23 +0300 Subject: [PATCH] Test framewrk update: check lambda inlining --- .../anonymousObjectOnCallSite.1.kt | 1 + .../anonymousObjectOnCallSiteSuperParams.1.kt | 4 +- .../anonymousObjectOnDeclarationSite.1.kt | 4 +- ...ousObjectOnDeclarationSiteSuperParams.1.kt | 4 +- .../codegen/boxInline/builders/builders.1.kt | 1 + .../builders/buildersAndLambdaCapturing.1.kt | 1 + .../boxInline/capture/captureInlinable.1.kt | 1 + .../capture/captureInlinableAndOther.1.kt | 1 + .../codegen/boxInline/complex/with.1.kt | 1 + .../lambdaClassClash/lambdaClassClash.1.kt | 1 + .../lambdaClassClash/noInlineLambdaX2.1.kt | 1 + .../lambdaTransformation/lambdaCloning.1.kt | 1 + .../lambdaTransformation/lambdaInLambda2.1.kt | 3 +- .../lambdaTransformation/lambdaInLambda2.2.kt | 2 +- .../lambdaInLambdaNoInline.1.kt | 2 +- .../regeneratedLambdaName.1.kt | 1 + .../lambdaTransformation/sameCaptured.1.kt | 1 + .../localFunInLambda/localFunInLambda.1.kt | 1 + .../boxInline/noInline/lambdaAsGeneric.1.kt | 1 + .../noInline/lambdaAsNonFunction.1.kt | 1 + .../codegen/boxInline/noInline/noInline.1.kt | 1 + .../noInline/noInlineLambdaChain.1.kt | 1 + ...noInlineLambdaChainWithCapturedInline.1.kt | 2 +- .../boxInline/noInline/withoutInline.1.kt | 1 + .../nonLocalReturns/noInlineLocalReturn.1.kt | 1 + .../callSite/exceptionTableSplit.1.kt | 2 +- .../callSite/exceptionTableSplitNoReturn.1.kt | 2 +- .../exceptionTable/exceptionInFinally.1.kt | 2 +- .../codegen/boxInline/reified/packages.1.kt | 1 + .../boxInline/simple/rootConstructor.1.kt | 1 + .../boxInline/smap/anonymous/lambda.1.kt | 2 +- .../smap/anonymous/lambdaOnCallSite.2.kt | 2 +- .../anonymous/lambdaOnInlineCallSite.1.kt | 2 +- .../boxInline/smap/anonymous/object.1.kt | 2 +- .../smap/anonymous/objectOnCallSite.1.kt | 2 +- .../anonymous/objectOnInlineCallSite.1.kt | 2 +- .../anonymous/objectOnInlineCallSite2.1.kt | 2 +- .../objectOnInlineCallSiteWithCapture.1.kt | 2 +- .../kotlin/codegen/InlineTestUtil.kt | 160 +++++++++++++++--- .../AbstractBlackBoxInlineCodegenTest.kt | 2 +- ...actCompileKotlinAgainstInlineKotlinTest.kt | 2 +- 41 files changed, 176 insertions(+), 51 deletions(-) diff --git a/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnCallSite.1.kt b/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnCallSite.1.kt index 277fbf785a9..35d62b85f2c 100644 --- a/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnCallSite.1.kt +++ b/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnCallSite.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun box() : String { diff --git a/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnCallSiteSuperParams.1.kt b/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnCallSiteSuperParams.1.kt index 843531fdac5..a303896590c 100644 --- a/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnCallSiteSuperParams.1.kt +++ b/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnCallSiteSuperParams.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun box() : String { @@ -20,5 +21,4 @@ fun box() : String { if (result != "OK11") return "fail $result" return "OK" -} - +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnDeclarationSite.1.kt b/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnDeclarationSite.1.kt index 0b2754c9115..555cf37409a 100644 --- a/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnDeclarationSite.1.kt +++ b/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnDeclarationSite.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun test1(): String { @@ -26,5 +27,4 @@ fun box() : String { if (result2 != "OKGOOD") return "fail2 $result2" return "OK" -} - +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnDeclarationSiteSuperParams.1.kt b/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnDeclarationSiteSuperParams.1.kt index 64eb69081f7..26bec3965f5 100644 --- a/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnDeclarationSiteSuperParams.1.kt +++ b/compiler/testData/codegen/boxInline/anonymousObject/anonymousObjectOnDeclarationSiteSuperParams.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun test1(): String { @@ -26,5 +27,4 @@ fun box() : String { if (result2 != "OK11") return "fail2 $result2" return "OK" -} - +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/builders/builders.1.kt b/compiler/testData/codegen/boxInline/builders/builders.1.kt index 2d5412ca075..d6b45d5e316 100644 --- a/compiler/testData/codegen/boxInline/builders/builders.1.kt +++ b/compiler/testData/codegen/boxInline/builders/builders.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import builders.* fun testAllInline() : String { diff --git a/compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.1.kt b/compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.1.kt index 8a29493b425..928829b3899 100644 --- a/compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.1.kt +++ b/compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import builders.* import kotlin.InlineOption.* diff --git a/compiler/testData/codegen/boxInline/capture/captureInlinable.1.kt b/compiler/testData/codegen/boxInline/capture/captureInlinable.1.kt index 3fba232be37..a2945faed5a 100644 --- a/compiler/testData/codegen/boxInline/capture/captureInlinable.1.kt +++ b/compiler/testData/codegen/boxInline/capture/captureInlinable.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun box(): String { diff --git a/compiler/testData/codegen/boxInline/capture/captureInlinableAndOther.1.kt b/compiler/testData/codegen/boxInline/capture/captureInlinableAndOther.1.kt index 3fba232be37..a2945faed5a 100644 --- a/compiler/testData/codegen/boxInline/capture/captureInlinableAndOther.1.kt +++ b/compiler/testData/codegen/boxInline/capture/captureInlinableAndOther.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun box(): String { diff --git a/compiler/testData/codegen/boxInline/complex/with.1.kt b/compiler/testData/codegen/boxInline/complex/with.1.kt index 888e80b9fe1..72a04ac8a21 100644 --- a/compiler/testData/codegen/boxInline/complex/with.1.kt +++ b/compiler/testData/codegen/boxInline/complex/with.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun Data.test1(d: Data) : Long { diff --git a/compiler/testData/codegen/boxInline/lambdaClassClash/lambdaClassClash.1.kt b/compiler/testData/codegen/boxInline/lambdaClassClash/lambdaClassClash.1.kt index 2e5353e11cd..a98c23be44c 100644 --- a/compiler/testData/codegen/boxInline/lambdaClassClash/lambdaClassClash.1.kt +++ b/compiler/testData/codegen/boxInline/lambdaClassClash/lambdaClassClash.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import zzz.* fun box(): String { diff --git a/compiler/testData/codegen/boxInline/lambdaClassClash/noInlineLambdaX2.1.kt b/compiler/testData/codegen/boxInline/lambdaClassClash/noInlineLambdaX2.1.kt index 518a1448e13..420074aa930 100644 --- a/compiler/testData/codegen/boxInline/lambdaClassClash/noInlineLambdaX2.1.kt +++ b/compiler/testData/codegen/boxInline/lambdaClassClash/noInlineLambdaX2.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun test1(): Int { return 1.inlineMethod() diff --git a/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaCloning.1.kt b/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaCloning.1.kt index 949e7bb68f0..98f7acdc2f0 100644 --- a/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaCloning.1.kt +++ b/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaCloning.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun test1(s: Long): String { diff --git a/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambda2.1.kt b/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambda2.1.kt index d802ad3891b..13a8b233387 100644 --- a/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambda2.1.kt +++ b/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambda2.1.kt @@ -1,10 +1,11 @@ +//NO_CHECK_LAMBDA_INLINING import test.* import java.util.* fun test1(prefix: String): String { var result = "fail" mfun { - concat("start") { + noInline("start") { if (it.startsWith(prefix)) { result = "OK" } diff --git a/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambda2.2.kt b/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambda2.2.kt index 7ef3b1ad153..36b3a560486 100644 --- a/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambda2.2.kt +++ b/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambda2.2.kt @@ -4,6 +4,6 @@ inline fun mfun(f: () -> R) { f() } -fun concat(suffix: String, l: (s: String) -> Unit) { +fun noInline(suffix: String, l: (s: String) -> Unit) { l(suffix) } \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambdaNoInline.1.kt b/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambdaNoInline.1.kt index 40c19f1c1e6..e91509eac84 100644 --- a/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambdaNoInline.1.kt +++ b/compiler/testData/codegen/boxInline/lambdaTransformation/lambdaInLambdaNoInline.1.kt @@ -1,5 +1,5 @@ +//NO_CHECK_LAMBDA_INLINING import test.* - import kotlin.InlineOption.* fun test1(param: String): String { diff --git a/compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName.1.kt b/compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName.1.kt index 43ef4fbfb8f..7eca801a40a 100644 --- a/compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName.1.kt +++ b/compiler/testData/codegen/boxInline/lambdaTransformation/regeneratedLambdaName.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun sameName(s: Long): Long { diff --git a/compiler/testData/codegen/boxInline/lambdaTransformation/sameCaptured.1.kt b/compiler/testData/codegen/boxInline/lambdaTransformation/sameCaptured.1.kt index f64c8ceaab1..aec9e6eba73 100644 --- a/compiler/testData/codegen/boxInline/lambdaTransformation/sameCaptured.1.kt +++ b/compiler/testData/codegen/boxInline/lambdaTransformation/sameCaptured.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* import kotlin.InlineOption.* diff --git a/compiler/testData/codegen/boxInline/localFunInLambda/localFunInLambda.1.kt b/compiler/testData/codegen/boxInline/localFunInLambda/localFunInLambda.1.kt index a73394908af..f0f4bea4894 100644 --- a/compiler/testData/codegen/boxInline/localFunInLambda/localFunInLambda.1.kt +++ b/compiler/testData/codegen/boxInline/localFunInLambda/localFunInLambda.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun test1(d: Data): Int { diff --git a/compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.1.kt b/compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.1.kt index 9d86f6ba42d..704045bc9a6 100644 --- a/compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.1.kt +++ b/compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING fun box() : String { test {"123"} diff --git a/compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.1.kt b/compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.1.kt index 9d86f6ba42d..704045bc9a6 100644 --- a/compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.1.kt +++ b/compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING fun box() : String { test {"123"} diff --git a/compiler/testData/codegen/boxInline/noInline/noInline.1.kt b/compiler/testData/codegen/boxInline/noInline/noInline.1.kt index 1e87ef9c877..0d7483a67c5 100644 --- a/compiler/testData/codegen/boxInline/noInline/noInline.1.kt +++ b/compiler/testData/codegen/boxInline/noInline/noInline.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING fun test1(): Int { return calc( { l: Int -> 2*l}, { l: Int -> 4*l}) } diff --git a/compiler/testData/codegen/boxInline/noInline/noInlineLambdaChain.1.kt b/compiler/testData/codegen/boxInline/noInline/noInlineLambdaChain.1.kt index d094ac6aa69..1175c59fe81 100644 --- a/compiler/testData/codegen/boxInline/noInline/noInlineLambdaChain.1.kt +++ b/compiler/testData/codegen/boxInline/noInline/noInlineLambdaChain.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun test1(param: String): String { diff --git a/compiler/testData/codegen/boxInline/noInline/noInlineLambdaChainWithCapturedInline.1.kt b/compiler/testData/codegen/boxInline/noInline/noInlineLambdaChainWithCapturedInline.1.kt index 6c67851060d..5d889cce9c8 100644 --- a/compiler/testData/codegen/boxInline/noInline/noInlineLambdaChainWithCapturedInline.1.kt +++ b/compiler/testData/codegen/boxInline/noInline/noInlineLambdaChainWithCapturedInline.1.kt @@ -1,5 +1,5 @@ +//NO_CHECK_LAMBDA_INLINING import test.* - import kotlin.InlineOption.* inline fun test1(inlineOptions(ONLY_LOCAL_RETURN) param: () -> String): String { diff --git a/compiler/testData/codegen/boxInline/noInline/withoutInline.1.kt b/compiler/testData/codegen/boxInline/noInline/withoutInline.1.kt index 39a2be7e16a..49709d833bf 100644 --- a/compiler/testData/codegen/boxInline/noInline/withoutInline.1.kt +++ b/compiler/testData/codegen/boxInline/noInline/withoutInline.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING fun test1(): Int { val inlineX = Inline() var p = { l : Int -> l}; diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/noInlineLocalReturn.1.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/noInlineLocalReturn.1.kt index f45881082a3..896835c77d5 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/noInlineLocalReturn.1.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/noInlineLocalReturn.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun test1(b: Boolean): String { diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplit.1.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplit.1.kt index c901065d900..d69176542ba 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplit.1.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplit.1.kt @@ -90,7 +90,7 @@ fun box(): String { } -public fun assertError(index: Int, h: Holder, expected: String, l: (h: Holder) -> Holder) { +inline fun assertError(index: Int, h: Holder, expected: String, l: (h: Holder) -> Holder) { try { l(h) fail("fail $index: no error") diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplitNoReturn.1.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplitNoReturn.1.kt index 3b3cf3c880b..282cb8d341e 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplitNoReturn.1.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/callSite/exceptionTableSplitNoReturn.1.kt @@ -90,7 +90,7 @@ fun box(): String { } -public fun assertError(index: Int, h: Holder, expected: String, l: (h: Holder) -> Holder) { +inline fun assertError(index: Int, h: Holder, expected: String, l: (h: Holder) -> Holder) { try { l(h) fail("fail $index: no error") diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/exceptionInFinally.1.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/exceptionInFinally.1.kt index 29d41c116f9..84661766f8c 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/exceptionInFinally.1.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/exceptionInFinally.1.kt @@ -53,7 +53,7 @@ fun box() : String { return "OK" } -public fun assertError(index: Int, expected: String, l: Test.()->Unit) { +inline fun assertError(index: Int, expected: String, l: Test.()->Unit) { val testLocal = Test() try { testLocal.l() diff --git a/compiler/testData/codegen/boxInline/reified/packages.1.kt b/compiler/testData/codegen/boxInline/reified/packages.1.kt index fc7d111bcd2..7fa3e6360ac 100644 --- a/compiler/testData/codegen/boxInline/reified/packages.1.kt +++ b/compiler/testData/codegen/boxInline/reified/packages.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* fun box(): String { diff --git a/compiler/testData/codegen/boxInline/simple/rootConstructor.1.kt b/compiler/testData/codegen/boxInline/simple/rootConstructor.1.kt index 500559012fa..401f57cdd27 100644 --- a/compiler/testData/codegen/boxInline/simple/rootConstructor.1.kt +++ b/compiler/testData/codegen/boxInline/simple/rootConstructor.1.kt @@ -1,3 +1,4 @@ +//NO_CHECK_LAMBDA_INLINING import test.* val s = doWork({11}) diff --git a/compiler/testData/codegen/boxInline/smap/anonymous/lambda.1.kt b/compiler/testData/codegen/boxInline/smap/anonymous/lambda.1.kt index f00f642ece2..197d9496179 100644 --- a/compiler/testData/codegen/boxInline/smap/anonymous/lambda.1.kt +++ b/compiler/testData/codegen/boxInline/smap/anonymous/lambda.1.kt @@ -15,7 +15,7 @@ fun test(): String { fun box(): String { return test() } - +//NO_CHECK_LAMBDA_INLINING //SMAP //lambda.1.kt diff --git a/compiler/testData/codegen/boxInline/smap/anonymous/lambdaOnCallSite.2.kt b/compiler/testData/codegen/boxInline/smap/anonymous/lambdaOnCallSite.2.kt index 625d4182bbf..38514f9ab7b 100644 --- a/compiler/testData/codegen/boxInline/smap/anonymous/lambdaOnCallSite.2.kt +++ b/compiler/testData/codegen/boxInline/smap/anonymous/lambdaOnCallSite.2.kt @@ -3,5 +3,5 @@ package builders inline fun call(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) init: () -> Unit) { return init() } - +//NO_CHECK_LAMBDA_INLINING //SMAP ABSENT diff --git a/compiler/testData/codegen/boxInline/smap/anonymous/lambdaOnInlineCallSite.1.kt b/compiler/testData/codegen/boxInline/smap/anonymous/lambdaOnInlineCallSite.1.kt index e6be370a6a5..b076459b8ee 100644 --- a/compiler/testData/codegen/boxInline/smap/anonymous/lambdaOnInlineCallSite.1.kt +++ b/compiler/testData/codegen/boxInline/smap/anonymous/lambdaOnInlineCallSite.1.kt @@ -17,8 +17,8 @@ inline fun test(): String { fun box(): String { return test() } +//NO_CHECK_LAMBDA_INLINING //TODO SHOULD BE LESS - //SMAP //lambdaOnInlineCallSite.1.kt //Kotlin diff --git a/compiler/testData/codegen/boxInline/smap/anonymous/object.1.kt b/compiler/testData/codegen/boxInline/smap/anonymous/object.1.kt index 69927d95d4d..79f00fbc0f0 100644 --- a/compiler/testData/codegen/boxInline/smap/anonymous/object.1.kt +++ b/compiler/testData/codegen/boxInline/smap/anonymous/object.1.kt @@ -15,7 +15,7 @@ fun test(): String { fun box(): String { return test() } - +//NO_CHECK_LAMBDA_INLINING //SMAP //object.1.kt //Kotlin diff --git a/compiler/testData/codegen/boxInline/smap/anonymous/objectOnCallSite.1.kt b/compiler/testData/codegen/boxInline/smap/anonymous/objectOnCallSite.1.kt index 95d5dd49699..80f427db242 100644 --- a/compiler/testData/codegen/boxInline/smap/anonymous/objectOnCallSite.1.kt +++ b/compiler/testData/codegen/boxInline/smap/anonymous/objectOnCallSite.1.kt @@ -19,7 +19,7 @@ fun test(): String { fun box(): String { return test() } - +//NO_CHECK_LAMBDA_INLINING //SMAP //objectOnCallSite.1.kt diff --git a/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSite.1.kt b/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSite.1.kt index 053ab339681..717b53334ab 100644 --- a/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSite.1.kt +++ b/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSite.1.kt @@ -19,8 +19,8 @@ inline fun test(): String { fun box(): String { return test() } +//NO_CHECK_LAMBDA_INLINING //TODO SHOULD BE LESS - //SMAP //objectOnInlineCallSite.1.kt //Kotlin diff --git a/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSite2.1.kt b/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSite2.1.kt index 301f7b82ed3..d0ba07278fb 100644 --- a/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSite2.1.kt +++ b/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSite2.1.kt @@ -4,7 +4,7 @@ import kotlin.InlineOption.* fun box(): String { return test() } - +//NO_CHECK_LAMBDA_INLINING //SXMAP //objectOnInlineCallSite2.1.kt diff --git a/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSiteWithCapture.1.kt b/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSiteWithCapture.1.kt index fba03d4b85b..9500c184fd7 100644 --- a/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSiteWithCapture.1.kt +++ b/compiler/testData/codegen/boxInline/smap/anonymous/objectOnInlineCallSiteWithCapture.1.kt @@ -4,6 +4,6 @@ import kotlin.InlineOption.* fun box(): String { return test{"OK"} } - +//NO_CHECK_LAMBDA_INLINING //TODO \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt b/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt index 27f858af72f..b6308f8a4c9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt +++ b/compiler/tests/org/jetbrains/kotlin/codegen/InlineTestUtil.kt @@ -18,81 +18,100 @@ package org.jetbrains.kotlin.codegen; import com.intellij.openapi.util.Ref import com.intellij.openapi.util.text.StringUtil +import org.jetbrains.kotlin import org.jetbrains.kotlin.backend.common.output.OutputFile import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass +import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache import org.jetbrains.kotlin.load.kotlin.PackageClassUtils +import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader +import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.resolve.jvm.JvmClassName +import org.jetbrains.kotlin.test.InTextDirectivesUtils +import org.jetbrains.kotlin.utils.join import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.tree.MethodNode import java.util.ArrayList import java.util.HashSet +import kotlin.properties.Delegates public object InlineTestUtil { public val INLINE_ANNOTATION_CLASS: String = "kotlin/inline" - public fun checkNoCallsToInline(files: List) { - val inlinedMethods = collectInlineMethods(files) - assert(!inlinedMethods.isEmpty(), "There are no inline methods") + public fun checkNoCallsToInline(files: List, sourceFiles: List) { + val inlineInfo = obtainInlineInfo(files) + val inlineMethods = inlineInfo.inlineMethods + assert(!inlineMethods.isEmpty(), "There are no inline methods") - val notInlinedCalls = checkInlineNotInvoked(files, inlinedMethods) - assert(notInlinedCalls.isEmpty()) { "All inline methods should be inlined but " + StringUtil.join(notInlinedCalls, "\n") } + val notInlinedCalls = checkInlineMethodNotInvoked(files, inlineMethods) + assert(notInlinedCalls.isEmpty()) { "All inline methods should be inlined but:\n" + notInlinedCalls.joinToString("\n") } + + + val skipParameterChecking = + sourceFiles.sequence().filter { + InTextDirectivesUtils.isDirectiveDefined(it.getText(), "NO_CHECK_LAMBDA_INLINING") + }.any() + + if (!skipParameterChecking) { + val notInlinedParameters = checkParametersInlined(files, inlineInfo) + assert(notInlinedParameters.isEmpty()) { "All inline parameters should be inlined but:\n${notInlinedParameters.joinToString("\n")}\n" + + "but if you have not inlined lambdas or anonymous objects enable NO_CHECK_LAMBDA_INLINING directive" } + } } - private fun collectInlineMethods(files: List): Set { + private fun obtainInlineInfo(files: List): InlineInfo { val inlineMethods = HashSet() + val classHeaders = hashMapOf() for (file in files) { val cr = ClassReader(file.asByteArray()) - var className: String? = null - cr.accept(object : ClassVisitor(Opcodes.ASM4) { - - override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array?) { - className = name - super.visit(version, access, name, signature, superName, interfaces) - } + val classVisitor = object : ClassVisitorWithName() { override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor { - return object : MethodNode(Opcodes.ASM4, access, name, desc, signature, exceptions) { + return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) { public override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor { val type = Type.getType(desc) val annotationClass = type.getInternalName() if (INLINE_ANNOTATION_CLASS == annotationClass) { - inlineMethods.add(MethodInfo(className!!, name, this.desc)) + inlineMethods.add(MethodInfo(className, name, this.desc)) } return super.visitAnnotation(desc, visible) } } } - }, 0) + } + cr.accept(classVisitor, 0) + classHeaders.put(classVisitor.className, getClassHeader(file)) } - return inlineMethods + return InlineInfo(inlineMethods, classHeaders) } - private fun checkInlineNotInvoked(files: List, inlinedMethods: Set): List { + private fun checkInlineMethodNotInvoked(files: List, inlinedMethods: Set): List { val notInlined = ArrayList() + files.forEach { file -> + val cr = ClassReader(file.asByteArray()) - var className: String? = null - cr.accept(object : ClassVisitor(Opcodes.ASM4) { - override fun visit(version: Int, access: Int, name: String, signature: String, superName: String, interfaces: Array) { - className = name - super.visit(version, access, name, signature, superName, interfaces) - } + cr.accept(object : ClassVisitorWithName() { override fun visitMethod(access: Int, name: String, desc: String, signature: String, exceptions: Array): MethodVisitor? { - val classFqName = JvmClassName.byInternalName(className!!).getFqNameForClassNameWithoutDollars() + val classFqName = JvmClassName.byInternalName(className).getFqNameForClassNameWithoutDollars() if (PackageClassUtils.isPackageClassFqName(classFqName)) { return null } - return object : MethodNode(Opcodes.ASM4, access, name, desc, signature, exceptions) { + return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) { public override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) { val methodCall = MethodInfo(owner, name, desc) if (inlinedMethods.contains(methodCall)) { - val fromCall = MethodInfo(className!!, this.name, this.desc) + val fromCall = MethodInfo(className, this.name, this.desc) //skip delegation to trait impl from child class if (methodCall.owner.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX) && fromCall.owner != methodCall.owner) { @@ -109,7 +128,92 @@ public object InlineTestUtil { return notInlined } - private data class NotInlinedCall(public val fromCall: MethodInfo, public val inlineMethod: MethodInfo) + private fun checkParametersInlined(files: List, inlineInfo: InlineInfo): ArrayList { + val inlinedMethods = inlineInfo.inlineMethods + val notInlinedParameters = ArrayList() + for (file in files) { + val kotlinClassHeader = getClassHeader(file) + if (isClassOrPackagePartKind(kotlinClassHeader)) { + val cr = ClassReader(file.asByteArray()) + + cr.accept(object : ClassVisitorWithName() { + + override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor? { + val classFqName = JvmClassName.byInternalName(className).getFqNameForClassNameWithoutDollars() + val declaration = MethodInfo(className, name, desc) + //do not check anonymous object creation in inline functions and in package facades + if (PackageClassUtils.isPackageClassFqName(classFqName) || declaration in inlinedMethods) { + return null + } + + return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) { + private fun isInlineParameterLikeOwner(owner: String) = owner.contains("$") && !isTopLevelOrInnerOrPackageClass(owner, inlineInfo) + + public override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) { + if ("".equals(name) && isInlineParameterLikeOwner(owner)) { + /*constuctor creation*/ + val fromCall = MethodInfo(className, this.name, this.desc) + notInlinedParameters.add(NotInlinedParameter(owner, fromCall)) + } + } + + override fun visitFieldInsn(opcode: Int, owner: String, name: String, desc: String) { + if (opcode == Opcodes.GETSTATIC && isInlineParameterLikeOwner(owner)) { + val fromCall = MethodInfo(className, this.name, this.desc) + notInlinedParameters.add(NotInlinedParameter(owner, fromCall)) + } + super.visitFieldInsn(opcode, owner, name, desc) + } + } + } + }, 0) + } + } + + return notInlinedParameters + } + + private fun isTopLevelOrInnerOrPackageClass(classInternalName: String, inlineInfo: InlineInfo): Boolean { + if (classInternalName.startsWith("kotlin/jvm/internal/")) + return true + + return isClassOrPackagePartKind(inlineInfo.classHeaders[classInternalName]!!) + } + + private fun isClassOrPackagePartKind(header: KotlinClassHeader): Boolean { + return header.classKind == JvmAnnotationNames.KotlinClass.Kind.CLASS + || header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART + || header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.TRAIT_IMPL + } + + private fun getClassHeader(file: OutputFile): KotlinClassHeader { + return FileBasedKotlinClass.create(file.asByteArray()) { + className, classHeader, innerClasses -> + object : FileBasedKotlinClass(className, classHeader, innerClasses) { + override fun getLocation(): String = throw UnsupportedOperationException() + override fun getFileContents(): ByteArray = throw UnsupportedOperationException() + override fun hashCode(): Int = throw UnsupportedOperationException() + override fun equals(other: Any?): Boolean = throw UnsupportedOperationException() + override fun toString(): String? = throw UnsupportedOperationException() + } + }.getClassHeader() + } + + private class InlineInfo(val inlineMethods: Set, val classHeaders: Map) + + private data class NotInlinedCall(val fromCall: MethodInfo, val inlineMethod: MethodInfo) + + private data class NotInlinedParameter(val parameterClassName: String, val fromCall: MethodInfo) private data class MethodInfo(val owner: String, val name: String, val desc: String) + + open private class ClassVisitorWithName() : ClassVisitor(Opcodes.ASM5) { + + var className: String by Delegates.notNull() + + override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array?) { + className = name + super.visit(version, access, name, signature, superName, interfaces) + } + } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/AbstractBlackBoxInlineCodegenTest.kt b/compiler/tests/org/jetbrains/kotlin/codegen/generated/AbstractBlackBoxInlineCodegenTest.kt index 78ce37dafb7..14e33f604a4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/AbstractBlackBoxInlineCodegenTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/AbstractBlackBoxInlineCodegenTest.kt @@ -28,7 +28,7 @@ public abstract class AbstractBlackBoxInlineCodegenTest : AbstractBlackBoxCodege doTestMultiFile(inputFiles) try { - InlineTestUtil.checkNoCallsToInline(initializedClassLoader.getAllGeneratedFiles()) + InlineTestUtil.checkNoCallsToInline(initializedClassLoader.getAllGeneratedFiles(), myFiles.getPsiFiles()) checkSMAP(myFiles.getPsiFiles(), generateClassesInFile().asList()) } catch (e: Throwable) { diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstInlineKotlinTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstInlineKotlinTest.kt index d156b80d031..eb9819055f6 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstInlineKotlinTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstInlineKotlinTest.kt @@ -30,8 +30,8 @@ public abstract class AbstractCompileKotlinAgainstInlineKotlinTest : AbstractCom val allGeneratedFiles = factory1.asList() + factory2.asList() try { - InlineTestUtil.checkNoCallsToInline(allGeneratedFiles) val sourceFiles = factory1.getInputFiles() + factory2.getInputFiles() + InlineTestUtil.checkNoCallsToInline(allGeneratedFiles, sourceFiles) checkSMAP(sourceFiles, allGeneratedFiles) } catch (e: Throwable) {