diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewComputable.kt b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewComputable.kt index 3b86475b48a1..c646af456b85 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewComputable.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewComputable.kt @@ -12,10 +12,8 @@ import com.intellij.diff.fragments.LineFragment import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.EditorFactory -import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.progress.DumbProgressIndicator import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProgressManager @@ -26,26 +24,17 @@ import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiFile import com.intellij.psi.PsiFileFactory -class IntentionPreviewComputable(private val originalFile: PsiFile, - private val project: Project, +class IntentionPreviewComputable(private val project: Project, + private val action: IntentionAction, + private val originalFile: PsiFile, private val originalEditor: Editor, - private val action: IntentionAction) : Computable>?> { - private val LOG = Logger.getInstance(IntentionPreviewComputable::class.java) - + private val psiFileCopy: PsiFile, + private val editorCopy: Editor + ) : Computable>?> { override fun compute(): Pair>? { - ProgressManager.checkCanceled() - val psiFileCopy = ApplicationManager.getApplication().runReadAction(Computable { nonPhysicalPsiCopy(originalFile, project) }) - ProgressManager.checkCanceled() - val documentCopy = ApplicationManager.getApplication().runReadAction( - Computable { FileDocumentManager.getInstance().getDocument(psiFileCopy.viewProvider.virtualFile) }) - if (documentCopy == null) return null - CommandProcessor.getInstance().runUndoTransparentAction(Runnable { try { - ApplicationManager.getApplication().runReadAction(ThrowableComputable { - val editorCopy = EditorFactory.getInstance().createEditor(documentCopy, project) - .also { it.caretModel.moveToOffset(originalEditor.caretModel.offset) } - + ApplicationManager.getApplication().runReadAction(ThrowableComputable { val actionWithTextCachingCopy = intentionActionWithTextCaching(editorCopy, psiFileCopy) if (actionWithTextCachingCopy == null) return@ThrowableComputable @@ -65,7 +54,7 @@ class IntentionPreviewComputable(private val originalFile: PsiFile, } catch (e: Exception) { LOG.warn("There are exceptions on invocation the intention: '${action.text}' on a copy of the file.", e) - throw ProcessCanceledException() + throw ProcessCanceledException(e) } }) @@ -98,4 +87,8 @@ class IntentionPreviewComputable(private val originalFile: PsiFile, .plus(cachedIntentions.intentions) .plus(cachedIntentions.inspectionFixes) .plus(cachedIntentions.errorFixes) + + companion object { + private val LOG = Logger.getInstance(IntentionPreviewComputable::class.java) + } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewPopupUpdateProcessor.kt b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewPopupUpdateProcessor.kt index 2e72419ab030..55c2774b6602 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewPopupUpdateProcessor.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewPopupUpdateProcessor.kt @@ -3,14 +3,18 @@ package com.intellij.codeInsight.intention.impl.preview import com.intellij.codeInsight.CodeInsightBundle import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.codeInsight.intention.impl.CachedIntentions +import com.intellij.codeInsight.intention.impl.IntentionActionWithTextCaching import com.intellij.codeInsight.intention.impl.IntentionHintComponent import com.intellij.codeInsight.intention.impl.preview.IntentionPreviewComponent.Companion.LOADING_PREVIEW import com.intellij.codeInsight.intention.impl.preview.IntentionPreviewComponent.Companion.NO_PREVIEW import com.intellij.diff.fragments.LineFragment import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.editor.ex.EditorEx +import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.progress.EmptyProgressIndicator import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProgressIndicator @@ -18,7 +22,9 @@ import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.openapi.ui.popup.JBPopup import com.intellij.openapi.ui.popup.JBPopupFactory +import com.intellij.openapi.util.Computable import com.intellij.psi.PsiFile +import com.intellij.psi.PsiFileFactory import com.intellij.ui.popup.PopupPositionManager import com.intellij.ui.popup.PopupUpdateProcessor import com.intellij.util.Alarm @@ -98,11 +104,26 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project, fun start() { component.startLoading() + + ProgressManager.checkCanceled() + val psiFileCopy = ApplicationManager.getApplication().runReadAction(Computable { nonPhysicalPsiCopy(originalFile, project) }) + ProgressManager.checkCanceled() + + val documentCopy = ApplicationManager.getApplication().runReadAction( + Computable { FileDocumentManager.getInstance().getDocument(psiFileCopy.viewProvider.virtualFile) }) + if (documentCopy == null) { + select(NO_PREVIEW) + return + } + + val editorCopy = EditorFactory.getInstance().createEditor(documentCopy, project) + .also { it.caretModel.moveToOffset(originalEditor.caretModel.offset) } + computation = ApplicationManager.getApplication().executeOnPooledThread( Callable { try { - ProgressManager.getInstance().runProcess(IntentionPreviewComputable(originalFile, project, originalEditor, action), - progressIndicator) + ProgressManager.getInstance().runProcess( + IntentionPreviewComputable(project, action, originalFile, originalEditor, psiFileCopy, editorCopy), progressIndicator) } catch (e: ProcessCanceledException) { Pair>(null, emptyList()) @@ -134,6 +155,21 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project, } } + private fun nonPhysicalPsiCopy(psiFile: PsiFile, project: Project): PsiFile { + ProgressManager.checkCanceled() + return PsiFileFactory.getInstance(project).createFileFromText(psiFile.name, + psiFile.language, + psiFile.text, false, true, false, + psiFile.virtualFile) + } + + + fun getFixes(cachedIntentions: CachedIntentions): Sequence = + sequenceOf() + .plus(cachedIntentions.intentions) + .plus(cachedIntentions.inspectionFixes) + .plus(cachedIntentions.errorFixes) + fun toggleShow() { show = !show }