From f4e3203cd8858c153dd04d80ec1a122c8a6d5615 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 7 Dec 2023 17:21:39 +0200 Subject: [PATCH] [FIR] Unregister java element finders from previous sessions The problem here is that for common session we register `FirJavaElementFinder` which provides light classes based on expect classes. And then at the start of analysis of jvm module we register one another `FirJavaElementFinder`, which sees actual classes and uses them to build light classes But, because class ids of expect and actual class pair are the same and element finders are ordered by creation order, when java resolve tries to resolve some class, it founds light class based on expect class, even if we are already in platform session To fix this problem, it was decided to unregister all previous element finders on creation of each new session, so old finders won't interfere with analysis ^KT-63612 Fixed ^KT-64296 --- ...LFirBlackBoxCodegenBasedTestGenerated.java | 6 +++ ...rsedBlackBoxCodegenBasedTestGenerated.java | 6 +++ .../cli/jvm/compiler/KotlinCoreEnvironment.kt | 2 +- .../compiler/VfsBasedProjectEnvironment.kt | 16 ++++++-- ...LightTreeBlackBoxCodegenTestGenerated.java | 6 +++ ...hIrFakeOverrideGeneratorTestGenerated.java | 6 +++ .../FirPsiBlackBoxCodegenTestGenerated.java | 6 +++ .../k2/javaClassReferencedActualType.kt | 37 +++++++++++++++++++ .../test/frontend/fir/FirFrontendFacade.kt | 3 +- 9 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java index a81813c9cf1..e8fa24d68ef 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java @@ -35247,6 +35247,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo runTest("compiler/testData/codegen/box/multiplatform/k2/internalOverride2.kt"); } + @Test + @TestMetadata("javaClassReferencedActualType.kt") + public void testJavaClassReferencedActualType() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt"); + } + @Test @TestMetadata("javaMethodWithTypeParameter.kt") public void testJavaMethodWithTypeParameter() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java index 737eda82b96..4e2e3bc4d40 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java @@ -35247,6 +35247,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi runTest("compiler/testData/codegen/box/multiplatform/k2/internalOverride2.kt"); } + @Test + @TestMetadata("javaClassReferencedActualType.kt") + public void testJavaClassReferencedActualType() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt"); + } + @Test @TestMetadata("javaMethodWithTypeParameter.kt") public void testJavaMethodWithTypeParameter() throws Exception { diff --git a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 0a7c85d3cbf..4d6b75ae872 100644 --- a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -799,7 +799,7 @@ class KotlinCoreEnvironment private constructor( // exception from `ExtensionPointImpl.doRegisterExtension`, because the registered extension can no longer be found // when the project is being disposed. // For example, see the `unregisterExtension` call in `GenerationUtils.compileFilesUsingFrontendIR`. - // TODO: refactor this to avoid registering unneeded extensions in the first place, and avoid using deprecated API. + // TODO: refactor this to avoid registering unneeded extensions in the first place, and avoid using deprecated API. (KT-64296) @Suppress("DEPRECATION") PsiElementFinder.EP.getPoint(project).registerExtension(JavaElementFinder(this)) @Suppress("DEPRECATION") diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt index 0f3536eae94..06333b7feb3 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.cli.jvm.compiler +import com.intellij.openapi.extensions.ExtensionPoint import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.VirtualFile @@ -66,13 +67,14 @@ open class VfsBasedProjectEnvironment( @OptIn(SessionConfiguration::class) override fun registerAsJavaElementFinder(firSession: FirSession) { val psiFinderExtensionPoint = PsiElementFinder.EP.getPoint(project) - if (psiFinderExtensionPoint.extensionList.any { it is JavaElementFinder }) { - psiFinderExtensionPoint.unregisterExtension(JavaElementFinder::class.java) - } + psiFinderExtensionPoint.unregisterFinders() + psiFinderExtensionPoint.unregisterFinders() val firJavaElementFinder = FirJavaElementFinder(firSession, project) firSession.register(FirJavaElementFinder::class, firJavaElementFinder) - psiFinderExtensionPoint.registerExtension(firJavaElementFinder, project) + // see comment and TODO in KotlinCoreEnvironment.registerKotlinLightClassSupport (KT-64296) + @Suppress("DEPRECATION") + PsiElementFinder.EP.getPoint(project).registerExtension(firJavaElementFinder) } private fun List.toSearchScope(allowOutOfProjectRoots: Boolean) = @@ -152,3 +154,9 @@ fun KotlinCoreEnvironment.toAbstractProjectEnvironment(): AbstractProjectEnviron fun GlobalSearchScope.toAbstractProjectFileSearchScope(): AbstractProjectFileSearchScope = PsiBasedProjectFileSearchScope(this) + +inline fun ExtensionPoint.unregisterFinders() { + if (extensionList.any { it is T }) { + unregisterExtension(T::class.java) + } +} diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index 2f458ee94b0..5025e84a8e7 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -34828,6 +34828,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/multiplatform/k2/internalOverride2.kt"); } + @Test + @TestMetadata("javaClassReferencedActualType.kt") + public void testJavaClassReferencedActualType() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt"); + } + @Test @TestMetadata("javaMethodWithTypeParameter.kt") public void testJavaMethodWithTypeParameter() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java index 8b6a84bcdc6..b9e32952fe3 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java @@ -34828,6 +34828,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated runTest("compiler/testData/codegen/box/multiplatform/k2/internalOverride2.kt"); } + @Test + @TestMetadata("javaClassReferencedActualType.kt") + public void testJavaClassReferencedActualType() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt"); + } + @Test @TestMetadata("javaMethodWithTypeParameter.kt") public void testJavaMethodWithTypeParameter() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index be83e646c7d..d36d447f568 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -34828,6 +34828,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/multiplatform/k2/internalOverride2.kt"); } + @Test + @TestMetadata("javaClassReferencedActualType.kt") + public void testJavaClassReferencedActualType() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt"); + } + @Test @TestMetadata("javaMethodWithTypeParameter.kt") public void testJavaMethodWithTypeParameter() throws Exception { diff --git a/compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt b/compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt new file mode 100644 index 00000000000..317d53a2c45 --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/k2/javaClassReferencedActualType.kt @@ -0,0 +1,37 @@ +// LANGUAGE: +MultiPlatformProjects +// IGNORE_BACKEND_K1: ANY +// TARGET_BACKEND: JVM_IR + +// MODULE: common +// FILE: Base.kt +expect interface Base + +// MODULE: jvm()()(common) +// FILE: Property.kt +public actual interface Base { + fun getValue(): PropType // /Base.PropType + + interface PropType { + val name: String + } +} + +// FILE: Derived.java +public abstract class Derived implements Base { + @Override + public Base.PropType getValue() { // /Base/PropType + return new Base.PropType() { + @Override + public String getName() { + return "OK"; + } + }; + } +} + +// FILE: main.kt +class Impl : Derived() + +fun box(): String { + return Impl().value.name +} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt index fa4c3c3f5f8..3a3bdcfb69b 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.asJava.finder.JavaElementFinder import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectFileSearchScope import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment +import org.jetbrains.kotlin.cli.jvm.compiler.unregisterFinders import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots import org.jetbrains.kotlin.config.CompilerConfiguration @@ -278,7 +279,7 @@ open class FirFrontendFacade( val project = compilerConfigurationProvider.getProject(module) - PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java) + PsiElementFinder.EP.getPoint(project).unregisterFinders() val parser = module.directives.singleValue(FirDiagnosticsDirectives.FIR_PARSER)