diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt index d329133244b..0ced4448466 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt @@ -41,23 +41,28 @@ import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.jvm.* +import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.pipeline.applyIrGenerationExtensions import org.jetbrains.kotlin.fir.pipeline.signatureComposerForJvmFir2Ir +import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirThisReference import org.jetbrains.kotlin.fir.references.toResolvedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.PsiIrFileEntry import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrConstructor -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.load.kotlin.toSourceElement import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -67,6 +72,7 @@ import org.jetbrains.kotlin.psi2ir.generators.fragments.EvaluatorFragmentInfo import org.jetbrains.kotlin.resolve.source.PsiSourceFile import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.utils.addToStdlib.runIf +import java.util.Collections internal class KtFirCompilerFacility( override val analysisSession: KtFirAnalysisSession @@ -147,6 +153,8 @@ internal class KtFirCompilerFacility( initializedIrBuiltIns = null ) + patchCodeFragmentIr(fir2IrResult) + ProgressManager.checkCanceled() val irGeneratorExtensions = IrGenerationExtension.getInstances(project) @@ -200,6 +208,22 @@ internal class KtFirCompilerFacility( } } + private fun patchCodeFragmentIr(fir2IrResult: Fir2IrResult) { + fun isCodeFragmentFile(irFile: IrFile): Boolean { + val firFiles = (irFile.metadata as? FirMetadataSource.File)?.files ?: return false + return firFiles.any { it.psi is KtCodeFragment } + } + + val (irCodeFragmentFiles, irOrdinaryFiles) = fir2IrResult.irModuleFragment.files.partition(::isCodeFragmentFile) + + // Collect original declarations from the context files + val collectingVisitor = IrDeclarationMappingCollectingVisitor() + irOrdinaryFiles.forEach { it.acceptVoid(collectingVisitor) } + + // Replace duplicate symbols with the original ones + val patchingVisitor = IrDeclarationPatchingVisitor(collectingVisitor.mappings) + irCodeFragmentFiles.forEach { it.acceptVoid(patchingVisitor) } + } private fun getFullyResolvedFirFile(file: KtFile): FirFile { val firFile = file.getOrBuildFirFile(firResolveSession) LLFirWholeFileResolveTarget(firFile).resolve(FirResolvePhase.BODY_RESOLVE) @@ -368,4 +392,96 @@ internal class KtFirCompilerFacility( ideCodegenSettings = ideCodegenSettings, ) } +} + +private class IrDeclarationMappingCollectingVisitor : IrElementVisitorVoid { + private val collectedMappings = HashMap() + + val mappings: Map + get() = Collections.unmodifiableMap(collectedMappings) + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitDeclaration(declaration: IrDeclarationBase) { + dumpDeclaration(declaration) + super.visitDeclaration(declaration) + } + + private fun dumpDeclaration(declaration: IrDeclaration) { + if (declaration is IrMetadataSourceOwner) { + val fir = (declaration.metadata as? FirMetadataSource)?.fir + if (fir != null) { + collectedMappings.putIfAbsent(fir, declaration) + } + } + } +} + +private class IrDeclarationPatchingVisitor(private val mapping: Map) : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitFieldAccess(expression: IrFieldAccessExpression) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + patchIfNeeded(expression.superQualifierSymbol) { expression.superQualifierSymbol = it } + super.visitFieldAccess(expression) + } + + override fun visitValueAccess(expression: IrValueAccessExpression) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + super.visitValueAccess(expression) + } + + override fun visitGetEnumValue(expression: IrGetEnumValue) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + super.visitGetEnumValue(expression) + } + + override fun visitGetObjectValue(expression: IrGetObjectValue) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + super.visitGetObjectValue(expression) + } + + override fun visitCall(expression: IrCall) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + patchIfNeeded(expression.superQualifierSymbol) { expression.superQualifierSymbol = it } + super.visitCall(expression) + } + + override fun visitConstructorCall(expression: IrConstructorCall) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + super.visitConstructorCall(expression) + } + + override fun visitPropertyReference(expression: IrPropertyReference) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + patchIfNeeded(expression.getter) { expression.getter = it } + patchIfNeeded(expression.setter) { expression.setter = it } + super.visitPropertyReference(expression) + } + + override fun visitFunctionReference(expression: IrFunctionReference) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + patchIfNeeded(expression.reflectionTarget) { expression.reflectionTarget = it } + super.visitFunctionReference(expression) + } + + override fun visitClassReference(expression: IrClassReference) { + patchIfNeeded(expression.symbol) { expression.symbol = it } + super.visitClassReference(expression) + } + + private inline fun patchIfNeeded(irSymbol: T?, patcher: (T) -> Unit) { + if (irSymbol != null) { + val irDeclaration = irSymbol.owner as? IrMetadataSourceOwner ?: return + val firDeclaration = (irDeclaration.metadata as? FirMetadataSource)?.fir ?: return + val correctedIrSymbol = mapping[firDeclaration]?.symbol as? T ?: return + if (correctedIrSymbol != irSymbol) { + patcher(correctedIrSymbol) + } + } + } } \ No newline at end of file diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisSourceModuleCompilerFacilityTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisSourceModuleCompilerFacilityTestGenerated.java index 28d9a1e57ee..cfbba221e6e 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisSourceModuleCompilerFacilityTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisSourceModuleCompilerFacilityTestGenerated.java @@ -172,6 +172,48 @@ public class FirIdeNormalAnalysisSourceModuleCompilerFacilityTestGenerated exten runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunction.kt"); } + @Test + @TestMetadata("localFunctionContainingClassClosure.kt") + public void testLocalFunctionContainingClassClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.kt"); + } + + @Test + @TestMetadata("localFunctionExtensionReceiverClosure.kt") + public void testLocalFunctionExtensionReceiverClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.kt"); + } + + @Test + @TestMetadata("localFunctionLambdaParameterClosure.kt") + public void testLocalFunctionLambdaParameterClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.kt"); + } + + @Test + @TestMetadata("localFunctionLocalClosure.kt") + public void testLocalFunctionLocalClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.kt"); + } + + @Test + @TestMetadata("localFunctionLocalClosureMutating.kt") + public void testLocalFunctionLocalClosureMutating() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.kt"); + } + + @Test + @TestMetadata("localFunctionMultipleCapturing.kt") + public void testLocalFunctionMultipleCapturing() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.kt"); + } + + @Test + @TestMetadata("localFunctionParameterClosure.kt") + public void testLocalFunctionParameterClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.kt"); + } + @Test @TestMetadata("localMutated.kt") public void testLocalMutated() throws Exception { diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/compilerFacility/AbstractCompilerFacilityTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/compilerFacility/AbstractCompilerFacilityTest.kt index ec21b4e12c4..f6020805538 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/compilerFacility/AbstractCompilerFacilityTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/compilerFacility/AbstractCompilerFacilityTest.kt @@ -26,10 +26,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.util.DumpIrTreeOptions import org.jetbrains.kotlin.ir.util.dump -import org.jetbrains.kotlin.psi.KtCodeFragment -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.directives.ConfigurationDirectives import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives @@ -181,7 +178,7 @@ internal fun createCodeFragment(ktFile: KtFile, module: TestModule, testServices return null } - val contextElement = testServices.expressionMarkerProvider.getElementOfTypeAtCaret(ktFile) + val contextElement = testServices.expressionMarkerProvider.getElementOfTypeAtCaret(ktFile) val fragmentText = ioFragmentFile.readText() val isBlockFragment = fragmentText.any { it == '\n' } diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.capturing.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.capturing.txt new file mode 100644 index 00000000000..53032d710d8 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.capturing.txt @@ -0,0 +1 @@ +No captured values diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.fragment.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.fragment.kt new file mode 100644 index 00000000000..bba16b0d864 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.fragment.kt @@ -0,0 +1 @@ +call() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.ir.txt new file mode 100644 index 00000000000..b7f45284850 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.ir.txt @@ -0,0 +1,42 @@ +MODULE_FRAGMENT name: + FILE fqName: fileName:/localFunctionContainingClassClosure.kt + CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo + CONSTRUCTOR visibility:public <> () returnType:.Foo [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:test visibility:public modality:FINAL <> ($this:.Foo) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.Foo + BLOCK_BODY + FUN LOCAL_FUNCTION name:call visibility:local modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun consume (obj: .Foo): kotlin.Unit declared in ' type=kotlin.Unit origin=null + obj: GET_VAR ': .Foo declared in .Foo.test' type=.Foo origin=null + CALL 'local final fun call (): kotlin.Unit declared in .Foo.test' type=kotlin.Unit origin=null + FUN name:consume visibility:public modality:FINAL <> (obj:.Foo) returnType:kotlin.Unit + VALUE_PARAMETER name:obj index:0 type:.Foo + BLOCK_BODY + FILE fqName: fileName:/fragment.kt + CLASS CLASS name:CodeFragment modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.CodeFragment + CONSTRUCTOR visibility:public <> () returnType:.CodeFragment [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + FUN name:run visibility:public modality:FINAL <> () returnType:kotlin.Unit + EXPRESSION_BODY + BLOCK type=kotlin.Unit origin=null + CALL 'local final fun call (): kotlin.Unit declared in .Foo.test' type=kotlin.Unit origin=null diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.kt new file mode 100644 index 00000000000..786b5e9b1ff --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.kt @@ -0,0 +1,11 @@ +class Foo { + fun test() { + fun call() { + consume(this@Foo) + } + + call() + } +} + +fun consume(obj: Foo) {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.txt new file mode 100644 index 00000000000..8a723e37436 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.txt @@ -0,0 +1,14 @@ +public final class CodeFragment { + // source: 'fragment.kt' + public method (): void + public final static method run(p0: Foo): void +} + +public final class Foo { + // source: 'localFunctionContainingClassClosure.kt' + public method (): void + private final static method test$call(p0: Foo): void + public final method test(): void +} + +public final class LocalFunctionContainingClassClosureKt \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.capturing.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.capturing.txt new file mode 100644 index 00000000000..53032d710d8 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.capturing.txt @@ -0,0 +1 @@ +No captured values diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.fragment.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.fragment.kt new file mode 100644 index 00000000000..bba16b0d864 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.fragment.kt @@ -0,0 +1 @@ +call() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.ir.txt new file mode 100644 index 00000000000..72f12760107 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.ir.txt @@ -0,0 +1,37 @@ +MODULE_FRAGMENT name: + FILE fqName: fileName:/localFunctionExtensionReceiverClosure.kt + FUN name:block visibility:public modality:FINAL (obj:T of .block, block:@[ExtensionFunctionType] kotlin.Function1.block, kotlin.Unit>) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false + VALUE_PARAMETER name:obj index:0 type:T of .block + VALUE_PARAMETER name:block index:1 type:@[ExtensionFunctionType] kotlin.Function1.block, kotlin.Unit> + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=INVOKE + $this: GET_VAR 'block: @[ExtensionFunctionType] kotlin.Function1.block, kotlin.Unit> declared in .block' type=@[ExtensionFunctionType] kotlin.Function1.block, kotlin.Unit> origin=VARIABLE_AS_FUNCTION + p1: GET_VAR 'obj: T of .block declared in .block' type=T of .block origin=null + FUN name:consume visibility:public modality:FINAL <> (text:kotlin.String) returnType:kotlin.Unit + VALUE_PARAMETER name:text index:0 type:kotlin.String + BLOCK_BODY + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun block (obj: T of .block, block: @[ExtensionFunctionType] kotlin.Function1.block, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : kotlin.String + obj: CONST String type=kotlin.String value="foo" + block: FUN_EXPR type=@[ExtensionFunctionType] kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:kotlin.String) returnType:kotlin.Unit + $receiver: VALUE_PARAMETER name:$this$block type:kotlin.String + BLOCK_BODY + FUN LOCAL_FUNCTION name:call visibility:local modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun consume (text: kotlin.String): kotlin.Unit declared in ' type=kotlin.Unit origin=null + text: GET_VAR '$this$block: kotlin.String declared in .test.' type=kotlin.String origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test.' type=kotlin.Unit origin=null + FILE fqName: fileName:/fragment.kt + CLASS CLASS name:CodeFragment modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.CodeFragment + CONSTRUCTOR visibility:public <> () returnType:.CodeFragment [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + FUN name:run visibility:public modality:FINAL <> () returnType:kotlin.Unit + EXPRESSION_BODY + BLOCK type=kotlin.Unit origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test.' type=kotlin.Unit origin=null diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.kt new file mode 100644 index 00000000000..2e0ccb01490 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.kt @@ -0,0 +1,15 @@ +fun test() { + block("foo") { + fun call() { + consume(this@block) + } + + call() + } +} + +fun block(obj: T, block: T.() -> Unit) { + obj.block() +} + +fun consume(text: String) {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.txt new file mode 100644 index 00000000000..3443f7644df --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.txt @@ -0,0 +1,8 @@ +public final class CodeFragment { + // source: 'fragment.kt' + inner (anonymous) class LocalFunctionExtensionReceiverClosureKt$test$1 + public method (): void + public final static method run(p0: java.lang.String): void +} + +public final class LocalFunctionExtensionReceiverClosureKt \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.capturing.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.capturing.txt new file mode 100644 index 00000000000..53032d710d8 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.capturing.txt @@ -0,0 +1 @@ +No captured values diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.fragment.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.fragment.kt new file mode 100644 index 00000000000..bba16b0d864 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.fragment.kt @@ -0,0 +1 @@ +call() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.ir.txt new file mode 100644 index 00000000000..3fa8f02cbd4 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.ir.txt @@ -0,0 +1,37 @@ +MODULE_FRAGMENT name: + FILE fqName: fileName:/localFunctionLambdaParameterClosure.kt + FUN name:block visibility:public modality:FINAL (obj:T of .block, block:kotlin.Function1.block, kotlin.Unit>) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false + VALUE_PARAMETER name:obj index:0 type:T of .block + VALUE_PARAMETER name:block index:1 type:kotlin.Function1.block, kotlin.Unit> + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=INVOKE + $this: GET_VAR 'block: kotlin.Function1.block, kotlin.Unit> declared in .block' type=kotlin.Function1.block, kotlin.Unit> origin=VARIABLE_AS_FUNCTION + p1: GET_VAR 'obj: T of .block declared in .block' type=T of .block origin=null + FUN name:consume visibility:public modality:FINAL <> (text:kotlin.String) returnType:kotlin.Unit + VALUE_PARAMETER name:text index:0 type:kotlin.String + BLOCK_BODY + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun block (obj: T of .block, block: kotlin.Function1.block, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : kotlin.String + obj: CONST String type=kotlin.String value="foo" + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (foo:kotlin.String) returnType:kotlin.Unit + VALUE_PARAMETER name:foo index:0 type:kotlin.String + BLOCK_BODY + FUN LOCAL_FUNCTION name:call visibility:local modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun consume (text: kotlin.String): kotlin.Unit declared in ' type=kotlin.Unit origin=null + text: GET_VAR 'foo: kotlin.String declared in .test.' type=kotlin.String origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test.' type=kotlin.Unit origin=null + FILE fqName: fileName:/fragment.kt + CLASS CLASS name:CodeFragment modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.CodeFragment + CONSTRUCTOR visibility:public <> () returnType:.CodeFragment [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + FUN name:run visibility:public modality:FINAL <> () returnType:kotlin.Unit + EXPRESSION_BODY + BLOCK type=kotlin.Unit origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test.' type=kotlin.Unit origin=null diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.kt new file mode 100644 index 00000000000..c4d7137402c --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.kt @@ -0,0 +1,15 @@ +fun test() { + block("foo") { foo -> + fun call() { + consume(foo) + } + + call() + } +} + +fun block(obj: T, block: (T) -> Unit) { + block(obj) +} + +fun consume(text: String) {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.txt new file mode 100644 index 00000000000..d0a1b76dd89 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.txt @@ -0,0 +1,8 @@ +public final class CodeFragment { + // source: 'fragment.kt' + inner (anonymous) class LocalFunctionLambdaParameterClosureKt$test$1 + public method (): void + public final static method run(p0: java.lang.String): void +} + +public final class LocalFunctionLambdaParameterClosureKt \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.capturing.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.capturing.txt new file mode 100644 index 00000000000..53032d710d8 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.capturing.txt @@ -0,0 +1 @@ +No captured values diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.fragment.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.fragment.kt new file mode 100644 index 00000000000..bba16b0d864 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.fragment.kt @@ -0,0 +1 @@ +call() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.ir.txt new file mode 100644 index 00000000000..bea983290dc --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.ir.txt @@ -0,0 +1,24 @@ +MODULE_FRAGMENT name: + FILE fqName: fileName:/localFunctionLocalClosure.kt + FUN name:consume visibility:public modality:FINAL <> (n:kotlin.Int) returnType:kotlin.Unit + VALUE_PARAMETER name:n index:0 type:kotlin.Int + BLOCK_BODY + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:x type:kotlin.Int [val] + CONST Int type=kotlin.Int value=0 + FUN LOCAL_FUNCTION name:call visibility:local modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun consume (n: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=null + n: GET_VAR 'val x: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test' type=kotlin.Unit origin=null + FILE fqName: fileName:/fragment.kt + CLASS CLASS name:CodeFragment modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.CodeFragment + CONSTRUCTOR visibility:public <> () returnType:.CodeFragment [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + FUN name:run visibility:public modality:FINAL <> () returnType:kotlin.Unit + EXPRESSION_BODY + BLOCK type=kotlin.Unit origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test' type=kotlin.Unit origin=null diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.kt new file mode 100644 index 00000000000..125f7b9125d --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.kt @@ -0,0 +1,11 @@ +fun test() { + val x = 0 + + fun call() { + consume(x) + } + + call() +} + +fun consume(n: Int) {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.txt new file mode 100644 index 00000000000..44471c1c98e --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.txt @@ -0,0 +1,7 @@ +public final class CodeFragment { + // source: 'fragment.kt' + public method (): void + public final static method run(p0: int): void +} + +public final class LocalFunctionLocalClosureKt \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.capturing.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.capturing.txt new file mode 100644 index 00000000000..53032d710d8 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.capturing.txt @@ -0,0 +1 @@ +No captured values diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.fragment.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.fragment.kt new file mode 100644 index 00000000000..bba16b0d864 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.fragment.kt @@ -0,0 +1 @@ +call() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.ir.txt new file mode 100644 index 00000000000..4e7ee0e8f8a --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.ir.txt @@ -0,0 +1,21 @@ +MODULE_FRAGMENT name: + FILE fqName: fileName:/localFunctionLocalClosureMutating.kt + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:x type:kotlin.Int [var] + CONST Int type=kotlin.Int value=0 + FUN LOCAL_FUNCTION name:call visibility:local modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + SET_VAR 'var x: kotlin.Int [var] declared in .test' type=kotlin.Unit origin=EQ + CONST Int type=kotlin.Int value=1 + CALL 'local final fun call (): kotlin.Unit declared in .test' type=kotlin.Unit origin=null + FILE fqName: fileName:/fragment.kt + CLASS CLASS name:CodeFragment modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.CodeFragment + CONSTRUCTOR visibility:public <> () returnType:.CodeFragment [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + FUN name:run visibility:public modality:FINAL <> () returnType:kotlin.Unit + EXPRESSION_BODY + BLOCK type=kotlin.Unit origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test' type=kotlin.Unit origin=null diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.kt new file mode 100644 index 00000000000..19fc9a2ad78 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.kt @@ -0,0 +1,9 @@ +fun test() { + var x = 0 + + fun call() { + x = 1 + } + + call() +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.txt new file mode 100644 index 00000000000..2c7993e6b8a --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.txt @@ -0,0 +1,8 @@ +public final class CodeFragment { + // source: 'fragment.kt' + public method (): void + public final static method run(p0: kotlin.jvm.internal.Ref$IntRef): void + public final inner class kotlin/jvm/internal/Ref$IntRef +} + +public final class LocalFunctionLocalClosureMutatingKt \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.capturing.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.capturing.txt new file mode 100644 index 00000000000..53032d710d8 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.capturing.txt @@ -0,0 +1 @@ +No captured values diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.fragment.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.fragment.kt new file mode 100644 index 00000000000..e2eaa5abdf9 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.fragment.kt @@ -0,0 +1 @@ +call(0) \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.ir.txt new file mode 100644 index 00000000000..2b9ad432c7d --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.ir.txt @@ -0,0 +1,53 @@ +MODULE_FRAGMENT name: + FILE fqName: fileName:/localFunctionMultipleCapturing.kt + CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo + CONSTRUCTOR visibility:public <> () returnType:.Foo [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:test visibility:public modality:FINAL <> ($this:.Foo, $receiver:kotlin.String) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.Foo + $receiver: VALUE_PARAMETER name: type:kotlin.String + BLOCK_BODY + VAR name:x type:kotlin.Int [var] + FUN LOCAL_FUNCTION name:call visibility:local modality:FINAL <> (a:kotlin.Int) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Int + BLOCK_BODY + CALL 'public final fun consume (obj: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + obj: GET_VAR 'a: kotlin.Int declared in .Foo.test.call' type=kotlin.Int origin=null + CALL 'public final fun consume (obj: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + obj: GET_VAR ': .Foo declared in .Foo.test' type=.Foo origin=null + CALL 'public final fun consume (obj: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + obj: GET_VAR ': kotlin.String declared in .Foo.test' type=kotlin.String origin=null + SET_VAR 'var x: kotlin.Int [var] declared in .Foo.test' type=kotlin.Unit origin=EQ + CONST Int type=kotlin.Int value=42 + CALL 'local final fun call (a: kotlin.Int): kotlin.Unit declared in .Foo.test' type=kotlin.Unit origin=null + a: CONST Int type=kotlin.Int value=1 + FUN name:consume visibility:public modality:FINAL <> (obj:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:obj index:0 type:kotlin.Any + BLOCK_BODY + FILE fqName: fileName:/fragment.kt + CLASS CLASS name:CodeFragment modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.CodeFragment + CONSTRUCTOR visibility:public <> () returnType:.CodeFragment [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + FUN name:run visibility:public modality:FINAL <> () returnType:kotlin.Unit + EXPRESSION_BODY + BLOCK type=kotlin.Unit origin=null + CALL 'local final fun call (a: kotlin.Int): kotlin.Unit declared in .Foo.test' type=kotlin.Unit origin=null + a: CONST Int type=kotlin.Int value=0 diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.kt new file mode 100644 index 00000000000..5889a98a0d8 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.kt @@ -0,0 +1,16 @@ +class Foo { + fun String.test() { + var x: Int + + fun call(a: Int) { + consume(a) + consume(this@Foo) + consume(this@test) + x = 42 + } + + call(1) + } +} + +fun consume(obj: Any) {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.txt new file mode 100644 index 00000000000..6eb5017d8c4 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.txt @@ -0,0 +1,16 @@ +public final class CodeFragment { + // source: 'fragment.kt' + public method (): void + public final static method run(p0: Foo, p1: java.lang.String, p2: kotlin.jvm.internal.Ref$IntRef): void + public final inner class kotlin/jvm/internal/Ref$IntRef +} + +public final class Foo { + // source: 'localFunctionMultipleCapturing.kt' + public method (): void + private final static method test$call(p0: Foo, p1: java.lang.String, p2: kotlin.jvm.internal.Ref$IntRef, p3: int): void + public final method test(p0: java.lang.String): void + public final inner class kotlin/jvm/internal/Ref$IntRef +} + +public final class LocalFunctionMultipleCapturingKt \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.capturing.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.capturing.txt new file mode 100644 index 00000000000..53032d710d8 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.capturing.txt @@ -0,0 +1 @@ +No captured values diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.fragment.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.fragment.kt new file mode 100644 index 00000000000..bba16b0d864 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.fragment.kt @@ -0,0 +1 @@ +call() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.ir.txt new file mode 100644 index 00000000000..5d7cc3ff360 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.ir.txt @@ -0,0 +1,23 @@ +MODULE_FRAGMENT name: + FILE fqName: fileName:/localFunctionParameterClosure.kt + FUN name:consume visibility:public modality:FINAL <> (n:kotlin.Int) returnType:kotlin.Unit + VALUE_PARAMETER name:n index:0 type:kotlin.Int + BLOCK_BODY + FUN name:test visibility:public modality:FINAL <> (x:kotlin.Int) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Int + BLOCK_BODY + FUN LOCAL_FUNCTION name:call visibility:local modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun consume (n: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=null + n: GET_VAR 'x: kotlin.Int declared in .test' type=kotlin.Int origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test' type=kotlin.Unit origin=null + FILE fqName: fileName:/fragment.kt + CLASS CLASS name:CodeFragment modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.CodeFragment + CONSTRUCTOR visibility:public <> () returnType:.CodeFragment [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + FUN name:run visibility:public modality:FINAL <> () returnType:kotlin.Unit + EXPRESSION_BODY + BLOCK type=kotlin.Unit origin=null + CALL 'local final fun call (): kotlin.Unit declared in .test' type=kotlin.Unit origin=null diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.kt new file mode 100644 index 00000000000..b4da293e8b2 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.kt @@ -0,0 +1,9 @@ +fun test(x: Int) { + fun call() { + consume(x) + } + + call() +} + +fun consume(n: Int) {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.txt new file mode 100644 index 00000000000..d53606defa5 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.txt @@ -0,0 +1,7 @@ +public final class CodeFragment { + // source: 'fragment.kt' + public method (): void + public final static method run(p0: int): void +} + +public final class LocalFunctionParameterClosureKt \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/CodeFragmentCapturingTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/CodeFragmentCapturingTestGenerated.java index 9bed8e823ed..c406d9d5325 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/CodeFragmentCapturingTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/CodeFragmentCapturingTestGenerated.java @@ -72,6 +72,48 @@ public class CodeFragmentCapturingTestGenerated extends AbstractCodeFragmentCapt runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunction.kt"); } + @Test + @TestMetadata("localFunctionContainingClassClosure.kt") + public void testLocalFunctionContainingClassClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.kt"); + } + + @Test + @TestMetadata("localFunctionExtensionReceiverClosure.kt") + public void testLocalFunctionExtensionReceiverClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.kt"); + } + + @Test + @TestMetadata("localFunctionLambdaParameterClosure.kt") + public void testLocalFunctionLambdaParameterClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.kt"); + } + + @Test + @TestMetadata("localFunctionLocalClosure.kt") + public void testLocalFunctionLocalClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.kt"); + } + + @Test + @TestMetadata("localFunctionLocalClosureMutating.kt") + public void testLocalFunctionLocalClosureMutating() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.kt"); + } + + @Test + @TestMetadata("localFunctionMultipleCapturing.kt") + public void testLocalFunctionMultipleCapturing() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.kt"); + } + + @Test + @TestMetadata("localFunctionParameterClosure.kt") + public void testLocalFunctionParameterClosure() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.kt"); + } + @Test @TestMetadata("localMutated.kt") public void testLocalMutated() throws Exception {