From fb9b3f96dec787acd46336e74860b958151c4d50 Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Tue, 14 Jul 2020 19:42:39 +0300 Subject: [PATCH] KT-40301 Add more diagnostics for 'Module is not contained in resolver' - See [EA-214260](https://ea.jetbrains.com/browser/ea_problems/214260) --- .../analyzer/AbstractResolverForProject.kt | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AbstractResolverForProject.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AbstractResolverForProject.kt index 41cf335de7e..667de3bdb0a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AbstractResolverForProject.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AbstractResolverForProject.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.RESOLUTION_ANCHOR_PROVIDER_CAPABILITY import org.jetbrains.kotlin.resolve.ResolutionAnchorProvider +import org.jetbrains.kotlin.utils.checkWithAttachment abstract class AbstractResolverForProject( private val debugName: String, @@ -95,14 +96,43 @@ abstract class AbstractResolverForProject( private fun isCorrectModuleInfo(moduleInfo: M) = moduleInfo in allModules - override fun resolverForModuleDescriptor(descriptor: ModuleDescriptor): ResolverForModule { + final override fun resolverForModuleDescriptor(descriptor: ModuleDescriptor): ResolverForModule { + val moduleResolver = resolverForModuleDescriptorImpl(descriptor) + + // Please, attach exceptions from here to EA-214260 (see `resolverForModuleDescriptorImpl` comment) + checkWithAttachment( + moduleResolver != null, + lazyMessage = { "$descriptor is not contained in resolver $name" }, + attachments = { + it.withAttachment( + "resolverContents.txt", + "Expected module descriptor: $descriptor\n\n${renderResolversChainContents()}" + ) + } + ) + + return moduleResolver + } + + /** + * We have a problem investigating EA-214260 (KT-40301), that is why we separated searching the + * [ResolverForModule] and reporting the problem in [resolverForModuleDescriptor] (so we can tweak the reported information more + * accurately). + * + * We use the fact that [ResolverForProject] have only two inheritors: [EmptyResolverForProject] and [AbstractResolverForProject]. + * So if the [delegateResolver] is not an [EmptyResolverForProject], it has to be [AbstractResolverForProject]. + * + * Knowing that, we can safely use [resolverForModuleDescriptorImpl] recursively, and get the same result + * as with [resolverForModuleDescriptor]. + */ + private fun resolverForModuleDescriptorImpl(descriptor: ModuleDescriptor): ResolverForModule? { return projectContext.storageManager.compute { val module = moduleInfoByDescriptor[descriptor] if (module == null) { if (delegateResolver is EmptyResolverForProject<*>) { - throw IllegalStateException("$descriptor is not contained in resolver $name") + return@compute null } - return@compute delegateResolver.resolverForModuleDescriptor(descriptor) + return@compute (delegateResolver as AbstractResolverForProject).resolverForModuleDescriptorImpl(descriptor) } resolverByModuleDescriptor.getOrPut(descriptor) { checkModuleIsCorrect(module) @@ -182,6 +212,25 @@ abstract class AbstractResolverForProject( val modificationTracker = (module as? TrackableModuleInfo)?.createModificationTracker() ?: fallbackModificationTracker return ModuleData(moduleDescriptor, modificationTracker) } + + private fun renderResolversChainContents(): String { + val resolversChain = generateSequence(this) { it.delegateResolver as? AbstractResolverForProject } + + return resolversChain.joinToString("\n\n") { resolver -> + "Resolver: ${resolver.name}\n'moduleInfoByDescriptor' content:\n[${resolver.renderResolverModuleInfos()}]" + } + } + + private fun renderResolverModuleInfos(): String = projectContext.storageManager.compute { + moduleInfoByDescriptor.entries.joinToString(",\n") { (descriptor, moduleInfo) -> + """ + { + moduleDescriptor: $descriptor + moduleInfo: $moduleInfo + } + """.trimIndent() + } + } } private class DelegatingPackageFragmentProvider(