[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,
override val builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
private val firstDependency: M? = null,
private val sdkDependency: (M) -> M?,
private val packageOracleFactory: PackageOracleFactory = PackageOracleFactory.OptimisticFactory,
private val isReleaseCoroutines: Boolean? = null
) : ResolverForProject<M>() {
@@ -139,7 +139,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
LazyModuleDependencies(
projectContext.storageManager,
module,
firstDependency,
sdkDependency(module),
this
)
)
@@ -96,7 +96,7 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
resolverForModuleFactoryByPlatform = {
JvmResolverForModuleFactory(platformParameters, CompilerEnvironment, JvmPlatforms.defaultJvmPlatform)
},
builtIns = builtIns
sdkDependency = { null }
)
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.KtLightClassForFacade
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.core.isInTestSourceContentKotlinAware
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.psiUtil.getParentOfType
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.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.sure
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)
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? =
collectInfosByVirtualFile(
project, virtualFile,
@@ -167,14 +167,19 @@ internal class ProjectResolutionFacade(
},
builtIns = builtIns,
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),
invalidateOnOOCB = invalidateOnOOCB,
isReleaseCoroutines = settings.isReleaseCoroutines
)
if (delegateBuiltIns == null && builtIns is JvmBuiltIns) {
val sdkModuleDescriptor = settings.sdk!!.let {
val sdkModuleDescriptor = (settings as PlatformAnalysisSettingsImpl).sdk!!.let {
resolverForProject.descriptorForModule(
SdkInfo(project, it)
)