From 4f5b20a8dbc154c637586c64c0a8471079d614f5 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 18 Feb 2014 12:14:06 +0400 Subject: [PATCH] Test framework for inline --- .../checkLocalVariablesTable/itInLambda.kt | 6 +- .../testData/codegen/boxInline/builders/1.kt | 173 ++++++++++++ .../testData/codegen/boxInline/builders/2.kt | 108 ++++++++ .../codegen/boxInline/captureInlinable/1.kt | 11 + .../codegen/boxInline/captureInlinable/2.kt | 10 + .../boxInline/captureInlinableAndOther/1.kt | 11 + .../boxInline/captureInlinableAndOther/2.kt | 11 + .../boxInline/captureThisAndReceiver/1.kt | 28 ++ .../boxInline/captureThisAndReceiver/2.kt | 6 + .../codegen/boxInline/classObject/1.kt | 21 ++ .../codegen/boxInline/classObject/2.kt | 18 ++ .../codegen/boxInline/closureChain/1.kt | 11 + .../codegen/boxInline/closureChain/2.kt | 7 + .../testData/codegen/boxInline/extension/1.kt | 37 +++ .../testData/codegen/boxInline/extension/2.kt | 29 ++ .../codegen/boxInline/forEachLine/1.kt | 23 ++ .../codegen/boxInline/forEachLine/2.kt | 20 ++ .../testData/codegen/boxInline/generics/1.kt | 17 ++ .../testData/codegen/boxInline/generics/2.kt | 9 + .../codegen/boxInline/identityCheck/1.kt | 23 ++ .../codegen/boxInline/identityCheck/2.kt | 5 + .../codegen/boxInline/ifBranches/1.kt | 43 +++ .../codegen/boxInline/ifBranches/2.kt | 25 ++ compiler/testData/codegen/boxInline/iinc/1.kt | 13 + compiler/testData/codegen/boxInline/iinc/2.kt | 7 + .../codegen/boxInline/inlineChain/1.kt | 18 ++ .../codegen/boxInline/inlineChain/2.kt | 20 ++ .../codegen/boxInline/lambdaClassClash/1.kt | 12 + .../codegen/boxInline/lambdaClassClash/2.kt | 9 + .../codegen/boxInline/lambdaCloning/1.kt | 19 ++ .../codegen/boxInline/lambdaCloning/2.kt | 9 + .../codegen/boxInline/lambdaInLambda/1.kt | 23 ++ .../codegen/boxInline/lambdaInLambda/2.kt | 19 ++ .../codegen/boxInline/lambdaInLambda2/1.kt | 22 ++ .../codegen/boxInline/lambdaInLambda2/2.kt | 9 + .../boxInline/lambdaInLambdaNoInline/1.kt | 19 ++ .../boxInline/lambdaInLambdaNoInline/2.kt | 13 + .../codegen/boxInline/localFunInLambda/1.kt | 21 ++ .../codegen/boxInline/localFunInLambda/2.kt | 12 + .../testData/codegen/boxInline/noInline/1.kt | 10 + .../testData/codegen/boxInline/noInline/2.kt | 4 + .../codegen/boxInline/noInlineLambdaX2/1.kt | 10 + .../codegen/boxInline/noInlineLambdaX2/2.kt | 8 + .../testData/codegen/boxInline/params/1.kt | 32 +++ .../testData/codegen/boxInline/params/2.kt | 15 + .../codegen/boxInline/plusAssign/1.kt | 14 + .../codegen/boxInline/plusAssign/2.kt | 7 + .../boxInline/regeneratedLambdaName/1.kt | 23 ++ .../boxInline/regeneratedLambdaName/2.kt | 5 + .../codegen/boxInline/rootConstructor/1.kt | 9 + .../codegen/boxInline/rootConstructor/2.kt | 10 + .../codegen/boxInline/severalClosures/1.kt | 23 ++ .../codegen/boxInline/severalClosures/2.kt | 11 + .../codegen/boxInline/severalUsage/1.kt | 7 + .../codegen/boxInline/severalUsage/2.kt | 10 + .../boxInline/simpleCapturingInClass/1.kt | 70 +++++ .../boxInline/simpleCapturingInClass/2.kt | 7 + .../boxInline/simpleCapturingInPackage/1.kt | 62 +++++ .../boxInline/simpleCapturingInPackage/2.kt | 4 + .../codegen/boxInline/simpleDouble/1.kt | 48 ++++ .../codegen/boxInline/simpleDouble/2.kt | 23 ++ .../codegen/boxInline/simpleEnum/1.kt | 12 + .../codegen/boxInline/simpleEnum/2.kt | 9 + .../codegen/boxInline/simpleGenerics/1.kt | 12 + .../codegen/boxInline/simpleGenerics/2.kt | 5 + .../testData/codegen/boxInline/simpleInt/1.kt | 48 ++++ .../testData/codegen/boxInline/simpleInt/2.kt | 24 ++ .../codegen/boxInline/simpleLambda/1.kt | 23 ++ .../codegen/boxInline/simpleLambda/2.kt | 14 + .../codegen/boxInline/simpleObject/1.kt | 49 ++++ .../codegen/boxInline/simpleObject/2.kt | 24 ++ .../codegen/boxInline/stackHeightBug/1.kt | 6 + .../codegen/boxInline/stackHeightBug/2.kt | 8 + .../testData/codegen/boxInline/trait/1.kt | 21 ++ .../testData/codegen/boxInline/trait/2.kt | 18 ++ .../testData/codegen/boxInline/tryCatch/1.kt | 53 ++++ .../testData/codegen/boxInline/tryCatch/2.kt | 7 + .../testData/codegen/boxInline/tryCatch2/1.kt | 107 ++++++++ .../testData/codegen/boxInline/tryCatch2/2.kt | 19 ++ .../codegen/boxInline/tryCatchFinally/1.kt | 73 +++++ .../codegen/boxInline/tryCatchFinally/2.kt | 21 ++ compiler/testData/codegen/boxInline/use/1.kt | 22 ++ compiler/testData/codegen/boxInline/use/2.kt | 38 +++ .../testData/codegen/boxInline/vararg/1.kt | 12 + .../testData/codegen/boxInline/vararg/2.kt | 5 + compiler/testData/codegen/boxInline/with/1.kt | 25 ++ compiler/testData/codegen/boxInline/with/2.kt | 27 ++ .../codegen/boxInline/withoutInline/1.kt | 11 + .../codegen/boxInline/withoutInline/2.kt | 7 + .../BlackBoxInlineCodegenTestGenerated.java | 259 ++++++++++++++++++ ...bstractCompileKotlinAgainstKotlinTest.java | 66 ++++- ...otlinAgainstInlineKotlinTestGenerated.java | 259 ++++++++++++++++++ .../jet/generators/tests/GenerateTests.kt | 8 + 93 files changed, 2593 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/codegen/boxInline/builders/1.kt create mode 100644 compiler/testData/codegen/boxInline/builders/2.kt create mode 100644 compiler/testData/codegen/boxInline/captureInlinable/1.kt create mode 100644 compiler/testData/codegen/boxInline/captureInlinable/2.kt create mode 100644 compiler/testData/codegen/boxInline/captureInlinableAndOther/1.kt create mode 100644 compiler/testData/codegen/boxInline/captureInlinableAndOther/2.kt create mode 100644 compiler/testData/codegen/boxInline/captureThisAndReceiver/1.kt create mode 100644 compiler/testData/codegen/boxInline/captureThisAndReceiver/2.kt create mode 100644 compiler/testData/codegen/boxInline/classObject/1.kt create mode 100644 compiler/testData/codegen/boxInline/classObject/2.kt create mode 100644 compiler/testData/codegen/boxInline/closureChain/1.kt create mode 100644 compiler/testData/codegen/boxInline/closureChain/2.kt create mode 100644 compiler/testData/codegen/boxInline/extension/1.kt create mode 100644 compiler/testData/codegen/boxInline/extension/2.kt create mode 100644 compiler/testData/codegen/boxInline/forEachLine/1.kt create mode 100644 compiler/testData/codegen/boxInline/forEachLine/2.kt create mode 100644 compiler/testData/codegen/boxInline/generics/1.kt create mode 100644 compiler/testData/codegen/boxInline/generics/2.kt create mode 100644 compiler/testData/codegen/boxInline/identityCheck/1.kt create mode 100644 compiler/testData/codegen/boxInline/identityCheck/2.kt create mode 100644 compiler/testData/codegen/boxInline/ifBranches/1.kt create mode 100644 compiler/testData/codegen/boxInline/ifBranches/2.kt create mode 100644 compiler/testData/codegen/boxInline/iinc/1.kt create mode 100644 compiler/testData/codegen/boxInline/iinc/2.kt create mode 100644 compiler/testData/codegen/boxInline/inlineChain/1.kt create mode 100644 compiler/testData/codegen/boxInline/inlineChain/2.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaClassClash/1.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaClassClash/2.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaCloning/1.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaCloning/2.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaInLambda/1.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaInLambda/2.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaInLambda2/1.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaInLambda2/2.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaInLambdaNoInline/1.kt create mode 100644 compiler/testData/codegen/boxInline/lambdaInLambdaNoInline/2.kt create mode 100644 compiler/testData/codegen/boxInline/localFunInLambda/1.kt create mode 100644 compiler/testData/codegen/boxInline/localFunInLambda/2.kt create mode 100644 compiler/testData/codegen/boxInline/noInline/1.kt create mode 100644 compiler/testData/codegen/boxInline/noInline/2.kt create mode 100644 compiler/testData/codegen/boxInline/noInlineLambdaX2/1.kt create mode 100644 compiler/testData/codegen/boxInline/noInlineLambdaX2/2.kt create mode 100644 compiler/testData/codegen/boxInline/params/1.kt create mode 100644 compiler/testData/codegen/boxInline/params/2.kt create mode 100644 compiler/testData/codegen/boxInline/plusAssign/1.kt create mode 100644 compiler/testData/codegen/boxInline/plusAssign/2.kt create mode 100644 compiler/testData/codegen/boxInline/regeneratedLambdaName/1.kt create mode 100644 compiler/testData/codegen/boxInline/regeneratedLambdaName/2.kt create mode 100644 compiler/testData/codegen/boxInline/rootConstructor/1.kt create mode 100644 compiler/testData/codegen/boxInline/rootConstructor/2.kt create mode 100644 compiler/testData/codegen/boxInline/severalClosures/1.kt create mode 100644 compiler/testData/codegen/boxInline/severalClosures/2.kt create mode 100644 compiler/testData/codegen/boxInline/severalUsage/1.kt create mode 100644 compiler/testData/codegen/boxInline/severalUsage/2.kt create mode 100644 compiler/testData/codegen/boxInline/simpleCapturingInClass/1.kt create mode 100644 compiler/testData/codegen/boxInline/simpleCapturingInClass/2.kt create mode 100644 compiler/testData/codegen/boxInline/simpleCapturingInPackage/1.kt create mode 100644 compiler/testData/codegen/boxInline/simpleCapturingInPackage/2.kt create mode 100644 compiler/testData/codegen/boxInline/simpleDouble/1.kt create mode 100644 compiler/testData/codegen/boxInline/simpleDouble/2.kt create mode 100644 compiler/testData/codegen/boxInline/simpleEnum/1.kt create mode 100644 compiler/testData/codegen/boxInline/simpleEnum/2.kt create mode 100644 compiler/testData/codegen/boxInline/simpleGenerics/1.kt create mode 100644 compiler/testData/codegen/boxInline/simpleGenerics/2.kt create mode 100644 compiler/testData/codegen/boxInline/simpleInt/1.kt create mode 100644 compiler/testData/codegen/boxInline/simpleInt/2.kt create mode 100644 compiler/testData/codegen/boxInline/simpleLambda/1.kt create mode 100644 compiler/testData/codegen/boxInline/simpleLambda/2.kt create mode 100644 compiler/testData/codegen/boxInline/simpleObject/1.kt create mode 100644 compiler/testData/codegen/boxInline/simpleObject/2.kt create mode 100644 compiler/testData/codegen/boxInline/stackHeightBug/1.kt create mode 100644 compiler/testData/codegen/boxInline/stackHeightBug/2.kt create mode 100644 compiler/testData/codegen/boxInline/trait/1.kt create mode 100644 compiler/testData/codegen/boxInline/trait/2.kt create mode 100644 compiler/testData/codegen/boxInline/tryCatch/1.kt create mode 100644 compiler/testData/codegen/boxInline/tryCatch/2.kt create mode 100644 compiler/testData/codegen/boxInline/tryCatch2/1.kt create mode 100644 compiler/testData/codegen/boxInline/tryCatch2/2.kt create mode 100644 compiler/testData/codegen/boxInline/tryCatchFinally/1.kt create mode 100644 compiler/testData/codegen/boxInline/tryCatchFinally/2.kt create mode 100644 compiler/testData/codegen/boxInline/use/1.kt create mode 100644 compiler/testData/codegen/boxInline/use/2.kt create mode 100644 compiler/testData/codegen/boxInline/vararg/1.kt create mode 100644 compiler/testData/codegen/boxInline/vararg/2.kt create mode 100644 compiler/testData/codegen/boxInline/with/1.kt create mode 100644 compiler/testData/codegen/boxInline/with/2.kt create mode 100644 compiler/testData/codegen/boxInline/withoutInline/1.kt create mode 100644 compiler/testData/codegen/boxInline/withoutInline/2.kt create mode 100644 compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxInlineCodegenTestGenerated.java create mode 100644 compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java diff --git a/compiler/testData/checkLocalVariablesTable/itInLambda.kt b/compiler/testData/checkLocalVariablesTable/itInLambda.kt index df4472388ee..2d5d3c431fc 100644 --- a/compiler/testData/checkLocalVariablesTable/itInLambda.kt +++ b/compiler/testData/checkLocalVariablesTable/itInLambda.kt @@ -1,5 +1,9 @@ +public fun Iterable.myforEach(operation: (T) -> Unit) : Unit { + for (element in this) operation(element) +} + fun foo1() { - (1..5).forEach { + (1..5).myforEach { println(it) } } diff --git a/compiler/testData/codegen/boxInline/builders/1.kt b/compiler/testData/codegen/boxInline/builders/1.kt new file mode 100644 index 00000000000..2d5412ca075 --- /dev/null +++ b/compiler/testData/codegen/boxInline/builders/1.kt @@ -0,0 +1,173 @@ +import builders.* + +fun testAllInline() : String { + val args = array("1", "2", "3") + val result = + html { + val htmlVal = 0 + head { + title { +"XML encoding with Kotlin" } + } + body { + var bodyVar = 1 + h1 { +"XML encoding with Kotlin" } + p { +"this format can be used as an alternative markup to XML" } + + // an element with attributes and text content + a(href = "http://jetbrains.com/kotlin") { +"Kotlin" } + + // mixed content + p { + +"This is some" + b { +"mixed" } + +"text. For more see the" + a(href = "http://jetbrains.com/kotlin") { +"Kotlin" } + +"project" + } + p { +"some text" } + + // content generated from command-line arguments + p { + +"Command line arguments were:" + ul { + for (arg in args) + li { +arg; +"$htmlVal"; +"$bodyVar" } + } + } + } + } + + return result.toString()!! +} + +fun testHtmlNoInline() : String { + val args = array("1", "2", "3") + val result = + htmlNoInline() { + val htmlVal = 0 + head { + title { +"XML encoding with Kotlin" } + } + body { + var bodyVar = 1 + h1 { +"XML encoding with Kotlin" } + p { +"this format can be used as an alternative markup to XML" } + + // an element with attributes and text content + a(href = "http://jetbrains.com/kotlin") { +"Kotlin" } + + // mixed content + p { + +"This is some" + b { +"mixed" } + +"text. For more see the" + a(href = "http://jetbrains.com/kotlin") { +"Kotlin" } + +"project" + } + p { +"some text" } + + // content generated from command-line arguments + p { + +"Command line arguments were:" + ul { + for (arg in args) + li { +arg; +"$htmlVal"; +"$bodyVar" } + } + } + } + } + + return result.toString()!! +} + +fun testBodyNoInline() : String { + val args = array("1", "2", "3") + val result = + html { + val htmlVal = 0 + head { + title { +"XML encoding with Kotlin" } + } + bodyNoInline { + var bodyVar = 1 + h1 { +"XML encoding with Kotlin" } + p { +"this format can be used as an alternative markup to XML" } + + // an element with attributes and text content + a(href = "http://jetbrains.com/kotlin") { +"Kotlin" } + + // mixed content + p { + +"This is some" + b { +"mixed" } + +"text. For more see the" + a(href = "http://jetbrains.com/kotlin") { +"Kotlin" } + +"project" + } + p { +"some text" } + + // content generated from command-line arguments + p { + +"Command line arguments were:" + ul { + for (arg in args) + li { +arg; +"$htmlVal"; +"$bodyVar" } + } + } + } + } + + return result.toString()!! +} + +fun testBodyHtmlNoInline() : String { + val args = array("1", "2", "3") + val result = + htmlNoInline { + val htmlVal = 0 + head { + title { +"XML encoding with Kotlin" } + } + bodyNoInline { + var bodyVar = 1 + h1 { +"XML encoding with Kotlin" } + p { +"this format can be used as an alternative markup to XML" } + + // an element with attributes and text content + a(href = "http://jetbrains.com/kotlin") { +"Kotlin" } + + // mixed content + p { + +"This is some" + b { +"mixed" } + +"text. For more see the" + a(href = "http://jetbrains.com/kotlin") { +"Kotlin" } + +"project" + } + p { +"some text" } + + // content generated from command-line arguments + p { + +"Command line arguments were:" + ul { + for (arg in args) + li { +arg; +"$htmlVal"; +"$bodyVar" } + } + } + } + } + + return result.toString()!! +} + +fun box(): String { + var expected = testAllInline(); + + if (expected != testHtmlNoInline()) return "fail 1: ${testHtmlNoInline()}\nbut expected\n${expected} " + + if (expected != testBodyNoInline()) return "fail 2: ${testBodyNoInline()}\nbut expected\n${expected} " + + if (expected != testBodyHtmlNoInline()) return "fail 3: ${testBodyHtmlNoInline()}\nbut expected\n${expected} " + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/builders/2.kt b/compiler/testData/codegen/boxInline/builders/2.kt new file mode 100644 index 00000000000..f2c29052b97 --- /dev/null +++ b/compiler/testData/codegen/boxInline/builders/2.kt @@ -0,0 +1,108 @@ +package builders + +import java.util.ArrayList +import java.util.HashMap + +trait Element { + fun render(builder: StringBuilder, indent: String) + + override fun toString(): String { + val builder = StringBuilder() + render(builder, "") + return builder.toString() + } +} + +class TextElement(val text: String) : Element { + override fun render(builder: StringBuilder, indent: String) { + builder.append("$indent$text\n") + } +} + +abstract class Tag(val name: String) : Element { + val children = ArrayList() + val attributes = HashMap() + + inline protected fun initTag(tag: T, init: T.() -> Unit): T { + tag.init() + children.add(tag) + return tag + } + + override fun render(builder: StringBuilder, indent: String) { + builder.append("$indent<$name${renderAttributes()}>\n") + for (c in children) { + c.render(builder, indent + " ") + } + builder.append("$indent\n") + } + + private fun renderAttributes(): String? { + val builder = StringBuilder() + for (a in attributes.keySet()) { + builder.append(" $a=\"${attributes[a]}\"") + } + return builder.toString() + } +} + +abstract class TagWithText(name: String) : Tag(name) { + fun String.plus() { + children.add(TextElement(this)) + } +} + +class HTML() : TagWithText("html") { + inline fun head(init: Head.() -> Unit) = initTag(Head(), init) + + inline fun body(init: Body.() -> Unit) = initTag(Body(), init) + + fun bodyNoInline(init: Body.() -> Unit) = initTag(Body(), init) +} + +class Head() : TagWithText("head") { + inline fun title(init: Title.() -> Unit) = initTag(Title(), init) +} + +class Title() : TagWithText("title") + +abstract class BodyTag(name: String) : TagWithText(name) { + inline fun b(init: B.() -> Unit) = initTag(B(), init) + inline fun p(init: P.() -> Unit) = initTag(P(), init) + inline fun pNoInline(init: P.() -> Unit) = initTag(P(), init) + inline fun h1(init: H1.() -> Unit) = initTag(H1(), init) + inline fun ul(init: UL.() -> Unit) = initTag(UL(), init) + inline fun a(href: String, init: A.() -> Unit) { + val a = initTag(A(), init) + a.href = href + } +} + +class Body() : BodyTag("body") +class UL() : BodyTag("ul") { + inline fun li(init: LI.() -> Unit) = initTag(LI(), init) +} + +class B() : BodyTag("b") +class LI() : BodyTag("li") +class P() : BodyTag("p") +class H1() : BodyTag("h1") +class A() : BodyTag("a") { + public var href: String + get() = attributes["href"]!! + set(value) { + attributes["href"] = value + } +} + +inline fun html(init: HTML.() -> Unit): HTML { + val html = HTML() + html.init() + return html +} + +fun htmlNoInline(init: HTML.() -> Unit): HTML { + val html = HTML() + html.init() + return html +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/captureInlinable/1.kt b/compiler/testData/codegen/boxInline/captureInlinable/1.kt new file mode 100644 index 00000000000..3fba232be37 --- /dev/null +++ b/compiler/testData/codegen/boxInline/captureInlinable/1.kt @@ -0,0 +1,11 @@ +import test.* + +fun box(): String { + val result = doWork({11}) + if (result != 11) return "test1: ${result}" + + val result2 = doWork({12; result+1}) + if (result2 != 12) return "test2: ${result2}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/captureInlinable/2.kt b/compiler/testData/codegen/boxInline/captureInlinable/2.kt new file mode 100644 index 00000000000..8d35830e78b --- /dev/null +++ b/compiler/testData/codegen/boxInline/captureInlinable/2.kt @@ -0,0 +1,10 @@ +package test + +inline fun doWork(job: ()-> R) : R { + return notInline({job()}) +} + +fun notInline(job: ()-> R) : R { + return job() +} + diff --git a/compiler/testData/codegen/boxInline/captureInlinableAndOther/1.kt b/compiler/testData/codegen/boxInline/captureInlinableAndOther/1.kt new file mode 100644 index 00000000000..3fba232be37 --- /dev/null +++ b/compiler/testData/codegen/boxInline/captureInlinableAndOther/1.kt @@ -0,0 +1,11 @@ +import test.* + +fun box(): String { + val result = doWork({11}) + if (result != 11) return "test1: ${result}" + + val result2 = doWork({12; result+1}) + if (result2 != 12) return "test2: ${result2}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/captureInlinableAndOther/2.kt b/compiler/testData/codegen/boxInline/captureInlinableAndOther/2.kt new file mode 100644 index 00000000000..513e63606c4 --- /dev/null +++ b/compiler/testData/codegen/boxInline/captureInlinableAndOther/2.kt @@ -0,0 +1,11 @@ +package test + +inline fun doWork(job: ()-> R) : R { + val k = 10; + return notInline({k; job()}) +} + +fun notInline(job: ()-> R) : R { + return job() +} + diff --git a/compiler/testData/codegen/boxInline/captureThisAndReceiver/1.kt b/compiler/testData/codegen/boxInline/captureThisAndReceiver/1.kt new file mode 100644 index 00000000000..7c2a36f9d72 --- /dev/null +++ b/compiler/testData/codegen/boxInline/captureThisAndReceiver/1.kt @@ -0,0 +1,28 @@ +fun test1() : Int { + val inlineX = My(111) + + return inlineX.perform{ + + val outX = My(1111111) + outX.perform( + {inlineX.value} + ) + } +} + +inline fun My.execute(): Int { + return perform { this.value } +} + +fun test2(): Int { + val inlineX = My(11) + + return inlineX.execute() +} + +fun box(): String { + if (test1() != 111) return "test1: ${test1()}" + if (test2() != 11) return "test2: ${test2()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/captureThisAndReceiver/2.kt b/compiler/testData/codegen/boxInline/captureThisAndReceiver/2.kt new file mode 100644 index 00000000000..433442c5a46 --- /dev/null +++ b/compiler/testData/codegen/boxInline/captureThisAndReceiver/2.kt @@ -0,0 +1,6 @@ +class My(val value: Int) + +inline fun T.perform(job: (T)-> R) : R { + return job(this) +} + diff --git a/compiler/testData/codegen/boxInline/classObject/1.kt b/compiler/testData/codegen/boxInline/classObject/1.kt new file mode 100644 index 00000000000..4d0f7cc3a67 --- /dev/null +++ b/compiler/testData/codegen/boxInline/classObject/1.kt @@ -0,0 +1,21 @@ +import test.* + +fun testClassObjectCall(): String { + return InlineAll.inline({"classobject"}) +} + +fun testInstanceCall(): String { + val inlineX = InlineAll() + return inlineX.inline({"instance"}) +} + +fun testPackageCall(): String { + return inline({"package"}) +} + +fun box(): String { + if (testClassObjectCall() != "classobject") return "test1: ${testClassObjectCall()}" + if (testInstanceCall() != "instance") return "test2: ${testInstanceCall()}" + if (testPackageCall() != "package") return "test3: ${testPackageCall()}" + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/classObject/2.kt b/compiler/testData/codegen/boxInline/classObject/2.kt new file mode 100644 index 00000000000..2cf3aa60984 --- /dev/null +++ b/compiler/testData/codegen/boxInline/classObject/2.kt @@ -0,0 +1,18 @@ +package test + +inline fun inline(s: () -> String): String { + return s() +} + +class InlineAll { + + inline fun inline(s: () -> String): String { + return s() + } + + class object { + inline fun inline(s: () -> String): String { + return s() + } + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/closureChain/1.kt b/compiler/testData/codegen/boxInline/closureChain/1.kt new file mode 100644 index 00000000000..2602d89f0c2 --- /dev/null +++ b/compiler/testData/codegen/boxInline/closureChain/1.kt @@ -0,0 +1,11 @@ + +fun test1(): Int { + val inlineX = Inline() + return inlineX.foo({(z: Int) -> "" + z}, 25, {String.() -> this.length}) +} + +fun box(): String { + if (test1() != 2) return "test1: ${test1()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/closureChain/2.kt b/compiler/testData/codegen/boxInline/closureChain/2.kt new file mode 100644 index 00000000000..e2f1f3b0914 --- /dev/null +++ b/compiler/testData/codegen/boxInline/closureChain/2.kt @@ -0,0 +1,7 @@ +class Inline() { + + inline fun foo(closure1 : (l: Int) -> String, param: Int, closure2: String.() -> Int) : Int { + return closure1(param).closure2() + } +} + diff --git a/compiler/testData/codegen/boxInline/extension/1.kt b/compiler/testData/codegen/boxInline/extension/1.kt new file mode 100644 index 00000000000..c86600273ab --- /dev/null +++ b/compiler/testData/codegen/boxInline/extension/1.kt @@ -0,0 +1,37 @@ +fun test1(): Int { + val inlineX = Inline(9) + return inlineX.calcExt({(z: Int) -> z}, 25) +} + +fun test2(): Int { + val inlineX = Inline(9) + return inlineX.calcExt2({Int.() -> this}, 25) +} + +fun test3(): Int { + val inlineX = Inline(9) + return inlineX.doWork(InlineX(11)) +} + +fun test4(): Double { + val inlineX = Inline(9) + return inlineX.doWorkWithDouble(11.0) +} + +fun test5(): Double { + val inlineX = Inline(9) + with(inlineX) { + 11.0.calcDouble{(a: Int, b: Double) -> a + b} + } + return inlineX.doWorkWithDouble(11.0) +} + +fun box(): String { + if (test1() != 25) return "test1: ${test1()}" + if (test2() != 25) return "test2: ${test2()}" + if (test3() != 20) return "test3: ${test3()}" + if (test4() != 20.0) return "test4: ${test4()}" + if (test5() != 20.0) return "test5: ${test5()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/extension/2.kt b/compiler/testData/codegen/boxInline/extension/2.kt new file mode 100644 index 00000000000..c77a879deeb --- /dev/null +++ b/compiler/testData/codegen/boxInline/extension/2.kt @@ -0,0 +1,29 @@ +inline fun Inline.calcExt(s: (Int) -> Int, p: Int) : Int { + return s(p) +} + +inline fun Inline.calcExt2(s: Int.() -> Int, p: Int) : Int { + return p.s() +} + +class InlineX(val value : Int) {} + +class Inline(val res: Int) { + + inline fun InlineX.calcInt(s: (Int, Int) -> Int) : Int { + return s(res, this.value) + } + + inline fun Double.calcDouble(s: (Int, Double) -> Double) : Double { + return s(res, this) + } + + fun doWork(l : InlineX) : Int { + return l.calcInt({(a: Int, b: Int) -> a + b}) + } + + fun doWorkWithDouble(s : Double) : Double { + return s.calcDouble({(a: Int, b: Double) -> a + b}) + } + +} diff --git a/compiler/testData/codegen/boxInline/forEachLine/1.kt b/compiler/testData/codegen/boxInline/forEachLine/1.kt new file mode 100644 index 00000000000..4feda8f080c --- /dev/null +++ b/compiler/testData/codegen/boxInline/forEachLine/1.kt @@ -0,0 +1,23 @@ +import test.* +import java.util.* + + +fun sample(): Input { + return Input("Hello", "World"); +} + +test fun testForEachLine() { + val list = ArrayList() + val reader = sample() + + reader.forEachLine{ + list.add(it) + } +} + + +fun box(): String { + testForEachLine() + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/forEachLine/2.kt b/compiler/testData/codegen/boxInline/forEachLine/2.kt new file mode 100644 index 00000000000..18d10a1a80d --- /dev/null +++ b/compiler/testData/codegen/boxInline/forEachLine/2.kt @@ -0,0 +1,20 @@ +package test + +public class Input(val s1: String, val s2: String) { + public fun iterator() : Iterator { + return arrayListOf(s1, s2).iterator() + } +} + +public inline fun T.use(block: (T)-> R) : R { + return block(this) +} + +public inline fun Input.forEachLine(block: (String) -> Unit): Unit { + useLines { lines -> lines.forEach(block) } +} + +public inline fun Input.useLines(block2: (Iterator) -> Unit): Unit { + this.use{ block2(it.iterator()) } +} + diff --git a/compiler/testData/codegen/boxInline/generics/1.kt b/compiler/testData/codegen/boxInline/generics/1.kt new file mode 100644 index 00000000000..85f385625f5 --- /dev/null +++ b/compiler/testData/codegen/boxInline/generics/1.kt @@ -0,0 +1,17 @@ +import test.* + +fun test1(s: Long): String { + var result = "OK" + result = mfun(s) { a -> + result + doSmth(s) + doSmth(a) + } + + return result +} + +fun box(): String { + val result = test1(11.toLong()) + if (result != "OK1111") return "fail1: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/generics/2.kt b/compiler/testData/codegen/boxInline/generics/2.kt new file mode 100644 index 00000000000..45dad11dbf8 --- /dev/null +++ b/compiler/testData/codegen/boxInline/generics/2.kt @@ -0,0 +1,9 @@ +package test + +inline fun mfun(arg: T, f: (T) -> R) : R { + return f(arg) +} + +inline fun doSmth(a: T): String { + return a.toString() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/identityCheck/1.kt b/compiler/testData/codegen/boxInline/identityCheck/1.kt new file mode 100644 index 00000000000..52de1c3c444 --- /dev/null +++ b/compiler/testData/codegen/boxInline/identityCheck/1.kt @@ -0,0 +1,23 @@ +import test.* + +fun test1(s: Long): Boolean { + return doSmth(s) +} + +fun test2(s: Int): Boolean { + return doSmth(s) +} + +inline fun test3(s: T): Boolean { + return doSmth(s) +} + +fun box(): String { + if (!test1(11111.toLong())) return "fail 1" + if (!test2(11111)) return "fail 2" + if (!test3(11111)) return "fail 3.1" + if (!test3("11111")) return "fail 3.2" + if (!test3(11111.3)) return "fail 3.3" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/identityCheck/2.kt b/compiler/testData/codegen/boxInline/identityCheck/2.kt new file mode 100644 index 00000000000..478c7ec2076 --- /dev/null +++ b/compiler/testData/codegen/boxInline/identityCheck/2.kt @@ -0,0 +1,5 @@ +package test + +inline fun doSmth(a: T) : Boolean { + return a.identityEquals(a) +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/ifBranches/1.kt b/compiler/testData/codegen/boxInline/ifBranches/1.kt new file mode 100644 index 00000000000..5db8c03ec61 --- /dev/null +++ b/compiler/testData/codegen/boxInline/ifBranches/1.kt @@ -0,0 +1,43 @@ +import test.* + +fun testIf(): String { + if (runIf({it}, 11, 11, 12) != 11) return "testIf 1 test fail" + if (runIf({it}, 11, 1, 12) != 12) return "testIf 2 test fail" + + if (runIf({if (it == 11) it else 12}, 11, 11, 0) != 11) return "testIf 3 test fail" + if (runIf({if (it == 11) it else 12}, 11, 1, 0) != 12) return "testIf 4 test fail" + + return "OK" +} + +fun testIf2(): String { + if (runIf2({it}, 11, 11, 12) != 11) return "testIf2 1 test fail" + if (runIf2({it}, 11, 1, 12) != 12) return "testIf2 2 test fail" + + if (runIf2({if (it == 11) it else 12}, 11, 11, 0) != 11) return "testIf2 3 test fail" + if (runIf2({if (it == 11) it else 12}, 11, 1, 0) != 12) return "testIf2 4 test fail" + + return "OK" +} + +fun testIfElse(): String { + if (runIfElse({it}, 11, 11, 12) != 11) return "testIfElse 1 test fail" + if (runIfElse({it}, 11, 1, 12) != 12) return "testIfElse 2 test fail" + + if (runIfElse({if (it == 11) it else 12}, 11, 11, 0) != 11) return "testIfElse 3 test fail" + if (runIfElse({if (it == 11) it else 12}, 11, 1, 0) != 12) return "testIfElse 4 test fail" + return "OK" +} + +fun box(): String { + var result = testIf() + if (result != "OK") return "fail1: ${result}" + + result = testIf2() + if (result != "OK") return "fail2: ${result}" + + result = testIfElse() + if (result != "OK") return "fail2: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/ifBranches/2.kt b/compiler/testData/codegen/boxInline/ifBranches/2.kt new file mode 100644 index 00000000000..df854b96662 --- /dev/null +++ b/compiler/testData/codegen/boxInline/ifBranches/2.kt @@ -0,0 +1,25 @@ +package test + +inline fun runIf(f: (T) -> T, start: T, stop: T, secondStart: T) : T { + if (f(start) == stop) { + return f(start) + } + return f(secondStart) +} + + +inline fun runIf2(f: (T) -> T, start: T, stop: T, secondStart: T) : T { + val result = f(start) + if (result == stop) { + return result + } + return f(secondStart) +} + +inline fun runIfElse(f: (T) -> T, start: T, stop: T, secondStart: T) : T { + if (f(start) == stop) { + return f(start) + } else { + return f(secondStart) + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/iinc/1.kt b/compiler/testData/codegen/boxInline/iinc/1.kt new file mode 100644 index 00000000000..fb46f17e338 --- /dev/null +++ b/compiler/testData/codegen/boxInline/iinc/1.kt @@ -0,0 +1,13 @@ +fun test1(): Int { + var s = 0; + 2.times2 { + s++ + } + return s; +} + +fun box(): String { + if (test1() != 2) return "test1: ${test1()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/iinc/2.kt b/compiler/testData/codegen/boxInline/iinc/2.kt new file mode 100644 index 00000000000..6c610eff998 --- /dev/null +++ b/compiler/testData/codegen/boxInline/iinc/2.kt @@ -0,0 +1,7 @@ +public inline fun Int.times2(body : () -> Unit) { + var count = this; + while (count > 0) { + body() + count-- + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/inlineChain/1.kt b/compiler/testData/codegen/boxInline/inlineChain/1.kt new file mode 100644 index 00000000000..d05e7703a57 --- /dev/null +++ b/compiler/testData/codegen/boxInline/inlineChain/1.kt @@ -0,0 +1,18 @@ +fun test1(): String { + val inlineX = My() + var d = ""; + inlineX.doWork({(z: String) -> d = z; z}) + return d +} + +fun test2(): Int { + val inlineX = My() + return inlineX.perform({(z: My) -> 11}) +} + +fun box(): String { + if (test1() != "OK") return "test1: ${test1()}" + if (test2() != 11) return "test1: ${test2()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/inlineChain/2.kt b/compiler/testData/codegen/boxInline/inlineChain/2.kt new file mode 100644 index 00000000000..180494efaa9 --- /dev/null +++ b/compiler/testData/codegen/boxInline/inlineChain/2.kt @@ -0,0 +1,20 @@ +class My + +inline fun T.perform(job: (T)-> R) : R { + return job(this) +} + + +inline fun My.someWork(job: (String) -> Any): Unit { + this.perform { + job("OK") + } +} + +inline fun My.doWork (closure : (param : String) -> Unit) : Unit { + this.someWork(closure) +} + +inline fun My.doPerform (closure : (param : My) -> Int) : Int { + return perform(closure) +} diff --git a/compiler/testData/codegen/boxInline/lambdaClassClash/1.kt b/compiler/testData/codegen/boxInline/lambdaClassClash/1.kt new file mode 100644 index 00000000000..2e5353e11cd --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaClassClash/1.kt @@ -0,0 +1,12 @@ +import zzz.* + +fun box(): String { + + val p = { calc { 11 }} () + + val z = { calc { 12 }}() + + if (p == z) return "fail" + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/lambdaClassClash/2.kt b/compiler/testData/codegen/boxInline/lambdaClassClash/2.kt new file mode 100644 index 00000000000..76f1b12511f --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaClassClash/2.kt @@ -0,0 +1,9 @@ +package zzz + +inline fun calc(lambda: () -> Int): Int { + return doCalc { lambda() } +} + +fun doCalc(lambda2: () -> Int): Int { + return lambda2() +} diff --git a/compiler/testData/codegen/boxInline/lambdaCloning/1.kt b/compiler/testData/codegen/boxInline/lambdaCloning/1.kt new file mode 100644 index 00000000000..949e7bb68f0 --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaCloning/1.kt @@ -0,0 +1,19 @@ +import test.* + +fun test1(s: Long): String { + return doSmth(s) +} + +fun test2(s: Int): String { + return doSmth2(s) +} + +fun box(): String { + var result = test1(11.toLong()) + if (result != "11") return "fail1: ${result}" + + result = test2(11) + if (result != "11") return "fail2: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/lambdaCloning/2.kt b/compiler/testData/codegen/boxInline/lambdaCloning/2.kt new file mode 100644 index 00000000000..6a5cf778de5 --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaCloning/2.kt @@ -0,0 +1,9 @@ +package test + +inline fun doSmth(a: T) : String { + return {a.toString()}() +} + +inline fun doSmth2(a: T) : String { + return {{a.toString()}()}() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/lambdaInLambda/1.kt b/compiler/testData/codegen/boxInline/lambdaInLambda/1.kt new file mode 100644 index 00000000000..ade1b1d20cc --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaInLambda/1.kt @@ -0,0 +1,23 @@ +import test.* +import java.util.* + + +fun sample(): Input { + return Input("Hello", "World"); +} + +test fun testForEachLine() { + val list = ArrayList() + val reader = sample() + + reader.forEachLine{ + list.add("111") + } +} + + +fun box(): String { + testForEachLine() + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/lambdaInLambda/2.kt b/compiler/testData/codegen/boxInline/lambdaInLambda/2.kt new file mode 100644 index 00000000000..f362630297d --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaInLambda/2.kt @@ -0,0 +1,19 @@ +package test + +public class Input(val s1: String, val s2: String) { + public fun iterator() : Iterator { + return arrayListOf(s1, s2).iterator() + } +} + +public inline fun T.use(block: ()-> R) : R { + return block() +} + +public inline fun T.use2(block: ()-> R) : R { + return block() +} + +public inline fun Input.forEachLine(block: () -> Unit): Unit { + use { use2 (block) } +} diff --git a/compiler/testData/codegen/boxInline/lambdaInLambda2/1.kt b/compiler/testData/codegen/boxInline/lambdaInLambda2/1.kt new file mode 100644 index 00000000000..d802ad3891b --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaInLambda2/1.kt @@ -0,0 +1,22 @@ +import test.* +import java.util.* + +fun test1(prefix: String): String { + var result = "fail" + mfun { + concat("start") { + if (it.startsWith(prefix)) { + result = "OK" + } + } + } + + return result +} + +fun box(): String { + if (test1("start") != "OK") return "fail1" + if (test1("nostart") != "fail") return "fail2" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/lambdaInLambda2/2.kt b/compiler/testData/codegen/boxInline/lambdaInLambda2/2.kt new file mode 100644 index 00000000000..7ef3b1ad153 --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaInLambda2/2.kt @@ -0,0 +1,9 @@ +package test + +inline fun mfun(f: () -> R) { + f() +} + +fun concat(suffix: String, l: (s: String) -> Unit) { + l(suffix) +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/lambdaInLambdaNoInline/1.kt b/compiler/testData/codegen/boxInline/lambdaInLambdaNoInline/1.kt new file mode 100644 index 00000000000..b1a1bb5e49d --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaInLambdaNoInline/1.kt @@ -0,0 +1,19 @@ +import test.* + +fun test1(param: String): String { + var result = "fail1" + mfun(param) { a -> + concat("start") { + result = doSmth(a).toString() + } + } + + return result +} + +fun box(): String { + if (test1("start") != "start") return "fail1" + if (test1("nostart") != "nostart") return "fail2" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/lambdaInLambdaNoInline/2.kt b/compiler/testData/codegen/boxInline/lambdaInLambdaNoInline/2.kt new file mode 100644 index 00000000000..6c89799fa66 --- /dev/null +++ b/compiler/testData/codegen/boxInline/lambdaInLambdaNoInline/2.kt @@ -0,0 +1,13 @@ +package test + +fun concat(suffix: String, l: (s: String) -> Unit) { + l(suffix) +} + +fun mfun(arg: T, f: (T) -> Unit) { + f(arg) +} + +inline fun doSmth(a: String): String { + return a.toString() +} diff --git a/compiler/testData/codegen/boxInline/localFunInLambda/1.kt b/compiler/testData/codegen/boxInline/localFunInLambda/1.kt new file mode 100644 index 00000000000..a73394908af --- /dev/null +++ b/compiler/testData/codegen/boxInline/localFunInLambda/1.kt @@ -0,0 +1,21 @@ +import test.* + +fun test1(d: Data): Int { + val input = Input(d) + var result = 10 + with(input) { + fun localFun() { + result = input.d.value + } + localFun() + } + return result +} + + +fun box(): String { + val result = test1(Data(11)) + if (result != 11) return "test1: ${result}" + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/localFunInLambda/2.kt b/compiler/testData/codegen/boxInline/localFunInLambda/2.kt new file mode 100644 index 00000000000..d1f197c475e --- /dev/null +++ b/compiler/testData/codegen/boxInline/localFunInLambda/2.kt @@ -0,0 +1,12 @@ +package test + +public class Data(val value: Int) + +public class Input(val d: Data) { + public fun data() : Int = 100 +} + +public inline fun use(block: ()-> R) : R { + return block() +} + diff --git a/compiler/testData/codegen/boxInline/noInline/1.kt b/compiler/testData/codegen/boxInline/noInline/1.kt new file mode 100644 index 00000000000..4358f5acfe5 --- /dev/null +++ b/compiler/testData/codegen/boxInline/noInline/1.kt @@ -0,0 +1,10 @@ +fun test1(): Int { + return calc( {(l : Int) -> 2*l}, {(l : Int) -> 4*l}) +} + + +fun box(): String { + if (test1() != 110) return "test1: ${test1()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/noInline/2.kt b/compiler/testData/codegen/boxInline/noInline/2.kt new file mode 100644 index 00000000000..9e38ef9e91e --- /dev/null +++ b/compiler/testData/codegen/boxInline/noInline/2.kt @@ -0,0 +1,4 @@ +inline fun calc(s: (Int) -> Int, noinline p: (Int) -> Int) : Int { + val z = p + return s(11) + z(11) + p(11) +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/noInlineLambdaX2/1.kt b/compiler/testData/codegen/boxInline/noInlineLambdaX2/1.kt new file mode 100644 index 00000000000..5725dfd6be7 --- /dev/null +++ b/compiler/testData/codegen/boxInline/noInlineLambdaX2/1.kt @@ -0,0 +1,10 @@ +fun test1(): Int { + return 1.inlineMethod() +} + +fun box(): String { + val result = test1() + if (result != 2) return "test1: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/noInlineLambdaX2/2.kt b/compiler/testData/codegen/boxInline/noInlineLambdaX2/2.kt new file mode 100644 index 00000000000..ba2101437aa --- /dev/null +++ b/compiler/testData/codegen/boxInline/noInlineLambdaX2/2.kt @@ -0,0 +1,8 @@ +var s: Int = 1; + +inline fun Int.inlineMethod() : Int { + noInlineLambda() + return noInlineLambda() +} + +inline fun Int.noInlineLambda() = { s++ } () diff --git a/compiler/testData/codegen/boxInline/params/1.kt b/compiler/testData/codegen/boxInline/params/1.kt new file mode 100644 index 00000000000..5548d48836f --- /dev/null +++ b/compiler/testData/codegen/boxInline/params/1.kt @@ -0,0 +1,32 @@ + +fun test1(): Int { + val inlineX = Inline() + return inlineX.foo1Int({(z: Int) -> z}, 25) +} + +fun test2(): Double { + val inlineX = Inline() + return inlineX.foo1Double(25.0, {(z: Double) -> z}) +} + +fun test3(): Double { + val inlineX = Inline() + return inlineX.foo2Param(15.0, {(z1: Int, z2: Double) -> z1 + z2}, 10) +} + +fun test3WithCaptured(): Double { + val inlineX = Inline() + var c = 11.0; + return inlineX.foo2Param(15.0, {(z1: Int, z2: Double) -> z1 + z2 + c}, 10) +} + + +fun box(): String { + if (test1() != 25) return "test1: ${test1()}" + if (test2() != 25.0) return "test2: ${test2()}" + if (test3() != 25.0) return "test3: ${test3()}" + if (test3WithCaptured() != 36.0) return "test3WithCaptured: ${test3WithCaptured()}" + + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/params/2.kt b/compiler/testData/codegen/boxInline/params/2.kt new file mode 100644 index 00000000000..f4ce53f635f --- /dev/null +++ b/compiler/testData/codegen/boxInline/params/2.kt @@ -0,0 +1,15 @@ +class Inline() { + + inline fun foo1Int(s : (l: Int) -> Int, param: Int) : Int { + return s(param) + } + + inline fun foo1Double(param: Double, s : (l: Double) -> Double) : Double { + return s(param) + } + + inline fun foo2Param(param1: Double, s : (i: Int, l: Double) -> Double, param2: Int) : Double { + return s(param2, param1) + } +} + diff --git a/compiler/testData/codegen/boxInline/plusAssign/1.kt b/compiler/testData/codegen/boxInline/plusAssign/1.kt new file mode 100644 index 00000000000..3d37d0baa6d --- /dev/null +++ b/compiler/testData/codegen/boxInline/plusAssign/1.kt @@ -0,0 +1,14 @@ +import test.* + +fun test1(s: Int): Int { + val z = Z(s) + z += {s} + return z.s +} + +fun box(): String { + val result = test1(11) + if (result != 22) return "fail1: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/plusAssign/2.kt b/compiler/testData/codegen/boxInline/plusAssign/2.kt new file mode 100644 index 00000000000..aa534265ff3 --- /dev/null +++ b/compiler/testData/codegen/boxInline/plusAssign/2.kt @@ -0,0 +1,7 @@ +package test + +public class Z(public var s: Int) + +inline fun Z.plusAssign(lambda: () -> Int) { + this.s += lambda() +} diff --git a/compiler/testData/codegen/boxInline/regeneratedLambdaName/1.kt b/compiler/testData/codegen/boxInline/regeneratedLambdaName/1.kt new file mode 100644 index 00000000000..43ef4fbfb8f --- /dev/null +++ b/compiler/testData/codegen/boxInline/regeneratedLambdaName/1.kt @@ -0,0 +1,23 @@ +import test.* + +fun sameName(s: Long): Long { + return call { + s + } +} + +fun sameName(s: Int): Int { + return call { + s + } +} + +fun box(): String { + val result = sameName(1.toLong()) + if (result != 1.toLong()) return "fail1: ${result}" + + val result2 = sameName(2) + if (result2 != 2) return "fail2: ${result2}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/regeneratedLambdaName/2.kt b/compiler/testData/codegen/boxInline/regeneratedLambdaName/2.kt new file mode 100644 index 00000000000..f063e5ec7e7 --- /dev/null +++ b/compiler/testData/codegen/boxInline/regeneratedLambdaName/2.kt @@ -0,0 +1,5 @@ +package test + +inline fun call(f: () -> R) : R { + return {f()} () +} diff --git a/compiler/testData/codegen/boxInline/rootConstructor/1.kt b/compiler/testData/codegen/boxInline/rootConstructor/1.kt new file mode 100644 index 00000000000..500559012fa --- /dev/null +++ b/compiler/testData/codegen/boxInline/rootConstructor/1.kt @@ -0,0 +1,9 @@ +import test.* + +val s = doWork({11}) + +fun box(): String { + if (s != 11) return "test1: ${s}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/rootConstructor/2.kt b/compiler/testData/codegen/boxInline/rootConstructor/2.kt new file mode 100644 index 00000000000..8d35830e78b --- /dev/null +++ b/compiler/testData/codegen/boxInline/rootConstructor/2.kt @@ -0,0 +1,10 @@ +package test + +inline fun doWork(job: ()-> R) : R { + return notInline({job()}) +} + +fun notInline(job: ()-> R) : R { + return job() +} + diff --git a/compiler/testData/codegen/boxInline/severalClosures/1.kt b/compiler/testData/codegen/boxInline/severalClosures/1.kt new file mode 100644 index 00000000000..75dbbea3542 --- /dev/null +++ b/compiler/testData/codegen/boxInline/severalClosures/1.kt @@ -0,0 +1,23 @@ +fun test1(): Double { + val inlineX = Inline() + return inlineX.foo1({(z: Int) -> z}, 25, {(z: Double) -> z}, 11.5) +} + +fun test1WithCaptured(): Double { + val inlineX = Inline() + var d = 0.0; + return inlineX.foo1({(z: Int) -> d = 1.0; z}, 25, {(z: Double) -> z + d}, 11.5) +} + +fun test2(): Double { + val inlineX = Inline() + return inlineX.foo2({(z: Int, p: Int) -> z + p}, 25, {(x: Double, y: Int, z: Int) -> z + x + y}, 11.5, 2) +} + +fun box(): String { + if (test1() != 36.5) return "test1: ${test1()}" + if (test1WithCaptured() != 37.5) return "test1WithCaptured: ${test1WithCaptured()}" + if (test2() != 65.5) return "test2: ${test2()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/severalClosures/2.kt b/compiler/testData/codegen/boxInline/severalClosures/2.kt new file mode 100644 index 00000000000..f8aeb881852 --- /dev/null +++ b/compiler/testData/codegen/boxInline/severalClosures/2.kt @@ -0,0 +1,11 @@ +class Inline() { + + inline fun foo1(closure1 : (l: Int) -> Int, param1: Int, closure2 : (l: Double) -> Double, param2: Double) : Double { + return closure1(param1) + closure2(param2) + } + + inline fun foo2(closure1 : (Int, Int) -> Int, param1: Int, closure2 : (Double, Int, Int) -> Double, param2: Double, param3: Int) : Double { + return closure1(param1, param3) + closure2(param2, param1, param3) + } +} + diff --git a/compiler/testData/codegen/boxInline/severalUsage/1.kt b/compiler/testData/codegen/boxInline/severalUsage/1.kt new file mode 100644 index 00000000000..d5616fb96c9 --- /dev/null +++ b/compiler/testData/codegen/boxInline/severalUsage/1.kt @@ -0,0 +1,7 @@ +fun box(): String { + val result = runTest{minByTest { it }} + + if (result != 1) return "test1: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/severalUsage/2.kt b/compiler/testData/codegen/boxInline/severalUsage/2.kt new file mode 100644 index 00000000000..2588f476460 --- /dev/null +++ b/compiler/testData/codegen/boxInline/severalUsage/2.kt @@ -0,0 +1,10 @@ +public inline fun runTest(f: () -> R): R { + return f() +} + +public inline fun minByTest(f: (Int) -> R): R { + var minValue = f(1) + val v = f(1) + return v +} + diff --git a/compiler/testData/codegen/boxInline/simpleCapturingInClass/1.kt b/compiler/testData/codegen/boxInline/simpleCapturingInClass/1.kt new file mode 100644 index 00000000000..66e16ee9e2d --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleCapturingInClass/1.kt @@ -0,0 +1,70 @@ +fun testAll(): String { + val inlineX = InlineAll() + + return inlineX.inline({(a1: Int, a2: Double, a3: Double, a4: String, a5: Long) -> + "" + a1 + a2 + a3 + a4 + a5}, + 1, 12.0, 13.0, "14", 15) +} + +fun testAllWithCapturedVal(): String { + val inlineX = InlineAll() + + val c1 = 21 + val c2 = 22.0 + val c3 = 23.0 + val c4 = "24" + val c5 = 25.toLong() + val c6 = 'H' + val c7 = 26.toByte() + val c8 = 27.toShort() + val c9 = 28.toFloat() + + return inlineX.inline({(a1: Int, a2: Double, a3: Double, a4: String, a5: Long) -> + "" + a1 + a2 + a3 + a4 + a5 + c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9}, + 1, 12.0, 13.0, "14", 15) +} + +fun testAllWithCapturedVar(): String { + val inlineX = InlineAll() + + var c1 = 21 + var c2 = 22.0 + var c3 = 23.0 + var c4 = "24" + var c5 = 25.toLong() + var c6 = 'H' + var c7 = 26.toByte() + var c8 = 27.toShort() + val c9 = 28.toFloat() + + return inlineX.inline({(a1: Int, a2: Double, a3: Double, a4: String, a5: Long) -> + "" + a1 + a2 + a3 + a4 + a5 + c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9}, + 1, 12.0, 13.0, "14", 15) +} + +fun testAllWithCapturedValAndVar(): String { + val inlineX = InlineAll() + + var c1 = 21 + var c2 = 22.0 + val c3 = 23.0 + val c4 = "24" + var c5 = 25.toLong() + val c6 = 'H' + var c7 = 26.toByte() + var c8 = 27.toShort() + val c9 = 28.toFloat() + + return inlineX.inline({(a1: Int, a2: Double, a3: Double, a4: String, a5: Long) -> + "" + a1 + a2 + a3 + a4 + a5 + c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9}, + 1, 12.0, 13.0, "14", 15) +} + + +fun box(): String { + if (testAll() != "112.013.01415") return "testAll: ${testAll()}" + if (testAllWithCapturedVal() != "112.013.014152122.023.02425H262728.0") return "testAllWithCapturedVal: ${testAllWithCapturedVal()}" + if (testAllWithCapturedVar() != "112.013.014152122.023.02425H262728.0") return "testAllWithCapturedVar: ${testAllWithCapturedVar()}" + if (testAllWithCapturedValAndVar() != "112.013.014152122.023.02425H262728.0") return "testAllWithCapturedVal: ${testAllWithCapturedValAndVar()}" + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleCapturingInClass/2.kt b/compiler/testData/codegen/boxInline/simpleCapturingInClass/2.kt new file mode 100644 index 00000000000..353dd2dceaa --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleCapturingInClass/2.kt @@ -0,0 +1,7 @@ +class InlineAll { + + inline fun inline(s: (Int, Double, Double, String, Long) -> String, + a1: Int, a2: Double, a3: Double, a4: String, a5: Long): String { + return s(a1, a2, a3, a4, a5) + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleCapturingInPackage/1.kt b/compiler/testData/codegen/boxInline/simpleCapturingInPackage/1.kt new file mode 100644 index 00000000000..d281a5506f2 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleCapturingInPackage/1.kt @@ -0,0 +1,62 @@ +fun testAll(): String { + return inline({(a1: Int, a2: Double, a3: Double, a4: String, a5: Long) -> + "" + a1 + a2 + a3 + a4 + a5}, + 1, 12.0, 13.0, "14", 15) +} + +fun testAllWithCapturedVal(): String { + val c1 = 21 + val c2 = 22.0 + val c3 = 23.0 + val c4 = "24" + val c5 = 25.toLong() + val c6 = 'H' + val c7 = 26.toByte() + val c8 = 27.toShort() + val c9 = 28.toFloat() + + return inline({(a1: Int, a2: Double, a3: Double, a4: String, a5: Long) -> + "" + a1 + a2 + a3 + a4 + a5 + c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9}, + 1, 12.0, 13.0, "14", 15) +} + +fun testAllWithCapturedVar(): String { + var c1 = 21 + var c2 = 22.0 + var c3 = 23.0 + var c4 = "24" + var c5 = 25.toLong() + var c6 = 'H' + var c7 = 26.toByte() + var c8 = 27.toShort() + val c9 = 28.toFloat() + + return inline({(a1: Int, a2: Double, a3: Double, a4: String, a5: Long) -> + "" + a1 + a2 + a3 + a4 + a5 + c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9}, + 1, 12.0, 13.0, "14", 15) +} + +fun testAllWithCapturedValAndVar(): String { + var c1 = 21 + var c2 = 22.0 + val c3 = 23.0 + val c4 = "24" + var c5 = 25.toLong() + val c6 = 'H' + var c7 = 26.toByte() + var c8 = 27.toShort() + val c9 = 28.toFloat() + + return inline({(a1: Int, a2: Double, a3: Double, a4: String, a5: Long) -> + "" + a1 + a2 + a3 + a4 + a5 + c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9}, + 1, 12.0, 13.0, "14", 15) +} + + +fun box(): String { + if (testAll() != "112.013.01415") return "testAll: ${testAll()}" + if (testAllWithCapturedVal() != "112.013.014152122.023.02425H262728.0") return "testAllWithCapturedVal: ${testAllWithCapturedVal()}" + if (testAllWithCapturedVar() != "112.013.014152122.023.02425H262728.0") return "testAllWithCapturedVar: ${testAllWithCapturedVar()}" + if (testAllWithCapturedValAndVar() != "112.013.014152122.023.02425H262728.0") return "testAllWithCapturedVal: ${testAllWithCapturedValAndVar()}" + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleCapturingInPackage/2.kt b/compiler/testData/codegen/boxInline/simpleCapturingInPackage/2.kt new file mode 100644 index 00000000000..1665ae4ae5d --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleCapturingInPackage/2.kt @@ -0,0 +1,4 @@ +inline fun inline(s: (Int, Double, Double, String, Long) -> String, + a1: Int, a2: Double, a3: Double, a4: String, a5: Long): String { + return s(a1, a2, a3, a4, a5) +} diff --git a/compiler/testData/codegen/boxInline/simpleDouble/1.kt b/compiler/testData/codegen/boxInline/simpleDouble/1.kt new file mode 100644 index 00000000000..4ae0853ab60 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleDouble/1.kt @@ -0,0 +1,48 @@ +fun test0Param(): Double { + val inlineX = InlineDouble(10.0) + return inlineX.foo({() -> 1.0}) +} + +fun test1Param(): Double { + val inlineX = InlineDouble(10.0) + return inlineX.foo11({(z: Double) -> z}) +} + +fun test1ParamCaptured(): Double { + val s = 100.0 + val inlineX = InlineDouble(10.0) + return inlineX.foo11({(z: Double) -> s}) +} + +fun test1ParamMissed() : Double { + val inlineX = InlineDouble(10.0) + return inlineX.foo11({(z: Double) -> 111.0}) +} + +fun test1ParamFromCallContext() : Double { + val inlineX = InlineDouble(1000.0) + return inlineX.fooRes({(z: Double) -> z}) +} + +fun test2Params() : Double { + val inlineX = InlineDouble(1000.0) + return inlineX.fooRes2({(y: Double, z: Double) -> 2.0 * y + 3.0 * z}) +} + +fun test2ParamsWithCaptured() : Double { + val inlineX = InlineDouble(1000.0) + val s = 9.0 + var t = 1.0 + return inlineX.fooRes2({(y: Double, z: Double) -> 2.0 * s + t}) +} + +fun box(): String { + if (test0Param() != 1.0) return "test0Param" + if (test1Param() != 11.0) return "test1Param()" + if (test1ParamCaptured() != 100.0) return "testtest1ParamCaptured()" + if (test1ParamMissed() != 111.0) return "test1ParamMissed()" + if (test1ParamFromCallContext() != 1000.0) return "test1ParamFromCallContext()" + if (test2Params() != 35.0) return "test2Params()" + if (test2ParamsWithCaptured() != 19.0) return "test2ParamsWithCaptured()" + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/simpleDouble/2.kt b/compiler/testData/codegen/boxInline/simpleDouble/2.kt new file mode 100644 index 00000000000..cdd765e2fae --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleDouble/2.kt @@ -0,0 +1,23 @@ +class InlineDouble(val res : Double) { + + inline fun foo(s : () -> Double) : Double { + val f = "fooStart" + val z = s() + return z + } + + inline fun foo11(s : (l: Double) -> Double) : Double { + return s(11.0) + } + + inline fun fooRes(s : (l: Double) -> Double) : Double { + val z = s(res) + return z + } + + inline fun fooRes2(s : (l: Double, t: Double) -> Double) : Double { + val f = "fooRes2Start" + val z = s(1.0, 11.0) + return z + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleEnum/1.kt b/compiler/testData/codegen/boxInline/simpleEnum/1.kt new file mode 100644 index 00000000000..c2cfb07fa66 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleEnum/1.kt @@ -0,0 +1,12 @@ +import test.* + +fun test1(): String { + return MyEnum.K.doSmth("O") +} + +fun box(): String { + val result = test1() + if (result != "OK") return "fail1: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleEnum/2.kt b/compiler/testData/codegen/boxInline/simpleEnum/2.kt new file mode 100644 index 00000000000..a1709b2f3ea --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleEnum/2.kt @@ -0,0 +1,9 @@ +package test + +enum class MyEnum { + K; + + inline fun doSmth(a: T) : String { + return a.toString() + K.name() + } +} diff --git a/compiler/testData/codegen/boxInline/simpleGenerics/1.kt b/compiler/testData/codegen/boxInline/simpleGenerics/1.kt new file mode 100644 index 00000000000..ca3de1f3956 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleGenerics/1.kt @@ -0,0 +1,12 @@ +import test.* + +fun test1(s: Long): String { + return doSmth(s) +} + +fun box(): String { + val result = test1(11.toLong()) + if (result != "11") return "fail1: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleGenerics/2.kt b/compiler/testData/codegen/boxInline/simpleGenerics/2.kt new file mode 100644 index 00000000000..bfb4c576bf4 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleGenerics/2.kt @@ -0,0 +1,5 @@ +package test + +inline fun doSmth(a: T) : String { + return a.toString() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleInt/1.kt b/compiler/testData/codegen/boxInline/simpleInt/1.kt new file mode 100644 index 00000000000..94e83c10a9f --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleInt/1.kt @@ -0,0 +1,48 @@ +fun test0Param(): Int { + val inlineX = Inline(10) + return inlineX.foo({() -> 1}) +} + +fun test1Param(): Int { + val inlineX = Inline(10) + return inlineX.foo11({(z: Int) -> z}) +} + +fun test1ParamCaptured(): Int { + val s = 100 + val inlineX = Inline(10) + return inlineX.foo11({(z: Int) -> s}) +} + +fun test1ParamMissed() : Int { + val inlineX = Inline(10) + return inlineX.foo11({(z: Int) -> 111}) +} + +fun test1ParamFromCallContext() : Int { + val inlineX = Inline(1000) + return inlineX.fooRes({(z: Int) -> z}) +} + +fun test2Params() : Int { + val inlineX = Inline(1000) + return inlineX.fooRes2({(y: Int, z: Int) -> 2 * y + 3 * z}) +} + +fun test2ParamsWithCaptured() : Int { + val inlineX = Inline(1000) + val s = 9 + var t = 1 + return inlineX.fooRes2({(y: Int, z: Int) -> 2 * s + t}) +} + +fun box(): String { + if (test0Param() != 1) return "test0Param: ${test0Param()}" + if (test1Param() != 11) return "test1Param: ${test1Param()}" + if (test1ParamCaptured() != 100) return "test1ParamCaptured: ${test1ParamCaptured()}" + if (test1ParamMissed() != 111) return "test1ParamMissed: ${test1ParamMissed()}" + if (test1ParamFromCallContext() != 1000) return "test1ParamFromCallContext: ${test1ParamFromCallContext()}" + if (test2Params() != 35) return "test2Params: ${test2Params()}" + if (test2ParamsWithCaptured() != 19) return "test2ParamsWithCaptured: ${test2ParamsWithCaptured()}" + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleInt/2.kt b/compiler/testData/codegen/boxInline/simpleInt/2.kt new file mode 100644 index 00000000000..d603e3a95a6 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleInt/2.kt @@ -0,0 +1,24 @@ +class Inline(val res : Int) { + + inline fun foo(s : () -> Int) : Int { + val f = "fooStart" + val z = s() + return z + } + + inline fun foo11(s : (l: Int) -> Int) : Int { + return s(11) + } + + inline fun fooRes(s : (l: Int) -> Int) : Int { + val z = s(res) + return z + } + + inline fun fooRes2(s : (l: Int, t: Int) -> Int) : Int { + val f = "fooRes2Start" + val z = s(1, 11) + return z + } +} + diff --git a/compiler/testData/codegen/boxInline/simpleLambda/1.kt b/compiler/testData/codegen/boxInline/simpleLambda/1.kt new file mode 100644 index 00000000000..5faf5c6f9b6 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleLambda/1.kt @@ -0,0 +1,23 @@ +import test.* + +class Z {} + +fun test1() : Int { + val input = Z() + return input.use{ + 100 + } +} + +fun test2() : Int { + val x = 1000 + return use2() + x +} + + +fun box(): String { + if (test1() != 100) return "test1: ${test1()}" + if (test2() != 1100) return "test1: ${test2()}" + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/simpleLambda/2.kt b/compiler/testData/codegen/boxInline/simpleLambda/2.kt new file mode 100644 index 00000000000..dc9d31f6be5 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleLambda/2.kt @@ -0,0 +1,14 @@ +package test + +public class Data() + +public inline fun T.use(block: (T)-> R) : R { + return block(this) +} + +public inline fun use2() : Int { + val s = 100 + return s +} + + diff --git a/compiler/testData/codegen/boxInline/simpleObject/1.kt b/compiler/testData/codegen/boxInline/simpleObject/1.kt new file mode 100644 index 00000000000..1578ba88194 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleObject/1.kt @@ -0,0 +1,49 @@ +fun test0Param(): String { + val inlineX = InlineString("10") + return inlineX.foo({() -> "1"}) +} + +fun test1Param(): String { + val inlineX = InlineString("10") + return inlineX.foo11({(z: String) -> z}) +} + +fun test1ParamCaptured(): String { + val s = "100" + val inlineX = InlineString("10") + return inlineX.foo11({(z: String) -> s}) +} + +fun test1ParamMissed() : String { + val inlineX = InlineString("10") + return inlineX.foo11({(z: String) -> "111"}) +} + +fun test1ParamFromCallContext() : String { + val inlineX = InlineString("1000") + return inlineX.fooRes({(z: String) -> z}) +} + +fun test2Params() : String { + val inlineX = InlineString("1000") + return inlineX.fooRes2({(y: String, z: String) -> y + "0" + z}) +} + +fun test2ParamsWithCaptured() : String { + val inlineX = InlineString("1000") + val s = "9" + var t = "1" + return inlineX.fooRes2({(y: String, z: String) -> s + t}) +} + +fun box(): String { + if (test0Param() != "1") return "test0Param: ${test0Param()}" + if (test1Param() != "11") return "test1Param: ${test1Param()}" + if (test1ParamCaptured() != "100") return "test1ParamCaptured: ${test1ParamCaptured()}" + if (test1ParamMissed() != "111") return "test1ParamMissed: ${test1ParamMissed()}" + if (test1ParamFromCallContext() != "1000") return "test1ParamFromCallContext: ${test1ParamFromCallContext()}" + if (test2Params() != "1011") return "test2Params: ${test2Params()}" + if (test2ParamsWithCaptured() != "91") return "test2ParamsWithCaptured: ${test2ParamsWithCaptured()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/simpleObject/2.kt b/compiler/testData/codegen/boxInline/simpleObject/2.kt new file mode 100644 index 00000000000..7038676faf8 --- /dev/null +++ b/compiler/testData/codegen/boxInline/simpleObject/2.kt @@ -0,0 +1,24 @@ +class InlineString(val res : String) { + + inline fun foo(s : () -> String) : String { + val f = "fooStart" + val z = s() + return z + } + + inline fun foo11(s : (l: String) -> String) : String { + return s("11") + } + + inline fun fooRes(s : (l: String) -> String) : String { + val z = s(res) + return z + } + + inline fun fooRes2(s : (l: String, t: String) -> String) : String { + val f = "fooRes2Start" + val z = s("1", "11") + return z + } +} + diff --git a/compiler/testData/codegen/boxInline/stackHeightBug/1.kt b/compiler/testData/codegen/boxInline/stackHeightBug/1.kt new file mode 100644 index 00000000000..8c191bf5e98 --- /dev/null +++ b/compiler/testData/codegen/boxInline/stackHeightBug/1.kt @@ -0,0 +1,6 @@ +import test.* + +fun box(): String { + mfun{ "".toLowerCase2() } + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/stackHeightBug/2.kt b/compiler/testData/codegen/boxInline/stackHeightBug/2.kt new file mode 100644 index 00000000000..d23cea583c3 --- /dev/null +++ b/compiler/testData/codegen/boxInline/stackHeightBug/2.kt @@ -0,0 +1,8 @@ +package test + +inline fun mfun(f: () -> R) { + f() + f() +} + +public inline fun String.toLowerCase2() : String = "" \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/trait/1.kt b/compiler/testData/codegen/boxInline/trait/1.kt new file mode 100644 index 00000000000..3729daa69e0 --- /dev/null +++ b/compiler/testData/codegen/boxInline/trait/1.kt @@ -0,0 +1,21 @@ +import test.* + +fun testFinalInline(): String { + return Z().finalInline({"final"}) +} + +fun testFinalInline2(instance: InlineTrait): String { + return instance.finalInline({"final2"}) +} + +fun testClassObject(): String { + return InlineTrait.finalInline({"classobject"}) +} + +fun box(): String { + if (testFinalInline() != "final") return "test1: ${testFinalInline()}" + if (testFinalInline2(Z()) != "final2") return "test2: ${testFinalInline2(Z())}" + if (testClassObject() != "classobject") return "test3: ${testClassObject()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/trait/2.kt b/compiler/testData/codegen/boxInline/trait/2.kt new file mode 100644 index 00000000000..56c55a4f6f5 --- /dev/null +++ b/compiler/testData/codegen/boxInline/trait/2.kt @@ -0,0 +1,18 @@ +package test + +trait InlineTrait { + + inline final fun finalInline(s: () -> String): String { + return s() + } + + class object { + inline final fun finalInline(s: () -> String): String { + return s() + } + } +} + +class Z: InlineTrait { + +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/tryCatch/1.kt b/compiler/testData/codegen/boxInline/tryCatch/1.kt new file mode 100644 index 00000000000..3561bd036ad --- /dev/null +++ b/compiler/testData/codegen/boxInline/tryCatch/1.kt @@ -0,0 +1,53 @@ +fun test1() : Int { + val inlineX = My(111) + var result = 0 + val res = inlineX.perform{ + + try { + throw RuntimeException() + } catch (e: RuntimeException) { + result = -1 + } + result + } + + return result +} + +fun test11() : Int { + val inlineX = My(111) + val res = inlineX.perform{ + try { + throw RuntimeException() + } catch (e: RuntimeException) { + -1 + } + } + + return res +} + +fun test2() : Int { + try { + val inlineX = My(111) + var result = 0 + val res = inlineX.perform{ + try { + throw RuntimeException("-1") + } catch (e: RuntimeException) { + throw RuntimeException("-2") + } + } + return result + } catch (e: RuntimeException) { + return e.getMessage()!!.toInt2()!! + } +} + +fun box(): String { + if (test1() != -1) return "test1: ${test1()}" + if (test11() != -1) return "test11: ${test11()}" + if (test2() != -2) return "test2: ${test2()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/tryCatch/2.kt b/compiler/testData/codegen/boxInline/tryCatch/2.kt new file mode 100644 index 00000000000..ca206130b36 --- /dev/null +++ b/compiler/testData/codegen/boxInline/tryCatch/2.kt @@ -0,0 +1,7 @@ +class My(val value: Int) + +inline fun T.perform(job: (T)-> R) : R { + return job(this) +} + +public inline fun String.toInt2() : Int = java.lang.Integer.parseInt(this) \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/tryCatch2/1.kt b/compiler/testData/codegen/boxInline/tryCatch2/1.kt new file mode 100644 index 00000000000..f51d910d570 --- /dev/null +++ b/compiler/testData/codegen/boxInline/tryCatch2/1.kt @@ -0,0 +1,107 @@ +fun test1(): Int { + val res = My(111).performWithFail( + { + throw RuntimeException() + }, { + it.value + }) + return res +} + +fun test11(): Int { + val res = My(111).performWithFail2( + { + try { + throw RuntimeException("1") + } catch (e: RuntimeException) { + throw RuntimeException("2") + } + }, + {(ex, thizz) -> + if (ex.getMessage() == "2") { + thizz.value + } else { + -11111 + } + }) + return res +} + +fun test2(): Int { + val res = My(111).performWithFail( + { + it.value + }, + { + it.value + 1 + }) + return res +} + +fun test22(): Int { + val res = My(111).performWithFail2( + { + try { + throw RuntimeException("1") + } catch (e: RuntimeException) { + it.value + 111 + } + }, + {(ex, thizz) -> + -11111 + }) + + return res +} + + +fun test3(): Int { + try { + val res = My(111).performWithFail( + { + throw RuntimeException("-1") + }, { + throw RuntimeException("-2") + }) + return res + } catch (e: RuntimeException) { + return e.getMessage()?.toInt2()!! + } +} + +fun test33(): Int { + try { + val res = My(111).performWithFail2( + { + try { + throw RuntimeException("-1") + } catch (e: RuntimeException) { + throw RuntimeException("-2") + } + }, + {(ex, thizz) -> + if (ex.getMessage() == "-2") { + throw RuntimeException("-3") + } else { + -11111 + } + }) + return res + } catch (e: RuntimeException) { + return e.getMessage()!!.toInt2()!! + } +} + +fun box(): String { + if (test1() != 111) return "test1: ${test1()}" + if (test11() != 111) return "test11: ${test11()}" + + if (test2() != 111) return "test2: ${test2()}" + if (test22() != 111) return "test22: ${test22()}" + + if (test3() != -2) return "test3: ${test3()}" + if (test33() != -3) return "test33: ${test33()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/tryCatch2/2.kt b/compiler/testData/codegen/boxInline/tryCatch2/2.kt new file mode 100644 index 00000000000..ac6eb698105 --- /dev/null +++ b/compiler/testData/codegen/boxInline/tryCatch2/2.kt @@ -0,0 +1,19 @@ +class My(val value: Int) + +inline fun T.performWithFail(job: (T)-> R, failJob : (T) -> R) : R { + try { + return job(this) + } catch (e: RuntimeException) { + return failJob(this) + } +} + +inline fun T.performWithFail2(job: (T)-> R, failJob : (e: RuntimeException, T) -> R) : R { + try { + return job(this) + } catch (e: RuntimeException) { + return failJob(e, this) + } +} + +public inline fun String.toInt2() : Int = java.lang.Integer.parseInt(this) \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/tryCatchFinally/1.kt b/compiler/testData/codegen/boxInline/tryCatchFinally/1.kt new file mode 100644 index 00000000000..b5c38dc9279 --- /dev/null +++ b/compiler/testData/codegen/boxInline/tryCatchFinally/1.kt @@ -0,0 +1,73 @@ +fun test1(): Int { + + var res = My(111).performWithFinally( + { + 1 + }, { + it.value + }) + return res +} + +fun test11(): Int { + var result = -1; + val res = My(111).performWithFinally( + { + try { + result = it.value + throw RuntimeException("1") + } catch (e: RuntimeException) { + ++result + throw RuntimeException("2") + } + }, + { + ++result + }) + return res +} + +fun test2(): Int { + var res = My(111).performWithFinally( + { + throw RuntimeException("1") + }, + { + it.value + }) + + + return res +} + +fun test3(): Int { + try { + var result = -1; + val res = My(111).performWithFailFinally( + { + result = it.value; + throw RuntimeException("-1") + }, + { (e, z)-> + ++result + throw RuntimeException("-2") + }, + { + ++result + }) + return res + } catch (e: RuntimeException) { + return e.getMessage()?.toInt()!! + } +} + +fun box(): String { + if (test1() != 111) return "test1: ${test1()}" + if (test11() != 113) return "test11: ${test11()}" + + if (test2() != 111) return "test2: ${test2()}" + + if (test3() != 113) return "test3: ${test3()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/tryCatchFinally/2.kt b/compiler/testData/codegen/boxInline/tryCatchFinally/2.kt new file mode 100644 index 00000000000..3cace55b524 --- /dev/null +++ b/compiler/testData/codegen/boxInline/tryCatchFinally/2.kt @@ -0,0 +1,21 @@ +class My(val value: Int) + +inline fun T.performWithFinally(job: (T)-> R, finally: (T) -> R) : R { + try { + return job(this) + } finally { + return finally(this) + } +} + +inline fun T.performWithFailFinally(job: (T)-> R, failJob : (e: RuntimeException, T) -> R, finally: (T) -> R) : R { + try { + return job(this) + } catch (e: RuntimeException) { + return failJob(e, this) + } finally { + return finally(this) + } +} + +inline fun String.toInt2() : Int = java.lang.Integer.parseInt(this) \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/use/1.kt b/compiler/testData/codegen/boxInline/use/1.kt new file mode 100644 index 00000000000..9f674c2cbb7 --- /dev/null +++ b/compiler/testData/codegen/boxInline/use/1.kt @@ -0,0 +1,22 @@ +import test.* + + +fun Data.test1(d: Data) : Long { + val input2 = Input(this) + val input = Input(this) + return input.use{ + val output = Output(d) + output.use{ + input.copyTo(output, 10) + } + } +} + + +fun box(): String { + + val result = Data().test1(Data()) + if (result != 100.toLong()) return "test1: ${result}" + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/use/2.kt b/compiler/testData/codegen/boxInline/use/2.kt new file mode 100644 index 00000000000..0c74af1e7b2 --- /dev/null +++ b/compiler/testData/codegen/boxInline/use/2.kt @@ -0,0 +1,38 @@ +package test + +public class Data() + +public class Input(val d: Data) : Closeable { + public fun data() : Int = 100 +} +public class Output(val d: Data) : Closeable { + public fun doOutput(data: Int): Int = data +} + +public open trait Closeable { + open public fun close() {} +} + +public inline fun T.use(block: (T)-> R) : R { + var closed = false + try { + return block(this) + } catch (e: Exception) { + closed = true + try { + this.close() + } catch (closeException: Exception) { + + } + throw e + } finally { + if (!closed) { + this.close() + } + } +} + + +public fun Input.copyTo(output: Output, size: Int): Long { + return output.doOutput(this.data()).toLong() +} diff --git a/compiler/testData/codegen/boxInline/vararg/1.kt b/compiler/testData/codegen/boxInline/vararg/1.kt new file mode 100644 index 00000000000..3262e38fe57 --- /dev/null +++ b/compiler/testData/codegen/boxInline/vararg/1.kt @@ -0,0 +1,12 @@ +import test.* + +fun test1(): String { + return doSmth("O", "K") +} + +fun box(): String { + val result = test1() + if (result != "OK") return "fail1: ${result}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/vararg/2.kt b/compiler/testData/codegen/boxInline/vararg/2.kt new file mode 100644 index 00000000000..aa416cbee16 --- /dev/null +++ b/compiler/testData/codegen/boxInline/vararg/2.kt @@ -0,0 +1,5 @@ +package test + +inline fun doSmth(vararg a: String) : String { + return a.foldRight("", {(a, b) -> a + b}) +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/with/1.kt b/compiler/testData/codegen/boxInline/with/1.kt new file mode 100644 index 00000000000..31d1c8f9aa3 --- /dev/null +++ b/compiler/testData/codegen/boxInline/with/1.kt @@ -0,0 +1,25 @@ +import test.* + +fun Data.test1(d: Data) : Long { + val input = Input(this) + var result = 10.toLong() + with(input) { + result = use{ + val output = Output(d) + useNoInline{ + data() + copyTo(output, 10) + } + } + } + return result +} + + +fun box(): String { + + val result = Data().test1(Data()) + if (result != 100.toLong()) return "test1: ${result}" + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/with/2.kt b/compiler/testData/codegen/boxInline/with/2.kt new file mode 100644 index 00000000000..8b4d1d51dfe --- /dev/null +++ b/compiler/testData/codegen/boxInline/with/2.kt @@ -0,0 +1,27 @@ +package test + +public class Data() + +public class Input(val d: Data) : Closeable { + public fun data() : Int = 100 +} +public class Output(val d: Data) : Closeable { + public fun doOutput(data: Int): Int = data +} + +public open trait Closeable { + open public fun close() {} +} + +public inline fun use(block: ()-> R) : R { + return block() +} + +public fun useNoInline(block: ()-> R) : R { + return block() +} + + +public fun Input.copyTo(output: Output, size: Int): Long { + return output.doOutput(this.data()).toLong() +} diff --git a/compiler/testData/codegen/boxInline/withoutInline/1.kt b/compiler/testData/codegen/boxInline/withoutInline/1.kt new file mode 100644 index 00000000000..a37ab7f198c --- /dev/null +++ b/compiler/testData/codegen/boxInline/withoutInline/1.kt @@ -0,0 +1,11 @@ +fun test1(): Int { + val inlineX = Inline() + var p = {(l : Int) -> l}; + return inlineX.calc(p, 25) +} + +fun box(): String { + if (test1() != 25) return "test1: ${test1()}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/withoutInline/2.kt b/compiler/testData/codegen/boxInline/withoutInline/2.kt new file mode 100644 index 00000000000..9eb116a0663 --- /dev/null +++ b/compiler/testData/codegen/boxInline/withoutInline/2.kt @@ -0,0 +1,7 @@ +class Inline { + + inline fun calc(s: (Int) -> Int, p: Int) : Int { + return s(p) + } +} + diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxInlineCodegenTestGenerated.java new file mode 100644 index 00000000000..44adb1fd31e --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxInlineCodegenTestGenerated.java @@ -0,0 +1,259 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.codegen.generated; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/codegen/boxInline") +public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInBoxInline() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxInline"), Pattern.compile("^([^\\.]+)$"), false); + } + + @TestMetadata("builders") + public void testBuilders() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/builders"); + } + + @TestMetadata("captureInlinable") + public void testCaptureInlinable() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/captureInlinable"); + } + + @TestMetadata("captureInlinableAndOther") + public void testCaptureInlinableAndOther() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/captureInlinableAndOther"); + } + + @TestMetadata("captureThisAndReceiver") + public void testCaptureThisAndReceiver() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/captureThisAndReceiver"); + } + + @TestMetadata("classObject") + public void testClassObject() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/classObject"); + } + + @TestMetadata("closureChain") + public void testClosureChain() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/closureChain"); + } + + @TestMetadata("extension") + public void testExtension() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/extension"); + } + + @TestMetadata("forEachLine") + public void testForEachLine() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/forEachLine"); + } + + @TestMetadata("generics") + public void testGenerics() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/generics"); + } + + @TestMetadata("identityCheck") + public void testIdentityCheck() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/identityCheck"); + } + + @TestMetadata("ifBranches") + public void testIfBranches() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/ifBranches"); + } + + @TestMetadata("iinc") + public void testIinc() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/iinc"); + } + + @TestMetadata("inlineChain") + public void testInlineChain() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/inlineChain"); + } + + @TestMetadata("lambdaClassClash") + public void testLambdaClassClash() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/lambdaClassClash"); + } + + @TestMetadata("lambdaCloning") + public void testLambdaCloning() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/lambdaCloning"); + } + + @TestMetadata("lambdaInLambda") + public void testLambdaInLambda() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/lambdaInLambda"); + } + + @TestMetadata("lambdaInLambda2") + public void testLambdaInLambda2() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/lambdaInLambda2"); + } + + @TestMetadata("lambdaInLambdaNoInline") + public void testLambdaInLambdaNoInline() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/lambdaInLambdaNoInline"); + } + + @TestMetadata("localFunInLambda") + public void testLocalFunInLambda() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/localFunInLambda"); + } + + @TestMetadata("noInline") + public void testNoInline() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/noInline"); + } + + @TestMetadata("noInlineLambdaX2") + public void testNoInlineLambdaX2() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/noInlineLambdaX2"); + } + + @TestMetadata("params") + public void testParams() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/params"); + } + + @TestMetadata("plusAssign") + public void testPlusAssign() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/plusAssign"); + } + + @TestMetadata("regeneratedLambdaName") + public void testRegeneratedLambdaName() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/regeneratedLambdaName"); + } + + @TestMetadata("rootConstructor") + public void testRootConstructor() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/rootConstructor"); + } + + @TestMetadata("severalClosures") + public void testSeveralClosures() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/severalClosures"); + } + + @TestMetadata("severalUsage") + public void testSeveralUsage() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/severalUsage"); + } + + @TestMetadata("simpleCapturingInClass") + public void testSimpleCapturingInClass() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/simpleCapturingInClass"); + } + + @TestMetadata("simpleCapturingInPackage") + public void testSimpleCapturingInPackage() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/simpleCapturingInPackage"); + } + + @TestMetadata("simpleDouble") + public void testSimpleDouble() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/simpleDouble"); + } + + @TestMetadata("simpleEnum") + public void testSimpleEnum() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/simpleEnum"); + } + + @TestMetadata("simpleGenerics") + public void testSimpleGenerics() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/simpleGenerics"); + } + + @TestMetadata("simpleInt") + public void testSimpleInt() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/simpleInt"); + } + + @TestMetadata("simpleLambda") + public void testSimpleLambda() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/simpleLambda"); + } + + @TestMetadata("simpleObject") + public void testSimpleObject() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/simpleObject"); + } + + @TestMetadata("stackHeightBug") + public void testStackHeightBug() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/stackHeightBug"); + } + + @TestMetadata("trait") + public void testTrait() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/trait"); + } + + @TestMetadata("tryCatch") + public void testTryCatch() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/tryCatch"); + } + + @TestMetadata("tryCatch2") + public void testTryCatch2() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/tryCatch2"); + } + + @TestMetadata("tryCatchFinally") + public void testTryCatchFinally() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/tryCatchFinally"); + } + + @TestMetadata("use") + public void testUse() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/use"); + } + + @TestMetadata("vararg") + public void testVararg() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/vararg"); + } + + @TestMetadata("with") + public void testWith() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/with"); + } + + @TestMetadata("withoutInline") + public void testWithoutInline() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxInline/withoutInline"); + } + +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstKotlinTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstKotlinTest.java index 79f00ec7f06..361675ae55e 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstKotlinTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstKotlinTest.java @@ -20,6 +20,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; +import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.ConfigurationKind; import org.jetbrains.jet.JetTestUtils; @@ -27,18 +28,23 @@ import org.jetbrains.jet.OutputFileCollection; import org.jetbrains.jet.TestJdkKind; import org.jetbrains.jet.cli.common.output.outputUtils.OutputUtilsPackage; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; +import org.jetbrains.jet.codegen.ClassFileFactory; import org.jetbrains.jet.codegen.GenerationUtils; import org.jetbrains.jet.config.CompilerConfiguration; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.test.TestCaseWithTmpdir; +import org.jetbrains.jet.utils.UtilsPackage; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public abstract class AbstractCompileKotlinAgainstKotlinTest extends TestCaseWithTmpdir { private File aDir; @@ -59,6 +65,39 @@ public abstract class AbstractCompileKotlinAgainstKotlinTest extends TestCaseWit invokeMain(); } + public void doBoxTest(@NotNull String folderName) throws Exception { + final List files = new ArrayList(2); + FileUtil.processFilesRecursively(new File(folderName), new Processor() { + @Override + public boolean process(File file) { + if (file.getName().endsWith(".kt")) { + files.add(file.getPath()); + } + return true; + } + }); + + Collections.sort(files); + + ClassFileFactory factory1 = null; + ClassFileFactory factory2 = null; + try { + factory1 = (ClassFileFactory) compileA(new File(files.get(1))); + factory2 = (ClassFileFactory) compileB(new File(files.get(0))); + invokeBox(); + } catch (Throwable e) { + String result = ""; + if (factory1 != null) { + result += "FIRST: \n\n" + factory1.createText(); + } + if (factory2 != null) { + result += "\n\nSECOND: \n\n" + factory2.createText(); + } + System.out.println(result); + throw UtilsPackage.rethrow(e); + } + } + private void invokeMain() throws Exception { URLClassLoader classLoader = new URLClassLoader( new URL[]{ aDir.toURI().toURL(), bDir.toURI().toURL() }, @@ -69,20 +108,32 @@ public abstract class AbstractCompileKotlinAgainstKotlinTest extends TestCaseWit main.invoke(null, new Object[] {ArrayUtil.EMPTY_STRING_ARRAY}); } - private void compileA(@NotNull File ktAFile) throws IOException { - JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable(), - ConfigurationKind.JDK_ONLY); - compileKotlin(ktAFile, aDir, jetCoreEnvironment, getTestRootDisposable()); + private void invokeBox() throws Exception { + URLClassLoader classLoader = new URLClassLoader( + new URL[]{ bDir.toURI().toURL(), aDir.toURI().toURL() }, + AbstractCompileKotlinAgainstKotlinTest.class.getClassLoader() + ); + Class clazz = classLoader.loadClass(PackageClassUtils.getPackageClassName(FqName.ROOT)); + Method box = clazz.getMethod("box", new Class[] {}); + String result = (String) box.invoke(null); + assertEquals("OK", result); } - private void compileB(@NotNull File ktBFile) throws IOException { + private OutputFileCollection compileA(@NotNull File ktAFile) throws IOException { + JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable(), + ConfigurationKind.JDK_ONLY); + return compileKotlin(ktAFile, aDir, jetCoreEnvironment, getTestRootDisposable()); + } + + private OutputFileCollection compileB(@NotNull File ktBFile) throws IOException { CompilerConfiguration configurationWithADirInClasspath = JetTestUtils .compilerConfigurationForTests(ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK, JetTestUtils.getAnnotationsJar(), aDir); - compileKotlin(ktBFile, bDir, JetCoreEnvironment.createForTests(getTestRootDisposable(), configurationWithADirInClasspath), + + return compileKotlin(ktBFile, bDir, JetCoreEnvironment.createForTests(getTestRootDisposable(), configurationWithADirInClasspath), getTestRootDisposable()); } - private static void compileKotlin( + private static OutputFileCollection compileKotlin( @NotNull File file, @NotNull File outputDir, @NotNull JetCoreEnvironment jetCoreEnvironment, @NotNull Disposable disposable ) throws IOException { @@ -96,5 +147,6 @@ public abstract class AbstractCompileKotlinAgainstKotlinTest extends TestCaseWit OutputUtilsPackage.writeAllTo(outputFiles, outputDir); Disposer.dispose(disposable); + return outputFiles; } } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java new file mode 100644 index 00000000000..36b64c9a17d --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -0,0 +1,259 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.jvm.compiler; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.jvm.compiler.AbstractCompileKotlinAgainstKotlinTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/codegen/boxInline") +public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompileKotlinAgainstKotlinTest { + public void testAllFilesPresentInBoxInline() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxInline"), Pattern.compile("^([^\\.]+)$"), false); + } + + @TestMetadata("builders") + public void testBuilders() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/builders"); + } + + @TestMetadata("captureInlinable") + public void testCaptureInlinable() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/captureInlinable"); + } + + @TestMetadata("captureInlinableAndOther") + public void testCaptureInlinableAndOther() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/captureInlinableAndOther"); + } + + @TestMetadata("captureThisAndReceiver") + public void testCaptureThisAndReceiver() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/captureThisAndReceiver"); + } + + @TestMetadata("classObject") + public void testClassObject() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/classObject"); + } + + @TestMetadata("closureChain") + public void testClosureChain() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/closureChain"); + } + + @TestMetadata("extension") + public void testExtension() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/extension"); + } + + @TestMetadata("forEachLine") + public void testForEachLine() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/forEachLine"); + } + + @TestMetadata("generics") + public void testGenerics() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/generics"); + } + + @TestMetadata("identityCheck") + public void testIdentityCheck() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/identityCheck"); + } + + @TestMetadata("ifBranches") + public void testIfBranches() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/ifBranches"); + } + + @TestMetadata("iinc") + public void testIinc() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/iinc"); + } + + @TestMetadata("inlineChain") + public void testInlineChain() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/inlineChain"); + } + + @TestMetadata("lambdaClassClash") + public void testLambdaClassClash() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/lambdaClassClash"); + } + + @TestMetadata("lambdaCloning") + public void testLambdaCloning() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/lambdaCloning"); + } + + @TestMetadata("lambdaInLambda") + public void testLambdaInLambda() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/lambdaInLambda"); + } + + @TestMetadata("lambdaInLambda2") + public void testLambdaInLambda2() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/lambdaInLambda2"); + } + + @TestMetadata("lambdaInLambdaNoInline") + public void testLambdaInLambdaNoInline() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/lambdaInLambdaNoInline"); + } + + @TestMetadata("localFunInLambda") + public void testLocalFunInLambda() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/localFunInLambda"); + } + + @TestMetadata("noInline") + public void testNoInline() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/noInline"); + } + + @TestMetadata("noInlineLambdaX2") + public void testNoInlineLambdaX2() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/noInlineLambdaX2"); + } + + @TestMetadata("params") + public void testParams() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/params"); + } + + @TestMetadata("plusAssign") + public void testPlusAssign() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/plusAssign"); + } + + @TestMetadata("regeneratedLambdaName") + public void testRegeneratedLambdaName() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/regeneratedLambdaName"); + } + + @TestMetadata("rootConstructor") + public void testRootConstructor() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/rootConstructor"); + } + + @TestMetadata("severalClosures") + public void testSeveralClosures() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/severalClosures"); + } + + @TestMetadata("severalUsage") + public void testSeveralUsage() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/severalUsage"); + } + + @TestMetadata("simpleCapturingInClass") + public void testSimpleCapturingInClass() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/simpleCapturingInClass"); + } + + @TestMetadata("simpleCapturingInPackage") + public void testSimpleCapturingInPackage() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/simpleCapturingInPackage"); + } + + @TestMetadata("simpleDouble") + public void testSimpleDouble() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/simpleDouble"); + } + + @TestMetadata("simpleEnum") + public void testSimpleEnum() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/simpleEnum"); + } + + @TestMetadata("simpleGenerics") + public void testSimpleGenerics() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/simpleGenerics"); + } + + @TestMetadata("simpleInt") + public void testSimpleInt() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/simpleInt"); + } + + @TestMetadata("simpleLambda") + public void testSimpleLambda() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/simpleLambda"); + } + + @TestMetadata("simpleObject") + public void testSimpleObject() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/simpleObject"); + } + + @TestMetadata("stackHeightBug") + public void testStackHeightBug() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/stackHeightBug"); + } + + @TestMetadata("trait") + public void testTrait() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/trait"); + } + + @TestMetadata("tryCatch") + public void testTryCatch() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/tryCatch"); + } + + @TestMetadata("tryCatch2") + public void testTryCatch2() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/tryCatch2"); + } + + @TestMetadata("tryCatchFinally") + public void testTryCatchFinally() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/tryCatchFinally"); + } + + @TestMetadata("use") + public void testUse() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/use"); + } + + @TestMetadata("vararg") + public void testVararg() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/vararg"); + } + + @TestMetadata("with") + public void testWith() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/with"); + } + + @TestMetadata("withoutInline") + public void testWithoutInline() throws Exception { + doBoxTest("compiler/testData/codegen/boxInline/withoutInline"); + } + +} diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index 45c5a11a75d..25e373d6978 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -135,6 +135,14 @@ fun main(args: Array) { model("codegen/box") } + testClass(javaClass(), "BlackBoxInlineCodegenTestGenerated") { + model("codegen/boxInline", extension = null, recursive = false, testMethod = "doTestMultiFile") + } + + testClass(javaClass(), "CompileKotlinAgainstInlineKotlinTestGenerated") { + model("codegen/boxInline", extension = null, recursive = false, testMethod = "doBoxTest") + } + testClass(javaClass(), "BlackBoxMultiFileCodegenTestGenerated") { model("codegen/boxMultiFile", extension = null, recursive = false, testMethod = "doTestMultiFile") }