From 9514f8f873a52dd093e8b5850f724d128d969552 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Thu, 7 Sep 2023 18:54:35 +0900 Subject: [PATCH] [LL API] Fix analysis of functions inside code fragments FirDeclarationsResolveTransformer.transformSimpleFunction() performs proper local function analysis only if the parent is properly set. ^KTIJ-26608 Fixed --- ...ceModuleCompilerFacilityTestGenerated.java | 6 ++++++ ...ceModuleCompilerFacilityTestGenerated.java | 6 ++++++ .../fragmentFunction.fragment.kt | 2 ++ .../codeFragments/fragmentFunction.ir.txt | 19 +++++++++++++++++++ .../codeFragments/fragmentFunction.kt | 3 +++ .../codeFragments/fragmentFunction.txt | 6 ++++++ .../codeFragments/localFunction.fragment.kt | 4 ++-- .../codeFragments/localFunction.txt | 6 +++--- .../body/resolve/BodyResolveContext.kt | 5 +++-- .../FirDeclarationsResolveTransformer.kt | 2 +- 10 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.fragment.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.txt diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisLibrarySourceModuleCompilerFacilityTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisLibrarySourceModuleCompilerFacilityTestGenerated.java index 641b355351d..552fad6bcd5 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisLibrarySourceModuleCompilerFacilityTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisLibrarySourceModuleCompilerFacilityTestGenerated.java @@ -91,6 +91,12 @@ public class FirIdeNormalAnalysisLibrarySourceModuleCompilerFacilityTestGenerate runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/duplicateLibrary.kt"); } + @Test + @TestMetadata("fragmentFunction.kt") + public void testFragmentFunction() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.kt"); + } + @Test @TestMetadata("imports.kt") public void testImports() throws Exception { 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 91a06a96f7c..ebdb12547b1 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 @@ -91,6 +91,12 @@ public class FirIdeNormalAnalysisSourceModuleCompilerFacilityTestGenerated exten runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/duplicateLibrary.kt"); } + @Test + @TestMetadata("fragmentFunction.kt") + public void testFragmentFunction() throws Exception { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.kt"); + } + @Test @TestMetadata("imports.kt") public void testImports() throws Exception { diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.fragment.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.fragment.kt new file mode 100644 index 00000000000..97d9de345af --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.fragment.kt @@ -0,0 +1,2 @@ +fun String.ext() = this + "EXT" +"base".ext() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.ir.txt new file mode 100644 index 00000000000..4b1f71dd969 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.ir.txt @@ -0,0 +1,19 @@ +MODULE_FRAGMENT + 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.String + EXPRESSION_BODY + BLOCK type=kotlin.String origin=null + FUN LOCAL_FUNCTION name:ext visibility:local modality:FINAL <> ($receiver:kotlin.String) returnType:kotlin.String + $receiver: VALUE_PARAMETER name: type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun ext (): kotlin.String declared in .CodeFragment.run' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: GET_VAR ': kotlin.String declared in .CodeFragment.run.ext' type=kotlin.String origin=null + other: CONST String type=kotlin.String value="EXT" + CALL 'local final fun ext (): kotlin.String declared in .CodeFragment.run' type=kotlin.String origin=null + $receiver: CONST String type=kotlin.String value="base" diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.kt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.kt new file mode 100644 index 00000000000..118d01da074 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.kt @@ -0,0 +1,3 @@ +fun test() { + val x = 0 +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.txt b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.txt new file mode 100644 index 00000000000..f5a54d326dd --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/fragmentFunction.txt @@ -0,0 +1,6 @@ +public final class CodeFragment { + // source: 'fragment.kt' + public method (): void + private final static method run$ext(p0: java.lang.String): java.lang.String + public final static method run(): java.lang.String +} diff --git a/analysis/low-level-api-fir/testdata/inBlockModification/codeFragments/localFunction.fragment.kt b/analysis/low-level-api-fir/testdata/inBlockModification/codeFragments/localFunction.fragment.kt index 273f803b6d8..7ddbd1dc316 100644 --- a/analysis/low-level-api-fir/testdata/inBlockModification/codeFragments/localFunction.fragment.kt +++ b/analysis/low-level-api-fir/testdata/inBlockModification/codeFragments/localFunction.fragment.kt @@ -1,7 +1,7 @@ -fun foo() {} +fun foo(a: Int, b: String) {} fun bar() { - foo() + foo(1, "foo") } bar() \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/inBlockModification/codeFragments/localFunction.txt b/analysis/low-level-api-fir/testdata/inBlockModification/codeFragments/localFunction.txt index c712fecbd00..9d891c1ba01 100644 --- a/analysis/low-level-api-fir/testdata/inBlockModification/codeFragments/localFunction.txt +++ b/analysis/low-level-api-fir/testdata/inBlockModification/codeFragments/localFunction.txt @@ -1,10 +1,10 @@ BEFORE MODIFICATION: CODE FRAGMENT: { - local final? [ResolvedTo(RAW_FIR)] fun foo(): R|kotlin/Unit| { + local final [ResolvedTo(RAW_FIR)] fun foo([ResolvedTo(RAW_FIR)] a: R|kotlin/Int|, [ResolvedTo(RAW_FIR)] b: R|kotlin/String|): R|kotlin/Unit| { } - local final? [ResolvedTo(RAW_FIR)] fun bar(): R|kotlin/Unit| { - R|/foo|() + local final [ResolvedTo(RAW_FIR)] fun bar(): R|kotlin/Unit| { + R|/foo|(Int(1), String(foo)) } R|/bar|() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index 3f66dbfe79e..5a9db757ab7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -541,7 +541,8 @@ class BodyResolveContext( } } - fun withScopesForCodeFragment(codeFragment: FirCodeFragment, holder: SessionHolder, f: () -> T): T { + @OptIn(PrivateForInline::class) + fun withCodeFragment(codeFragment: FirCodeFragment, holder: SessionHolder, f: () -> T): T { val codeFragmentContext = codeFragment.codeFragmentContext ?: error("Context is not set for a code fragment") val towerDataContext = codeFragmentContext.towerDataContext @@ -566,7 +567,7 @@ class BodyResolveContext( ) return withTowerDataContexts(newContext) { - f() + withContainer(codeFragment, f) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 9d19cd4b852..e5c344a2511 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -631,7 +631,7 @@ open class FirDeclarationsResolveTransformer( override fun transformCodeFragment(codeFragment: FirCodeFragment, data: ResolutionMode): FirCodeFragment { dataFlowAnalyzer.enterCodeFragment(codeFragment) - context.withScopesForCodeFragment(codeFragment, components) { + context.withCodeFragment(codeFragment, components) { transformBlock(codeFragment.block, data) } dataFlowAnalyzer.exitCodeFragment()