Refactoring: use KtScript.scriptDefinition instead of KotlinScriptDefinitionProvider.findScriptDefinition if possible

This commit is contained in:
Natalia Selezneva
2018-07-20 16:22:49 +03:00
parent 736361e345
commit f71269009a
9 changed files with 51 additions and 49 deletions
@@ -28,8 +28,7 @@ import kotlin.concurrent.write
import kotlin.script.experimental.dependencies.ScriptDependencies import kotlin.script.experimental.dependencies.ScriptDependencies
class CliScriptDependenciesProvider( class CliScriptDependenciesProvider(
private val project: Project, private val project: Project
private val scriptDefinitionProvider: ScriptDefinitionProvider
) : ScriptDependenciesProvider { ) : ScriptDependenciesProvider {
private val cacheLock = ReentrantReadWriteLock() private val cacheLock = ReentrantReadWriteLock()
@@ -45,7 +44,7 @@ class CliScriptDependenciesProvider(
val cached = cache[path] val cached = cache[path]
return if (cached != null) cached return if (cached != null) cached
else { else {
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) val scriptDef = findScriptDefinition(file, project)
if (scriptDef != null) { if (scriptDef != null) {
val result = scriptContentLoader.loadContentsAndResolveDependencies(scriptDef, file) val result = scriptContentLoader.loadContentsAndResolveDependencies(scriptDef, file)
@@ -603,7 +603,7 @@ class KotlinCoreEnvironment private constructor(
registerService(ScriptDefinitionProvider::class.java, scriptDefinitionProvider) registerService(ScriptDefinitionProvider::class.java, scriptDefinitionProvider)
registerService( registerService(
ScriptDependenciesProvider::class.java, ScriptDependenciesProvider::class.java,
CliScriptDependenciesProvider(projectEnvironment.project, scriptDefinitionProvider) CliScriptDependenciesProvider(projectEnvironment.project)
) )
registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this)) registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this))
registerService(KtLightClassForFacade.FacadeStubCache::class.java, KtLightClassForFacade.FacadeStubCache(this)) registerService(KtLightClassForFacade.FacadeStubCache::class.java, KtLightClassForFacade.FacadeStubCache(this))
@@ -38,7 +38,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
import org.jetbrains.kotlin.resolve.source.toSourceElement import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.script.KotlinScriptDefinition import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.ScriptPriorities import org.jetbrains.kotlin.script.ScriptPriorities
import org.jetbrains.kotlin.script.getScriptDefinition import org.jetbrains.kotlin.script.findScriptDefinition
import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.TypeSubstitutor
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.KType import kotlin.reflect.KType
@@ -69,7 +69,7 @@ class LazyScriptDescriptor(
val scriptDefinition: () -> KotlinScriptDefinition = resolveSession.storageManager.createLazyValue { val scriptDefinition: () -> KotlinScriptDefinition = resolveSession.storageManager.createLazyValue {
val file = scriptInfo.script.containingKtFile val file = scriptInfo.script.containingKtFile
getScriptDefinition(file) ?: throw RuntimeException("file ${file.name} is not a script") findScriptDefinition(file) ?: throw RuntimeException("file ${file.name} is not a script")
} }
override fun substitute(substitutor: TypeSubstitutor) = this override fun substitute(substitutor: TypeSubstitutor) = this
@@ -16,12 +16,15 @@
package org.jetbrains.kotlin.script package org.jetbrains.kotlin.script
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.ide.highlighter.JavaFileType import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.psi.KtFile
import java.util.concurrent.locks.ReentrantReadWriteLock import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.read import kotlin.concurrent.read
import kotlin.concurrent.write import kotlin.concurrent.write
@@ -37,18 +40,25 @@ interface ScriptDefinitionProvider {
} }
} }
fun ScriptDefinitionProvider.findScriptDefinition(file: VirtualFile): KotlinScriptDefinition? = fun findScriptDefinition(file: VirtualFile, project: Project): KotlinScriptDefinition? {
if (file.isDirectory) null if (file.isDirectory) return null
else findScriptDefinition(file.name) if (file.extension == KotlinFileType.EXTENSION || file.extension == JavaClassFileType.INSTANCE.defaultExtension) return null
val psiFile = PsiManager.getInstance(project).findFile(file)
if (psiFile != null) {
if (psiFile !is KtFile || !psiFile.isScript()) {
return null
}
return psiFile.script?.kotlinScriptDefinition?.value
}
fun getScriptDefinition(file: VirtualFile, project: Project): KotlinScriptDefinition? = return ScriptDefinitionProvider.getInstance(project).findScriptDefinition(file.name)
if (file.isDirectory) null }
else ScriptDefinitionProvider.getInstance(project).findScriptDefinition(file)
fun getScriptDefinition(psiFile: PsiFile): KotlinScriptDefinition? = fun findScriptDefinition(psiFile: PsiFile): KotlinScriptDefinition? {
if (psiFile.isDirectory) null if (psiFile.isDirectory) return null
else ScriptDefinitionProvider.getInstance(psiFile.project).findScriptDefinition(psiFile.name) return (psiFile as? KtFile)?.script?.kotlinScriptDefinition?.value
}
abstract class LazyScriptDefinitionProvider : ScriptDefinitionProvider { abstract class LazyScriptDefinitionProvider : ScriptDefinitionProvider {
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected
import org.jetbrains.kotlin.idea.util.isKotlinBinary 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.script.getScriptDefinition import org.jetbrains.kotlin.script.findScriptDefinition
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.sure import org.jetbrains.kotlin.utils.sure
import org.jetbrains.kotlin.utils.yieldIfNotNull import org.jetbrains.kotlin.utils.yieldIfNotNull
@@ -75,7 +75,7 @@ fun getScriptRelatedModuleInfo(project: Project, virtualFile: VirtualFile): Modu
return null return null
} }
private typealias VirtualFileProcessor<T> = (Project, VirtualFile, Boolean, Boolean) -> T private typealias VirtualFileProcessor<T> = (Project, VirtualFile, Boolean) -> T
private sealed class ModuleInfoCollector<out T>( private sealed class ModuleInfoCollector<out T>(
val onResult: (IdeaModuleInfo?) -> T, val onResult: (IdeaModuleInfo?) -> T,
@@ -88,12 +88,11 @@ private sealed class ModuleInfoCollector<out T>(
LOG.error("Could not find correct module information.\nReason: $reason") LOG.error("Could not find correct module information.\nReason: $reason")
NotUnderContentRootModuleInfo NotUnderContentRootModuleInfo
}, },
virtualFileProcessor = processor@ { project, virtualFile, isLibrarySource, isScript -> virtualFileProcessor = processor@ { project, virtualFile, isLibrarySource ->
collectInfosByVirtualFile( collectInfosByVirtualFile(
project, project,
virtualFile, virtualFile,
isLibrarySource, isLibrarySource,
isScript,
{ {
return@processor it ?: NotUnderContentRootModuleInfo return@processor it ?: NotUnderContentRootModuleInfo
}) })
@@ -106,12 +105,11 @@ private sealed class ModuleInfoCollector<out T>(
LOG.warn("Could not find correct module information.\nReason: $reason") LOG.warn("Could not find correct module information.\nReason: $reason")
null null
}, },
virtualFileProcessor = processor@ { project, virtualFile, isLibrarySource, isScript -> virtualFileProcessor = processor@ { project, virtualFile, isLibrarySource ->
collectInfosByVirtualFile( collectInfosByVirtualFile(
project, project,
virtualFile, virtualFile,
isLibrarySource, isLibrarySource,
isScript,
{ return@processor it }) { return@processor it })
} }
) )
@@ -122,13 +120,12 @@ private sealed class ModuleInfoCollector<out T>(
LOG.warn("Could not find correct module information.\nReason: $reason") LOG.warn("Could not find correct module information.\nReason: $reason")
emptySequence() emptySequence()
}, },
virtualFileProcessor = { project, virtualFile, isLibrarySource, isScript -> virtualFileProcessor = { project, virtualFile, isLibrarySource ->
buildSequence { buildSequence {
collectInfosByVirtualFile( collectInfosByVirtualFile(
project, project,
virtualFile, virtualFile,
isLibrarySource, isLibrarySource,
isScript,
{ yieldIfNotNull(it) }) { yieldIfNotNull(it) })
} }
} }
@@ -170,11 +167,19 @@ private fun <T> PsiElement.collectInfos(c: ModuleInfoCollector<T>): T {
val virtualFile = containingFile.originalFile.virtualFile 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") ?: return c.onFailure("Analyzing element of type ${this::class.java} in non-physical file $containingFile of type ${containingFile::class.java}\nText:\n$text")
if (containingKtFile?.isScript() == true) {
getModuleRelatedModuleInfo(ProjectFileIndex.SERVICE.getInstance(project), virtualFile)?.let {
return c.onResult(it)
}
findScriptDefinition(virtualFile, project)?.let {
return c.onResult(ScriptModuleInfo(project, virtualFile, it))
}
}
return c.virtualFileProcessor( return c.virtualFileProcessor(
project, project,
virtualFile, virtualFile,
(containingFile as? KtFile)?.isCompiled ?: false, (containingFile as? KtFile)?.isCompiled ?: false
containingKtFile?.isScript() ?: false
) )
} }
@@ -184,8 +189,7 @@ private fun <T> KtLightElement<*, *>.processLightElement(c: ModuleInfoCollector<
return c.virtualFileProcessor( return c.virtualFileProcessor(
project, project,
containingFile.virtualFile.sure { "Decompiled class should be build from physical file" }, containingFile.virtualFile.sure { "Decompiled class should be build from physical file" },
false, false
(containingFile as? KtFile)?.isScript() ?: false
) )
} }
@@ -202,7 +206,6 @@ private inline fun <T> collectInfosByVirtualFile(
project: Project, project: Project,
virtualFile: VirtualFile, virtualFile: VirtualFile,
treatAsLibrarySource: Boolean, treatAsLibrarySource: Boolean,
isScript: Boolean = getScriptDefinition(virtualFile, project) != null,
onOccurrence: (IdeaModuleInfo?) -> T onOccurrence: (IdeaModuleInfo?) -> T
): T { ): T {
@@ -213,12 +216,6 @@ private inline fun <T> collectInfosByVirtualFile(
onOccurrence(moduleRelatedModuleInfo) onOccurrence(moduleRelatedModuleInfo)
} }
if (moduleRelatedModuleInfo == null && isScript) {
getScriptDefinition(virtualFile, project)?.let {
onOccurrence(ScriptModuleInfo(project, virtualFile, it))
}
}
projectFileIndex.getOrderEntriesForFile(virtualFile).forEach { projectFileIndex.getOrderEntriesForFile(virtualFile).forEach {
it.toIdeaModuleInfo(project, virtualFile, treatAsLibrarySource)?.let(onOccurrence) it.toIdeaModuleInfo(project, virtualFile, treatAsLibrarySource)?.let(onOccurrence)
} }
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.idea.core.script.scriptDependencies
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.psi.KtCodeFragment import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.script.getScriptDefinition import org.jetbrains.kotlin.script.findScriptDefinition
import kotlin.script.experimental.dependencies.ScriptReport import kotlin.script.experimental.dependencies.ScriptReport
object KotlinHighlightingUtil { object KotlinHighlightingUtil {
@@ -67,7 +67,7 @@ object KotlinHighlightingUtil {
return false return false
} }
val scriptDefinition = getScriptDefinition(ktFile) ?: return false val scriptDefinition = findScriptDefinition(ktFile) ?: return false
return ScriptDefinitionsManager.getInstance(ktFile.project).isInExpectedLocation(ktFile, scriptDefinition) return ScriptDefinitionsManager.getInstance(ktFile.project).isInExpectedLocation(ktFile, scriptDefinition)
} }
} }
@@ -24,7 +24,6 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.io.URLUtil import com.intellij.util.io.URLUtil
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.core.script.dependencies.SyncScriptDependenciesLoader import org.jetbrains.kotlin.idea.core.script.dependencies.SyncScriptDependenciesLoader
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
import org.jetbrains.kotlin.script.ScriptDependenciesProvider import org.jetbrains.kotlin.script.ScriptDependenciesProvider
import org.jetbrains.kotlin.script.findScriptDefinition import org.jetbrains.kotlin.script.findScriptDefinition
import java.io.File import java.io.File
@@ -77,10 +76,8 @@ class ScriptDependenciesManager internal constructor(
@TestOnly @TestOnly
fun updateScriptDependenciesSynchronously(virtualFile: VirtualFile, project: Project) { fun updateScriptDependenciesSynchronously(virtualFile: VirtualFile, project: Project) {
with(getInstance(project)) { val scriptDefinition = findScriptDefinition(virtualFile, project)!!
val scriptDefinition = ScriptDefinitionProvider.getInstance(project).findScriptDefinition(virtualFile)!! SyncScriptDependenciesLoader(virtualFile, scriptDefinition, project, shouldNotifyRootsChanged = true).updateDependencies()
SyncScriptDependenciesLoader(virtualFile, scriptDefinition, project, shouldNotifyRootsChanged = true).updateDependencies()
}
} }
} }
} }
@@ -36,14 +36,12 @@ import org.jetbrains.kotlin.idea.core.script.dependencies.FromFileAttributeScrip
import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptDependenciesLoader import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptDependenciesLoader
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.NotNullableUserDataProperty import org.jetbrains.kotlin.psi.NotNullableUserDataProperty
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
import org.jetbrains.kotlin.script.findScriptDefinition import org.jetbrains.kotlin.script.findScriptDefinition
import kotlin.script.experimental.dependencies.ScriptDependencies import kotlin.script.experimental.dependencies.ScriptDependencies
class ScriptDependenciesUpdater( class ScriptDependenciesUpdater(
private val project: Project, private val project: Project,
private val cache: ScriptDependenciesCache, private val cache: ScriptDependenciesCache
private val scriptDefinitionProvider: ScriptDefinitionProvider
) { ) {
private val scriptsQueue = Alarm(Alarm.ThreadToUse.SWING_THREAD, project) private val scriptsQueue = Alarm(Alarm.ThreadToUse.SWING_THREAD, project)
private val scriptChangesListenerDelay = 1400 private val scriptChangesListenerDelay = 1400
@@ -55,7 +53,7 @@ class ScriptDependenciesUpdater(
fun getCurrentDependencies(file: VirtualFile): ScriptDependencies { fun getCurrentDependencies(file: VirtualFile): ScriptDependencies {
cache[file]?.let { return it } cache[file]?.let { return it }
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) ?: return ScriptDependencies.Empty val scriptDef = findScriptDefinition(file, project) ?: return ScriptDependencies.Empty
FromFileAttributeScriptDependenciesLoader(file, scriptDef, project).updateDependencies() FromFileAttributeScriptDependenciesLoader(file, scriptDef, project).updateDependencies()
ScriptDependenciesLoader.updateDependencies(file, scriptDef, project, shouldNotifyRootsChanged = false) ScriptDependenciesLoader.updateDependencies(file, scriptDef, project, shouldNotifyRootsChanged = false)
@@ -75,9 +73,10 @@ class ScriptDependenciesUpdater(
private fun runScriptDependenciesUpdateIfNeeded(file: VirtualFile) { private fun runScriptDependenciesUpdateIfNeeded(file: VirtualFile) {
if (file.fileType != KotlinFileType.INSTANCE) return if (file.fileType != KotlinFileType.INSTANCE) return
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) ?: return
val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return
val scriptDef = findScriptDefinition(ktFile) ?: return
if (!ScriptDefinitionsManager.getInstance(project).isInExpectedLocation(ktFile, scriptDef)) return if (!ScriptDefinitionsManager.getInstance(project).isInExpectedLocation(ktFile, scriptDef)) return
ScriptDependenciesLoader.updateDependencies(file, scriptDef, project, shouldNotifyRootsChanged = true) ScriptDependenciesLoader.updateDependencies(file, scriptDef, project, shouldNotifyRootsChanged = true)
} }
@@ -101,8 +100,8 @@ class ScriptDependenciesUpdater(
return return
} }
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) ?: return
val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return
val scriptDef = findScriptDefinition(ktFile) ?: return
if (!ScriptDefinitionsManager.getInstance(project).isInExpectedLocation(ktFile, scriptDef)) return if (!ScriptDefinitionsManager.getInstance(project).isInExpectedLocation(ktFile, scriptDef)) return
@@ -23,7 +23,7 @@ import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
import org.jetbrains.kotlin.idea.core.script.StandardIdeScriptDefinition import org.jetbrains.kotlin.idea.core.script.StandardIdeScriptDefinition
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.script.getScriptDefinition import org.jetbrains.kotlin.script.findScriptDefinition
class KotlinScriptResolveScopeProvider : ResolveScopeProvider() { class KotlinScriptResolveScopeProvider : ResolveScopeProvider() {
companion object { companion object {
@@ -32,7 +32,7 @@ class KotlinScriptResolveScopeProvider : ResolveScopeProvider() {
} }
override fun getResolveScope(file: VirtualFile, project: Project): GlobalSearchScope? { override fun getResolveScope(file: VirtualFile, project: Project): GlobalSearchScope? {
val scriptDefinition = getScriptDefinition(file, project) val scriptDefinition = findScriptDefinition(file, project)
// TODO: this should get this particular scripts dependencies // TODO: this should get this particular scripts dependencies
return when { return when {
scriptDefinition == null -> null scriptDefinition == null -> null