From 06e43027cf3310c95cc8669966675e19aa2fe196 Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Thu, 7 May 2020 14:48:49 +0300 Subject: [PATCH] gradle.kts, minor: move isInAffectedGradleProjectFiles inside GradleBuildRootsManager --- .../gradle/AsyncFileChangeListenerHelper.kt | 8 +++- .../AsyncFileChangeListenerHelper.kt.191 | 8 +++- .../AsyncFileChangeListenerHelper.kt.201 | 8 +++- .../scripting/gradle/GradleScriptListener.kt | 2 +- .../GradleLegacyScriptConfigurationLoader.kt | 6 ++- .../legacy/GradleLegacyScriptListener.kt | 6 +-- .../gradle/roots/GradleBuildRootIndex.kt | 2 +- .../gradle/roots/GradleBuildRootsManager.kt | 46 +++++++++++++++---- .../kotlin/idea/scripting/gradle/utils.kt | 15 ------ 9 files changed, 64 insertions(+), 37 deletions(-) diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt index 4e50a87b489..ccc50c982c4 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt @@ -9,12 +9,16 @@ import com.intellij.openapi.externalSystem.service.project.autoimport.AsyncFileC import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.newvfs.events.VFileEvent +import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager -fun addVfsListener(watcher: GradleScriptListener) { +fun addVfsListener( + watcher: GradleScriptListener, + buildRootsManager: GradleBuildRootsManager +) { VirtualFileManager.getInstance().addAsyncFileListener( object : AsyncFileChangeListenerBase() { override fun isRelevant(path: String): Boolean { - return isInAffectedGradleProjectFiles(watcher.project, path) + return buildRootsManager.maybeAffectedGradleProjectFile(path) } override fun updateFile(file: VirtualFile, event: VFileEvent) { diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt.191 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt.191 index 72d756b56c2..97e653c6b62 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt.191 +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt.191 @@ -9,8 +9,12 @@ import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.newvfs.BulkFileListener import com.intellij.openapi.vfs.newvfs.events.VFileEvent import com.intellij.util.concurrency.SequentialTaskExecutor +import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager -fun addVfsListener(watcher: GradleScriptListener) { +fun addVfsListener( + watcher: GradleScriptListener, + buildRootsManager: GradleBuildRootsManager +) { watcher.project.messageBus.connect().subscribe( VirtualFileManager.VFS_CHANGES, object : BulkFileListener { @@ -22,7 +26,7 @@ fun addVfsListener(watcher: GradleScriptListener) { if (watcher.project.isDisposed) return@Runnable for (event in events) { val file = event.file ?: continue - if (isInAffectedGradleProjectFiles(watcher.project, event.path)) { + if (buildRootsManager.maybeAffectedGradleProjectFile(event.path)) { watcher.fileChanged(event.path, file.timeStamp) } } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt.201 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt.201 index dda0beb20c8..1488d07332f 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt.201 +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/AsyncFileChangeListenerHelper.kt.201 @@ -9,12 +9,16 @@ import com.intellij.openapi.externalSystem.autoimport.AsyncFileChangeListenerBas import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.newvfs.events.VFileEvent +import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager -fun addVfsListener(watcher: GradleScriptListener) { +fun addVfsListener( + watcher: GradleScriptListener, + buildRootsManager: GradleBuildRootsManager +) { VirtualFileManager.getInstance().addAsyncFileListener( object : AsyncFileChangeListenerBase() { override fun isRelevant(path: String): Boolean { - return isInAffectedGradleProjectFiles(watcher.project, path) + return buildRootsManager.maybeAffectedGradleProjectFile(path) } override fun updateFile(file: VirtualFile, event: VFileEvent) { 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 e2f4babac91..d14921422eb 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 @@ -18,7 +18,7 @@ class GradleScriptListener(project: Project) : ScriptChangeListener(project) { init { // listen changes using VFS events, including gradle-configuration related files - addVfsListener(this) + addVfsListener(this, buildRootsManager) } fun fileChanged(filePath: String, ts: Long) = diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/legacy/GradleLegacyScriptConfigurationLoader.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/legacy/GradleLegacyScriptConfigurationLoader.kt index f4fcffc11db..f3429e70cb0 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/legacy/GradleLegacyScriptConfigurationLoader.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/legacy/GradleLegacyScriptConfigurationLoader.kt @@ -17,7 +17,7 @@ import org.jetbrains.kotlin.idea.core.script.configuration.loader.ScriptConfigur import org.jetbrains.kotlin.idea.core.util.EDT import org.jetbrains.kotlin.idea.scripting.gradle.getGradleScriptInputsStamp import org.jetbrains.kotlin.idea.scripting.gradle.isGradleKotlinScript -import org.jetbrains.kotlin.idea.scripting.gradle.isInAffectedGradleProjectFiles +import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager import org.jetbrains.kotlin.idea.scripting.gradle.useScriptConfigurationFromImportOnly import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.psi.KtFile @@ -58,6 +58,8 @@ class GradleLegacyScriptConfigurationLoaderForOutOfProjectScripts(project: Proje * TODO(gradle6): remove */ class GradleLegacyScriptConfigurationLoader(project: Project) : DefaultScriptConfigurationLoader(project) { + private val buildRootsManager = GradleBuildRootsManager.getInstance(project) + override fun shouldRunInBackground(scriptDefinition: ScriptDefinition): Boolean { return if (useScriptConfigurationFromImportOnly()) false else super.shouldRunInBackground(scriptDefinition) } @@ -78,7 +80,7 @@ class GradleLegacyScriptConfigurationLoader(project: Project) : DefaultScriptCon return true } - if (!isInAffectedGradleProjectFiles(ktFile.project, vFile.path)) { + if (!buildRootsManager.isAffectedGradleProjectFile(vFile.path)) { ScriptConfigurationManager.markFileWithManualConfigurationLoading(vFile) return true } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/legacy/GradleLegacyScriptListener.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/legacy/GradleLegacyScriptListener.kt index 3573026a1c1..dd6a1bbb31b 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/legacy/GradleLegacyScriptListener.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/legacy/GradleLegacyScriptListener.kt @@ -9,13 +9,13 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptChangeListener import org.jetbrains.kotlin.idea.scripting.gradle.isGradleKotlinScript -import org.jetbrains.kotlin.idea.scripting.gradle.isInAffectedGradleProjectFiles import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager -import org.jetbrains.kotlin.idea.scripting.gradle.useScriptConfigurationFromImportOnly // called from GradleScriptListener // todo(gradle6): remove class GradleLegacyScriptListener(project: Project) : ScriptChangeListener(project) { + private val buildRootsManager = GradleBuildRootsManager.getInstance(project) + override fun isApplicable(vFile: VirtualFile) = isGradleKotlinScript(vFile) @@ -26,7 +26,7 @@ class GradleLegacyScriptListener(project: Project) : ScriptChangeListener(projec checkUpToDate(vFile) private fun checkUpToDate(vFile: VirtualFile) { - if (!isInAffectedGradleProjectFiles(project, vFile.path)) return + if (!buildRootsManager.isAffectedGradleProjectFile(vFile.path)) return val file = getAnalyzableKtFileForScript(vFile) if (file != null) { 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 dbb5fc79b65..81a1436d222 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 @@ -27,7 +27,7 @@ class GradleBuildRootIndex { } @Synchronized - fun getBuildRoot(dir: String) = byWorkingDir[dir] + fun getBuildByRootDir(dir: String) = byWorkingDir[dir] @Synchronized fun findNearestRoot(path: String): GradleBuildRoot.Linked? { 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 928edaae3f2..c2be5aa6b0a 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 @@ -26,12 +26,12 @@ import org.jetbrains.kotlin.idea.scripting.gradle.* import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslGradleBuildSync import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance +import org.jetbrains.kotlin.utils.addToStdlib.lastIndexOfOrNull import org.jetbrains.plugins.gradle.config.GradleSettingsListenerAdapter import org.jetbrains.plugins.gradle.settings.* import org.jetbrains.plugins.gradle.util.GradleConstants import java.io.File import java.nio.file.Paths -import java.util.concurrent.CompletableFuture import java.util.concurrent.atomic.AtomicBoolean /** @@ -119,6 +119,39 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport.Provider( fun findScriptBuildRoot(gradleKtsFile: VirtualFile): ScriptUnderRoot? = findScriptBuildRoot(gradleKtsFile.path) + /** + * Fast method that can return false positive + */ + fun maybeAffectedGradleProjectFile(filePath: String): Boolean = + 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") + + fun isAffectedGradleProjectFile(filePath: String): Boolean = + findAffectedFileRoot(filePath) != null + + fun fileChanged(filePath: String, ts: Long = System.currentTimeMillis()) { + findAffectedFileRoot(filePath)?.fileChanged(filePath, ts) + } + + private fun findAffectedFileRoot(filePath: String): GradleBuildRoot.Linked? { + if (filePath.endsWith("/gradle.properties") || + filePath.endsWith("/gradle.local") + ) { + return roots.getBuildByProjectDir(filePath.substringBeforeLast("/")) + } else if (filePath.endsWith("/gradle-wrapper.properties")) { + val gradleWrapperDirIndex = filePath.lastIndexOfOrNull('/') ?: return null + val gradleDirIndex = filePath.lastIndexOfOrNull('/', gradleWrapperDirIndex) ?: return null + val buildDirIndex = filePath.lastIndexOfOrNull('/', gradleDirIndex) ?: return null + return roots.getBuildByRootDir(filePath.substring(0, buildDirIndex)) + } + + return findScriptBuildRoot(filePath, searchNearestLegacy = false)?.root as? GradleBuildRoot.Linked + } + private fun findScriptBuildRoot(filePath: String, searchNearestLegacy: Boolean = true): ScriptUnderRoot? { if (!filePath.endsWith(".gradle.kts")) return null @@ -151,12 +184,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport.Provider( roots.getBuildByProjectDir(localPath) != null fun getBuildRoot(gradleWorkingDir: String) = - roots.getBuildRoot(gradleWorkingDir) - - fun fileChanged(filePath: String, ts: Long = System.currentTimeMillis()) { - val root = findScriptBuildRoot(filePath, searchNearestLegacy = false)?.root as? GradleBuildRoot.Linked - root?.fileChanged(filePath, ts) - } + roots.getBuildByRootDir(gradleWorkingDir) fun markImportingInProgress(workingDir: String, inProgress: Boolean = true) { actualizeBuildRoot(workingDir)?.importing = inProgress @@ -167,7 +195,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport.Provider( fun update(build: KotlinDslGradleBuildSync) { // fast path for linked gradle builds without .gradle.kts support if (build.models.isEmpty()) { - val root = roots.getBuildRoot(build.workingDir) ?: return + val root = roots.getBuildByRootDir(build.workingDir) ?: return if (root is GradleBuildRoot.Imported && root.data.models.isEmpty()) return } @@ -256,7 +284,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport.Provider( */ private fun actualizeBuildRoot(workingDir: String): GradleBuildRoot.Linked? { val actualSettings = getGradleProjectSettings(workingDir) - val buildRoot = roots.getBuildRoot(workingDir) + val buildRoot = roots.getBuildByRootDir(workingDir) return when { buildRoot != null -> when { diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/utils.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/utils.kt index 5d7304e4d9a..aae6c0e1bc0 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/utils.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/utils.kt @@ -29,21 +29,6 @@ private val sections = arrayListOf("buildscript", "plugins", "initscript", "plug fun isGradleKotlinScript(virtualFile: VirtualFile) = virtualFile.name.endsWith(".gradle.kts") -fun isInAffectedGradleProjectFiles(project: Project, filePath: String): Boolean { - if (filePath.endsWith("/gradle.properties")) return true - if (filePath.endsWith("/gradle-wrapper.properties")) return true - - if (filePath.endsWith(".gradle") || filePath.endsWith(".gradle.kts")) { - if (ApplicationManager.getApplication().isUnitTestModeWithoutAffectedGradleProjectFilesCheck) { - return true - } - - return GradleBuildRootsManager.getInstance(project).isUnderProjectDir(filePath.substringBeforeLast("/")) - } - - return false -} - fun getGradleScriptInputsStamp( project: Project, file: VirtualFile,