GradleBuildRoot: remove classes nesting
This commit is contained in:
+2
-2
@@ -10,14 +10,14 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs
|
import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRoot
|
import org.jetbrains.kotlin.idea.scripting.gradle.roots.*
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Up to date of gradle script depends on following factors:
|
* Up to date of gradle script depends on following factors:
|
||||||
* 1. It is out of date when essential [sections] are changed. See [getGradleScriptInputsStamp].
|
* 1. It is out of date when essential [sections] are changed. See [getGradleScriptInputsStamp].
|
||||||
* 2. When some related file is changed (other gradle script, gradle.properties file)
|
* 2. When some related file is changed (other gradle script, gradle.properties file)
|
||||||
* See [GradleBuildRoot.Linked.areRelatedFilesChangedBefore].
|
* See [GradleBuildRoot.areRelatedFilesChangedBefore].
|
||||||
*
|
*
|
||||||
* [lastModifiedTs] is needed to check if some related file was changed since last update
|
* [lastModifiedTs] is needed to check if some related file was changed since last update
|
||||||
*/
|
*/
|
||||||
|
|||||||
+49
-17
@@ -14,6 +14,7 @@ import com.intellij.ui.EditorNotificationPanel
|
|||||||
import com.intellij.ui.EditorNotifications
|
import com.intellij.ui.EditorNotifications
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
|
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
|
||||||
|
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsLocator.NotificationKind.*
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
||||||
|
|
||||||
class MissingGradleScriptConfigurationNotificationProvider(private val project: Project) :
|
class MissingGradleScriptConfigurationNotificationProvider(private val project: Project) :
|
||||||
@@ -24,32 +25,63 @@ class MissingGradleScriptConfigurationNotificationProvider(private val project:
|
|||||||
if (!isGradleKotlinScript(file)) return null
|
if (!isGradleKotlinScript(file)) return null
|
||||||
if (file.fileType != KotlinFileType.INSTANCE) return null
|
if (file.fileType != KotlinFileType.INSTANCE) return null
|
||||||
|
|
||||||
val scriptUnderRoot = GradleBuildRootsManager.getInstance(project).findScriptBuildRoot(file) ?: return null
|
val rootsManager = GradleBuildRootsManager.getInstance(project)
|
||||||
return when {
|
val scriptUnderRoot = rootsManager.findScriptBuildRoot(file) ?: return null
|
||||||
scriptUnderRoot.isUnrelatedScript -> EditorNotificationPanel().apply {
|
return when (scriptUnderRoot.notificationKind) {
|
||||||
text(KotlinIdeaGradleBundle.message("text.the.associated.gradle.project.isn.t.imported"))
|
dontCare -> null
|
||||||
|
outsideAnyting -> EditorNotificationPanel().apply {
|
||||||
createActionLabel(KotlinIdeaGradleBundle.message("action.text.standalone")) {
|
text("Code insight unavailable (related Gradle project not linked)")
|
||||||
GradleBuildRootsManager.getInstance(project).addStandaloneScript(file)
|
// todo: Code insight unavailable (cannot find related Gradle project)
|
||||||
|
createActionLabel("Link related Gradle project") {
|
||||||
|
runPartialGradleImport(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
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.importRequired -> EditorNotificationPanel().apply {
|
wasNotImportedAfterCreation -> EditorNotificationPanel().apply {
|
||||||
text(getMissingConfigurationNotificationText())
|
text("Code insight unavailable (Gradle project Sync required)")
|
||||||
createActionLabel(getMissingConfigurationActionText()) {
|
createActionLabel(getMissingConfigurationActionText()) {
|
||||||
runPartialGradleImport(project)
|
runPartialGradleImport(project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> null
|
notEvaluatedInLastImport -> EditorNotificationPanel().apply {
|
||||||
|
text(KotlinIdeaGradleBundle.message("text.the.associated.gradle.project.isn.t.imported"))
|
||||||
|
|
||||||
|
createActionLabel(KotlinIdeaGradleBundle.message("action.text.standalone")) {
|
||||||
|
rootsManager.updateStandaloneScripts {
|
||||||
|
removeStandaloneScript(file.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contextHelp(
|
||||||
|
KotlinIdeaGradleBundle.message("tool.tip.text.the.external.gradle.project.needs.to.be.imported.to.get.this.script.analyzed")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
standalone -> EditorNotificationPanel().apply {
|
||||||
|
text("Standalone script")
|
||||||
|
createActionLabel("Disable script") {
|
||||||
|
rootsManager.updateStandaloneScripts {
|
||||||
|
addStandaloneScript(file.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contextHelp(
|
||||||
|
"""
|
||||||
|
<div width=400>\
|
||||||
|
<p>Configuration for this script will be loaded separately from Gradle project Sync. \
|
||||||
|
<br/>
|
||||||
|
<p>This can be expensive for large Gradle projects.</p>\
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun EditorNotificationPanel.contextHelp(text: String) {
|
||||||
|
val helpIcon = createActionLabel("") {}
|
||||||
|
helpIcon.setIcon(AllIcons.General.ContextHelp)
|
||||||
|
helpIcon.setUseIconAsLink(true)
|
||||||
|
helpIcon.toolTipText = text
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val KEY = Key.create<EditorNotificationPanel>("GradleScriptOutOfSourceNotification")
|
private val KEY = Key.create<EditorNotificationPanel>("GradleScriptOutOfSourceNotification")
|
||||||
}
|
}
|
||||||
|
|||||||
+102
-117
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.scripting.gradle.roots
|
package org.jetbrains.kotlin.idea.scripting.gradle.roots
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem
|
import com.intellij.openapi.vfs.LocalFileSystem
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
@@ -18,6 +17,10 @@ import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
|||||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
@set:TestOnly
|
||||||
|
@get:TestOnly
|
||||||
|
internal var skipLastModifiedFilesLoading = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [GradleBuildRoot] is a linked gradle build (don't confuse with gradle project and included build).
|
* [GradleBuildRoot] is a linked gradle build (don't confuse with gradle project and included build).
|
||||||
* Each [GradleBuildRoot] may have it's own Gradle version, Java home and other settings.
|
* Each [GradleBuildRoot] may have it's own Gradle version, Java home and other settings.
|
||||||
@@ -27,132 +30,114 @@ import java.io.File
|
|||||||
* See [GradleBuildRootsManager] for more details.
|
* See [GradleBuildRootsManager] for more details.
|
||||||
*/
|
*/
|
||||||
sealed class GradleBuildRoot {
|
sealed class GradleBuildRoot {
|
||||||
/**
|
@Volatile
|
||||||
* The script not related to any Gradle build that is linked to IntelliJ Project,
|
var importing = false
|
||||||
* or we cannot known what is it
|
|
||||||
*/
|
|
||||||
@Suppress("CanSealedSubClassBeObject")
|
|
||||||
class Unlinked : GradleBuildRoot()
|
|
||||||
|
|
||||||
/**
|
abstract val pathPrefix: String
|
||||||
* Linked project, that may be itself: [Legacy], [New] or [Imported].
|
|
||||||
*/
|
|
||||||
abstract class Linked : GradleBuildRoot() {
|
|
||||||
@Volatile
|
|
||||||
var importing = false
|
|
||||||
|
|
||||||
abstract val pathPrefix: String
|
abstract val projectRoots: Collection<String>
|
||||||
|
|
||||||
abstract val projectRoots: Collection<String>
|
val dir: VirtualFile?
|
||||||
|
get() = LocalFileSystem.getInstance().findFileByPath(pathPrefix)
|
||||||
|
|
||||||
val dir: VirtualFile?
|
private lateinit var lastModifiedFiles: LastModifiedFiles
|
||||||
get() = LocalFileSystem.getInstance().findFileByPath(pathPrefix)
|
|
||||||
|
|
||||||
private lateinit var lastModifiedFiles: LastModifiedFiles
|
fun loadLastModifiedFiles() {
|
||||||
|
val loaded = if (!skipLastModifiedFilesLoading) {
|
||||||
|
val dir = dir
|
||||||
|
if (dir != null) LastModifiedFiles.read(dir)
|
||||||
|
else null
|
||||||
|
} else null
|
||||||
|
|
||||||
fun loadLastModifiedFiles() {
|
lastModifiedFiles = loaded ?: LastModifiedFiles()
|
||||||
val loaded = if (!skipLastModifiedFilesLoading) {
|
|
||||||
val dir = dir
|
|
||||||
if (dir != null) LastModifiedFiles.read(dir)
|
|
||||||
else null
|
|
||||||
} else null
|
|
||||||
|
|
||||||
lastModifiedFiles = loaded ?: LastModifiedFiles()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveLastModifiedFiles() {
|
|
||||||
LastModifiedFiles.write(dir ?: return, lastModifiedFiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun areRelatedFilesChangedBefore(file: VirtualFile, lastModified: Long): Boolean =
|
|
||||||
lastModifiedFiles.lastModifiedTimeStampExcept(file.path) < lastModified
|
|
||||||
|
|
||||||
fun fileChanged(filePath: String, ts: Long) {
|
|
||||||
lastModifiedFiles.fileChanged(ts, filePath)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class WithoutScriptModels(settings: GradleProjectSettings) : Linked() {
|
fun saveLastModifiedFiles() {
|
||||||
final override val pathPrefix = settings.externalProjectPath!!
|
LastModifiedFiles.write(dir ?: return, lastModifiedFiles)
|
||||||
final override val projectRoots = settings.modules.takeIf { it.isNotEmpty() } ?: listOf(pathPrefix)
|
|
||||||
|
|
||||||
init {
|
|
||||||
loadLastModifiedFiles()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun areRelatedFilesChangedBefore(file: VirtualFile, lastModified: Long): Boolean =
|
||||||
* Gradle build with old Gradle version (<6.0)
|
lastModifiedFiles.lastModifiedTimeStampExcept(file.path) < lastModified
|
||||||
*/
|
|
||||||
class Legacy(
|
|
||||||
settings: GradleProjectSettings
|
|
||||||
) : WithoutScriptModels(settings) {
|
|
||||||
init {
|
|
||||||
loadLastModifiedFiles()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
fun fileChanged(filePath: String, ts: Long) {
|
||||||
* Linked but not yet imported Gradle build.
|
lastModifiedFiles.fileChanged(ts, filePath)
|
||||||
*/
|
}
|
||||||
class New(
|
}
|
||||||
settings: GradleProjectSettings
|
|
||||||
) : WithoutScriptModels(settings) {
|
sealed class WithoutScriptModels(settings: GradleProjectSettings) : GradleBuildRoot() {
|
||||||
init {
|
final override val pathPrefix = settings.externalProjectPath!!
|
||||||
loadLastModifiedFiles()
|
final override val projectRoots = settings.modules.takeIf { it.isNotEmpty() } ?: listOf(pathPrefix)
|
||||||
}
|
|
||||||
}
|
init {
|
||||||
|
loadLastModifiedFiles()
|
||||||
/**
|
}
|
||||||
* Imported Gradle build.
|
}
|
||||||
* Each imported build have info about all of it's Kotlin Build Scripts.
|
|
||||||
*/
|
/**
|
||||||
class Imported(
|
* Gradle build with old Gradle version (<6.0)
|
||||||
override val pathPrefix: String,
|
*/
|
||||||
val javaHome: File?,
|
class Legacy(
|
||||||
val data: GradleBuildRootData
|
settings: GradleProjectSettings
|
||||||
) : Linked() {
|
) : WithoutScriptModels(settings) {
|
||||||
override val projectRoots: Collection<String>
|
init {
|
||||||
get() = data.projectRoots
|
loadLastModifiedFiles()
|
||||||
|
}
|
||||||
init {
|
}
|
||||||
loadLastModifiedFiles()
|
|
||||||
}
|
/**
|
||||||
|
* Linked but not yet imported Gradle build.
|
||||||
fun collectConfigurations(builder: ScriptClassRootsBuilder) {
|
*/
|
||||||
if (javaHome != null) {
|
class New(
|
||||||
builder.sdks.addSdk(javaHome)
|
settings: GradleProjectSettings
|
||||||
}
|
) : WithoutScriptModels(settings) {
|
||||||
|
init {
|
||||||
val definitions = GradleScriptDefinitionsContributor.getDefinitions(builder.project)
|
loadLastModifiedFiles()
|
||||||
|
}
|
||||||
builder.addTemplateClassesRoots(data.templateClasspath)
|
}
|
||||||
|
|
||||||
data.models.forEach { script ->
|
/**
|
||||||
val definition = selectScriptDefinition(script, definitions)
|
* Imported Gradle build.
|
||||||
|
* Each imported build have info about all of it's Kotlin Build Scripts.
|
||||||
builder.addCustom(
|
*/
|
||||||
script.file,
|
class Imported(
|
||||||
script.classPath,
|
override val pathPrefix: String,
|
||||||
script.sourcePath,
|
val javaHome: File?,
|
||||||
GradleScriptInfo(this, definition, script)
|
val data: GradleBuildRootData
|
||||||
)
|
) : GradleBuildRoot() {
|
||||||
}
|
override val projectRoots: Collection<String>
|
||||||
}
|
get() = data.projectRoots
|
||||||
|
|
||||||
private fun selectScriptDefinition(
|
init {
|
||||||
script: KotlinDslScriptModel,
|
loadLastModifiedFiles()
|
||||||
definitions: List<ScriptDefinition>
|
}
|
||||||
): ScriptDefinition? {
|
|
||||||
val file = LocalFileSystem.getInstance().findFileByPath(script.file) ?: return null
|
fun collectConfigurations(builder: ScriptClassRootsBuilder) {
|
||||||
val scriptSource = VirtualFileScriptSource(file)
|
if (javaHome != null) {
|
||||||
return definitions.firstOrNull { it.isScript(scriptSource) }
|
builder.sdks.addSdk(javaHome)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
val definitions = GradleScriptDefinitionsContributor.getDefinitions(builder.project)
|
||||||
companion object {
|
|
||||||
@set:TestOnly
|
builder.addTemplateClassesRoots(data.templateClasspath)
|
||||||
@get:TestOnly
|
|
||||||
internal var skipLastModifiedFilesLoading = false
|
data.models.forEach { script ->
|
||||||
|
val definition = selectScriptDefinition(script, definitions)
|
||||||
|
|
||||||
|
builder.addCustom(
|
||||||
|
script.file,
|
||||||
|
script.classPath,
|
||||||
|
script.sourcePath,
|
||||||
|
GradleScriptInfo(this, definition, script)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectScriptDefinition(
|
||||||
|
script: KotlinDslScriptModel,
|
||||||
|
definitions: List<ScriptDefinition>
|
||||||
|
): ScriptDefinition? {
|
||||||
|
val file = LocalFileSystem.getInstance().findFileByPath(script.file) ?: return null
|
||||||
|
val scriptSource = VirtualFileScriptSource(file)
|
||||||
|
return definitions.firstOrNull { it.isScript(scriptSource) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+14
-10
@@ -7,15 +7,15 @@ package org.jetbrains.kotlin.idea.scripting.gradle.roots
|
|||||||
|
|
||||||
import com.intellij.openapi.diagnostic.logger
|
import com.intellij.openapi.diagnostic.logger
|
||||||
|
|
||||||
class GradleBuildRootIndex {
|
class GradleBuildRootIndex : StandaloneScriptsUpdater {
|
||||||
private val log = logger<GradleBuildRootIndex>()
|
private val log = logger<GradleBuildRootIndex>()
|
||||||
|
|
||||||
private val standaloneScriptRoots = mutableMapOf<String, GradleBuildRoot.Linked?>()
|
private val standaloneScriptRoots = mutableMapOf<String, GradleBuildRoot?>()
|
||||||
|
|
||||||
private val byWorkingDir = HashMap<String, GradleBuildRoot.Linked>()
|
private val byWorkingDir = HashMap<String, GradleBuildRoot>()
|
||||||
private val byProjectDir = HashMap<String, GradleBuildRoot.Linked>()
|
private val byProjectDir = HashMap<String, GradleBuildRoot>()
|
||||||
|
|
||||||
val list: Collection<GradleBuildRoot.Linked>
|
val list: Collection<GradleBuildRoot>
|
||||||
get() = byWorkingDir.values
|
get() = byWorkingDir.values
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@@ -34,8 +34,8 @@ class GradleBuildRootIndex {
|
|||||||
fun getBuildByRootDir(dir: String) = byWorkingDir[dir]
|
fun getBuildByRootDir(dir: String) = byWorkingDir[dir]
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun findNearestRoot(path: String): GradleBuildRoot.Linked? {
|
fun findNearestRoot(path: String): GradleBuildRoot? {
|
||||||
var max: Pair<String, GradleBuildRoot.Linked>? = null
|
var max: Pair<String, GradleBuildRoot>? = null
|
||||||
byWorkingDir.entries.forEach {
|
byWorkingDir.entries.forEach {
|
||||||
if (path.startsWith(it.key) && (max == null || it.key.length > max!!.first.length)) {
|
if (path.startsWith(it.key) && (max == null || it.key.length > max!!.first.length)) {
|
||||||
max = it.key to it.value
|
max = it.key to it.value
|
||||||
@@ -54,7 +54,7 @@ class GradleBuildRootIndex {
|
|||||||
fun getStandaloneScriptRoot(path: String) = standaloneScriptRoots[path]
|
fun getStandaloneScriptRoot(path: String) = standaloneScriptRoots[path]
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun add(value: GradleBuildRoot.Linked): GradleBuildRoot.Linked? {
|
fun add(value: GradleBuildRoot): GradleBuildRoot? {
|
||||||
val prefix = value.pathPrefix
|
val prefix = value.pathPrefix
|
||||||
val old = byWorkingDir.put(prefix, value)
|
val old = byWorkingDir.put(prefix, value)
|
||||||
rebuildProjectRoots()
|
rebuildProjectRoots()
|
||||||
@@ -69,11 +69,15 @@ class GradleBuildRootIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun addStandaloneScript(path: String) {
|
override fun addStandaloneScript(path: String) {
|
||||||
computeStandaloneScriptRoot(path)
|
computeStandaloneScriptRoot(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
var standaloneScripts: Collection<String>
|
@Synchronized
|
||||||
|
override fun removeStandaloneScript(path: String) =
|
||||||
|
standaloneScriptRoots.remove(path)
|
||||||
|
|
||||||
|
override var standaloneScripts: Collection<String>
|
||||||
@Synchronized get() = standaloneScriptRoots.keys
|
@Synchronized get() = standaloneScriptRoots.keys
|
||||||
@Synchronized set(value) {
|
@Synchronized set(value) {
|
||||||
standaloneScriptRoots.clear()
|
standaloneScriptRoots.clear()
|
||||||
|
|||||||
+35
-16
@@ -38,7 +38,7 @@ abstract class GradleBuildRootsLocator {
|
|||||||
findAffectedFileRoot(filePath) != null ||
|
findAffectedFileRoot(filePath) != null ||
|
||||||
roots.isStandaloneScript(filePath)
|
roots.isStandaloneScript(filePath)
|
||||||
|
|
||||||
fun findAffectedFileRoot(filePath: String): GradleBuildRoot.Linked? {
|
fun findAffectedFileRoot(filePath: String): GradleBuildRoot? {
|
||||||
if (filePath.endsWith("/gradle.properties") ||
|
if (filePath.endsWith("/gradle.properties") ||
|
||||||
filePath.endsWith("/gradle.local")
|
filePath.endsWith("/gradle.local")
|
||||||
) {
|
) {
|
||||||
@@ -50,25 +50,42 @@ abstract class GradleBuildRootsLocator {
|
|||||||
return roots.getBuildByRootDir(filePath.substring(0, buildDirIndex))
|
return roots.getBuildByRootDir(filePath.substring(0, buildDirIndex))
|
||||||
}
|
}
|
||||||
|
|
||||||
return findScriptBuildRoot(filePath, searchNearestLegacy = false)?.root as? GradleBuildRoot.Linked
|
return findScriptBuildRoot(filePath, searchNearestLegacy = false)?.root as? GradleBuildRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class NotificationKind {
|
||||||
|
dontCare, // one of: imported, inside linked legacy gradle build
|
||||||
|
outsideAnyting, // suggest link related gradle build or just say that there is no one
|
||||||
|
wasNotImportedAfterCreation, // project not yet imported after this file was created
|
||||||
|
notEvaluatedInLastImport, // all other scripts, suggest to sync or mark as standalone
|
||||||
|
standalone
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScriptUnderRoot(
|
class ScriptUnderRoot(
|
||||||
val root: GradleBuildRoot?,
|
val root: GradleBuildRoot?,
|
||||||
val script: GradleScriptInfo? = null,
|
val script: GradleScriptInfo? = null,
|
||||||
val standalone: Boolean = false
|
val standalone: Boolean = false,
|
||||||
|
val nearest: GradleBuildRoot? = null
|
||||||
) {
|
) {
|
||||||
val isUnrelatedScript: Boolean
|
val notificationKind: NotificationKind
|
||||||
get() = root is GradleBuildRoot.Unlinked
|
get() = when {
|
||||||
|
isImported -> NotificationKind.dontCare
|
||||||
val importRequired: Boolean
|
standalone -> NotificationKind.standalone
|
||||||
get() = root is GradleBuildRoot.Linked &&
|
nearest == null -> NotificationKind.outsideAnyting
|
||||||
!isImported &&
|
nearest.importing -> NotificationKind.dontCare
|
||||||
!root.importing &&
|
else -> when (nearest) {
|
||||||
!standalone
|
is Legacy -> NotificationKind.dontCare
|
||||||
|
is New -> NotificationKind.wasNotImportedAfterCreation
|
||||||
|
is Imported -> NotificationKind.notEvaluatedInLastImport // todo: wasNotImportedAfterCreation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val isImported: Boolean
|
private val isImported: Boolean
|
||||||
get() = script != null
|
get() = script != null
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "ScriptUnderRoot(root=$root, script=$script, standalone=$standalone, nearest=$nearest)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findScriptBuildRoot(gradleKtsFile: VirtualFile): ScriptUnderRoot? =
|
fun findScriptBuildRoot(gradleKtsFile: VirtualFile): ScriptUnderRoot? =
|
||||||
@@ -98,12 +115,14 @@ abstract class GradleBuildRootsLocator {
|
|||||||
return ScriptUnderRoot(standaloneScriptRoot, standalone = true)
|
return ScriptUnderRoot(standaloneScriptRoot, standalone = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo(gradle6): remove, it is required only for projects with old gradle
|
|
||||||
if (searchNearestLegacy) {
|
if (searchNearestLegacy) {
|
||||||
val found = roots.findNearestRoot(filePath)
|
val nearest = roots.findNearestRoot(filePath)
|
||||||
if (found is GradleBuildRoot.Legacy) return ScriptUnderRoot(found)
|
return when (nearest) {
|
||||||
|
is Legacy -> ScriptUnderRoot(nearest)
|
||||||
|
else -> ScriptUnderRoot(null, nearest = nearest)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ScriptUnderRoot(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ScriptUnderRoot(GradleBuildRoot.Unlinked())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+47
-39
@@ -21,11 +21,11 @@ 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.CompositeScriptConfigurationManager
|
||||||
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.ScriptingSupport.Companion.EPN
|
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.script.ucache.ScriptClassRootsBuilder
|
||||||
import org.jetbrains.kotlin.idea.core.util.EDT
|
import org.jetbrains.kotlin.idea.core.util.EDT
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.*
|
import org.jetbrains.kotlin.idea.scripting.gradle.*
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslGradleBuildSync
|
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslGradleBuildSync
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||||
import org.jetbrains.plugins.gradle.config.GradleSettingsListenerAdapter
|
import org.jetbrains.plugins.gradle.config.GradleSettingsListenerAdapter
|
||||||
@@ -50,12 +50,10 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||||||
* It also used to show related notification and floating actions depending on root kind, state and script state itself.
|
* It also used to show related notification and floating actions depending on root kind, state and script state itself.
|
||||||
*
|
*
|
||||||
* Roots may be:
|
* Roots may be:
|
||||||
* - [GradleBuildRoot.Unlinked] - The script not related to any Gradle build that is linked to IntelliJ Project,
|
* - [GradleBuildRoot] - Linked project, that may be itself:
|
||||||
* or we cannot known what is it
|
* - [Legacy] - Gradle build with old Gradle version (<6.0)
|
||||||
* - [GradleBuildRoot.Linked] - Linked project, that may be itself:
|
* - [New] - not yet imported
|
||||||
* - [GradleBuildRoot.Legacy] - Gradle build with old Gradle version (<6.0)
|
* - [Imported] - imported
|
||||||
* - [GradleBuildRoot.New] - not yet imported
|
|
||||||
* - [GradleBuildRoot.Imported] - imported
|
|
||||||
*/
|
*/
|
||||||
class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(), ScriptingSupport {
|
class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(), ScriptingSupport {
|
||||||
private val manager: CompositeScriptConfigurationManager
|
private val manager: CompositeScriptConfigurationManager
|
||||||
@@ -69,14 +67,14 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
|
|
||||||
override fun isApplicable(file: VirtualFile): Boolean {
|
override fun isApplicable(file: VirtualFile): Boolean {
|
||||||
val scriptUnderRoot = findScriptBuildRoot(file) ?: return false
|
val scriptUnderRoot = findScriptBuildRoot(file) ?: return false
|
||||||
if (scriptUnderRoot.root is GradleBuildRoot.Legacy) return false
|
if (scriptUnderRoot.root is Legacy) return false
|
||||||
if (roots.isStandaloneScript(file.path)) return false
|
if (roots.isStandaloneScript(file.path)) return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isConfigurationLoadingInProgress(file: KtFile): Boolean {
|
override fun isConfigurationLoadingInProgress(file: KtFile): Boolean {
|
||||||
return when (val root = findScriptBuildRoot(file.originalFile.virtualFile)?.root) {
|
return when (val root = findScriptBuildRoot(file.originalFile.virtualFile)?.root) {
|
||||||
is GradleBuildRoot.Linked -> root.importing
|
is GradleBuildRoot -> root.importing
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +96,7 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
|
|
||||||
override fun collectConfigurations(builder: ScriptClassRootsBuilder) {
|
override fun collectConfigurations(builder: ScriptClassRootsBuilder) {
|
||||||
roots.list.forEach { root ->
|
roots.list.forEach { root ->
|
||||||
if (root is GradleBuildRoot.Imported) {
|
if (root is Imported) {
|
||||||
root.collectConfigurations(builder)
|
root.collectConfigurations(builder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,32 +114,32 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
|
|
||||||
fun markImportingInProgress(workingDir: String, inProgress: Boolean = true) {
|
fun markImportingInProgress(workingDir: String, inProgress: Boolean = true) {
|
||||||
actualizeBuildRoot(workingDir)?.importing = inProgress
|
actualizeBuildRoot(workingDir)?.importing = inProgress
|
||||||
updateNotifications(workingDir)
|
updateNotifications { it.startsWith(workingDir) }
|
||||||
scriptConfigurationsAreUpToDate(project)
|
hideNotificationForProjectImport(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update(build: KotlinDslGradleBuildSync) {
|
fun update(build: KotlinDslGradleBuildSync) {
|
||||||
// fast path for linked gradle builds without .gradle.kts support
|
// fast path for linked gradle builds without .gradle.kts support
|
||||||
if (build.models.isEmpty()) {
|
if (build.models.isEmpty()) {
|
||||||
val root = getBuildRootByWorkingDir(build.workingDir) ?: return
|
val root = getBuildRootByWorkingDir(build.workingDir) ?: return
|
||||||
if (root is GradleBuildRoot.Imported && root.data.models.isEmpty()) return
|
if (root is Imported && root.data.models.isEmpty()) return
|
||||||
}
|
}
|
||||||
|
|
||||||
val root = actualizeBuildRoot(build.workingDir) ?: return
|
val root = actualizeBuildRoot(build.workingDir) ?: return
|
||||||
root.importing = false
|
root.importing = false
|
||||||
|
|
||||||
if (root is GradleBuildRoot.Legacy) return
|
if (root is Legacy) return
|
||||||
|
|
||||||
val templateClasspath = GradleScriptDefinitionsContributor.getDefinitionsTemplateClasspath(project)
|
val templateClasspath = GradleScriptDefinitionsContributor.getDefinitionsTemplateClasspath(project)
|
||||||
val newData = GradleBuildRootData(build.projectRoots, templateClasspath, build.models)
|
val newData = GradleBuildRootData(build.projectRoots, templateClasspath, build.models)
|
||||||
val mergedData = if (build.failed && root is GradleBuildRoot.Imported) merge(root.data, newData) else newData
|
val mergedData = if (build.failed && root is Imported) merge(root.data, newData) else newData
|
||||||
|
|
||||||
val newSupport = tryCreateImportedRoot(build.workingDir) { mergedData } ?: return
|
val newSupport = tryCreateImportedRoot(build.workingDir) { mergedData } ?: return
|
||||||
GradleBuildRootDataSerializer.write(newSupport.dir ?: return, mergedData)
|
GradleBuildRootDataSerializer.write(newSupport.dir ?: return, mergedData)
|
||||||
|
|
||||||
add(newSupport)
|
add(newSupport)
|
||||||
|
|
||||||
scriptConfigurationsAreUpToDate(project)
|
hideNotificationForProjectImport(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun merge(old: GradleBuildRootData, new: GradleBuildRootData): GradleBuildRootData {
|
private fun merge(old: GradleBuildRootData, new: GradleBuildRootData): GradleBuildRootData {
|
||||||
@@ -168,12 +166,22 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addStandaloneScript(file: VirtualFile) {
|
fun updateStandaloneScripts(update: StandaloneScriptsUpdater.() -> Unit) {
|
||||||
roots.addStandaloneScript(file.path)
|
val changes = StandaloneScriptsUpdater.collectChanges(delegate = roots, update)
|
||||||
roots.rebuildProjectRoots()
|
|
||||||
updateNotifications(file.path)
|
updateNotifications { it in changes.new || it in changes.removed }
|
||||||
val ktFile = project.getKtFile(file) ?: return
|
|
||||||
ScriptConfigurationManager.getInstance(project).getConfiguration(ktFile)
|
runReadAction {
|
||||||
|
changes.new.forEach {
|
||||||
|
val virtualFile = LocalFileSystem.getInstance().findFileByPath(it)
|
||||||
|
if (virtualFile != null) {
|
||||||
|
val ktFile = PsiManager.getInstance(project).findFile(virtualFile) as? KtFile
|
||||||
|
if (ktFile != null) {
|
||||||
|
ScriptConfigurationManager.getInstance(project).getConfiguration(ktFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -218,7 +226,7 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
* Actually this should be true, but we may miss some change events.
|
* Actually this should be true, but we may miss some change events.
|
||||||
* For that cases we are rechecking this on each Gradle Project sync (importing/reimporting)
|
* For that cases we are rechecking this on each Gradle Project sync (importing/reimporting)
|
||||||
*/
|
*/
|
||||||
private fun actualizeBuildRoot(workingDir: String): GradleBuildRoot.Linked? {
|
private fun actualizeBuildRoot(workingDir: String): GradleBuildRoot? {
|
||||||
val actualSettings = getGradleProjectSettings(workingDir)
|
val actualSettings = getGradleProjectSettings(workingDir)
|
||||||
val buildRoot = getBuildRootByWorkingDir(workingDir)
|
val buildRoot = getBuildRootByWorkingDir(workingDir)
|
||||||
|
|
||||||
@@ -232,15 +240,15 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun GradleBuildRoot.Linked.checkActual(actualSettings: GradleProjectSettings?): Boolean {
|
private fun GradleBuildRoot.checkActual(actualSettings: GradleProjectSettings?): Boolean {
|
||||||
if (actualSettings == null) return false
|
if (actualSettings == null) return false
|
||||||
|
|
||||||
val knownAsSupported = this !is GradleBuildRoot.Legacy
|
val knownAsSupported = this !is Legacy
|
||||||
val shouldBeSupported = kotlinDslScriptsModelImportSupported(actualSettings.resolveGradleVersion().version)
|
val shouldBeSupported = kotlinDslScriptsModelImportSupported(actualSettings.resolveGradleVersion().version)
|
||||||
return knownAsSupported == shouldBeSupported
|
return knownAsSupported == shouldBeSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reloadBuildRoot(rootPath: String): GradleBuildRoot.Linked? {
|
private fun reloadBuildRoot(rootPath: String): GradleBuildRoot? {
|
||||||
val settings = getGradleProjectSettings(rootPath)
|
val settings = getGradleProjectSettings(rootPath)
|
||||||
if (settings == null) {
|
if (settings == null) {
|
||||||
remove(rootPath)
|
remove(rootPath)
|
||||||
@@ -267,45 +275,45 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
settings: GradleProjectSettings
|
settings: GradleProjectSettings
|
||||||
) = data.copy(projectRoots = data.projectRoots.toSet() + settings.modules)
|
) = data.copy(projectRoots = data.projectRoots.toSet() + settings.modules)
|
||||||
|
|
||||||
private fun createOtherLinkedRoot(settings: GradleProjectSettings): GradleBuildRoot.Linked {
|
private fun createOtherLinkedRoot(settings: GradleProjectSettings): GradleBuildRoot {
|
||||||
val supported = kotlinDslScriptsModelImportSupported(settings.resolveGradleVersion().version)
|
val supported = kotlinDslScriptsModelImportSupported(settings.resolveGradleVersion().version)
|
||||||
return when {
|
return when {
|
||||||
supported -> GradleBuildRoot.New(settings)
|
supported -> New(settings)
|
||||||
else -> GradleBuildRoot.Legacy(settings)
|
else -> Legacy(settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryCreateImportedRoot(
|
private fun tryCreateImportedRoot(
|
||||||
externalProjectPath: String,
|
externalProjectPath: String,
|
||||||
dataProvider: (buildRoot: VirtualFile) -> GradleBuildRootData?
|
dataProvider: (buildRoot: VirtualFile) -> GradleBuildRootData?
|
||||||
): GradleBuildRoot.Imported? {
|
): Imported? {
|
||||||
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
|
||||||
val javaHome = ExternalSystemApiUtil
|
val javaHome = ExternalSystemApiUtil
|
||||||
.getExecutionSettings<GradleExecutionSettings>(project, externalProjectPath, GradleConstants.SYSTEM_ID)
|
.getExecutionSettings<GradleExecutionSettings>(project, externalProjectPath, GradleConstants.SYSTEM_ID)
|
||||||
.javaHome?.let { File(it) }
|
.javaHome?.let { File(it) }
|
||||||
|
|
||||||
return GradleBuildRoot.Imported(externalProjectPath, javaHome, data)
|
return Imported(externalProjectPath, javaHome, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun add(newRoot: GradleBuildRoot.Linked) {
|
private fun add(newRoot: GradleBuildRoot) {
|
||||||
val old = roots.add(newRoot)
|
val old = roots.add(newRoot)
|
||||||
if (old is GradleBuildRoot.Imported && newRoot !is GradleBuildRoot.Imported) removeData(old.pathPrefix)
|
if (old is Imported && newRoot !is Imported) removeData(old.pathPrefix)
|
||||||
if (old is GradleBuildRoot.Imported || newRoot is GradleBuildRoot.Imported) {
|
if (old is Imported || newRoot is Imported) {
|
||||||
updater.invalidateAndCommit()
|
updater.invalidateAndCommit()
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNotifications(newRoot.pathPrefix)
|
updateNotifications { it.startsWith(newRoot.pathPrefix) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun remove(rootPath: String) {
|
private fun remove(rootPath: String) {
|
||||||
val removed = roots.remove(rootPath)
|
val removed = roots.remove(rootPath)
|
||||||
if (removed is GradleBuildRoot.Imported) {
|
if (removed is Imported) {
|
||||||
removeData(rootPath)
|
removeData(rootPath)
|
||||||
updater.invalidateAndCommit()
|
updater.invalidateAndCommit()
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNotifications(rootPath)
|
updateNotifications { it.startsWith(rootPath) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeData(rootPath: String) {
|
private fun removeData(rootPath: String) {
|
||||||
@@ -317,11 +325,11 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
private fun updateNotifications(dir: String) {
|
private fun updateNotifications(shouldUpdatePath: (String) -> Boolean) {
|
||||||
if (!project.isOpen) return
|
if (!project.isOpen) return
|
||||||
|
|
||||||
val openedScripts = FileEditorManager.getInstance(project).openFiles.filter {
|
val openedScripts = FileEditorManager.getInstance(project).openFiles.filter {
|
||||||
it.path.startsWith(dir) && maybeAffectedGradleProjectFile(it.path)
|
shouldUpdatePath(it.path) && maybeAffectedGradleProjectFile(it.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openedScripts.isEmpty()) return
|
if (openedScripts.isEmpty()) return
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ import kotlin.script.experimental.jvm.jdkHome
|
|||||||
import kotlin.script.experimental.jvm.jvm
|
import kotlin.script.experimental.jvm.jvm
|
||||||
|
|
||||||
class GradleScriptInfo(
|
class GradleScriptInfo(
|
||||||
val buildRoot: GradleBuildRoot.Imported,
|
val buildRoot: Imported,
|
||||||
scriptDefinition: ScriptDefinition?,
|
scriptDefinition: ScriptDefinition?,
|
||||||
val model: KotlinDslScriptModel
|
val model: KotlinDslScriptModel
|
||||||
) : ScriptClassRootsCache.LightScriptInfo(scriptDefinition) {
|
) : ScriptClassRootsCache.LightScriptInfo(scriptDefinition) {
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.scripting.gradle.roots
|
||||||
|
|
||||||
|
interface StandaloneScriptsUpdater {
|
||||||
|
var standaloneScripts: Collection<String>
|
||||||
|
|
||||||
|
fun addStandaloneScript(path: String)
|
||||||
|
|
||||||
|
fun removeStandaloneScript(path: String): GradleBuildRoot?
|
||||||
|
|
||||||
|
class Changes {
|
||||||
|
val new = mutableSetOf<String>()
|
||||||
|
val removed = mutableSetOf<String>()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun collectChanges(
|
||||||
|
delegate: StandaloneScriptsUpdater,
|
||||||
|
update: StandaloneScriptsUpdater.() -> Unit
|
||||||
|
): Changes {
|
||||||
|
synchronized(delegate) {
|
||||||
|
val old = delegate.standaloneScripts.toSet()
|
||||||
|
delegate.update()
|
||||||
|
val changes = Changes()
|
||||||
|
val new = delegate.standaloneScripts
|
||||||
|
|
||||||
|
new.forEach {
|
||||||
|
if (it !in old) changes.new.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
old.forEach {
|
||||||
|
if (it !in new) changes.removed.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.idea.scripting.gradle
|
|||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.registry.Registry
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
@@ -64,7 +63,7 @@ fun getGradleScriptInputsStamp(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildRoot = GradleBuildRootsManager.getInstance(project).findScriptBuildRoot(file)?.root as? GradleBuildRoot.Linked
|
val buildRoot = GradleBuildRootsManager.getInstance(project).findScriptBuildRoot(file)?.root as? GradleBuildRoot
|
||||||
GradleKotlinScriptConfigurationInputs(result.toString(), givenTimeStamp, buildRoot?.pathPrefix)
|
GradleKotlinScriptConfigurationInputs(result.toString(), givenTimeStamp, buildRoot?.pathPrefix)
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-3
@@ -7,10 +7,11 @@ package org.jetbrains.kotlin.idea.scripting.gradle.roots
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.GradleKotlinScriptConfigurationInputs
|
import org.jetbrains.kotlin.idea.scripting.gradle.GradleKotlinScriptConfigurationInputs
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModel
|
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModel
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
open class AbstractGradleBuildRootsLocatorTest {
|
open class AbstractGradleBuildRootsLocatorTest {
|
||||||
init {
|
init {
|
||||||
GradleBuildRoot.skipLastModifiedFilesLoading = true
|
skipLastModifiedFilesLoading = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private val scripts = mutableMapOf<String, GradleScriptInfo>()
|
private val scripts = mutableMapOf<String, GradleScriptInfo>()
|
||||||
@@ -21,7 +22,7 @@ open class AbstractGradleBuildRootsLocatorTest {
|
|||||||
fun accessRoots() = roots
|
fun accessRoots() = roots
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun add(root: GradleBuildRoot.Linked) {
|
private fun add(root: GradleBuildRoot) {
|
||||||
locator.accessRoots().add(root)
|
locator.accessRoots().add(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ open class AbstractGradleBuildRootsLocatorTest {
|
|||||||
relativeScripts: List<String> = listOf("build.gradle.kts")
|
relativeScripts: List<String> = listOf("build.gradle.kts")
|
||||||
) {
|
) {
|
||||||
val pathPrefix = "$dir/"
|
val pathPrefix = "$dir/"
|
||||||
val root = GradleBuildRoot.Imported(
|
val root = Imported(
|
||||||
dir,
|
dir,
|
||||||
null,
|
null,
|
||||||
GradleBuildRootData(
|
GradleBuildRootData(
|
||||||
@@ -62,4 +63,8 @@ open class AbstractGradleBuildRootsLocatorTest {
|
|||||||
|
|
||||||
fun findScriptBuildRoot(filePath: String, searchNearestLegacy: Boolean = true) =
|
fun findScriptBuildRoot(filePath: String, searchNearestLegacy: Boolean = true) =
|
||||||
locator.findScriptBuildRoot(filePath, searchNearestLegacy)
|
locator.findScriptBuildRoot(filePath, searchNearestLegacy)
|
||||||
|
|
||||||
|
fun assertNotificationKind(filePath: String, notificationKind: GradleBuildRootsLocator.NotificationKind) {
|
||||||
|
assertEquals(notificationKind, findScriptBuildRoot(filePath)?.notificationKind)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+7
-8
@@ -5,7 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.scripting.gradle.roots
|
package org.jetbrains.kotlin.idea.scripting.gradle.roots
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsLocator.NotificationKind.dontCare
|
||||||
|
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsLocator.NotificationKind.wasNotImportedAfterCreation
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@@ -16,18 +19,14 @@ class GradleBuildRootsLocatorTest : AbstractGradleBuildRootsLocatorTest() {
|
|||||||
// the build.gradle.kts under the project root will be definitive import at next import
|
// the build.gradle.kts under the project root will be definitive import at next import
|
||||||
// so, we should not treat it as unlinked
|
// so, we should not treat it as unlinked
|
||||||
newImportedGradleProject("imported", relativeScripts = listOf())
|
newImportedGradleProject("imported", relativeScripts = listOf())
|
||||||
val scriptUnderRoot = findScriptBuildRoot("imported/build.gradle.kts")
|
|
||||||
assertNotNull(scriptUnderRoot)
|
assertNotificationKind("imported/build.gradle.kts", wasNotImportedAfterCreation)
|
||||||
assertTrue(scriptUnderRoot.importRequired)
|
|
||||||
assertFalse(scriptUnderRoot.isUnrelatedScript)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testBuildGradleKtsNearProjectRoot() {
|
fun testBuildGradleKtsNearProjectRoot() {
|
||||||
newImportedGradleProject("imported", relativeScripts = listOf("build.gradle.kts"))
|
newImportedGradleProject("imported", relativeScripts = listOf("build.gradle.kts"))
|
||||||
val scriptUnderRoot = findScriptBuildRoot("imported/build.gradle.kts")
|
|
||||||
assertNotNull(scriptUnderRoot)
|
assertNotificationKind("imported/build.gradle.kts", dontCare)
|
||||||
assertFalse(scriptUnderRoot.importRequired)
|
|
||||||
assertFalse(scriptUnderRoot.isUnrelatedScript)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user