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