New J2K: do not call custom diagnostic fixes in EDT as they may have resolve inside

This commit is contained in:
Ilya Kirillov
2020-02-18 15:34:30 +03:00
parent 810966e408
commit 17a0e3a078
2 changed files with 19 additions and 15 deletions
@@ -11,7 +11,6 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.util.range
import org.jetbrains.kotlin.idea.quickfix.AddExclExclCallFix
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
@@ -36,17 +35,20 @@ class DiagnosticBasedPostProcessingGroup(diagnosticBasedProcessings: List<Diagno
}
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
val resolutionFacade = runReadAction { KotlinCacheService.getInstance(converterContext.project).getResolutionFacade(allFiles) }
val diagnostics = runReadAction { analyzeFileRange(file, rangeMarker, resolutionFacade).all() }
runUndoTransparentActionInEdt(inWriteAction = true) {
for (diagnostic in diagnostics) {
val diagnostics = runReadAction {
val resolutionFacade = KotlinCacheService.getInstance(converterContext.project).getResolutionFacade(allFiles)
analyzeFileRange(file, rangeMarker, resolutionFacade).all()
}
for (diagnostic in diagnostics) {
val elementIsInRange = runReadAction {
val range = rangeMarker?.range ?: file.textRange
if (diagnostic.psiElement.isInRange(range)) {
diagnosticToFix[diagnostic.factory]?.forEach { fix ->
if (diagnostic.psiElement.isValid) {
fix(diagnostic)
}
}
diagnostic.psiElement.isInRange(range)
}
if (!elementIsInRange) continue
diagnosticToFix[diagnostic.factory]?.forEach { fix ->
val elementIsValid = runReadAction { diagnostic.psiElement.isValid }
if (elementIsValid) {
fix(diagnostic)
}
}
}
@@ -78,7 +80,7 @@ inline fun <reified T : PsiElement> diagnosticBasedProcessing(
override val diagnosticFactories = diagnosticFactory.toList()
override fun fix(diagnostic: Diagnostic) {
val element = diagnostic.psiElement as? T
if (element != null) {
if (element != null) runUndoTransparentActionInEdt(inWriteAction = true) {
fix(element, diagnostic)
}
}
@@ -88,8 +90,10 @@ fun diagnosticBasedProcessing(fixFactory: KotlinIntentionActionsFactory, vararg
object : DiagnosticBasedProcessing {
override val diagnosticFactories = diagnosticFactory.toList()
override fun fix(diagnostic: Diagnostic) {
val fix = fixFactory.createActions(diagnostic).singleOrNull()
fix?.invoke(diagnostic.psiElement.project, null, diagnostic.psiFile)
val fix = runReadAction { fixFactory.createActions(diagnostic).singleOrNull() } ?: return
runUndoTransparentActionInEdt(inWriteAction = true) {
fix.invoke(diagnostic.psiElement.project, null, diagnostic.psiFile)
}
}
}
@@ -83,7 +83,7 @@ inline fun <reified T : PsiElement> List<PsiElement>.descendantsOfType(): List<T
fun PsiElement.isInRange(outerRange: TextRange) =
outerRange.contains(range)
internal fun runUndoTransparentActionInEdt(inWriteAction: Boolean, action: () -> Unit) {
fun runUndoTransparentActionInEdt(inWriteAction: Boolean, action: () -> Unit) {
ApplicationManager.getApplication().invokeAndWait {
CommandProcessor.getInstance().runUndoTransparentAction {
if (inWriteAction) {