diff --git a/.idea/modules.xml b/.idea/modules.xml
index e09a99b7117..86992a19673 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -14,6 +14,7 @@
+
diff --git a/compiler/ir/backend.common/backend.common.iml b/compiler/ir/backend.common/backend.common.iml
new file mode 100644
index 00000000000..56e15c15f12
--- /dev/null
+++ b/compiler/ir/backend.common/backend.common.iml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/xbackend/common/AbstractClosureAnnotator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/xbackend/common/AbstractClosureAnnotator.kt
new file mode 100644
index 00000000000..76addd66009
--- /dev/null
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/xbackend/common/AbstractClosureAnnotator.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2010-2016 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.kotlin.xbackend.common
+
+import org.jetbrains.kotlin.descriptors.*
+import org.jetbrains.kotlin.ir.IrElement
+import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrGeneralFunction
+import org.jetbrains.kotlin.ir.declarations.IrLocalPropertyAccessor
+import org.jetbrains.kotlin.ir.expressions.*
+import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
+import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
+import org.jetbrains.kotlin.resolve.DescriptorUtils
+import java.util.*
+
+class Closure(
+ val capturedThisReferences: List,
+ val capturedReceiverParameters: List,
+ val capturedVariables: List
+)
+
+abstract class AbstractClosureAnnotator : IrElementVisitorVoid {
+ protected abstract fun recordFunctionClosure(functionDescriptor: FunctionDescriptor, closure: Closure)
+ protected abstract fun recordClassClosure(classDescriptor: ClassDescriptor, closure: Closure)
+
+ private class ClosureBuilder(val owner: DeclarationDescriptor) {
+ val capturedThisReferences = mutableSetOf()
+ val capturedReceiverParameters = mutableSetOf()
+ val capturedVariables = mutableSetOf()
+
+ fun buildClosure() = Closure(
+ capturedThisReferences.toList(),
+ capturedReceiverParameters.toList(),
+ capturedVariables.toList()
+ )
+
+ fun addNested(closure: Closure) {
+ fillInCapturedThisReferences(closure)
+ fillInNestedClosure(capturedReceiverParameters, closure.capturedReceiverParameters)
+ fillInNestedClosure(capturedVariables, closure.capturedVariables)
+ }
+
+ private fun fillInCapturedThisReferences(closure: Closure) {
+ if (owner is ClassDescriptor) {
+ closure.capturedThisReferences.filterTo(capturedThisReferences) { it != owner }
+ }
+ else if (owner is CallableMemberDescriptor && owner.dispatchReceiverParameter != null) {
+ val ownerClass = owner.containingDeclaration as? ClassDescriptor
+ closure.capturedThisReferences.filterTo(capturedThisReferences) { it != ownerClass }
+ }
+ }
+
+ private fun fillInNestedClosure(destination: MutableSet, nested: List) {
+ nested.filterTo(destination) {
+ it.containingDeclaration != owner
+ }
+ }
+
+ fun addCapturedThis(classDescriptor: ClassDescriptor) {
+ if (owner is ClassDescriptor && owner != classDescriptor) {
+ capturedThisReferences.add(classDescriptor)
+ }
+ else if (owner is CallableMemberDescriptor && owner.containingDeclaration != classDescriptor) {
+ capturedThisReferences.add(classDescriptor)
+ }
+ }
+ }
+
+ private val closuresStack = ArrayDeque()
+
+ override fun visitElement(element: IrElement) {
+ element.acceptChildrenVoid(this)
+ }
+
+ override fun visitClass(declaration: IrClass) {
+ val classDescriptor = declaration.descriptor
+ val closureBuilder = ClosureBuilder(classDescriptor)
+
+ closuresStack.push(closureBuilder)
+ declaration.acceptChildrenVoid(this)
+ closuresStack.pop()
+
+ val closure = closureBuilder.buildClosure()
+
+ if (DescriptorUtils.isLocal(classDescriptor)) {
+ recordClassClosure(classDescriptor, closure)
+ }
+
+ closuresStack.peek()?.addNested(closure)
+ }
+
+ override fun visitGeneralFunction(declaration: IrGeneralFunction) {
+ val functionDescriptor = declaration.descriptor
+ val closureBuilder = ClosureBuilder(functionDescriptor)
+
+ closuresStack.push(closureBuilder)
+ declaration.acceptChildrenVoid(this)
+ closuresStack.pop()
+
+ val closure = closureBuilder.buildClosure()
+
+ if (DescriptorUtils.isLocal(functionDescriptor)) {
+ recordFunctionClosure(functionDescriptor, closure)
+ }
+
+ closuresStack.peek()?.addNested(closure)
+ }
+
+ override fun visitLocalPropertyAccessor(declaration: IrLocalPropertyAccessor) {
+ // Local property accessors are created for delegated local properties and have no closure.
+ }
+
+ override fun visitThisReference(expression: IrThisReference) {
+ closuresStack.peek().addCapturedThis(expression.classDescriptor)
+ }
+
+ override fun visitVariableAccess(expression: IrVariableAccessExpression) {
+ val closureBuilder = closuresStack.peek()
+ val variableDescriptor = expression.descriptor
+ if (variableDescriptor.containingDeclaration != closureBuilder.owner) {
+ closureBuilder.capturedVariables.add(variableDescriptor)
+ }
+
+ expression.acceptChildrenVoid(this)
+ }
+
+ override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver) {
+ val closureBuilder = closuresStack.peek()
+ val receiverDescriptor = expression.descriptor
+ if (receiverDescriptor.containingDeclaration != closureBuilder.owner) {
+ closureBuilder.capturedReceiverParameters.add(receiverDescriptor)
+ }
+ }
+}
diff --git a/compiler/ir/ir.tests/ir.tests.iml b/compiler/ir/ir.tests/ir.tests.iml
index e30224002d3..d50982cac59 100644
--- a/compiler/ir/ir.tests/ir.tests.iml
+++ b/compiler/ir/ir.tests/ir.tests.iml
@@ -15,5 +15,6 @@
+
\ No newline at end of file
diff --git a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractClosureAnnotatorTestCase.kt b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractClosureAnnotatorTestCase.kt
new file mode 100644
index 00000000000..349ab54c65e
--- /dev/null
+++ b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractClosureAnnotatorTestCase.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010-2016 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.kotlin.ir
+
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
+import org.jetbrains.kotlin.descriptors.FunctionDescriptor
+import org.jetbrains.kotlin.ir.declarations.IrFile
+import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
+import org.jetbrains.kotlin.test.KotlinTestUtils
+import org.jetbrains.kotlin.xbackend.common.AbstractClosureAnnotator
+import org.jetbrains.kotlin.xbackend.common.Closure
+import java.io.File
+import java.io.PrintWriter
+import java.io.StringWriter
+
+abstract class AbstractClosureAnnotatorTestCase : AbstractIrGeneratorTestCase() {
+ override fun doTest(wholeFile: File, testFiles: List) {
+ val dir = wholeFile.parentFile
+ val ignoreErrors = shouldIgnoreErrors(wholeFile)
+ for ((testFile, irFile) in generateIrFilesAsSingleModule(testFiles, ignoreErrors)) {
+ doTestIrFileAgainstExpectations(dir, testFile, irFile)
+ }
+ }
+
+ private fun doTestIrFileAgainstExpectations(dir: File, testFile: TestFile, irFile: IrFile) {
+ val expectedFile = File(dir, testFile.name.replace(".kt", ".closure"))
+ val actualClosures = renderClosures(irFile)
+ KotlinTestUtils.assertEqualsToFile(expectedFile, actualClosures)
+ }
+
+ private fun renderClosures(irFile: IrFile): String {
+ val actualStringWriter = StringWriter()
+ val actualOut = PrintWriter(actualStringWriter)
+
+ irFile.acceptChildrenVoid(object : AbstractClosureAnnotator() {
+ override fun recordClassClosure(classDescriptor: ClassDescriptor, closure: Closure) {
+ actualOut.println("Closure for class ${classDescriptor.name}:")
+ printClosure(closure)
+ actualOut.println()
+ }
+
+ override fun recordFunctionClosure(functionDescriptor: FunctionDescriptor, closure: Closure) {
+ if (functionDescriptor is ConstructorDescriptor) {
+ actualOut.println("Closure for constructor ${functionDescriptor.containingDeclaration.name}:")
+ }
+ else {
+ actualOut.println("Closure for function ${functionDescriptor.name}:")
+ }
+ printClosure(closure)
+ actualOut.println()
+ }
+
+ private fun printClosure(closure: Closure) {
+ closure.capturedThisReferences.forEach {
+ actualOut.println(" 'this' for ${it.name}")
+ }
+ closure.capturedReceiverParameters.forEach {
+ actualOut.println(" receiver for ${it.containingDeclaration.name}")
+ }
+ closure.capturedVariables.forEach {
+ actualOut.println(" variable ${it.name}")
+ }
+ }
+ })
+
+ return actualStringWriter.toString()
+ }
+}
diff --git a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt
index bfa42b88b17..03c06ad89d4 100644
--- a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt
+++ b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.ir
+import junit.framework.TestCase
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.codegen.CodegenTestCase
@@ -28,6 +29,8 @@ import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils.getAnnotationsJar
import java.io.File
+import java.io.FileWriter
+import java.io.PrintWriter
import java.util.*
abstract class AbstractIrGeneratorTestCase : CodegenTestCase() {
@@ -86,6 +89,24 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() {
val ktFiles = testFiles.filter { it.name.endsWith(".kt") }
return ktFiles.zip(irModule.files).toMap()
}
+
+ companion object {
+ private val IGNORE_ERRORS_PATTERN = Regex("""// !IGNORE_ERRORS""")
+
+ internal fun shouldIgnoreErrors(wholeFile: File): Boolean =
+ IGNORE_ERRORS_PATTERN.containsMatchIn(wholeFile.readText())
+
+ internal fun createExpectedTextFile(testFile: TestFile, dir: File, fileName: String): File {
+ val textFile = File(dir, fileName)
+ if (!textFile.exists()) {
+ TestCase.assertTrue("Can't create an expected text containingFile: ${textFile.absolutePath}", textFile.createNewFile())
+ PrintWriter(FileWriter(textFile)).use {
+ it.println("$fileName: new expected text containingFile for ${testFile.name}")
+ }
+ }
+ return textFile
+ }
+ }
}
diff --git a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt
index 3468f5dda26..76c62efe051 100644
--- a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt
+++ b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt
@@ -75,10 +75,6 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
companion object {
private val EXPECTED_OCCURRENCES_PATTERN = Regex("""^\s*//\s*(\d+)\s*(.*)$""")
private val IR_FILE_TXT_PATTERN = Regex("""// IR_FILE: (.*)$""")
- private val IGNORE_ERRORS_PATTERN = Regex("""// !IGNORE_ERRORS""")
-
- internal fun shouldIgnoreErrors(wholeFile: File): Boolean =
- IGNORE_ERRORS_PATTERN.containsMatchIn(wholeFile.readText())
internal fun parseExpectations(dir: File, testFile: TestFile): Expectations {
val regexps = ArrayList()
@@ -102,17 +98,6 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
return Expectations(regexps, treeFiles)
}
-
- internal fun createExpectedTextFile(testFile: TestFile, dir: File, fileName: String): File {
- val textFile = File(dir, fileName)
- if (!textFile.exists()) {
- TestCase.assertTrue("Can't create an IR expected text containingFile: ${textFile.absolutePath}", textFile.createNewFile())
- PrintWriter(FileWriter(textFile)).use {
- it.println("$fileName: new IR expected text containingFile for ${testFile.name}")
- }
- }
- return textFile
- }
}
}
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt
index 5350ffa6d10..11a5d1a0671 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt
@@ -60,8 +60,9 @@ interface IrElementVisitor {
fun visitSingletonReference(expression: IrGetSingletonValue, data: D) = visitDeclarationReference(expression, data)
fun visitGetObjectValue(expression: IrGetObjectValue, data: D) = visitSingletonReference(expression, data)
fun visitGetEnumValue(expression: IrGetEnumValue, data: D) = visitSingletonReference(expression, data)
- fun visitGetVariable(expression: IrGetVariable, data: D) = visitDeclarationReference(expression, data)
- fun visitSetVariable(expression: IrSetVariable, data: D) = visitDeclarationReference(expression, data)
+ fun visitVariableAccess(expression: IrVariableAccessExpression, data: D) = visitDeclarationReference(expression, data)
+ fun visitGetVariable(expression: IrGetVariable, data: D) = visitVariableAccess(expression, data)
+ fun visitSetVariable(expression: IrSetVariable, data: D) = visitVariableAccess(expression, data)
fun visitBackingFieldReference(expression: IrBackingFieldExpression, data: D) = visitDeclarationReference(expression, data)
fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitBackingFieldReference(expression, data)
fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitBackingFieldReference(expression, data)
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt
index b3c0fef7e75..133e4cbf3f8 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt
@@ -123,10 +123,13 @@ interface IrElementVisitorVoid : IrElementVisitor {
fun visitGetEnumValue(expression: IrGetEnumValue) = visitSingletonReference(expression)
override fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?) = visitGetEnumValue(expression)
- fun visitGetVariable(expression: IrGetVariable) = visitDeclarationReference(expression)
+ fun visitVariableAccess(expression: IrVariableAccessExpression) = visitDeclarationReference(expression)
+ override fun visitVariableAccess(expression: IrVariableAccessExpression, data: Nothing?) = visitVariableAccess(expression)
+
+ fun visitGetVariable(expression: IrGetVariable) = visitVariableAccess(expression)
override fun visitGetVariable(expression: IrGetVariable, data: Nothing?) = visitGetVariable(expression)
- fun visitSetVariable(expression: IrSetVariable) = visitDeclarationReference(expression)
+ fun visitSetVariable(expression: IrSetVariable) = visitVariableAccess(expression)
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?) = visitSetVariable(expression)
fun visitBackingFieldReference(expression: IrBackingFieldExpression) = visitDeclarationReference(expression)
diff --git a/compiler/testData/ir/closureAnnotator/localFunctions.closure b/compiler/testData/ir/closureAnnotator/localFunctions.closure
new file mode 100644
index 00000000000..5f075e464fa
--- /dev/null
+++ b/compiler/testData/ir/closureAnnotator/localFunctions.closure
@@ -0,0 +1,7 @@
+Closure for function test2:
+ receiver for outer
+ variable y
+
+Closure for function test1:
+ receiver for outer
+
diff --git a/compiler/testData/ir/closureAnnotator/localFunctions.kt b/compiler/testData/ir/closureAnnotator/localFunctions.kt
new file mode 100644
index 00000000000..f52502beac1
--- /dev/null
+++ b/compiler/testData/ir/closureAnnotator/localFunctions.kt
@@ -0,0 +1,7 @@
+fun String.outer(x: Int) {
+ fun test1(x: Int, y: Int) {
+ fun test2(x: Int) = this + x + y
+ test2(y).length + x + y
+ }
+ test1(x, x * x)
+}
\ No newline at end of file
diff --git a/compiler/testData/ir/closureAnnotator/multipleThisReferences.closure b/compiler/testData/ir/closureAnnotator/multipleThisReferences.closure
new file mode 100644
index 00000000000..e6a5403d14a
--- /dev/null
+++ b/compiler/testData/ir/closureAnnotator/multipleThisReferences.closure
@@ -0,0 +1,15 @@
+Closure for constructor :
+
+Closure for function test1:
+ 'this' for C
+
+Closure for function :
+ 'this' for C
+ 'this' for
+
+Closure for function test2:
+ 'this' for C
+
+Closure for class :
+ 'this' for C
+
diff --git a/compiler/testData/ir/closureAnnotator/multipleThisReferences.kt b/compiler/testData/ir/closureAnnotator/multipleThisReferences.kt
new file mode 100644
index 00000000000..4b8f116ab1e
--- /dev/null
+++ b/compiler/testData/ir/closureAnnotator/multipleThisReferences.kt
@@ -0,0 +1,6 @@
+class C {
+ fun foo() = object {
+ fun test1() = this@C.toString() + this.toString()
+ fun test2() = { this@C.toString() + this.toString() }
+ }
+}
\ No newline at end of file
diff --git a/compiler/testData/ir/closureAnnotator/topLevelDeclarations.closure b/compiler/testData/ir/closureAnnotator/topLevelDeclarations.closure
new file mode 100644
index 00000000000..a0a3948e6ce
--- /dev/null
+++ b/compiler/testData/ir/closureAnnotator/topLevelDeclarations.closure
@@ -0,0 +1,6 @@
+Closure for constructor :
+
+Closure for function test6:
+
+Closure for class :
+
diff --git a/compiler/testData/ir/closureAnnotator/topLevelDeclarations.kt b/compiler/testData/ir/closureAnnotator/topLevelDeclarations.kt
new file mode 100644
index 00000000000..9395cd8e52c
--- /dev/null
+++ b/compiler/testData/ir/closureAnnotator/topLevelDeclarations.kt
@@ -0,0 +1,10 @@
+fun Int.test1(x: Int) = this + x
+
+class Test2(val x: Int) {
+ fun test3() = x
+ fun Int.test4() = this + x
+}
+
+val test5 = object {
+ fun Int.test6(x: Int) = this + x
+}
\ No newline at end of file
diff --git a/compiler/tests/org/jetbrains/kotlin/ir/ClosureAnnotatorTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/ClosureAnnotatorTestCaseGenerated.java
new file mode 100644
index 00000000000..89aafd18774
--- /dev/null
+++ b/compiler/tests/org/jetbrains/kotlin/ir/ClosureAnnotatorTestCaseGenerated.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010-2016 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.kotlin.ir;
+
+import com.intellij.testFramework.TestDataPath;
+import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
+import org.jetbrains.kotlin.test.KotlinTestUtils;
+import org.jetbrains.kotlin.test.TestMetadata;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
+@SuppressWarnings("all")
+@TestMetadata("compiler/testData/ir/closureAnnotator")
+@TestDataPath("$PROJECT_ROOT")
+@RunWith(JUnit3RunnerWithInners.class)
+public class ClosureAnnotatorTestCaseGenerated extends AbstractClosureAnnotatorTestCase {
+ public void testAllFilesPresentInClosureAnnotator() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/closureAnnotator"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("localFunctions.kt")
+ public void testLocalFunctions() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/closureAnnotator/localFunctions.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("multipleThisReferences.kt")
+ public void testMultipleThisReferences() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/closureAnnotator/multipleThisReferences.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("topLevelDeclarations.kt")
+ public void testTopLevelDeclarations() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/closureAnnotator/topLevelDeclarations.kt");
+ doTest(fileName);
+ }
+}
diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
index a98cf230951..db036e5f57f 100755
--- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
+++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
@@ -121,6 +121,7 @@ import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest
import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest
import org.jetbrains.kotlin.idea.stubs.AbstractStubBuilderTest
import org.jetbrains.kotlin.integration.AbstractAntTaskTest
+import org.jetbrains.kotlin.ir.AbstractClosureAnnotatorTestCase
import org.jetbrains.kotlin.ir.AbstractIrTextTestCase
import org.jetbrains.kotlin.ir.AbstractPsi2IrAcceptanceTestCase
import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterForWebDemoTest
@@ -249,6 +250,10 @@ fun main(args: Array) {
model("codegen/box")
}
+ testClass {
+ model("ir/closureAnnotator")
+ }
+
testClass() {
model("codegen/bytecodeListing")
}