Fix freeze on configure kotlin for the project
#KT-30541 Fixed #KT-36289 Fixed
This commit is contained in:
@@ -73,6 +73,8 @@ configure=Configure
|
||||
kotlin.not.configured=Kotlin not configured
|
||||
there.aren.t.configurators.available=There aren't configurators available
|
||||
all.modules.with.kotlin.files.are.configured=All modules with Kotlin files are configured
|
||||
lookup.project.configurators.progress.text=Looking up for project configurators ...
|
||||
lookup.modules.configurations.progress.text=Looking up for modules configurations ...
|
||||
added.0.requirement.to.module.info.in.1=Added {0} requirement to module-info in {1}
|
||||
updated.javascript.libraries.in.module.0=Updated JavaScript libraries in module {0}
|
||||
added.0.to.library.configuration=Added {0} to library configuration
|
||||
|
||||
+10
-3
@@ -12,6 +12,7 @@ import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.util.PlatformUtils
|
||||
import org.jetbrains.kotlin.idea.KotlinJvmBundle
|
||||
import org.jetbrains.kotlin.idea.configuration.*
|
||||
import org.jetbrains.kotlin.idea.util.ProgressIndicatorUtils.underModalProgress
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
|
||||
import org.jetbrains.kotlin.platform.js.isJs
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
@@ -23,14 +24,20 @@ abstract class ConfigureKotlinInProjectAction : AnAction() {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val project = e.project ?: return
|
||||
|
||||
val modules = getConfigurableModules(project)
|
||||
val (modules, configurators) = underModalProgress(project, KotlinJvmBundle.message("lookup.project.configurators.progress.text")) {
|
||||
val modules = getConfigurableModules(project)
|
||||
if (modules.all(::isModuleConfigured)) {
|
||||
return@underModalProgress modules to emptyList<KotlinProjectConfigurator>()
|
||||
}
|
||||
val configurators = getApplicableConfigurators(project)
|
||||
modules to configurators
|
||||
}
|
||||
|
||||
if (modules.all(::isModuleConfigured)) {
|
||||
Messages.showInfoMessage(KotlinJvmBundle.message("all.modules.with.kotlin.files.are.configured"), e.presentation.text!!)
|
||||
return
|
||||
}
|
||||
|
||||
val configurators = getApplicableConfigurators(project)
|
||||
|
||||
when {
|
||||
configurators.size == 1 -> configurators.first().configure(project, emptyList())
|
||||
configurators.isEmpty() -> Messages.showErrorDialog(
|
||||
|
||||
+10
@@ -5,7 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -28,6 +30,7 @@ import org.jetbrains.kotlin.idea.core.util.getKotlinJvmRuntimeMarkerClass
|
||||
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.effectiveKind
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinAddRequiredModuleFix
|
||||
import org.jetbrains.kotlin.idea.util.application.isUnitTestMode
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.idea.util.findFirstPsiJavaModule
|
||||
import org.jetbrains.kotlin.idea.util.isDev
|
||||
@@ -42,6 +45,8 @@ import org.jetbrains.kotlin.idea.vfilefinder.IDEVirtualFileFinder
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
|
||||
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtils")
|
||||
|
||||
data class RepositoryDescription(val id: String, val name: String, val url: String, val bintrayUrl: String?, val isSnapshot: Boolean)
|
||||
|
||||
const val LAST_SNAPSHOT_VERSION = "1.4-SNAPSHOT"
|
||||
@@ -122,8 +127,13 @@ fun isModuleConfigured(moduleSourceRootGroup: ModuleSourceRootGroup): Boolean {
|
||||
/**
|
||||
* Returns a list of modules which contain sources in Kotlin.
|
||||
* Note that this method is expensive and should not be called more often than strictly necessary.
|
||||
*
|
||||
* DO NOT CALL THIS ON AWT THREAD
|
||||
*/
|
||||
fun getModulesWithKotlinFiles(project: Project): Collection<Module> {
|
||||
if (!isUnitTestMode() && ApplicationManager.getApplication().isDispatchThread) {
|
||||
LOG.error("getModulesWithKotlinFiles could be a heavy operation and should not be call on AWT thread")
|
||||
}
|
||||
if (!runReadAction {
|
||||
!project.isDisposed &&
|
||||
FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project))
|
||||
|
||||
+1
-4
@@ -20,10 +20,7 @@ import kotlin.reflect.KClass
|
||||
|
||||
object ConfigureKotlinNotificationManager : KotlinSingleNotificationManager<ConfigureKotlinNotification> {
|
||||
fun notify(project: Project, excludeModules: List<Module> = emptyList()) {
|
||||
val notificationState = ConfigureKotlinNotification.getNotificationState(project, excludeModules)
|
||||
if (notificationState != null) {
|
||||
notify(project, ConfigureKotlinNotification(project, excludeModules, notificationState))
|
||||
}
|
||||
notify(this, project, excludeModules)
|
||||
}
|
||||
|
||||
fun getVisibleNotifications(project: Project): Array<out ConfigureKotlinNotification> {
|
||||
|
||||
+9
-4
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.idea.facet.toApiVersion
|
||||
import org.jetbrains.kotlin.idea.framework.ui.CreateLibraryDialogWithModules
|
||||
import org.jetbrains.kotlin.idea.framework.ui.FileUIUtils
|
||||
import org.jetbrains.kotlin.idea.quickfix.askUpdateRuntime
|
||||
import org.jetbrains.kotlin.idea.util.ProgressIndicatorUtils.underModalProgress
|
||||
import org.jetbrains.kotlin.idea.util.application.isUnitTestMode
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.sdk
|
||||
import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor
|
||||
@@ -68,10 +70,13 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro
|
||||
val defaultPathToJar = getDefaultPathToJarFile(project)
|
||||
val showPathToJarPanel = needToChooseJarPath(project)
|
||||
|
||||
var nonConfiguredModules = if (!ApplicationManager.getApplication().isUnitTestMode)
|
||||
getCanBeConfiguredModules(project, this)
|
||||
else
|
||||
var nonConfiguredModules = if (!isUnitTestMode()) {
|
||||
underModalProgress(project, KotlinJvmBundle.message("lookup.modules.configurations.progress.text")) {
|
||||
getCanBeConfiguredModules(project, this)
|
||||
}
|
||||
} else {
|
||||
listOf(*ModuleManager.getInstance(project).modules)
|
||||
}
|
||||
nonConfiguredModules -= excludeModules
|
||||
|
||||
var modulesToConfigure = nonConfiguredModules
|
||||
@@ -85,7 +90,7 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro
|
||||
excludeModules
|
||||
)
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode) {
|
||||
if (!isUnitTestMode()) {
|
||||
dialog.show()
|
||||
if (!dialog.isOK) return
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.configuration
|
||||
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.ReadAction.nonBlocking
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.concurrency.AppExecutorUtil
|
||||
import org.jetbrains.kotlin.idea.configuration.ui.notifications.ConfigureKotlinNotification
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
fun notify(manager: ConfigureKotlinNotificationManager, project: Project, excludeModules: List<Module>) {
|
||||
nonBlocking(Callable {
|
||||
ConfigureKotlinNotification.getNotificationState(project, excludeModules)
|
||||
})
|
||||
.expireWith(project)
|
||||
.coalesceBy(manager)
|
||||
.finishOnUiThread(ModalityState.any()) { notificationState ->
|
||||
notificationState?.let {
|
||||
manager.notify(project, ConfigureKotlinNotification(project, excludeModules, it))
|
||||
}
|
||||
}
|
||||
.submit(AppExecutorUtil.getAppExecutorService())
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.configuration
|
||||
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.ReadAction.nonBlocking
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.concurrency.AppExecutorUtil
|
||||
import org.jetbrains.kotlin.idea.configuration.ui.notifications.ConfigureKotlinNotification
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
fun notify(manager: ConfigureKotlinNotificationManager, project: Project, excludeModules: List<Module>) {
|
||||
nonBlocking(Callable {
|
||||
ConfigureKotlinNotification.getNotificationState(project, excludeModules)
|
||||
})
|
||||
.expireWith(project)
|
||||
.finishOnUiThread(ModalityState.any()) { notificationState ->
|
||||
notificationState?.let {
|
||||
manager.notify(project, ConfigureKotlinNotification(project, excludeModules, it))
|
||||
}
|
||||
}
|
||||
.submit(AppExecutorUtil.getAppExecutorService())
|
||||
}
|
||||
+2
-3
@@ -22,7 +22,6 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.MessageType
|
||||
import com.intellij.openapi.ui.popup.Balloon
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||
import com.intellij.ui.awt.RelativePoint
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
@@ -61,9 +60,9 @@ class ExtractionEngine(
|
||||
val project = extractionData.project
|
||||
|
||||
val adjustExtractionData = helper.adjustExtractionData(extractionData)
|
||||
val analysisResult = ProgressIndicatorUtils.underModalProgress(project, "Analyze extraction data...", Computable {
|
||||
val analysisResult = ProgressIndicatorUtils.underModalProgress(project, "Analyze extraction data...") {
|
||||
adjustExtractionData.performAnalysis()
|
||||
})
|
||||
}
|
||||
|
||||
if (ApplicationManager.getApplication()!!.isUnitTestMode && analysisResult.status != AnalysisResult.Status.SUCCESS) {
|
||||
throw BaseRefactoringProcessor.ConflictsInTestsException(analysisResult.messages.map { it.renderMessage() })
|
||||
|
||||
@@ -78,6 +78,7 @@ import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper
|
||||
import org.jetbrains.kotlin.idea.refactoring.rename.canonicalRender
|
||||
import org.jetbrains.kotlin.idea.roots.isOutsideKotlinAwareSourceRoot
|
||||
import org.jetbrains.kotlin.idea.util.*
|
||||
import org.jetbrains.kotlin.idea.util.ProgressIndicatorUtils.underModalProgress
|
||||
import org.jetbrains.kotlin.idea.util.string.collapseSpaces
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.OVERRIDE_KEYWORD
|
||||
@@ -859,31 +860,31 @@ fun checkSuperMethods(
|
||||
val project = declaration.project
|
||||
|
||||
val (declarationDescriptor, overriddenElementsToDescriptor) =
|
||||
ProgressIndicatorUtils.underModalProgress(
|
||||
underModalProgress(
|
||||
project,
|
||||
KotlinBundle.message("find.usages.progress.text.declaration.superMethods"),
|
||||
Computable {
|
||||
val declarationDescriptor = declaration.unsafeResolveToDescriptor() as CallableDescriptor
|
||||
KotlinBundle.message("find.usages.progress.text.declaration.superMethods"))
|
||||
{
|
||||
val declarationDescriptor = declaration.unsafeResolveToDescriptor() as CallableDescriptor
|
||||
|
||||
if (declarationDescriptor is LocalVariableDescriptor) return@Computable (declarationDescriptor to emptyMap<PsiElement, CallableDescriptor>())
|
||||
if (declarationDescriptor is LocalVariableDescriptor) return@underModalProgress (declarationDescriptor to emptyMap<PsiElement, CallableDescriptor>())
|
||||
|
||||
val overriddenElementsToDescriptor = HashMap<PsiElement, CallableDescriptor>()
|
||||
for (overriddenDescriptor in DescriptorUtils.getAllOverriddenDescriptors(
|
||||
declarationDescriptor
|
||||
)) {
|
||||
val overriddenDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(
|
||||
project,
|
||||
overriddenDescriptor
|
||||
) ?: continue
|
||||
if (overriddenDeclaration is KtNamedFunction || overriddenDeclaration is KtProperty || overriddenDeclaration is PsiMethod || overriddenDeclaration is KtParameter) {
|
||||
overriddenElementsToDescriptor[overriddenDeclaration] = overriddenDescriptor
|
||||
}
|
||||
val overriddenElementsToDescriptor = HashMap<PsiElement, CallableDescriptor>()
|
||||
for (overriddenDescriptor in DescriptorUtils.getAllOverriddenDescriptors(
|
||||
declarationDescriptor
|
||||
)) {
|
||||
val overriddenDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(
|
||||
project,
|
||||
overriddenDescriptor
|
||||
) ?: continue
|
||||
if (overriddenDeclaration is KtNamedFunction || overriddenDeclaration is KtProperty || overriddenDeclaration is PsiMethod || overriddenDeclaration is KtParameter) {
|
||||
overriddenElementsToDescriptor[overriddenDeclaration] = overriddenDescriptor
|
||||
}
|
||||
if (ignore != null) {
|
||||
overriddenElementsToDescriptor.keys.removeAll(ignore)
|
||||
}
|
||||
(declarationDescriptor to overriddenElementsToDescriptor)
|
||||
})
|
||||
}
|
||||
if (ignore != null) {
|
||||
overriddenElementsToDescriptor.keys.removeAll(ignore)
|
||||
}
|
||||
(declarationDescriptor to overriddenElementsToDescriptor)
|
||||
}
|
||||
|
||||
if (overriddenElementsToDescriptor.isEmpty()) return listOf(declaration)
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.util.ExceptionUtil
|
||||
import org.jetbrains.annotations.Nls
|
||||
import java.util.concurrent.CancellationException
|
||||
@@ -25,7 +24,7 @@ object ProgressIndicatorUtils {
|
||||
fun <T> underModalProgress(
|
||||
project: Project,
|
||||
@Nls progressTitle: String,
|
||||
computable: Computable<T>
|
||||
computable: () -> T
|
||||
): T = com.intellij.openapi.actionSystem.ex.ActionUtil.underModalProgress(project, progressTitle, computable)
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -25,12 +25,12 @@ object ProgressIndicatorUtils {
|
||||
fun <T> underModalProgress(
|
||||
project: Project,
|
||||
@Nls progressTitle: String,
|
||||
computable: Computable<T>
|
||||
computable: () -> T
|
||||
): T {
|
||||
val dumbService = DumbService.getInstance(project)
|
||||
val useAlternativeResolve = dumbService.isAlternativeResolveEnabled
|
||||
val inReadAction =
|
||||
ThrowableComputable<T, RuntimeException> { runReadAction { return@runReadAction computable.compute() } }
|
||||
ThrowableComputable<T, RuntimeException> { runReadAction { return@runReadAction computable() } }
|
||||
val process =
|
||||
if (useAlternativeResolve) ThrowableComputable { dumbService.computeWithAlternativeResolveEnabled(inReadAction) } else inReadAction
|
||||
return ProgressManager.getInstance().runProcessWithProgressSynchronously(process, progressTitle, true, project)
|
||||
|
||||
@@ -25,12 +25,12 @@ object ProgressIndicatorUtils {
|
||||
fun <T> underModalProgress(
|
||||
project: Project,
|
||||
@Nls progressTitle: String,
|
||||
computable: Computable<T>
|
||||
computable: () -> T
|
||||
): T {
|
||||
val dumbService = DumbService.getInstance(project)
|
||||
val useAlternativeResolve = dumbService.isAlternativeResolveEnabled
|
||||
val inReadAction =
|
||||
ThrowableComputable<T, RuntimeException> { runReadAction { return@runReadAction computable.compute() } }
|
||||
ThrowableComputable<T, RuntimeException> { runReadAction { return@runReadAction computable() } }
|
||||
val prioritizedRunnable =
|
||||
ThrowableComputable<T, RuntimeException> { ProgressManager.getInstance().computePrioritized(inReadAction) }
|
||||
val process =
|
||||
|
||||
Reference in New Issue
Block a user