Distinguish exceptions about unknown module info
This commit is contained in:
@@ -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)
|
||||
}
|
||||
+10
-5
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user