Allow to use internal declarations from special modules in IDEA
(e.g. IDEA 16 gradle tests loaded in separate module) #KT-10595 Fixed
This commit is contained in:
@@ -98,7 +98,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
}
|
||||
|
||||
private fun doGetDescriptorForModule(moduleInfo: M): ModuleDescriptorImpl {
|
||||
return descriptorByModule[moduleInfo] ?: return delegateResolver.descriptorForModule(moduleInfo) as ModuleDescriptorImpl
|
||||
return descriptorByModule[moduleInfo] ?: delegateResolver.descriptorForModule(moduleInfo) as ModuleDescriptorImpl
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ interface ModuleInfo {
|
||||
get() = false
|
||||
val name: Name
|
||||
fun dependencies(): List<ModuleInfo>
|
||||
fun friends(): Collection<ModuleInfo> = listOf()
|
||||
fun modulesWhichInternalsAreVisible(): Collection<ModuleInfo> = listOf()
|
||||
fun dependencyOnBuiltins(): DependencyOnBuiltins = DependenciesOnBuiltins.LAST
|
||||
val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||
get() = emptyMap()
|
||||
@@ -193,8 +193,8 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||
modules.forEach {
|
||||
module ->
|
||||
val descriptor = resolverForProject.descriptorForModule(module)
|
||||
module.friends().forEach {
|
||||
descriptor.addFriend(resolverForProject.descriptorForModule(it as M))
|
||||
module.modulesWhichInternalsAreVisible().forEach {
|
||||
resolverForProject.descriptorForModule(it as M).addFriend(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,4 +249,4 @@ private class DelegatingPackageFragmentProvider(
|
||||
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
|
||||
return delegate().getSubPackagesOf(fqName, nameFilter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,10 @@ private val ALWAYS_TRUE: (Any?) -> Boolean = { true }
|
||||
|
||||
fun <T> alwaysTrue(): (T) -> Boolean = ALWAYS_TRUE
|
||||
|
||||
private val ALWAYS_NULL: (Any?) -> Any? = { null }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T, R: Any> alwaysNull(): (T) -> R? = ALWAYS_NULL as (T) -> R?
|
||||
|
||||
val DO_NOTHING: (Any?) -> Unit = { }
|
||||
|
||||
|
||||
@@ -26,13 +26,44 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.alwaysNull
|
||||
import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
||||
import java.lang.reflect.Method
|
||||
import java.util.*
|
||||
|
||||
val LIBRARY_NAME_PREFIX: String = "library "
|
||||
private val LIBRARY_NAME_PREFIX: String = "library "
|
||||
|
||||
// TODO used reflection to be compatible with IDEA from both 143 and 144 branches,
|
||||
// TODO switch to directly using when "since-build" will be >= 144.3357.4
|
||||
private val getRelatedProductionModule: (Module) -> Module? = run {
|
||||
val klass =
|
||||
try {
|
||||
Class.forName("com.intellij.openapi.roots.TestModuleProperties")
|
||||
} catch (e: ClassNotFoundException) {
|
||||
return@run alwaysNull()
|
||||
}
|
||||
|
||||
|
||||
val getInstanceMethod: Method
|
||||
val getProductionModuleMethod: Method
|
||||
|
||||
try {
|
||||
getInstanceMethod = klass.getDeclaredMethod("getInstance", Module::class.java)
|
||||
getProductionModuleMethod = klass.getDeclaredMethod("getProductionModule")
|
||||
}
|
||||
catch (e: NoSuchMethodException) {
|
||||
return@run alwaysNull()
|
||||
}
|
||||
|
||||
return@run { module ->
|
||||
val instance = getInstanceMethod(null, module)
|
||||
getProductionModuleMethod(instance) as Module?
|
||||
}
|
||||
}
|
||||
|
||||
interface IdeaModuleInfo : ModuleInfo {
|
||||
fun contentScope(): GlobalSearchScope
|
||||
@@ -71,7 +102,7 @@ private fun <T> Module.cached(provider: CachedValueProvider<T>): T {
|
||||
return CachedValuesManager.getManager(project).getCachedValue(this, provider)
|
||||
}
|
||||
|
||||
fun ideaModelDependencies(module: Module, productionOnly: Boolean): List<IdeaModuleInfo> {
|
||||
private fun ideaModelDependencies(module: Module, productionOnly: Boolean): List<IdeaModuleInfo> {
|
||||
//NOTE: lib dependencies can be processed several times during recursive traversal
|
||||
val result = LinkedHashSet<IdeaModuleInfo>()
|
||||
val dependencyEnumerator = ModuleRootManager.getInstance(module).orderEntries().compileOnly().recursively().exportedOnly()
|
||||
@@ -102,8 +133,6 @@ data class ModuleProductionSourceInfo(override val module: Module) : ModuleSourc
|
||||
ideaModelDependencies(module, productionOnly = true),
|
||||
ProjectRootModificationTracker.getInstance(module.project))
|
||||
})
|
||||
|
||||
override fun friends() = listOf(module.testSourceInfo())
|
||||
}
|
||||
|
||||
//TODO: (module refactoring) do not create ModuleTestSourceInfo when there are no test roots for module
|
||||
@@ -117,6 +146,16 @@ data class ModuleTestSourceInfo(override val module: Module) : ModuleSourceInfo
|
||||
ideaModelDependencies(module, productionOnly = false),
|
||||
ProjectRootModificationTracker.getInstance(module.project))
|
||||
})
|
||||
|
||||
override fun modulesWhichInternalsAreVisible() = module.cached(CachedValueProvider {
|
||||
val list = SmartList<ModuleInfo>(module.productionSourceInfo())
|
||||
|
||||
getRelatedProductionModule(module)?.let {
|
||||
list.add(it.productionSourceInfo())
|
||||
}
|
||||
|
||||
CachedValueProvider.Result(list, ProjectRootModificationTracker.getInstance(module.project))
|
||||
})
|
||||
}
|
||||
|
||||
internal fun ModuleSourceInfo.isTests() = this is ModuleTestSourceInfo
|
||||
@@ -249,4 +288,4 @@ enum class ModuleOrigin {
|
||||
MODULE,
|
||||
LIBRARY,
|
||||
OTHER
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user