From 48a8618952060737f7e5cb05195c919c9a199f3d Mon Sep 17 00:00:00 2001 From: Mariano De Achaval Date: Mon, 12 Aug 2024 13:35:02 -0300 Subject: [PATCH] Fixing executing things on the right thread --- .../dw/annotator/WeaveValidatorAnnotator.java | 9 ++- .../lang/dw/preview/InputsComponent.java | 48 +++++++++------ .../dw/preview/PreviewToolWindowPanel.java | 13 +++- .../dw/preview/WeavePreviewComponent.java | 59 ++++++++++++------- .../dw/service/agent/WeaveAgentService.java | 12 ++-- 5 files changed, 89 insertions(+), 52 deletions(-) diff --git a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/annotator/WeaveValidatorAnnotator.java b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/annotator/WeaveValidatorAnnotator.java index a443be66..d6f0cfe7 100644 --- a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/annotator/WeaveValidatorAnnotator.java +++ b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/annotator/WeaveValidatorAnnotator.java @@ -1,7 +1,7 @@ package org.mule.tooling.lang.dw.annotator; import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.lang.annotation.Annotation; +import com.intellij.lang.annotation.AnnotationBuilder; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.ExternalAnnotator; import com.intellij.lang.annotation.HighlightSeverity; @@ -88,11 +88,14 @@ public void apply(@NotNull AnnotationHolder holder, ValidationMessage[] errorMes final WeaveLocation location = validationMessage.location(); final int startIndex = getValidIndex(location.startPosition()); final int endIndex = getValidIndex(location.endPosition()); - final Annotation annotation = holder.createAnnotation(severity, new TextRange(startIndex, endIndex), validationMessage.message().message(), WeaveToolingService.toHtml(validationMessage.message().message())); + @NotNull AnnotationBuilder annotationBuilder = holder.newAnnotation(severity, validationMessage.message().message()) + .range(new TextRange(startIndex, endIndex)) + .tooltip(WeaveToolingService.toHtml(validationMessage.message().message())); final QuickFix[] quickFixes = validationMessage.quickFix(); for (QuickFix quickFix : quickFixes) { - annotation.registerFix(new WeaveIntentionAction(quickFix)); + annotationBuilder = annotationBuilder.withFix(new WeaveIntentionAction(quickFix)); } + annotationBuilder.create(); } } diff --git a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/InputsComponent.java b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/InputsComponent.java index 77345652..5edf8aee 100644 --- a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/InputsComponent.java +++ b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/InputsComponent.java @@ -2,6 +2,7 @@ import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; @@ -13,13 +14,17 @@ import com.intellij.psi.PsiManager; import com.intellij.ui.JBTabsPaneImpl; import com.intellij.ui.tabs.TabInfo; +import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.ui.components.BorderLayoutPanel; import org.jetbrains.annotations.NotNull; +import org.jetbrains.concurrency.CancellablePromise; import javax.swing.*; import java.util.ArrayList; import java.util.List; +import static com.intellij.openapi.application.ReadAction.nonBlocking; + public class InputsComponent implements Disposable { private List editors = new ArrayList<>(); @@ -49,26 +54,33 @@ private JComponent createInputsPanel() { public void loadInputFiles(VirtualFile inputsFolder) { closeAllInputs(); - List children = VfsUtil.collectChildrenRecursively(inputsFolder); - for (VirtualFile input : children) { - if (input.isDirectory()) { - continue; - } - PsiFile file = PsiManager.getInstance(myProject).findFile(input); - if (file == null) { - continue; + CancellablePromise> documents = nonBlocking(() -> { + List children = VfsUtil.collectChildrenRecursively(inputsFolder); + return children.stream().map((input) -> { + if (input.isDirectory()) { + return null; + } + return PsiManager.getInstance(myProject).findFile(input); + }).toList(); + }).submit(AppExecutorUtil.getAppExecutorService()); + documents.onSuccess((documentList) -> { + for (PsiFile file : documentList) { + if (file != null) { + final VirtualFile input = file.getVirtualFile(); + final Document document = file.getViewProvider().getDocument(); + if (document != null) { + ApplicationManager.getApplication().invokeLater(() -> { + Editor editor = EditorFactory.getInstance().createEditor(document, myProject, input, false); + editors.add(editor); + TabInfo tabInfo = createTabInfo(inputsFolder, input, file, editor); + inputTabs.getTabs().addTab(tabInfo); + inputTabs.setSelectedIndex(0); + }); + } + } } + }); - Document document = file.getViewProvider().getDocument(); - if (document == null) { - continue; - } - Editor editor = EditorFactory.getInstance().createEditor(document, myProject, input, false); - editors.add(editor); - TabInfo tabInfo = createTabInfo(inputsFolder, input, file, editor); - inputTabs.getTabs().addTab(tabInfo); - inputTabs.setSelectedIndex(0); - } } @NotNull diff --git a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/PreviewToolWindowPanel.java b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/PreviewToolWindowPanel.java index a5b991a0..6f706ce8 100644 --- a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/PreviewToolWindowPanel.java +++ b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/PreviewToolWindowPanel.java @@ -95,7 +95,11 @@ public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile f final PsiFile psiFile = file.isValid() ? PsiManager.getInstance(myProject).findFile(file) : null; // This invokeLater is required. The problem is open does a commit to PSI, but open is // invoked inside PSI change event. It causes an Exception like "Changes to PSI are not allowed inside event processing" - DumbService.getInstance(myProject).smartInvokeLater(() -> setFile(psiFile)); + DumbService.getInstance(myProject).smartInvokeLater(() -> { + ApplicationManager.getApplication().invokeLater(() -> { + setFile(psiFile); + }); + }); } } @@ -141,7 +145,12 @@ private void showFile(@NotNull FileEditorManagerEvent e) { final PsiFile psiFile = ReadAction.compute(() -> file != null && file.isValid() ? PsiManager.getInstance(myProject).findFile(file) : null); // This invokeLater is required. The problem is open does a commit to PSI, but open is // invoked inside PSI change event. It causes an Exception like "Changes to PSI are not allowed inside event processing" - DumbService.getInstance(myProject).smartInvokeLater(() -> setFile(psiFile)); + DumbService.getInstance(myProject).smartInvokeLater(() -> { + ApplicationManager.getApplication().invokeLater(() -> { + setFile(psiFile); + }); + + }); } } diff --git a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/WeavePreviewComponent.java b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/WeavePreviewComponent.java index fcdd81e5..9366520b 100644 --- a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/WeavePreviewComponent.java +++ b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/preview/WeavePreviewComponent.java @@ -15,12 +15,15 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComponentWithActions; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.ui.content.Content; import com.intellij.util.Alarm; +import com.intellij.util.concurrency.AppExecutorUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.concurrency.CancellablePromise; import org.mule.tooling.lang.dw.WeaveConstants; import org.mule.tooling.lang.dw.WeaveFileType; import org.mule.tooling.lang.dw.parser.psi.WeaveDocument; @@ -44,6 +47,8 @@ import java.util.List; import java.util.Objects; +import static com.intellij.openapi.application.ReadAction.nonBlocking; + public class WeavePreviewComponent implements Disposable { private final Project myProject; @@ -244,18 +249,19 @@ public void open(@Nullable PsiFile psiFile) { WeaveDocument weaveDocument = WeavePsiUtils.getWeaveDocument(psiFile); if (weaveDocument != null) { WeaveRuntimeService instance = getScenariosManager(); - List scenarios = instance.getScenariosFor(weaveDocument); - - if (scenarios.isEmpty()) { - listener.doRunPreviewWithoutScenario(); - } else { - //Load first scenario - Scenario currentScenarioFor = instance.getCurrentScenarioFor(weaveDocument); - if (currentScenarioFor == null) { - return; - } - loadScenario(currentScenarioFor); - } + CancellablePromise selectedFilePromise = nonBlocking(() -> { + return instance.getCurrentScenarioFor(weaveDocument); + }).submit(AppExecutorUtil.getAppExecutorService()); + selectedFilePromise + .onSuccess((currentScenarioFor) -> { + ApplicationManager.getApplication().invokeLater(() -> { + if (currentScenarioFor == null) { + listener.doRunPreviewWithoutScenario(); + } else { + loadScenario(currentScenarioFor); + } + }); + }); } } @@ -275,7 +281,9 @@ public void loadScenario(Scenario scenario) { } else { inputsComponent.closeAllInputs(); } - listener.doRunPreview(); + nonBlocking(() -> { + listener.doRunPreview(); + }).submit(AppExecutorUtil.getAppExecutorService()); } public void clearScenario() { @@ -554,19 +562,26 @@ private class MyRunPreviewCallback implements RunPreviewCallback { @Override public void onPreviewSuccessful(PreviewExecutedSuccessfulEvent result, long duration) { - Scenario scenario = getCurrentScenario(); - final VirtualFile file = getOutputFile(scenario); - outputComponent.onPreviewResult(result, file, duration); - previewLogsViewer.clear(); - previewLogsViewer.logInfo(ScalaUtils.toList(result.messages())); + VirtualFile vFile = ApplicationManager.getApplication().runReadAction((Computable) () -> { + Scenario scenario = getCurrentScenario(); + return getOutputFile(scenario); + }); + + ApplicationManager.getApplication().invokeLater(() -> { + outputComponent.onPreviewResult(result, vFile, duration); + previewLogsViewer.clear(); + previewLogsViewer.logInfo(ScalaUtils.toList(result.messages())); + }); } @Override public void onPreviewFailed(PreviewExecutedFailedEvent message) { - outputComponent.onPreviewResultFailed(); - previewLogsViewer.clear(); - previewLogsViewer.logInfo(ScalaUtils.toList(message.messages())); - previewLogsViewer.logError(message.message()); + ApplicationManager.getApplication().invokeLater(() -> { + outputComponent.onPreviewResultFailed(); + previewLogsViewer.clear(); + previewLogsViewer.logInfo(ScalaUtils.toList(message.messages())); + previewLogsViewer.logError(message.message()); + }); } } diff --git a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/service/agent/WeaveAgentService.java b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/service/agent/WeaveAgentService.java index 30d7c753..b290babb 100644 --- a/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/service/agent/WeaveAgentService.java +++ b/data-weave-plugin/src/main/java/org/mule/tooling/lang/dw/service/agent/WeaveAgentService.java @@ -297,13 +297,11 @@ public void runPreview(String inputsPath, String script, String identifier, Stri @Override public void onPreviewExecuted(PreviewExecutedEvent result) { long duration = System.currentTimeMillis() - startTime; - ApplicationManager.getApplication().invokeLater(() -> { - if (result instanceof PreviewExecutedSuccessfulEvent successfulEvent) { - callback.onPreviewSuccessful(successfulEvent, duration); - } else if (result instanceof PreviewExecutedFailedEvent) { - callback.onPreviewFailed((PreviewExecutedFailedEvent) result); - } - }); + if (result instanceof PreviewExecutedSuccessfulEvent successfulEvent) { + callback.onPreviewSuccessful(successfulEvent, duration); + } else if (result instanceof PreviewExecutedFailedEvent) { + callback.onPreviewFailed((PreviewExecutedFailedEvent) result); + } } @Override