diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt index 8bd375780a4..13dd9997cff 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt @@ -81,11 +81,10 @@ fun getScriptRelatedModuleInfo(project: Project, virtualFile: VirtualFile): Modu return moduleRelatedModuleInfo } - return if (ScratchFileService.findRootType(virtualFile) != ScratchRootType.getInstance()) null - else { + return if (ScratchFileService.getInstance().getRootType(virtualFile) is ScratchRootType) { val scratchModule = virtualFile.scriptRelatedModuleName?.let { ModuleManager.getInstance(project).findModuleByName(it) } scratchModule?.testSourceInfo() ?: scratchModule?.productionSourceInfo() - } + } else null } private typealias VirtualFileProcessor = (Project, VirtualFile, Boolean) -> T diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.191 b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.191 deleted file mode 100644 index 6180f5e1fd5..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.191 +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.idea.caches.project - -import com.intellij.ide.scratch.ScratchFileService -import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.* -import com.intellij.openapi.util.Key -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -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.ScriptConfigurationManager -import org.jetbrains.kotlin.idea.core.script.scriptRelatedModuleName -import org.jetbrains.kotlin.idea.highlighter.OutsidersPsiFileSupportUtils -import org.jetbrains.kotlin.idea.util.ProjectRootsUtil -import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected -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.scripting.definitions.runReadAction -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 - -var PsiFile.forcedModuleInfo: ModuleInfo? by UserDataProperty(Key.create("FORCED_MODULE_INFO")) - -fun PsiElement.getModuleInfo(): IdeaModuleInfo = this.collectInfos(ModuleInfoCollector.NotNullTakeFirst) - -fun PsiElement.getNullableModuleInfo(): IdeaModuleInfo? = this.collectInfos(ModuleInfoCollector.NullableTakeFirst) - -fun PsiElement.getModuleInfos(): Sequence = this.collectInfos(ModuleInfoCollector.ToSequence) - -private fun ModuleInfo.doFindSdk(): SdkInfo? = dependencies().lazyClosure { it.dependencies() }.firstIsInstanceOrNull() - -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, - treatAsLibrarySource = false, - onOccurrence = { return@getModuleInfoByVirtualFile it } - ) - -fun getBinaryLibrariesModuleInfos(project: Project, virtualFile: VirtualFile) = - collectModuleInfosByType( - project, - virtualFile - ) - -fun getLibrarySourcesModuleInfos(project: Project, virtualFile: VirtualFile) = - collectModuleInfosByType( - project, - virtualFile - ) - -fun getScriptRelatedModuleInfo(project: Project, virtualFile: VirtualFile): ModuleSourceInfo? { - val moduleRelatedModuleInfo = getModuleRelatedModuleInfo(project, virtualFile) - if (moduleRelatedModuleInfo != null) { - return moduleRelatedModuleInfo - } - - if (ScratchFileService.isInScratchRoot(virtualFile)) { - val scratchModule = virtualFile.scriptRelatedModuleName?.let { ModuleManager.getInstance(project).findModuleByName(it) } - return scratchModule?.testSourceInfo() ?: scratchModule?.productionSourceInfo() - } - - return null -} - -private typealias VirtualFileProcessor = (Project, VirtualFile, Boolean) -> T - -private sealed class ModuleInfoCollector( - val onResult: (IdeaModuleInfo?) -> T, - val onFailure: (String) -> T, - val virtualFileProcessor: VirtualFileProcessor -) { - object NotNullTakeFirst : ModuleInfoCollector( - onResult = { it ?: NotUnderContentRootModuleInfo }, - onFailure = { reason -> - LOG.error("Could not find correct module information.\nReason: $reason") - NotUnderContentRootModuleInfo - }, - virtualFileProcessor = processor@{ project, virtualFile, isLibrarySource -> - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { - return@processor it ?: NotUnderContentRootModuleInfo - } - } - ) - - object NullableTakeFirst : ModuleInfoCollector( - onResult = { it }, - onFailure = { reason -> - LOG.warn("Could not find correct module information.\nReason: $reason") - null - }, - virtualFileProcessor = processor@{ project, virtualFile, isLibrarySource -> - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { return@processor it } - } - ) - - object ToSequence : ModuleInfoCollector>( - onResult = { result -> result?.let { sequenceOf(it) } ?: emptySequence() }, - onFailure = { reason -> - LOG.warn("Could not find correct module information.\nReason: $reason") - emptySequence() - }, - virtualFileProcessor = { project, virtualFile, isLibrarySource -> - sequence { - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { yieldIfNotNull(it) } - } - } - ) -} - -private fun PsiElement.collectInfos(c: ModuleInfoCollector): T { - (containingFile?.forcedModuleInfo as? IdeaModuleInfo)?.let { - return c.onResult(it) - } - - if (this is KtLightElement<*, *>) { - return this.processLightElement(c) - } - - collectModuleInfoByUserData(this).firstOrNull()?.let { - return c.onResult(it) - } - - val containingFile = - containingFile ?: return c.onFailure("Analyzing element of type ${this::class.java} with no containing file\nText:\n$text") - - val containingKtFile = (this as? KtElement)?.containingFile as? KtFile - containingKtFile?.analysisContext?.let { - return it.collectInfos(c) - } - - containingKtFile?.doNotAnalyze?.let { - return c.onFailure("Should not analyze element: $text in file ${containingKtFile.name}\n$it") - } - - val explicitModuleInfo = containingKtFile?.forcedModuleInfo ?: (containingKtFile?.originalFile as? KtFile)?.forcedModuleInfo - if (explicitModuleInfo is IdeaModuleInfo) { - return c.onResult(explicitModuleInfo) - } - - if (containingKtFile is KtCodeFragment) { - val context = containingKtFile.getContext() - ?: return c.onFailure("Analyzing code fragment of type ${containingKtFile::class.java} with no context element\nText:\n${containingKtFile.getText()}") - return context.collectInfos(c) - } - - val virtualFile = containingFile.originalFile.virtualFile - ?: return c.onFailure("Analyzing element of type ${this::class.java} in non-physical file $containingFile of type ${containingFile::class.java}\nText:\n$text") - - val isScript = runReadAction { containingKtFile?.isScript() == true } - if (isScript) { - getModuleRelatedModuleInfo(project, virtualFile)?.let { - return c.onResult(it) - } - val script = runReadAction { containingKtFile?.script } - script?.let { - containingKtFile?.findScriptDefinition()?.let { - return c.onResult(ScriptModuleInfo(project, virtualFile, it)) - } - } - } - - return c.virtualFileProcessor( - project, - virtualFile, - (containingFile as? KtFile)?.isCompiled ?: false - ) -} - -private fun KtLightElement<*, *>.processLightElement(c: ModuleInfoCollector): T { - val decompiledClass = this.getParentOfType(strict = false) - if (decompiledClass != null) { - return c.virtualFileProcessor( - project, - containingFile.virtualFile.sure { "Decompiled class should be build from physical file" }, - false - ) - } - - val element = kotlinOrigin ?: when (this) { - is FakeLightClassForFileOfPackage -> this.getContainingFile()!! - is KtLightClassForFacade -> this.files.first() - else -> return c.onFailure("Light element without origin is referenced by resolve:\n$this\n${this.clsDelegate.text}") - } - - return element.collectInfos(c) -} - -private inline fun collectInfosByVirtualFile( - project: Project, - virtualFile: VirtualFile, - treatAsLibrarySource: Boolean, - onOccurrence: (IdeaModuleInfo?) -> T -): T { - collectModuleInfoByUserData(project, virtualFile).map(onOccurrence) - - val moduleRelatedModuleInfo = getModuleRelatedModuleInfo(project, virtualFile) - if (moduleRelatedModuleInfo != null) { - onOccurrence(moduleRelatedModuleInfo) - } - - val projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project) - projectFileIndex.getOrderEntriesForFile(virtualFile).forEach { - it.toIdeaModuleInfo(project, virtualFile, treatAsLibrarySource).map(onOccurrence) - } - - val isBinary = virtualFile.fileType.isKotlinBinary() - val scriptConfigurationManager = ScriptConfigurationManager.getInstance(project) - if (isBinary && virtualFile in scriptConfigurationManager.getAllScriptsDependenciesClassFilesScope()) { - if (treatAsLibrarySource) { - onOccurrence(ScriptDependenciesSourceInfo.ForProject(project)) - } else { - onOccurrence(ScriptDependenciesInfo.ForProject(project)) - } - } - if (!isBinary && virtualFile in scriptConfigurationManager.getAllScriptDependenciesSourcesScope()) { - onOccurrence(ScriptDependenciesSourceInfo.ForProject(project)) - } - - return onOccurrence(null) -} - -private fun getModuleRelatedModuleInfo(project: Project, virtualFile: VirtualFile): ModuleSourceInfo? { - val projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project) - - val module = projectFileIndex.getModuleForFile(virtualFile) - if (module != null && !module.isDisposed) { - val moduleFileIndex = ModuleRootManager.getInstance(module).fileIndex - if (moduleFileIndex.isInTestSourceContentKotlinAware(virtualFile)) { - return module.testSourceInfo() - } else if (moduleFileIndex.isInSourceContentWithoutInjected(virtualFile)) { - return module.productionSourceInfo() - } - } - - val fileOrigin = OutsidersPsiFileSupportUtils.getOutsiderFileOrigin(project, virtualFile) - if (fileOrigin != null) { - return getModuleRelatedModuleInfo(project, fileOrigin) - } - - return null -} - -private inline fun collectModuleInfosByType(project: Project, virtualFile: VirtualFile): Collection { - val result = linkedSetOf() - collectInfosByVirtualFile(project, virtualFile, treatAsLibrarySource = false) { - result.addIfNotNull(it as? T) - } - - return result -} - -private fun OrderEntry.toIdeaModuleInfo( - project: Project, - virtualFile: VirtualFile, - treatAsLibrarySource: Boolean = false -): List { - if (this is ModuleOrderEntry) return emptyList() - if (!isValid) return emptyList() - - when (this) { - is LibraryOrderEntry -> { - val library = library ?: return emptyList() - if (ProjectRootsUtil.isLibraryClassFile(project, virtualFile) && !treatAsLibrarySource) { - return createLibraryInfo(project, library) - } else if (ProjectRootsUtil.isLibraryFile(project, virtualFile) || treatAsLibrarySource) { - return createLibraryInfo(project, library).map { it.sourcesModuleInfo } - } - } - is JdkOrderEntry -> { - return listOf(SdkInfo(project, jdk ?: return emptyList())) - } - else -> return emptyList() - } - return emptyList() -} - -/** - * @see [org.jetbrains.kotlin.types.typeUtil.closure]. - */ -fun Collection.lazyClosure(f: (T) -> Collection): Sequence = sequence { - if (size == 0) return@sequence - var sizeBeforeIteration = 0 - - yieldAll(this@lazyClosure) - var yieldedCount = size - var elementsToCheck = this@lazyClosure - - while (yieldedCount > sizeBeforeIteration) { - val toAdd = hashSetOf() - elementsToCheck.forEach { - val neighbours = f(it) - yieldAll(neighbours) - yieldedCount += neighbours.size - toAdd.addAll(neighbours) - } - elementsToCheck = toAdd - sizeBeforeIteration = yieldedCount - } -} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.192 b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.192 deleted file mode 100644 index 6180f5e1fd5..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.192 +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.idea.caches.project - -import com.intellij.ide.scratch.ScratchFileService -import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.* -import com.intellij.openapi.util.Key -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -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.ScriptConfigurationManager -import org.jetbrains.kotlin.idea.core.script.scriptRelatedModuleName -import org.jetbrains.kotlin.idea.highlighter.OutsidersPsiFileSupportUtils -import org.jetbrains.kotlin.idea.util.ProjectRootsUtil -import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected -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.scripting.definitions.runReadAction -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 - -var PsiFile.forcedModuleInfo: ModuleInfo? by UserDataProperty(Key.create("FORCED_MODULE_INFO")) - -fun PsiElement.getModuleInfo(): IdeaModuleInfo = this.collectInfos(ModuleInfoCollector.NotNullTakeFirst) - -fun PsiElement.getNullableModuleInfo(): IdeaModuleInfo? = this.collectInfos(ModuleInfoCollector.NullableTakeFirst) - -fun PsiElement.getModuleInfos(): Sequence = this.collectInfos(ModuleInfoCollector.ToSequence) - -private fun ModuleInfo.doFindSdk(): SdkInfo? = dependencies().lazyClosure { it.dependencies() }.firstIsInstanceOrNull() - -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, - treatAsLibrarySource = false, - onOccurrence = { return@getModuleInfoByVirtualFile it } - ) - -fun getBinaryLibrariesModuleInfos(project: Project, virtualFile: VirtualFile) = - collectModuleInfosByType( - project, - virtualFile - ) - -fun getLibrarySourcesModuleInfos(project: Project, virtualFile: VirtualFile) = - collectModuleInfosByType( - project, - virtualFile - ) - -fun getScriptRelatedModuleInfo(project: Project, virtualFile: VirtualFile): ModuleSourceInfo? { - val moduleRelatedModuleInfo = getModuleRelatedModuleInfo(project, virtualFile) - if (moduleRelatedModuleInfo != null) { - return moduleRelatedModuleInfo - } - - if (ScratchFileService.isInScratchRoot(virtualFile)) { - val scratchModule = virtualFile.scriptRelatedModuleName?.let { ModuleManager.getInstance(project).findModuleByName(it) } - return scratchModule?.testSourceInfo() ?: scratchModule?.productionSourceInfo() - } - - return null -} - -private typealias VirtualFileProcessor = (Project, VirtualFile, Boolean) -> T - -private sealed class ModuleInfoCollector( - val onResult: (IdeaModuleInfo?) -> T, - val onFailure: (String) -> T, - val virtualFileProcessor: VirtualFileProcessor -) { - object NotNullTakeFirst : ModuleInfoCollector( - onResult = { it ?: NotUnderContentRootModuleInfo }, - onFailure = { reason -> - LOG.error("Could not find correct module information.\nReason: $reason") - NotUnderContentRootModuleInfo - }, - virtualFileProcessor = processor@{ project, virtualFile, isLibrarySource -> - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { - return@processor it ?: NotUnderContentRootModuleInfo - } - } - ) - - object NullableTakeFirst : ModuleInfoCollector( - onResult = { it }, - onFailure = { reason -> - LOG.warn("Could not find correct module information.\nReason: $reason") - null - }, - virtualFileProcessor = processor@{ project, virtualFile, isLibrarySource -> - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { return@processor it } - } - ) - - object ToSequence : ModuleInfoCollector>( - onResult = { result -> result?.let { sequenceOf(it) } ?: emptySequence() }, - onFailure = { reason -> - LOG.warn("Could not find correct module information.\nReason: $reason") - emptySequence() - }, - virtualFileProcessor = { project, virtualFile, isLibrarySource -> - sequence { - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { yieldIfNotNull(it) } - } - } - ) -} - -private fun PsiElement.collectInfos(c: ModuleInfoCollector): T { - (containingFile?.forcedModuleInfo as? IdeaModuleInfo)?.let { - return c.onResult(it) - } - - if (this is KtLightElement<*, *>) { - return this.processLightElement(c) - } - - collectModuleInfoByUserData(this).firstOrNull()?.let { - return c.onResult(it) - } - - val containingFile = - containingFile ?: return c.onFailure("Analyzing element of type ${this::class.java} with no containing file\nText:\n$text") - - val containingKtFile = (this as? KtElement)?.containingFile as? KtFile - containingKtFile?.analysisContext?.let { - return it.collectInfos(c) - } - - containingKtFile?.doNotAnalyze?.let { - return c.onFailure("Should not analyze element: $text in file ${containingKtFile.name}\n$it") - } - - val explicitModuleInfo = containingKtFile?.forcedModuleInfo ?: (containingKtFile?.originalFile as? KtFile)?.forcedModuleInfo - if (explicitModuleInfo is IdeaModuleInfo) { - return c.onResult(explicitModuleInfo) - } - - if (containingKtFile is KtCodeFragment) { - val context = containingKtFile.getContext() - ?: return c.onFailure("Analyzing code fragment of type ${containingKtFile::class.java} with no context element\nText:\n${containingKtFile.getText()}") - return context.collectInfos(c) - } - - val virtualFile = containingFile.originalFile.virtualFile - ?: return c.onFailure("Analyzing element of type ${this::class.java} in non-physical file $containingFile of type ${containingFile::class.java}\nText:\n$text") - - val isScript = runReadAction { containingKtFile?.isScript() == true } - if (isScript) { - getModuleRelatedModuleInfo(project, virtualFile)?.let { - return c.onResult(it) - } - val script = runReadAction { containingKtFile?.script } - script?.let { - containingKtFile?.findScriptDefinition()?.let { - return c.onResult(ScriptModuleInfo(project, virtualFile, it)) - } - } - } - - return c.virtualFileProcessor( - project, - virtualFile, - (containingFile as? KtFile)?.isCompiled ?: false - ) -} - -private fun KtLightElement<*, *>.processLightElement(c: ModuleInfoCollector): T { - val decompiledClass = this.getParentOfType(strict = false) - if (decompiledClass != null) { - return c.virtualFileProcessor( - project, - containingFile.virtualFile.sure { "Decompiled class should be build from physical file" }, - false - ) - } - - val element = kotlinOrigin ?: when (this) { - is FakeLightClassForFileOfPackage -> this.getContainingFile()!! - is KtLightClassForFacade -> this.files.first() - else -> return c.onFailure("Light element without origin is referenced by resolve:\n$this\n${this.clsDelegate.text}") - } - - return element.collectInfos(c) -} - -private inline fun collectInfosByVirtualFile( - project: Project, - virtualFile: VirtualFile, - treatAsLibrarySource: Boolean, - onOccurrence: (IdeaModuleInfo?) -> T -): T { - collectModuleInfoByUserData(project, virtualFile).map(onOccurrence) - - val moduleRelatedModuleInfo = getModuleRelatedModuleInfo(project, virtualFile) - if (moduleRelatedModuleInfo != null) { - onOccurrence(moduleRelatedModuleInfo) - } - - val projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project) - projectFileIndex.getOrderEntriesForFile(virtualFile).forEach { - it.toIdeaModuleInfo(project, virtualFile, treatAsLibrarySource).map(onOccurrence) - } - - val isBinary = virtualFile.fileType.isKotlinBinary() - val scriptConfigurationManager = ScriptConfigurationManager.getInstance(project) - if (isBinary && virtualFile in scriptConfigurationManager.getAllScriptsDependenciesClassFilesScope()) { - if (treatAsLibrarySource) { - onOccurrence(ScriptDependenciesSourceInfo.ForProject(project)) - } else { - onOccurrence(ScriptDependenciesInfo.ForProject(project)) - } - } - if (!isBinary && virtualFile in scriptConfigurationManager.getAllScriptDependenciesSourcesScope()) { - onOccurrence(ScriptDependenciesSourceInfo.ForProject(project)) - } - - return onOccurrence(null) -} - -private fun getModuleRelatedModuleInfo(project: Project, virtualFile: VirtualFile): ModuleSourceInfo? { - val projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project) - - val module = projectFileIndex.getModuleForFile(virtualFile) - if (module != null && !module.isDisposed) { - val moduleFileIndex = ModuleRootManager.getInstance(module).fileIndex - if (moduleFileIndex.isInTestSourceContentKotlinAware(virtualFile)) { - return module.testSourceInfo() - } else if (moduleFileIndex.isInSourceContentWithoutInjected(virtualFile)) { - return module.productionSourceInfo() - } - } - - val fileOrigin = OutsidersPsiFileSupportUtils.getOutsiderFileOrigin(project, virtualFile) - if (fileOrigin != null) { - return getModuleRelatedModuleInfo(project, fileOrigin) - } - - return null -} - -private inline fun collectModuleInfosByType(project: Project, virtualFile: VirtualFile): Collection { - val result = linkedSetOf() - collectInfosByVirtualFile(project, virtualFile, treatAsLibrarySource = false) { - result.addIfNotNull(it as? T) - } - - return result -} - -private fun OrderEntry.toIdeaModuleInfo( - project: Project, - virtualFile: VirtualFile, - treatAsLibrarySource: Boolean = false -): List { - if (this is ModuleOrderEntry) return emptyList() - if (!isValid) return emptyList() - - when (this) { - is LibraryOrderEntry -> { - val library = library ?: return emptyList() - if (ProjectRootsUtil.isLibraryClassFile(project, virtualFile) && !treatAsLibrarySource) { - return createLibraryInfo(project, library) - } else if (ProjectRootsUtil.isLibraryFile(project, virtualFile) || treatAsLibrarySource) { - return createLibraryInfo(project, library).map { it.sourcesModuleInfo } - } - } - is JdkOrderEntry -> { - return listOf(SdkInfo(project, jdk ?: return emptyList())) - } - else -> return emptyList() - } - return emptyList() -} - -/** - * @see [org.jetbrains.kotlin.types.typeUtil.closure]. - */ -fun Collection.lazyClosure(f: (T) -> Collection): Sequence = sequence { - if (size == 0) return@sequence - var sizeBeforeIteration = 0 - - yieldAll(this@lazyClosure) - var yieldedCount = size - var elementsToCheck = this@lazyClosure - - while (yieldedCount > sizeBeforeIteration) { - val toAdd = hashSetOf() - elementsToCheck.forEach { - val neighbours = f(it) - yieldAll(neighbours) - yieldedCount += neighbours.size - toAdd.addAll(neighbours) - } - elementsToCheck = toAdd - sizeBeforeIteration = yieldedCount - } -} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.as40 b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.as40 deleted file mode 100644 index 6180f5e1fd5..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt.as40 +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.idea.caches.project - -import com.intellij.ide.scratch.ScratchFileService -import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.* -import com.intellij.openapi.util.Key -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -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.ScriptConfigurationManager -import org.jetbrains.kotlin.idea.core.script.scriptRelatedModuleName -import org.jetbrains.kotlin.idea.highlighter.OutsidersPsiFileSupportUtils -import org.jetbrains.kotlin.idea.util.ProjectRootsUtil -import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected -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.scripting.definitions.runReadAction -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 - -var PsiFile.forcedModuleInfo: ModuleInfo? by UserDataProperty(Key.create("FORCED_MODULE_INFO")) - -fun PsiElement.getModuleInfo(): IdeaModuleInfo = this.collectInfos(ModuleInfoCollector.NotNullTakeFirst) - -fun PsiElement.getNullableModuleInfo(): IdeaModuleInfo? = this.collectInfos(ModuleInfoCollector.NullableTakeFirst) - -fun PsiElement.getModuleInfos(): Sequence = this.collectInfos(ModuleInfoCollector.ToSequence) - -private fun ModuleInfo.doFindSdk(): SdkInfo? = dependencies().lazyClosure { it.dependencies() }.firstIsInstanceOrNull() - -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, - treatAsLibrarySource = false, - onOccurrence = { return@getModuleInfoByVirtualFile it } - ) - -fun getBinaryLibrariesModuleInfos(project: Project, virtualFile: VirtualFile) = - collectModuleInfosByType( - project, - virtualFile - ) - -fun getLibrarySourcesModuleInfos(project: Project, virtualFile: VirtualFile) = - collectModuleInfosByType( - project, - virtualFile - ) - -fun getScriptRelatedModuleInfo(project: Project, virtualFile: VirtualFile): ModuleSourceInfo? { - val moduleRelatedModuleInfo = getModuleRelatedModuleInfo(project, virtualFile) - if (moduleRelatedModuleInfo != null) { - return moduleRelatedModuleInfo - } - - if (ScratchFileService.isInScratchRoot(virtualFile)) { - val scratchModule = virtualFile.scriptRelatedModuleName?.let { ModuleManager.getInstance(project).findModuleByName(it) } - return scratchModule?.testSourceInfo() ?: scratchModule?.productionSourceInfo() - } - - return null -} - -private typealias VirtualFileProcessor = (Project, VirtualFile, Boolean) -> T - -private sealed class ModuleInfoCollector( - val onResult: (IdeaModuleInfo?) -> T, - val onFailure: (String) -> T, - val virtualFileProcessor: VirtualFileProcessor -) { - object NotNullTakeFirst : ModuleInfoCollector( - onResult = { it ?: NotUnderContentRootModuleInfo }, - onFailure = { reason -> - LOG.error("Could not find correct module information.\nReason: $reason") - NotUnderContentRootModuleInfo - }, - virtualFileProcessor = processor@{ project, virtualFile, isLibrarySource -> - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { - return@processor it ?: NotUnderContentRootModuleInfo - } - } - ) - - object NullableTakeFirst : ModuleInfoCollector( - onResult = { it }, - onFailure = { reason -> - LOG.warn("Could not find correct module information.\nReason: $reason") - null - }, - virtualFileProcessor = processor@{ project, virtualFile, isLibrarySource -> - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { return@processor it } - } - ) - - object ToSequence : ModuleInfoCollector>( - onResult = { result -> result?.let { sequenceOf(it) } ?: emptySequence() }, - onFailure = { reason -> - LOG.warn("Could not find correct module information.\nReason: $reason") - emptySequence() - }, - virtualFileProcessor = { project, virtualFile, isLibrarySource -> - sequence { - collectInfosByVirtualFile( - project, - virtualFile, - isLibrarySource - ) { yieldIfNotNull(it) } - } - } - ) -} - -private fun PsiElement.collectInfos(c: ModuleInfoCollector): T { - (containingFile?.forcedModuleInfo as? IdeaModuleInfo)?.let { - return c.onResult(it) - } - - if (this is KtLightElement<*, *>) { - return this.processLightElement(c) - } - - collectModuleInfoByUserData(this).firstOrNull()?.let { - return c.onResult(it) - } - - val containingFile = - containingFile ?: return c.onFailure("Analyzing element of type ${this::class.java} with no containing file\nText:\n$text") - - val containingKtFile = (this as? KtElement)?.containingFile as? KtFile - containingKtFile?.analysisContext?.let { - return it.collectInfos(c) - } - - containingKtFile?.doNotAnalyze?.let { - return c.onFailure("Should not analyze element: $text in file ${containingKtFile.name}\n$it") - } - - val explicitModuleInfo = containingKtFile?.forcedModuleInfo ?: (containingKtFile?.originalFile as? KtFile)?.forcedModuleInfo - if (explicitModuleInfo is IdeaModuleInfo) { - return c.onResult(explicitModuleInfo) - } - - if (containingKtFile is KtCodeFragment) { - val context = containingKtFile.getContext() - ?: return c.onFailure("Analyzing code fragment of type ${containingKtFile::class.java} with no context element\nText:\n${containingKtFile.getText()}") - return context.collectInfos(c) - } - - val virtualFile = containingFile.originalFile.virtualFile - ?: return c.onFailure("Analyzing element of type ${this::class.java} in non-physical file $containingFile of type ${containingFile::class.java}\nText:\n$text") - - val isScript = runReadAction { containingKtFile?.isScript() == true } - if (isScript) { - getModuleRelatedModuleInfo(project, virtualFile)?.let { - return c.onResult(it) - } - val script = runReadAction { containingKtFile?.script } - script?.let { - containingKtFile?.findScriptDefinition()?.let { - return c.onResult(ScriptModuleInfo(project, virtualFile, it)) - } - } - } - - return c.virtualFileProcessor( - project, - virtualFile, - (containingFile as? KtFile)?.isCompiled ?: false - ) -} - -private fun KtLightElement<*, *>.processLightElement(c: ModuleInfoCollector): T { - val decompiledClass = this.getParentOfType(strict = false) - if (decompiledClass != null) { - return c.virtualFileProcessor( - project, - containingFile.virtualFile.sure { "Decompiled class should be build from physical file" }, - false - ) - } - - val element = kotlinOrigin ?: when (this) { - is FakeLightClassForFileOfPackage -> this.getContainingFile()!! - is KtLightClassForFacade -> this.files.first() - else -> return c.onFailure("Light element without origin is referenced by resolve:\n$this\n${this.clsDelegate.text}") - } - - return element.collectInfos(c) -} - -private inline fun collectInfosByVirtualFile( - project: Project, - virtualFile: VirtualFile, - treatAsLibrarySource: Boolean, - onOccurrence: (IdeaModuleInfo?) -> T -): T { - collectModuleInfoByUserData(project, virtualFile).map(onOccurrence) - - val moduleRelatedModuleInfo = getModuleRelatedModuleInfo(project, virtualFile) - if (moduleRelatedModuleInfo != null) { - onOccurrence(moduleRelatedModuleInfo) - } - - val projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project) - projectFileIndex.getOrderEntriesForFile(virtualFile).forEach { - it.toIdeaModuleInfo(project, virtualFile, treatAsLibrarySource).map(onOccurrence) - } - - val isBinary = virtualFile.fileType.isKotlinBinary() - val scriptConfigurationManager = ScriptConfigurationManager.getInstance(project) - if (isBinary && virtualFile in scriptConfigurationManager.getAllScriptsDependenciesClassFilesScope()) { - if (treatAsLibrarySource) { - onOccurrence(ScriptDependenciesSourceInfo.ForProject(project)) - } else { - onOccurrence(ScriptDependenciesInfo.ForProject(project)) - } - } - if (!isBinary && virtualFile in scriptConfigurationManager.getAllScriptDependenciesSourcesScope()) { - onOccurrence(ScriptDependenciesSourceInfo.ForProject(project)) - } - - return onOccurrence(null) -} - -private fun getModuleRelatedModuleInfo(project: Project, virtualFile: VirtualFile): ModuleSourceInfo? { - val projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project) - - val module = projectFileIndex.getModuleForFile(virtualFile) - if (module != null && !module.isDisposed) { - val moduleFileIndex = ModuleRootManager.getInstance(module).fileIndex - if (moduleFileIndex.isInTestSourceContentKotlinAware(virtualFile)) { - return module.testSourceInfo() - } else if (moduleFileIndex.isInSourceContentWithoutInjected(virtualFile)) { - return module.productionSourceInfo() - } - } - - val fileOrigin = OutsidersPsiFileSupportUtils.getOutsiderFileOrigin(project, virtualFile) - if (fileOrigin != null) { - return getModuleRelatedModuleInfo(project, fileOrigin) - } - - return null -} - -private inline fun collectModuleInfosByType(project: Project, virtualFile: VirtualFile): Collection { - val result = linkedSetOf() - collectInfosByVirtualFile(project, virtualFile, treatAsLibrarySource = false) { - result.addIfNotNull(it as? T) - } - - return result -} - -private fun OrderEntry.toIdeaModuleInfo( - project: Project, - virtualFile: VirtualFile, - treatAsLibrarySource: Boolean = false -): List { - if (this is ModuleOrderEntry) return emptyList() - if (!isValid) return emptyList() - - when (this) { - is LibraryOrderEntry -> { - val library = library ?: return emptyList() - if (ProjectRootsUtil.isLibraryClassFile(project, virtualFile) && !treatAsLibrarySource) { - return createLibraryInfo(project, library) - } else if (ProjectRootsUtil.isLibraryFile(project, virtualFile) || treatAsLibrarySource) { - return createLibraryInfo(project, library).map { it.sourcesModuleInfo } - } - } - is JdkOrderEntry -> { - return listOf(SdkInfo(project, jdk ?: return emptyList())) - } - else -> return emptyList() - } - return emptyList() -} - -/** - * @see [org.jetbrains.kotlin.types.typeUtil.closure]. - */ -fun Collection.lazyClosure(f: (T) -> Collection): Sequence = sequence { - if (size == 0) return@sequence - var sizeBeforeIteration = 0 - - yieldAll(this@lazyClosure) - var yieldedCount = size - var elementsToCheck = this@lazyClosure - - while (yieldedCount > sizeBeforeIteration) { - val toAdd = hashSetOf() - elementsToCheck.forEach { - val neighbours = f(it) - yieldAll(neighbours) - yieldedCount += neighbours.size - toAdd.addAll(neighbours) - } - elementsToCheck = toAdd - sizeBeforeIteration = yieldedCount - } -} diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt index e4dd35195e9..7e68708f954 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt @@ -5,8 +5,6 @@ package org.jetbrains.kotlin.idea.scratch -import com.intellij.ide.scratch.ScratchFileService -import com.intellij.ide.scratch.ScratchRootType import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project @@ -20,7 +18,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull class ScratchAdditionalIdeaDependenciesProvider : ScriptAdditionalIdeaDependenciesProvider() { override fun getRelatedModules(file: VirtualFile, project: Project): List { - if (!isInScratchRoot(file)) return emptyList() + if (!file.isKotlinScratch) return emptyList() val scratchModule = file.scriptRelatedModuleName?.let { ModuleManager.getInstance(project).findModuleByName(it) @@ -38,7 +36,7 @@ class ScratchAdditionalIdeaDependenciesProvider : ScriptAdditionalIdeaDependenci } override fun getRelatedLibraries(file: VirtualFile, project: Project): List { - if (!isInScratchRoot(file)) return emptyList() + if (!file.isKotlinScratch) return emptyList() val result = linkedSetOf() getRelatedModules(file, project).forEach { @@ -52,8 +50,6 @@ class ScratchAdditionalIdeaDependenciesProvider : ScriptAdditionalIdeaDependenci return result.toList() } - private inline fun isInScratchRoot(file: VirtualFile) = ScratchFileService.findRootType(file) == ScratchRootType.getInstance() - private fun moduleDependencyEnumerator(it: Module): OrderEnumerator { return ModuleRootManager.getInstance(it).orderEntries() .compileOnly().withoutSdk().recursively().exportedOnly() diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.191 b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.191 deleted file mode 100644 index 40e4aea0d63..00000000000 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.191 +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.idea.scratch - -import com.intellij.ide.scratch.ScratchFileService -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.* -import com.intellij.openapi.roots.libraries.Library -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptAdditionalIdeaDependenciesProvider -import org.jetbrains.kotlin.idea.core.script.scriptRelatedModuleName -import org.jetbrains.kotlin.utils.addIfNotNull - -class ScratchAdditionalIdeaDependenciesProvider : ScriptAdditionalIdeaDependenciesProvider() { - - override fun getRelatedModules(file: VirtualFile, project: Project): List { - if (!ScratchFileService.isInScratchRoot(file)) return emptyList() - - val scratchModule = file.scriptRelatedModuleName?.let { - ModuleManager.getInstance(project).findModuleByName(it) - } ?: return emptyList() - - val modules = linkedSetOf(scratchModule) - moduleDependencyEnumerator(scratchModule).withoutLibraries().forEach { orderEntry -> - when (orderEntry) { - is ModuleSourceOrderEntry -> modules.add(orderEntry.getOwnerModule()) - is ModuleOrderEntry -> modules.addIfNotNull(orderEntry.module) - } - true - } - return modules.toList() - } - - override fun getRelatedLibraries(file: VirtualFile, project: Project): List { - if (!ScratchFileService.isInScratchRoot(file)) return emptyList() - - val result = linkedSetOf() - getRelatedModules(file, project).forEach { - moduleDependencyEnumerator(it).withoutDepModules().forEach { orderEntry -> - if (orderEntry is LibraryOrderEntry) { - result.addIfNotNull(orderEntry.library) - } - true - } - } - return result.toList() - } - - private fun moduleDependencyEnumerator(it: Module): OrderEnumerator { - return ModuleRootManager.getInstance(it).orderEntries() - .compileOnly().withoutSdk().recursively().exportedOnly() - } -} \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.192 b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.192 deleted file mode 100644 index 40e4aea0d63..00000000000 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.192 +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.idea.scratch - -import com.intellij.ide.scratch.ScratchFileService -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.* -import com.intellij.openapi.roots.libraries.Library -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptAdditionalIdeaDependenciesProvider -import org.jetbrains.kotlin.idea.core.script.scriptRelatedModuleName -import org.jetbrains.kotlin.utils.addIfNotNull - -class ScratchAdditionalIdeaDependenciesProvider : ScriptAdditionalIdeaDependenciesProvider() { - - override fun getRelatedModules(file: VirtualFile, project: Project): List { - if (!ScratchFileService.isInScratchRoot(file)) return emptyList() - - val scratchModule = file.scriptRelatedModuleName?.let { - ModuleManager.getInstance(project).findModuleByName(it) - } ?: return emptyList() - - val modules = linkedSetOf(scratchModule) - moduleDependencyEnumerator(scratchModule).withoutLibraries().forEach { orderEntry -> - when (orderEntry) { - is ModuleSourceOrderEntry -> modules.add(orderEntry.getOwnerModule()) - is ModuleOrderEntry -> modules.addIfNotNull(orderEntry.module) - } - true - } - return modules.toList() - } - - override fun getRelatedLibraries(file: VirtualFile, project: Project): List { - if (!ScratchFileService.isInScratchRoot(file)) return emptyList() - - val result = linkedSetOf() - getRelatedModules(file, project).forEach { - moduleDependencyEnumerator(it).withoutDepModules().forEach { orderEntry -> - if (orderEntry is LibraryOrderEntry) { - result.addIfNotNull(orderEntry.library) - } - true - } - } - return result.toList() - } - - private fun moduleDependencyEnumerator(it: Module): OrderEnumerator { - return ModuleRootManager.getInstance(it).orderEntries() - .compileOnly().withoutSdk().recursively().exportedOnly() - } -} \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.as40 b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.as40 deleted file mode 100644 index 40e4aea0d63..00000000000 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ScratchAdditionalIdeaDependenciesProvider.kt.as40 +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.idea.scratch - -import com.intellij.ide.scratch.ScratchFileService -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.* -import com.intellij.openapi.roots.libraries.Library -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptAdditionalIdeaDependenciesProvider -import org.jetbrains.kotlin.idea.core.script.scriptRelatedModuleName -import org.jetbrains.kotlin.utils.addIfNotNull - -class ScratchAdditionalIdeaDependenciesProvider : ScriptAdditionalIdeaDependenciesProvider() { - - override fun getRelatedModules(file: VirtualFile, project: Project): List { - if (!ScratchFileService.isInScratchRoot(file)) return emptyList() - - val scratchModule = file.scriptRelatedModuleName?.let { - ModuleManager.getInstance(project).findModuleByName(it) - } ?: return emptyList() - - val modules = linkedSetOf(scratchModule) - moduleDependencyEnumerator(scratchModule).withoutLibraries().forEach { orderEntry -> - when (orderEntry) { - is ModuleSourceOrderEntry -> modules.add(orderEntry.getOwnerModule()) - is ModuleOrderEntry -> modules.addIfNotNull(orderEntry.module) - } - true - } - return modules.toList() - } - - override fun getRelatedLibraries(file: VirtualFile, project: Project): List { - if (!ScratchFileService.isInScratchRoot(file)) return emptyList() - - val result = linkedSetOf() - getRelatedModules(file, project).forEach { - moduleDependencyEnumerator(it).withoutDepModules().forEach { orderEntry -> - if (orderEntry is LibraryOrderEntry) { - result.addIfNotNull(orderEntry.library) - } - true - } - } - return result.toList() - } - - private fun moduleDependencyEnumerator(it: Module): OrderEnumerator { - return ModuleRootManager.getInstance(it).orderEntries() - .compileOnly().withoutSdk().recursively().exportedOnly() - } -} \ No newline at end of file