KT-40301 Add more diagnostics for 'Module is not contained in resolver'

- See [EA-214260](https://ea.jetbrains.com/browser/ea_problems/214260)
This commit is contained in:
Roman Golyshev
2020-07-14 19:42:39 +03:00
committed by Roman Golyshev
parent 8fd16f4a39
commit fb9b3f96de
@@ -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<M : ModuleInfo>(
private val debugName: String,
@@ -95,14 +96,43 @@ abstract class AbstractResolverForProject<M : ModuleInfo>(
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<M>).resolverForModuleDescriptorImpl(descriptor)
}
resolverByModuleDescriptor.getOrPut(descriptor) {
checkModuleIsCorrect(module)
@@ -182,6 +212,25 @@ abstract class AbstractResolverForProject<M : ModuleInfo>(
val modificationTracker = (module as? TrackableModuleInfo)?.createModificationTracker() ?: fallbackModificationTracker
return ModuleData(moduleDescriptor, modificationTracker)
}
private fun renderResolversChainContents(): String {
val resolversChain = generateSequence(this) { it.delegateResolver as? AbstractResolverForProject<M> }
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<M : ModuleInfo>(