From 5a67b0d7dc89ac98872170e156af80d277203d06 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Tue, 8 Aug 2023 02:51:53 +0900 Subject: [PATCH] [LL API] Correct used IR symbols in code fragments As 'FirCodeFragments' are converted to IR independently of its context, in some cases duplicate (and not quite correct) symbols for local classes and functions are created. Until properly fixed in fir2ir, here we replace such duplicates with original symbols. --- .../fir/components/KtFirCompilerFacility.kt | 124 +++++++++++++++++- ...ceModuleCompilerFacilityTestGenerated.java | 42 ++++++ .../AbstractCompilerFacilityTest.kt | 7 +- ...nctionContainingClassClosure.capturing.txt | 1 + ...FunctionContainingClassClosure.fragment.kt | 1 + ...localFunctionContainingClassClosure.ir.txt | 42 ++++++ .../localFunctionContainingClassClosure.kt | 11 ++ .../localFunctionContainingClassClosure.txt | 14 ++ ...tionExtensionReceiverClosure.capturing.txt | 1 + ...nctionExtensionReceiverClosure.fragment.kt | 1 + ...calFunctionExtensionReceiverClosure.ir.txt | 37 ++++++ .../localFunctionExtensionReceiverClosure.kt | 15 +++ .../localFunctionExtensionReceiverClosure.txt | 8 ++ ...nctionLambdaParameterClosure.capturing.txt | 1 + ...FunctionLambdaParameterClosure.fragment.kt | 1 + ...localFunctionLambdaParameterClosure.ir.txt | 37 ++++++ .../localFunctionLambdaParameterClosure.kt | 15 +++ .../localFunctionLambdaParameterClosure.txt | 8 ++ .../localFunctionLocalClosure.capturing.txt | 1 + .../localFunctionLocalClosure.fragment.kt | 1 + .../localFunctionLocalClosure.ir.txt | 24 ++++ .../capturing/localFunctionLocalClosure.kt | 11 ++ .../capturing/localFunctionLocalClosure.txt | 7 + ...FunctionLocalClosureMutating.capturing.txt | 1 + ...alFunctionLocalClosureMutating.fragment.kt | 1 + .../localFunctionLocalClosureMutating.ir.txt | 21 +++ .../localFunctionLocalClosureMutating.kt | 9 ++ .../localFunctionLocalClosureMutating.txt | 8 ++ ...calFunctionMultipleCapturing.capturing.txt | 1 + ...localFunctionMultipleCapturing.fragment.kt | 1 + .../localFunctionMultipleCapturing.ir.txt | 53 ++++++++ .../localFunctionMultipleCapturing.kt | 16 +++ .../localFunctionMultipleCapturing.txt | 16 +++ ...ocalFunctionParameterClosure.capturing.txt | 1 + .../localFunctionParameterClosure.fragment.kt | 1 + .../localFunctionParameterClosure.ir.txt | 23 ++++ .../localFunctionParameterClosure.kt | 9 ++ .../localFunctionParameterClosure.txt | 7 + .../CodeFragmentCapturingTestGenerated.java | 42 ++++++ 39 files changed, 611 insertions(+), 9 deletions(-) create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.capturing.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.fragment.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionContainingClassClosure.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.capturing.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.fragment.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionExtensionReceiverClosure.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.capturing.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.fragment.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLambdaParameterClosure.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.capturing.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.fragment.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosure.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.capturing.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.fragment.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionLocalClosureMutating.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.capturing.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.fragment.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionMultipleCapturing.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.capturing.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.fragment.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing/localFunctionParameterClosure.txt 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 {