Configure modules Kotlin language settings in a background with a progress

^KT-41936 Fixed
This commit is contained in:
Vladimir Dolzhenko
2020-09-23 09:18:52 +00:00
parent f0cbd6b1a5
commit be20a8bd80
3 changed files with 40 additions and 33 deletions
@@ -86,6 +86,8 @@ can.t.find.library.jar.file.0=Can''t find library JAR file {0}
0.library.was.added.to.module.1={0} library was added to module {1} 0.library.was.added.to.module.1={0} library was added to module {1}
0.library.was.created={0} library was created 0.library.was.created={0} library was created
configure.kotlin=Configure Kotlin configure.kotlin=Configure Kotlin
configure.kotlin.language.settings=Configure Kotlin language settings
configure.kotlin.language.settings.0.module=Configure language settings in module {0}
configure.0.in.1.project.br.2=Configure {0} in ''{1}'' project<br/> {2} configure.0.in.1.project.br.2=Configure {0} in ''{1}'' project<br/> {2}
configure.0.module=''{0}'' module configure.0.module=''{0}'' module
configure.modules=modules configure.modules=modules
@@ -133,7 +133,8 @@ fun getModulesWithKotlinFiles(project: Project): Collection<Module> {
if (!isUnitTestMode() && ApplicationManager.getApplication().isDispatchThread) { if (!isUnitTestMode() && ApplicationManager.getApplication().isDispatchThread) {
LOG.error("getModulesWithKotlinFiles could be a heavy operation and should not be call on AWT thread") LOG.error("getModulesWithKotlinFiles could be a heavy operation and should not be call on AWT thread")
} }
if (!runReadAction {
if (!project.runReadActionInSmartMode {
!project.isDisposed && !project.isDisposed &&
FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project)) FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project))
}) { }) {
@@ -142,7 +143,7 @@ fun getModulesWithKotlinFiles(project: Project): Collection<Module> {
return project.allModules() return project.allModules()
.filter { module -> .filter { module ->
runReadAction { project.runReadActionInSmartMode {
!project.isDisposed && !module.isDisposed !project.isDisposed && !module.isDisposed
&& FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(true)) && FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(true))
} }
@@ -18,23 +18,23 @@ package org.jetbrains.kotlin.idea.configuration.ui
import com.intellij.notification.NotificationDisplayType import com.intellij.notification.NotificationDisplayType
import com.intellij.notification.NotificationsConfiguration import com.intellij.notification.NotificationsConfiguration
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.ReadAction.nonBlocking
import com.intellij.openapi.application.runReadAction import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataImportListener import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataImportListener
import com.intellij.openapi.module.Module import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupActivity import com.intellij.openapi.startup.StartupActivity
import com.intellij.util.concurrency.AppExecutorUtil import com.intellij.psi.search.FileTypeIndex
import org.jetbrains.kotlin.idea.configuration.getModulesWithKotlinFiles import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.KotlinJvmBundle
import org.jetbrains.kotlin.idea.configuration.notifyOutdatedBundledCompilerIfNecessary import org.jetbrains.kotlin.idea.configuration.notifyOutdatedBundledCompilerIfNecessary
import org.jetbrains.kotlin.idea.configuration.ui.notifications.notifyKotlinStyleUpdateIfNeeded import org.jetbrains.kotlin.idea.configuration.ui.notifications.notifyKotlinStyleUpdateIfNeeded
import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies
import org.jetbrains.kotlin.idea.util.application.getServiceSafe import org.jetbrains.kotlin.idea.util.application.getServiceSafe
import org.jetbrains.kotlin.idea.util.application.isUnitTestMode import org.jetbrains.kotlin.idea.util.projectStructure.allModules
import java.util.concurrent.Callable import org.jetbrains.kotlin.idea.util.runReadActionInSmartMode
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
class KotlinConfigurationCheckerStartupActivity : StartupActivity { class KotlinConfigurationCheckerStartupActivity : StartupActivity {
@@ -60,33 +60,37 @@ class KotlinConfigurationCheckerService(val project: Project) {
private val syncDepth = AtomicInteger() private val syncDepth = AtomicInteger()
fun performProjectPostOpenActions() { fun performProjectPostOpenActions() {
val callable = Callable { val task = object : Task.Backgroundable(project, KotlinJvmBundle.message("configure.kotlin.language.settings"), true) {
return@Callable getModulesWithKotlinFiles(project) override fun run(indicator: ProgressIndicator) {
} val anyKotlinFileInProject = project.runReadActionInSmartMode {
!project.isDisposed &&
FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project))
}
if (!anyKotlinFileInProject) return
fun continuation(modulesWithKotlinFiles: Collection<Module>) { val modules = runReadAction {
for (module in modulesWithKotlinFiles) { project.allModules()
ProgressManager.checkCanceled() }
runReadAction {
module.getAndCacheLanguageLevelByDependencies() val totalModules = modules.size
for ((index, module) in modules.withIndex()) {
indicator.fraction = index * 1.0 / totalModules
val anyKotlinFileInModule = project.runReadActionInSmartMode {
!project.isDisposed && !module.isDisposed
&& FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(true))
}
if (anyKotlinFileInModule) {
indicator.text2 = KotlinJvmBundle.message("configure.kotlin.language.settings.0.module", module.name)
runReadAction {
module.getAndCacheLanguageLevelByDependencies()
}
}
} }
} }
} }
ProgressManager.getInstance().run(task)
if (!isUnitTestMode()) {
nonBlocking(callable)
.inSmartMode(project)
.expireWith(project)
.coalesceBy(this)
.finishOnUiThread(ModalityState.any()) { modulesWithKotlinFiles ->
ApplicationManager.getApplication().executeOnPooledThread {
continuation(modulesWithKotlinFiles)
}
}
.submit(AppExecutorUtil.getAppExecutorService())
} else {
continuation(callable.call())
}
} }
val isSyncing: Boolean get() = syncDepth.get() > 0 val isSyncing: Boolean get() = syncDepth.get() > 0