Distinguish exceptions about unknown module info

This commit is contained in:
Natalia Selezneva
2018-07-24 15:02:31 +03:00
parent 9b1915799c
commit 0750de73e1
2 changed files with 70 additions and 7 deletions
@@ -64,6 +64,15 @@ abstract class ResolverForProject<M : ModuleInfo> {
abstract val builtIns: KotlinBuiltIns
override fun toString() = name
companion object {
const val resolverForSdkName = "sdk"
const val resolverForLibrariesName = "project libraries"
const val resolverForModulesName = "project source roots and libraries"
const val resolverForScriptDependenciesName = "dependencies of scripts"
const val resolverForSpecialInfoName = "completion/highlighting in "
}
}
class EmptyResolverForProject<M : ModuleInfo> : ResolverForProject<M>() {
@@ -205,8 +214,9 @@ class ResolverForProjectImpl<M : ModuleInfo>(
return doGetDescriptorForModule(moduleInfo)
}
override fun diagnoseUnknownModuleInfo(infos: List<ModuleInfo>) =
throw AssertionError("$name does not know how to resolve $infos")
override fun diagnoseUnknownModuleInfo(infos: List<ModuleInfo>): Nothing {
DiagnoseUnknownModuleInfoReporter.report(name, infos)
}
private fun checkModuleIsCorrect(moduleInfo: M) {
if (!isCorrectModuleInfo(moduleInfo)) {
@@ -445,3 +455,51 @@ interface ResolverForModuleComputationTracker {
ServiceManager.getService(project, ResolverForModuleComputationTracker::class.java) ?: null
}
}
private object DiagnoseUnknownModuleInfoReporter {
fun report(name: String, infos: List<ModuleInfo>): Nothing {
val message = "$name does not know how to resolve $infos"
when {
name.contains(ResolverForProject.resolverForSdkName) -> errorInSdkResolver(message)
name.contains(ResolverForProject.resolverForLibrariesName) -> errorInLibrariesResolver(message)
name.contains(ResolverForProject.resolverForModulesName) -> {
when {
infos.isEmpty() -> errorInModulesResolverWithEmptyInfos(message)
infos.size == 1 -> {
val infoAsString = infos.single().toString()
when {
infoAsString.contains("ScriptDependencies") -> errorInModulesResolverWithScriptDependencies(message)
infoAsString.contains("Library") -> errorInModulesResolverWithLibraryInfo(message)
else -> errorInModulesResolver(message)
}
}
else -> throw errorInModulesResolver(message)
}
}
name.contains(ResolverForProject.resolverForScriptDependenciesName) -> errorInScriptDependenciesInfoResolver(message)
name.contains(ResolverForProject.resolverForSpecialInfoName) -> {
when {
name.contains("ScriptModuleInfo") -> errorInScriptModuleInfoResolver(message)
else -> errorInSpecialModuleInfoResolver(message)
}
}
else -> otherError(message)
}
}
// Do not inline 'error*'-methods, they are needed to avoid Exception Analyzer merging those AssertionErrors
private fun errorInSdkResolver(message: String): Nothing = throw AssertionError(message)
private fun errorInLibrariesResolver(message: String): Nothing = throw AssertionError(message)
private fun errorInModulesResolver(message: String): Nothing = throw AssertionError(message)
private fun errorInModulesResolverWithEmptyInfos(message: String): Nothing = throw AssertionError(message)
private fun errorInModulesResolverWithScriptDependencies(message: String): Nothing = throw AssertionError(message)
private fun errorInModulesResolverWithLibraryInfo(message: String): Nothing = throw AssertionError(message)
private fun errorInScriptDependenciesInfoResolver(message: String): Nothing = throw AssertionError(message)
private fun errorInScriptModuleInfoResolver(message: String): Nothing = throw AssertionError(message)
private fun errorInSpecialModuleInfoResolver(message: String): Nothing = throw AssertionError(message)
private fun otherError(message: String): Nothing = throw AssertionError(message)
}
@@ -29,6 +29,11 @@ import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ResolverForProject.Companion.resolverForLibrariesName
import org.jetbrains.kotlin.analyzer.ResolverForProject.Companion.resolverForModulesName
import org.jetbrains.kotlin.analyzer.ResolverForProject.Companion.resolverForScriptDependenciesName
import org.jetbrains.kotlin.analyzer.ResolverForProject.Companion.resolverForSdkName
import org.jetbrains.kotlin.analyzer.ResolverForProject.Companion.resolverForSpecialInfoName
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.config.LanguageFeature
@@ -116,7 +121,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
val globalContext = globalFacade.globalContext.contextWithNewLockAndCompositeExceptionTracker()
return ProjectResolutionFacade(
"facadeForScriptDependencies",
"dependencies of scripts",
resolverForScriptDependenciesName,
project, globalContext, settings,
reuseDataFrom = globalFacade,
allModules = dependenciesModuleInfo.dependencies(),
@@ -132,7 +137,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
private inner class GlobalFacade(settings: PlatformAnalysisSettings) {
private val sdkContext = GlobalContext()
val facadeForSdk = ProjectResolutionFacade(
"facadeForSdk", "sdk ${settings.sdk}",
"facadeForSdk", "$resolverForSdkName ${settings.sdk}",
project, sdkContext, settings,
moduleFilter = { it is SdkInfo },
dependencies = listOf(
@@ -145,7 +150,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
private val librariesContext = sdkContext.contextWithNewLockAndCompositeExceptionTracker()
val facadeForLibraries = ProjectResolutionFacade(
"facadeForLibraries", "project libraries for platform ${settings.sdk}",
"facadeForLibraries", "$resolverForLibrariesName for platform ${settings.sdk}",
project, librariesContext, settings,
reuseDataFrom = facadeForSdk,
moduleFilter = { it is LibraryInfo },
@@ -158,7 +163,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
private val modulesContext = librariesContext.contextWithNewLockAndCompositeExceptionTracker()
val facadeForModules = ProjectResolutionFacade(
"facadeForModules", "project source roots and libraries for platform ${settings.platform}",
"facadeForModules", "$resolverForModulesName for platform ${settings.platform}",
project, modulesContext, settings,
reuseDataFrom = facadeForLibraries,
moduleFilter = { !it.isLibraryClasses() },
@@ -225,7 +230,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
)
val resolverDebugName =
"completion/highlighting in $specialModuleInfo for files ${files.joinToString { it.name }} for platform $targetPlatform"
"$resolverForSpecialInfoName $specialModuleInfo for files ${files.joinToString { it.name }} for platform $targetPlatform"
fun makeProjectResolutionFacade(
debugName: String,