From 83a4b6396a33b8894d1d93fd3a23fcbb736f12a2 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 12 Mar 2021 20:32:15 +0100 Subject: [PATCH] Deduplicate source roots in psi2ir and CLI Compiler plugins can add new source roots to the next compilation round by using `AnalysisResult.RetryWithAdditionalRoots`. Some plugins added already existing source roots to this list in some cases. For example, this is reproducible with `square/anvil` with incremental compilation (KT-45100, KT-44925). Psi2ir didn't deduplicate the source files before, which resulted in several classes with the same name linked to the same symbol. This led to a "symbol is already bound" exception, and in case of KT-44925, to an additional NPE when we were rendering the class to display it in the message. The solution is to deduplicate classes before psi2ir. Note that this commit has two changes, in CLI and in psi2ir. Any one of these is sufficient for fixing the problem, however both are made just to make it more future-proof against new components and/or changes in existing subsystems (e.g. fir2ir). In the old JVM backend, similar deduplication was happening in `ClassFileFactory.registerSourceFiles`, which is why the problem is not reproducible there. #KT-45100 Fixed --- .../jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt | 2 +- .../org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 37a70e03dc9..088ccd6873a 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -283,7 +283,7 @@ class KotlinCoreEnvironment private constructor( fun addKotlinSourceRoots(rootDirs: List) { val roots = rootDirs.map { KotlinSourceRoot(it.absolutePath, isCommon = false) } - sourceFiles += createSourceFilesFromSourceRoots(configuration, project, roots) + sourceFiles += createSourceFilesFromSourceRoots(configuration, project, roots).toSet() - sourceFiles } fun createPackagePartProvider(scope: GlobalSearchScope): JvmPackagePartProvider { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt index c8b582789d8..7e056f8813d 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt @@ -46,7 +46,7 @@ class ModuleGenerator( fun generateModuleFragment(ktFiles: Collection): IrModuleFragment = IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule -> val irDeclarationGenerator = DeclarationGenerator(context) - ktFiles.mapTo(irModule.files) { ktFile -> + ktFiles.toSet().mapTo(irModule.files) { ktFile -> generateSingleFile(irDeclarationGenerator, ktFile) } }