Refactor ScriptDependenciesModuleInfo

Do not mix ScriptDependenciesInfo for all project and for concrete script.
Rename ScriptDependenciesModuleInfo to ScriptDependenciesInfo
Rename ScriptDependenciesModuleSourceInfo to ScriptDependenciesSourceInfo
This commit is contained in:
Natalia Selezneva
2018-03-26 15:58:56 +03:00
parent f8ad244899
commit d75d0d8711
6 changed files with 65 additions and 55 deletions
@@ -44,16 +44,14 @@ data class ScriptModuleInfo(
override fun contentScope() = GlobalSearchScope.fileScope(project, scriptFile)
override fun dependencies(): List<IdeaModuleInfo> {
val result = arrayListOf(this, ScriptDependenciesModuleInfo(project, this))
relatedModuleSourceInfo?.let { result.add(it) }
result.addAll(sdkDependencies(externalDependencies, project))
return result
return arrayListOf<IdeaModuleInfo>(this).apply {
add(ScriptDependenciesInfo.ForFile(project, this@ScriptModuleInfo))
relatedModuleSourceInfo?.let { add(it) }
findJdk(externalDependencies, project)?.let { add(SdkInfo(project, it)) }
}
}
}
private fun sdkDependencies(scriptDependencies: ScriptDependencies?, project: Project): List<SdkInfo> =
listOfNotNull(findJdk(scriptDependencies, project)?.let { SdkInfo(project, it) })
fun findJdk(dependencies: ScriptDependencies?, project: Project): Sdk? {
val allJdks = getAllProjectSdks()
// workaround for mismatched gradle wrapper and plugin version
@@ -67,52 +65,62 @@ fun findJdk(dependencies: ScriptDependencies?, project: Project): Sdk? {
?: allJdks.firstOrNull()
}
class ScriptDependenciesModuleInfo(
val project: Project,
val scriptModuleInfo: ScriptModuleInfo?
) : IdeaModuleInfo, BinaryModuleInfo {
override fun dependencies() = (listOf(this) + sdkDependencies(
scriptModuleInfo?.externalDependencies,
project
))
sealed class ScriptDependenciesInfo(val project: Project) : IdeaModuleInfo, BinaryModuleInfo {
abstract val sdk: Sdk?
override val name = Name.special("<Script dependencies>")
override fun contentScope(): GlobalSearchScope {
if (scriptModuleInfo == null) {
// we do not know which scripts these dependencies are
return KotlinSourceFilterScope.libraryClassFiles(
ScriptDependenciesManager.getInstance(project).getAllScriptsClasspathScope(), project
)
}
return ServiceManager.getService(project, ScriptBinariesScopeCache::class.java).get(scriptModuleInfo.externalDependencies)
}
override fun dependencies(): List<IdeaModuleInfo> = listOfNotNull(this, sdk?.let { SdkInfo(project, it) })
// NOTE: intentionally not taking corresponding script info into account
// otherwise there is no way to implement getModuleInfo
override fun hashCode() = project.hashCode()
override fun equals(other: Any?): Boolean = other is ScriptDependenciesModuleInfo && this.project == other.project
override fun equals(other: Any?): Boolean = other is ScriptDependenciesInfo && this.project == other.project
override val moduleOrigin: ModuleOrigin
get() = ModuleOrigin.LIBRARY
override val sourcesModuleInfo: SourceForBinaryModuleInfo?
get() = ScriptDependenciesSourceModuleInfo(project)
get() = ScriptDependenciesSourceInfo.ForProject(project)
class ForFile(project: Project, val scriptModuleInfo: ScriptModuleInfo) : ScriptDependenciesInfo(project) {
override val sdk: Sdk?
get() = findJdk(scriptModuleInfo.externalDependencies, project)
override fun contentScope(): GlobalSearchScope {
return ServiceManager.getService(project, ScriptBinariesScopeCache::class.java).get(scriptModuleInfo.externalDependencies)
}
}
class ForProject(project: Project) : ScriptDependenciesInfo(project) {
override val sdk: Sdk?
get() = findJdk(null, project)
override fun contentScope(): GlobalSearchScope {
// we do not know which scripts these dependencies are
return KotlinSourceFilterScope.libraryClassFiles(
ScriptDependenciesManager.getInstance(project).getAllScriptsClasspathScope(), project
)
}
}
}
data class ScriptDependenciesSourceModuleInfo(
val project: Project
) : IdeaModuleInfo, SourceForBinaryModuleInfo {
sealed class ScriptDependenciesSourceInfo(val project: Project) : IdeaModuleInfo, SourceForBinaryModuleInfo {
override val name = Name.special("<Source for script dependencies>")
override val binariesModuleInfo: ScriptDependenciesModuleInfo
get() = ScriptDependenciesModuleInfo(project, null)
override val binariesModuleInfo: ScriptDependenciesInfo
get() = ScriptDependenciesInfo.ForProject(project)
override fun sourceScope(): GlobalSearchScope = KotlinSourceFilterScope.librarySources(
ScriptDependenciesManager.getInstance(project).getAllLibrarySourcesScope(), project
)
override fun hashCode() = project.hashCode()
override fun equals(other: Any?): Boolean = other is ScriptDependenciesSourceInfo && this.project == other.project
class ForProject(project: Project) : ScriptDependenciesSourceInfo(project)
}
private class ScriptBinariesScopeCache(private val project: Project) : SLRUCache<ScriptDependencies, GlobalSearchScope>(6, 6) {
@@ -261,13 +261,13 @@ private inline fun <T> collectInfosByVirtualFile(
val scriptConfigurationManager = ScriptDependenciesManager.getInstance(project)
if (isBinary && virtualFile in scriptConfigurationManager.getAllScriptsClasspathScope()) {
if (treatAsLibrarySource) {
onOccurrence(ScriptDependenciesSourceModuleInfo(project))
onOccurrence(ScriptDependenciesSourceInfo.ForProject(project))
} else {
onOccurrence(ScriptDependenciesModuleInfo(project, null))
onOccurrence(ScriptDependenciesInfo.ForProject(project))
}
}
if (!isBinary && virtualFile in scriptConfigurationManager.getAllLibrarySourcesScope()) {
onOccurrence(ScriptDependenciesSourceModuleInfo(project))
onOccurrence(ScriptDependenciesSourceInfo.ForProject(project))
}
return onOccurrence(null)
@@ -83,12 +83,12 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
private val facadesForScriptDependencies: SLRUCache<ScriptModuleInfo, ProjectResolutionFacade> =
object : SLRUCache<ScriptModuleInfo, ProjectResolutionFacade>(2, 3) {
override fun createValue(scriptModuleInfo: ScriptModuleInfo?): ProjectResolutionFacade {
return createFacadeForScriptDependencies(
ScriptDependenciesModuleInfo(
project,
scriptModuleInfo
)
)
val dependenciesInfo = if (scriptModuleInfo != null) {
ScriptDependenciesInfo.ForFile(project, scriptModuleInfo)
} else {
ScriptDependenciesInfo.ForProject(project)
}
return createFacadeForScriptDependencies(dependenciesInfo)
}
}
@@ -99,11 +99,10 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
}
private fun createFacadeForScriptDependencies(
dependenciesModuleInfo: ScriptDependenciesModuleInfo,
dependenciesModuleInfo: ScriptDependenciesInfo,
syntheticFiles: Collection<KtFile> = listOf()
): ProjectResolutionFacade {
val scriptModuleInfo = dependenciesModuleInfo.scriptModuleInfo
val sdk = findJdk(scriptModuleInfo?.externalDependencies, project)
val sdk = dependenciesModuleInfo.sdk
val platform = JvmPlatform // TODO: Js scripts?
val settings = PlatformAnalysisSettings(platform, sdk, true)
@@ -113,6 +112,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
ScriptDependenciesModificationTracker.getInstance(project)
)
val scriptModuleInfo = (dependenciesModuleInfo as? ScriptDependenciesInfo.ForFile)?.scriptModuleInfo
val globalFacade = if (scriptModuleInfo?.relatedModuleSourceInfo != null) {
globalFacade(settings)
} else {
@@ -268,15 +268,15 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
moduleFilter = { it == specialModuleInfo }
)
}
specialModuleInfo is ScriptDependenciesModuleInfo -> {
specialModuleInfo is ScriptDependenciesInfo -> {
createFacadeForScriptDependencies(specialModuleInfo, files)
}
specialModuleInfo is ScriptDependenciesSourceModuleInfo -> {
specialModuleInfo is ScriptDependenciesSourceInfo -> {
// TODO: can be optimized by caching facadeForScriptDependencies
val facadeForScriptDependencies = createFacadeForScriptDependencies(specialModuleInfo.binariesModuleInfo, files)
val globalContext = facadeForScriptDependencies.globalContext.contextWithNewLockAndCompositeExceptionTracker()
makeProjectResolutionFacade(
"facadeForSpecialModuleInfo (ScriptDependenciesSourceModuleInfo)",
"facadeForSpecialModuleInfo (ScriptDependenciesSourceInfo)",
globalContext,
reuseDataFrom = facadeForScriptDependencies,
allModules = specialModuleInfo.dependencies(),
@@ -33,7 +33,10 @@ import org.jetbrains.kotlin.config.AnalysisFlag
import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.TargetPlatformVersion
import org.jetbrains.kotlin.idea.caches.project.*
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.caches.project.ScriptDependenciesInfo
import org.jetbrains.kotlin.idea.caches.project.ScriptModuleInfo
import org.jetbrains.kotlin.idea.project.getLanguageVersionSettings
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.project.targetPlatform
@@ -45,7 +48,7 @@ object IDELanguageSettingsProvider : LanguageSettingsProvider {
moduleInfo is ModuleSourceInfo -> moduleInfo.module.languageVersionSettings
moduleInfo is LibraryInfo -> project.getLanguageVersionSettings(extraAnalysisFlags = getExtraAnalysisFlags(project))
moduleInfo is ScriptModuleInfo -> getVersionLanguageSettingsForScripts(project, moduleInfo.scriptDefinition)
moduleInfo is ScriptDependenciesModuleInfo && moduleInfo.scriptModuleInfo != null ->
moduleInfo is ScriptDependenciesInfo.ForFile ->
getVersionLanguageSettingsForScripts(project, moduleInfo.scriptModuleInfo.scriptDefinition)
else -> project.getLanguageVersionSettings()
}
@@ -20,15 +20,15 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.ResolveScopeProvider
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.idea.caches.project.ScriptDependenciesModuleInfo
import org.jetbrains.kotlin.idea.caches.project.ScriptDependenciesSourceModuleInfo
import org.jetbrains.kotlin.idea.caches.project.ScriptDependenciesInfo
import org.jetbrains.kotlin.idea.caches.project.ScriptDependenciesSourceInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfoByVirtualFile
class ScriptDependenciesResolveScopeProvider : ResolveScopeProvider() {
override fun getResolveScope(file: VirtualFile, project: Project): GlobalSearchScope? {
val moduleInfo = getModuleInfoByVirtualFile(project, file) ?: return null
val scriptDependenciesModuleInfo = (moduleInfo as? ScriptDependenciesModuleInfo)
?: (moduleInfo as? ScriptDependenciesSourceModuleInfo)?.binariesModuleInfo
val scriptDependenciesModuleInfo = (moduleInfo as? ScriptDependenciesInfo)
?: (moduleInfo as? ScriptDependenciesSourceInfo)?.binariesModuleInfo
?: return null
return GlobalSearchScope.union(
arrayOf(
@@ -29,14 +29,13 @@ import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.idea.caches.project.ModuleProductionSourceInfo
import org.jetbrains.kotlin.idea.caches.project.ScriptDependenciesModuleInfo
import org.jetbrains.kotlin.idea.caches.project.ScriptDependenciesInfo
import org.jetbrains.kotlin.idea.caches.project.ScriptModuleInfo
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.samWithReceiver.SamWithReceiverCommandLineProcessor.Companion.ANNOTATION_OPTION
import org.jetbrains.kotlin.samWithReceiver.SamWithReceiverCommandLineProcessor.Companion.PLUGIN_ID
import org.jetbrains.kotlin.samWithReceiver.SamWithReceiverResolverExtension
import java.util.*
class IdeSamWithReceiverComponentContributor(val project: Project) : StorageComponentContainerContributor {
private companion object {
@@ -68,7 +67,7 @@ class IdeSamWithReceiverComponentContributor(val project: Project) : StorageComp
val annotations =
when (moduleInfo) {
is ScriptModuleInfo -> moduleInfo.scriptDefinition.annotationsForSamWithReceivers
is ScriptDependenciesModuleInfo -> moduleInfo.scriptModuleInfo?.scriptDefinition?.annotationsForSamWithReceivers
is ScriptDependenciesInfo.ForFile -> moduleInfo.scriptModuleInfo.scriptDefinition?.annotationsForSamWithReceivers
is ModuleProductionSourceInfo -> getAnnotationsForModule(moduleInfo.module)
else -> null
} ?: return