201: Implement floating notification update

This commit is contained in:
Natalia Selezneva
2020-04-23 14:31:35 +03:00
parent 2fba813a53
commit 294df3a7e9
3 changed files with 46 additions and 52 deletions
@@ -13,7 +13,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
@@ -23,10 +22,8 @@ import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver
import org.jetbrains.kotlin.psi.UserDataProperty import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
import org.jetbrains.plugins.gradle.service.project.GradlePartialResolverPolicy import org.jetbrains.plugins.gradle.service.project.GradlePartialResolverPolicy
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.util.GradleConstants import org.jetbrains.plugins.gradle.util.GradleConstants
import java.util.function.Predicate import java.util.function.Predicate
@@ -45,18 +42,9 @@ fun runPartialGradleImport(project: Project) {
fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.load.changes") fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.load.changes")
fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.text.load.script.configurations") fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.text.load.script.configurations")
private var Project.shouldShowLoadConfiguraionsAction: Boolean? fun showNotificationForProjectImport(project: Project) {}
by UserDataProperty<Project, Boolean>(Key.create("load.script.configuration.action"))
fun hideNotificationForProjectImport(project: Project): Boolean = true
fun showNotificationForProjectImport(project: Project) {
project.shouldShowLoadConfiguraionsAction = true
}
fun hideNotificationForProjectImport(project: Project): Boolean {
project.shouldShowLoadConfiguraionsAction = false
return true
}
class LoadConfigurationAction : AnAction( class LoadConfigurationAction : AnAction(
KotlinIdeaGradleBundle.message("action.text.load.script.configurations"), KotlinIdeaGradleBundle.message("action.text.load.script.configurations"),
@@ -75,19 +63,17 @@ class LoadConfigurationAction : AnAction(
} }
private fun ensureValidActionVisibility(e: AnActionEvent) { private fun ensureValidActionVisibility(e: AnActionEvent) {
if (e.project?.shouldShowLoadConfiguraionsAction != true) {
e.presentation.isVisible = false
return
}
val editor = e.getData(CommonDataKeys.EDITOR) ?: return val editor = e.getData(CommonDataKeys.EDITOR) ?: return
if (DiffUtil.isDiffEditor(editor)) { if (DiffUtil.isDiffEditor(editor)) {
e.presentation.isVisible = false e.presentation.isVisible = false
return return
} }
e.presentation.isVisible = editor.isScriptEditor()
e.presentation.isVisible = editor.getNotificationVisibility()
} }
private fun Editor.isScriptEditor(): Boolean { private fun Editor.getNotificationVisibility(): Boolean {
val project = project ?: return false val project = project ?: return false
val documentManager = FileDocumentManager.getInstance() val documentManager = FileDocumentManager.getInstance()
@@ -95,8 +81,6 @@ class LoadConfigurationAction : AnAction(
if (virtualFile is LightVirtualFileBase) return false if (virtualFile is LightVirtualFileBase) return false
if (virtualFile == null || !virtualFile.isValid) return false if (virtualFile == null || !virtualFile.isValid) return false
return GradleScriptingSupportProvider.getInstance(project).shouldShowNotificationInEditor(virtualFile)
// todo only for gradle script
return virtualFile.findScriptDefinition(project) != null
} }
} }
@@ -9,13 +9,11 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupport import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupport
import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupportHelper
import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptConfigurationUpdater import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptConfigurationUpdater
import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsIndexer import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsIndexer
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModel import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModel
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
data class ConfigurationData( data class ConfigurationData(
val templateClasspath: List<String>, val templateClasspath: List<String>,
@@ -51,33 +49,11 @@ class GradleScriptingSupport(
val configuration: Configuration val configuration: Configuration
) : ScriptingSupport() { ) : ScriptingSupport() {
init {
rootsIndexer.transaction {
if (classpathRoots.hasNotCachedRoots(GradleClassRootsCache.extractRoots(context, configuration, project))) {
rootsIndexer.markNewRoot()
}
clearClassRootsCaches(project)
ScriptingSupportHelper.updateHighlighting(project) {
configuration.scriptModel(it) != null
}
}
hideNotificationForProjectImport(project)
}
override fun recreateRootsCache() = GradleClassRootsCache(project, context, configuration) override fun recreateRootsCache() = GradleClassRootsCache(project, context, configuration)
private fun updateNotification(file: KtFile) { fun shouldShowNotificationInEditor(file: VirtualFile): Boolean {
val vFile = file.originalFile.virtualFile val scriptModel = configuration.scriptModel(file) ?: return false
val scriptModel = configuration?.scriptModel(vFile) ?: return return !scriptModel.inputs.isUpToDate(project, file)
if (scriptModel.inputs.isUpToDate(project, vFile)) {
hideNotificationForProjectImport(project)
} else {
showNotificationForProjectImport(project)
}
} }
override fun clearCaches() { override fun clearCaches() {
@@ -104,7 +80,13 @@ class GradleScriptingSupport(
override fun ensureConfigurationUpToDate(files: List<KtFile>): Boolean = true override fun ensureConfigurationUpToDate(files: List<KtFile>): Boolean = true
override fun suggestToUpdateConfigurationIfOutOfDate(file: KtFile) { override fun suggestToUpdateConfigurationIfOutOfDate(file: KtFile) {
updateNotification(file) val vFile = file.originalFile.virtualFile
if (shouldShowNotificationInEditor(vFile)) {
showNotificationForProjectImport(project)
} else {
hideNotificationForProjectImport(project)
}
} }
} }
} }
@@ -11,6 +11,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupport import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupport
import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupportHelper
import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptConfigurationUpdater import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptConfigurationUpdater
import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsCache import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsCache
import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsIndexer import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsIndexer
@@ -124,13 +125,33 @@ class GradleScriptingSupportProvider(val project: Project) : ScriptingSupport.Pr
val buildRoot = VfsUtil.findFile(Paths.get(externalProjectPath), true) ?: return null val buildRoot = VfsUtil.findFile(Paths.get(externalProjectPath), true) ?: return null
val data = dataProvider(buildRoot) ?: return null val data = dataProvider(buildRoot) ?: return null
return GradleScriptingSupport( val newSupport = GradleScriptingSupport(
rootsIndexer, rootsIndexer,
project, project,
buildRoot, buildRoot,
GradleKtsContext(gradleExeSettings.javaHome?.let { File(it) }), GradleKtsContext(gradleExeSettings.javaHome?.let { File(it) }),
Configuration(data) Configuration(data)
) )
val oldSupport = roots.findRoot(externalProjectPath)
if (oldSupport != null) {
rootsIndexer.transaction {
val newRoots = GradleClassRootsCache.extractRoots(newSupport.context, newSupport.configuration, project)
if (oldSupport.classpathRoots.hasNotCachedRoots(newRoots)) {
rootsIndexer.markNewRoot()
}
newSupport.clearClassRootsCaches(project)
ScriptingSupportHelper.updateHighlighting(project) {
newSupport.configuration.scriptModel(it) != null
}
}
hideNotificationForProjectImport(project)
}
return newSupport
} }
private fun findTemplateClasspath(build: KotlinDslGradleBuildSync): List<String>? { private fun findTemplateClasspath(build: KotlinDslGradleBuildSync): List<String>? {
@@ -177,6 +198,13 @@ class GradleScriptingSupportProvider(val project: Project) : ScriptingSupport.Pr
return false return false
} }
// used in 201
@Suppress("UNUSED")
fun shouldShowNotificationInEditor(file: VirtualFile): Boolean {
val support = findRoot(file) ?: return false
return support.shouldShowNotificationInEditor(file)
}
companion object { companion object {
fun getInstance(project: Project): GradleScriptingSupportProvider = fun getInstance(project: Project): GradleScriptingSupportProvider =
EPN.getPoint(project).extensionList.firstIsInstance() EPN.getPoint(project).extensionList.firstIsInstance()