[Resolve] Compute dependency on SDK properly

Under COMPOSITE resolution mode (see ResolutionModeComponent) we have
no fixed and globally known SDK, instead, for each module we have to
find SDK it it's transitive dependencies.

Currently, this is necessary in order to create proper JvmBuiltIns,
which need dependency on SDK to be present in immediate dependencies.
This commit is contained in:
Dmitry Savvinov
2019-06-05 12:36:12 +03:00
parent 02c07a4a6c
commit 9f2a03947c
4 changed files with 25 additions and 5 deletions
@@ -96,7 +96,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
private val invalidateOnOOCB: Boolean, private val invalidateOnOOCB: Boolean,
override val builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance, override val builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject(), private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
private val firstDependency: M? = null, private val sdkDependency: (M) -> M?,
private val packageOracleFactory: PackageOracleFactory = PackageOracleFactory.OptimisticFactory, private val packageOracleFactory: PackageOracleFactory = PackageOracleFactory.OptimisticFactory,
private val isReleaseCoroutines: Boolean? = null private val isReleaseCoroutines: Boolean? = null
) : ResolverForProject<M>() { ) : ResolverForProject<M>() {
@@ -139,7 +139,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
LazyModuleDependencies( LazyModuleDependencies(
projectContext.storageManager, projectContext.storageManager,
module, module,
firstDependency, sdkDependency(module),
this this
) )
) )
@@ -96,7 +96,7 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
resolverForModuleFactoryByPlatform = { resolverForModuleFactoryByPlatform = {
JvmResolverForModuleFactory(platformParameters, CompilerEnvironment, JvmPlatforms.defaultJvmPlatform) JvmResolverForModuleFactory(platformParameters, CompilerEnvironment, JvmPlatforms.defaultJvmPlatform)
}, },
builtIns = builtIns sdkDependency = { null }
) )
builtIns.initialize( builtIns.initialize(
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications
import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration
import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
@@ -28,7 +29,9 @@ import org.jetbrains.kotlin.idea.util.isKotlinBinary
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
import org.jetbrains.kotlin.types.typeUtil.lazyClosure
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.sure import org.jetbrains.kotlin.utils.sure
import org.jetbrains.kotlin.utils.yieldIfNotNull import org.jetbrains.kotlin.utils.yieldIfNotNull
@@ -40,6 +43,18 @@ fun PsiElement.getNullableModuleInfo(): IdeaModuleInfo? = this.collectInfos(Modu
fun PsiElement.getModuleInfos(): Sequence<IdeaModuleInfo> = this.collectInfos(ModuleInfoCollector.ToSequence) fun PsiElement.getModuleInfos(): Sequence<IdeaModuleInfo> = this.collectInfos(ModuleInfoCollector.ToSequence)
private fun ModuleInfo.doFindSdk(): SdkInfo? = dependencies().lazyClosure { it.dependencies() }.firstIsInstanceOrNull<SdkInfo>()
fun ModuleInfo.findSdkAcrossDependencies(): SdkInfo? {
return when (this) {
// It is important to check for cases of test/production explicitly, because we're using lambda's class
// of 'cacheInvalidatingOnRootModifications' as key for cache, and it should be different for Production/Source
is ModuleProductionSourceInfo -> module.cacheInvalidatingOnRootModifications { doFindSdk() }
is ModuleTestSourceInfo -> module.cacheInvalidatingOnRootModifications { doFindSdk() }
else -> doFindSdk()
}
}
fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFile): IdeaModuleInfo? = fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFile): IdeaModuleInfo? =
collectInfosByVirtualFile( collectInfosByVirtualFile(
project, virtualFile, project, virtualFile,
@@ -167,14 +167,19 @@ internal class ProjectResolutionFacade(
}, },
builtIns = builtIns, builtIns = builtIns,
delegateResolver = delegateResolverForProject, delegateResolver = delegateResolverForProject,
firstDependency = (settings as PlatformAnalysisSettingsImpl).sdk?.let { SdkInfo(project, it) }, sdkDependency = { module ->
if (settings is PlatformAnalysisSettingsImpl)
settings.sdk?.let { SdkInfo(project, it) }
else
module.findSdkAcrossDependencies()
},
packageOracleFactory = ServiceManager.getService(project, IdePackageOracleFactory::class.java), packageOracleFactory = ServiceManager.getService(project, IdePackageOracleFactory::class.java),
invalidateOnOOCB = invalidateOnOOCB, invalidateOnOOCB = invalidateOnOOCB,
isReleaseCoroutines = settings.isReleaseCoroutines isReleaseCoroutines = settings.isReleaseCoroutines
) )
if (delegateBuiltIns == null && builtIns is JvmBuiltIns) { if (delegateBuiltIns == null && builtIns is JvmBuiltIns) {
val sdkModuleDescriptor = settings.sdk!!.let { val sdkModuleDescriptor = (settings as PlatformAnalysisSettingsImpl).sdk!!.let {
resolverForProject.descriptorForModule( resolverForProject.descriptorForModule(
SdkInfo(project, it) SdkInfo(project, it)
) )