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 {
|
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
|
get() = false
|
||||||
val name: Name
|
val name: Name
|
||||||
fun dependencies(): List<ModuleInfo>
|
fun dependencies(): List<ModuleInfo>
|
||||||
fun friends(): Collection<ModuleInfo> = listOf()
|
fun modulesWhichInternalsAreVisible(): Collection<ModuleInfo> = listOf()
|
||||||
fun dependencyOnBuiltins(): DependencyOnBuiltins = DependenciesOnBuiltins.LAST
|
fun dependencyOnBuiltins(): DependencyOnBuiltins = DependenciesOnBuiltins.LAST
|
||||||
val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||||
get() = emptyMap()
|
get() = emptyMap()
|
||||||
@@ -193,8 +193,8 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
|||||||
modules.forEach {
|
modules.forEach {
|
||||||
module ->
|
module ->
|
||||||
val descriptor = resolverForProject.descriptorForModule(module)
|
val descriptor = resolverForProject.descriptorForModule(module)
|
||||||
module.friends().forEach {
|
module.modulesWhichInternalsAreVisible().forEach {
|
||||||
descriptor.addFriend(resolverForProject.descriptorForModule(it as M))
|
resolverForProject.descriptorForModule(it as M).addFriend(descriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,4 +249,4 @@ private class DelegatingPackageFragmentProvider(
|
|||||||
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
|
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
|
||||||
return delegate().getSubPackagesOf(fqName, nameFilter)
|
return delegate().getSubPackagesOf(fqName, nameFilter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ private val ALWAYS_TRUE: (Any?) -> Boolean = { true }
|
|||||||
|
|
||||||
fun <T> alwaysTrue(): (T) -> Boolean = ALWAYS_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 = { }
|
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.search.GlobalSearchScope
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
import com.intellij.psi.util.CachedValuesManager
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.utils.alwaysNull
|
||||||
import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
||||||
|
import java.lang.reflect.Method
|
||||||
import java.util.*
|
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 {
|
interface IdeaModuleInfo : ModuleInfo {
|
||||||
fun contentScope(): GlobalSearchScope
|
fun contentScope(): GlobalSearchScope
|
||||||
@@ -71,7 +102,7 @@ private fun <T> Module.cached(provider: CachedValueProvider<T>): T {
|
|||||||
return CachedValuesManager.getManager(project).getCachedValue(this, provider)
|
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
|
//NOTE: lib dependencies can be processed several times during recursive traversal
|
||||||
val result = LinkedHashSet<IdeaModuleInfo>()
|
val result = LinkedHashSet<IdeaModuleInfo>()
|
||||||
val dependencyEnumerator = ModuleRootManager.getInstance(module).orderEntries().compileOnly().recursively().exportedOnly()
|
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),
|
ideaModelDependencies(module, productionOnly = true),
|
||||||
ProjectRootModificationTracker.getInstance(module.project))
|
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
|
//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),
|
ideaModelDependencies(module, productionOnly = false),
|
||||||
ProjectRootModificationTracker.getInstance(module.project))
|
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
|
internal fun ModuleSourceInfo.isTests() = this is ModuleTestSourceInfo
|
||||||
@@ -249,4 +288,4 @@ enum class ModuleOrigin {
|
|||||||
MODULE,
|
MODULE,
|
||||||
LIBRARY,
|
LIBRARY,
|
||||||
OTHER
|
OTHER
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user