diff --git a/idea/idea-gradle/res/messages/KotlinIdeaGradleBundle.properties b/idea/idea-gradle/res/messages/KotlinIdeaGradleBundle.properties
index 9ccfb3dfaf4..8845a2368ae 100644
--- a/idea/idea-gradle/res/messages/KotlinIdeaGradleBundle.properties
+++ b/idea/idea-gradle/res/messages/KotlinIdeaGradleBundle.properties
@@ -1,3 +1,4 @@
+action.text.standalone=Add as standalone script
action.label.text.load.script.configuration=Load related Gradle project
action.text.install=Install
action.text.show.kotlin.gradle.dsl.logs.in=Show Kotlin Gradle DSL Logs in {0}
@@ -37,7 +38,7 @@ text.couldn.t.configure.kotlin.gradle.plugin.automatically=Couldn't configure ko
text.default.kotlin.gradle.script=Default Kotlin Gradle Script
text.gradle.dsl.logs.cannot.be.found.automatically.see.how.to.find.logs=Gradle DSL Logs cannot be found automatically.
See how to find logs here.
text.see.manual.installation.instructions=See manual installation instructions here.
-text.the.associated.gradle.project.isn.t.imported=The associated Gradle Project isn't imported.
+text.the.associated.gradle.project.isn.t.imported=Cannot find related Gradle project. Kotlin DSL Code insight unavailable.
text.was.modified={0} was modified
title.configure.kotlin.gradle.plugin=Configure Kotlin-Gradle Plugin
title.kotlin.build.script=Gradle Kotlin DSL Scripts errors
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt
index 355934599b9..345d5213cb7 100644
--- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt
+++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
+const val disableNotificationForProjectImport = true
+
fun runPartialGradleImport(project: Project) {
getGradleProjectSettings(project).forEach {
ExternalSystemUtil.refreshProject(
@@ -51,6 +53,8 @@ private var Project.notificationPanel: ScriptConfigurationChangedNotification?
by UserDataProperty(Key.create("load.script.configuration.panel"))
fun scriptConfigurationsNeedToBeUpdated(project: Project) {
+ if (disableNotificationForProjectImport) return
+
if (autoReloadScriptConfigurations(project)) {
// import should be run automatically by Gradle plugin
return
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptListener.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptListener.kt
index 11b93513757..379c02a9532 100644
--- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptListener.kt
+++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptListener.kt
@@ -50,13 +50,6 @@ class GradleScriptListener(project: Project) : ScriptChangeListener(project) {
}
private fun checkUpToDate(vFile: VirtualFile) {
- val upToDate = GradleBuildRootsManager.getInstance(project)
- .getScriptInfo(vFile)?.model?.inputs?.isUpToDate(project, vFile) ?: return
-
- if (upToDate) {
- scriptConfigurationsAreUpToDate(project)
- } else {
- scriptConfigurationsNeedToBeUpdated(project)
- }
+ GradleBuildRootsManager.getInstance(project).checkUpToDate(vFile)
}
}
\ No newline at end of file
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/MissingGradleScriptConfigurationNotificationProvider.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/MissingGradleScriptConfigurationNotificationProvider.kt
index 67e2f43a170..30d693c4669 100644
--- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/MissingGradleScriptConfigurationNotificationProvider.kt
+++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/MissingGradleScriptConfigurationNotificationProvider.kt
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.idea.scripting.gradle
import com.intellij.icons.AllIcons
-import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode
-import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
@@ -16,11 +14,7 @@ import com.intellij.ui.EditorNotificationPanel
import com.intellij.ui.EditorNotifications
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
-import org.jetbrains.kotlin.idea.scripting.gradle.legacy.GradleLegacyScriptConfigurationLoaderForOutOfProjectScripts
-import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRoot
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
-import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
-import org.jetbrains.plugins.gradle.util.GradleConstants
class MissingGradleScriptConfigurationNotificationProvider(private val project: Project) :
EditorNotifications.Provider() {
@@ -35,30 +29,18 @@ class MissingGradleScriptConfigurationNotificationProvider(private val project:
scriptUnderRoot.isUnrelatedScript -> EditorNotificationPanel().apply {
text(KotlinIdeaGradleBundle.message("text.the.associated.gradle.project.isn.t.imported"))
- val linkProjectText = KotlinIdeaGradleBundle.message("action.label.text.load.script.configuration")
- createActionLabel(linkProjectText) {
- val newProjectSettings = GradleProjectSettings()
- newProjectSettings.externalProjectPath = file.parent.path
- ExternalSystemUtil.linkExternalProject(
- GradleConstants.SYSTEM_ID,
- newProjectSettings,
- project,
- {
-
- },
- false,
- ProgressExecutionMode.IN_BACKGROUND_ASYNC
- )
+ createActionLabel(KotlinIdeaGradleBundle.message("action.text.standalone")) {
+ GradleBuildRootsManager.getInstance(project).addStandaloneScript(file)
}
- val link = createActionLabel("") {}
- link.setIcon(AllIcons.General.ContextHelp)
- link.setUseIconAsLink(true)
- link.toolTipText = KotlinIdeaGradleBundle.message(
- "tool.tip.text.the.external.gradle.project.needs.to.be.imported.to.get.this.script.analyzed",
- linkProjectText
+
+ val helpIcon = createActionLabel("") {}
+ helpIcon.setIcon(AllIcons.General.ContextHelp)
+ helpIcon.setUseIconAsLink(true)
+ helpIcon.toolTipText = KotlinIdeaGradleBundle.message(
+ "tool.tip.text.the.external.gradle.project.needs.to.be.imported.to.get.this.script.analyzed"
)
}
- scriptUnderRoot.isNewScript -> EditorNotificationPanel().apply {
+ scriptUnderRoot.importRequired -> EditorNotificationPanel().apply {
text(getMissingConfigurationNotificationText())
createActionLabel(getMissingConfigurationActionText()) {
runPartialGradleImport(project)
@@ -68,12 +50,6 @@ class MissingGradleScriptConfigurationNotificationProvider(private val project:
}
}
- private val loaderForOutOfProjectScripts by lazy {
- GradleLegacyScriptConfigurationLoaderForOutOfProjectScripts(
- project
- )
- }
-
companion object {
private val KEY = Key.create("GradleScriptOutOfSourceNotification")
}
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootIndex.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootIndex.kt
index 81a1436d222..68e104f5c94 100644
--- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootIndex.kt
+++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootIndex.kt
@@ -10,6 +10,8 @@ import com.intellij.openapi.diagnostic.logger
class GradleBuildRootIndex {
private val log = logger()
+ private val standaloneScriptRoots = mutableMapOf()
+
private val byWorkingDir = HashMap()
private val byProjectDir = HashMap()
@@ -24,6 +26,8 @@ class GradleBuildRootIndex {
byProjectDir[it] = buildRoot
}
}
+
+ standaloneScriptRoots.keys.forEach(::computeStandaloneScriptRoot)
}
@Synchronized
@@ -43,6 +47,12 @@ class GradleBuildRootIndex {
@Synchronized
fun getBuildByProjectDir(projectDir: String) = byProjectDir[projectDir]
+ @Synchronized
+ fun isStandaloneScript(path: String) = path in standaloneScriptRoots
+
+ @Synchronized
+ fun getStandaloneScriptRoot(path: String) = standaloneScriptRoots[path]
+
@Synchronized
fun add(value: GradleBuildRoot.Linked): GradleBuildRoot.Linked? {
val prefix = value.pathPrefix
@@ -57,4 +67,20 @@ class GradleBuildRootIndex {
rebuildProjectRoots()
log.info("$prefix: removed")
}
+
+ @Synchronized
+ fun addStandaloneScript(path: String) {
+ computeStandaloneScriptRoot(path)
+ }
+
+ var standaloneScripts: Collection
+ @Synchronized get() = standaloneScriptRoots.keys
+ @Synchronized set(value) {
+ standaloneScriptRoots.clear()
+ value.forEach(::computeStandaloneScriptRoot)
+ }
+
+ private fun computeStandaloneScriptRoot(path: String) {
+ standaloneScriptRoots[path] = findNearestRoot(path)
+ }
}
\ No newline at end of file
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsLocator.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsLocator.kt
index 01eeac61aa1..3545e1affbb 100644
--- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsLocator.kt
+++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsLocator.kt
@@ -32,12 +32,11 @@ abstract class GradleBuildRootsLocator {
filePath.endsWith("/gradle.properties") ||
filePath.endsWith("/gradle.local") ||
filePath.endsWith("/gradle-wrapper.properties") ||
- filePath.endsWith("/build.gradle.kts") ||
- filePath.endsWith("/settings.gradle.kts") ||
- filePath.endsWith("/init.gradle.kts")
+ filePath.endsWith(".gradle.kts")
fun isAffectedGradleProjectFile(filePath: String): Boolean =
- findAffectedFileRoot(filePath) != null
+ findAffectedFileRoot(filePath) != null ||
+ roots.isStandaloneScript(filePath)
fun findAffectedFileRoot(filePath: String): GradleBuildRoot.Linked? {
if (filePath.endsWith("/gradle.properties") ||
@@ -56,15 +55,17 @@ abstract class GradleBuildRootsLocator {
class ScriptUnderRoot(
val root: GradleBuildRoot?,
- val script: GradleScriptInfo? = null
+ val script: GradleScriptInfo? = null,
+ val standalone: Boolean = false
) {
val isUnrelatedScript: Boolean
get() = root is GradleBuildRoot.Unlinked
- val isNewScript: Boolean
+ val importRequired: Boolean
get() = root is GradleBuildRoot.Linked &&
!isImported &&
- !root.importing
+ !root.importing &&
+ !standalone
private val isImported: Boolean
get() = script != null
@@ -92,6 +93,11 @@ abstract class GradleBuildRootsLocator {
// other scripts: "included", "precompiled" scripts, scripts in unlinked projects,
// or just random files with ".gradle.kts" ending
+ val standaloneScriptRoot = roots.getStandaloneScriptRoot(filePath)
+ if (standaloneScriptRoot != null) {
+ return ScriptUnderRoot(standaloneScriptRoot, standalone = true)
+ }
+
// todo(gradle6): remove, it is required only for projects with old gradle
if (searchNearestLegacy) {
val found = roots.findNearestRoot(filePath)
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsManager.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsManager.kt
index 03bfa3132fd..0351aa7410d 100644
--- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsManager.kt
+++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsManager.kt
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.configuration.CompositeScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupport
import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupport.Companion.EPN
+import org.jetbrains.kotlin.idea.core.script.configuration.utils.getKtFile
import org.jetbrains.kotlin.idea.core.script.ucache.ScriptClassRootsBuilder
import org.jetbrains.kotlin.idea.core.util.EDT
import org.jetbrains.kotlin.idea.scripting.gradle.*
@@ -69,6 +70,7 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
override fun isApplicable(file: VirtualFile): Boolean {
val scriptUnderRoot = findScriptBuildRoot(file) ?: return false
if (scriptUnderRoot.root is GradleBuildRoot.Legacy) return false
+ if (roots.isStandaloneScript(file.path)) return false
return true
}
@@ -79,8 +81,16 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
}
}
- // used in 201
- @Suppress("UNUSED")
+ @Suppress("MemberVisibilityCanBePrivate") // used in GradleImportHelper.kt.193
+ fun checkUpToDate(file: VirtualFile) {
+ if (isConfigurationOutOfDate(file)) {
+ showNotificationForProjectImport(project)
+ } else {
+ hideNotificationForProjectImport(project)
+ }
+ }
+
+ @Suppress("MemberVisibilityCanBePrivate") // used in GradleImportHelper.kt.201
fun isConfigurationOutOfDate(file: VirtualFile): Boolean {
val script = getScriptInfo(file) ?: return false
return !script.model.inputs.isUpToDate(project, file)
@@ -158,6 +168,14 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
}
}
+ fun addStandaloneScript(file: VirtualFile) {
+ roots.addStandaloneScript(file.path)
+ roots.rebuildProjectRoots()
+ updateNotifications(file.path)
+ val ktFile = project.getKtFile(file) ?: return
+ ScriptConfigurationManager.getInstance(project).getConfiguration(ktFile)
+ }
+
init {
getGradleProjectSettings(project).forEach {
// don't call this.add, as we are inside scripting manager initialization
@@ -298,15 +316,20 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
}
}
- private fun updateNotifications(dir1: String) {
+ @Suppress("MemberVisibilityCanBePrivate")
+ private fun updateNotifications(dir: String) {
if (!project.isOpen) return
val openedScripts = FileEditorManager.getInstance(project).openFiles.filter {
- it.path.startsWith(dir1) && isGradleKotlinScript(it)
+ it.path.startsWith(dir) && maybeAffectedGradleProjectFile(it.path)
}
if (openedScripts.isEmpty()) return
+ openedScripts.forEach {
+ checkUpToDate(it)
+ }
+
GlobalScope.launch(EDT(project)) {
if (project.isDisposed) return@launch
diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsLocatorTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsLocatorTest.kt
index 6882107aece..a4765fd0f66 100644
--- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsLocatorTest.kt
+++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsLocatorTest.kt
@@ -18,7 +18,7 @@ class GradleBuildRootsLocatorTest : AbstractGradleBuildRootsLocatorTest() {
newImportedGradleProject("imported", relativeScripts = listOf())
val scriptUnderRoot = findScriptBuildRoot("imported/build.gradle.kts")
assertNotNull(scriptUnderRoot)
- assertTrue(scriptUnderRoot.isNewScript)
+ assertTrue(scriptUnderRoot.importRequired)
assertFalse(scriptUnderRoot.isUnrelatedScript)
}
@@ -27,7 +27,7 @@ class GradleBuildRootsLocatorTest : AbstractGradleBuildRootsLocatorTest() {
newImportedGradleProject("imported", relativeScripts = listOf("build.gradle.kts"))
val scriptUnderRoot = findScriptBuildRoot("imported/build.gradle.kts")
assertNotNull(scriptUnderRoot)
- assertFalse(scriptUnderRoot.isNewScript)
+ assertFalse(scriptUnderRoot.importRequired)
assertFalse(scriptUnderRoot.isUnrelatedScript)
}
}
\ No newline at end of file