mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
update editor highlighters on VFS changes asynchronously (IDEA-167482)
This commit is contained in:
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.fileEditor.impl.text;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
|
||||
import com.intellij.openapi.progress.util.ReadTask;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class AsyncHighlighterUpdater extends ReadTask {
|
||||
private static final ExecutorService ourExecutor = AppExecutorUtil.createBoundedApplicationPoolExecutor("AsyncEditorLoader pool", 2);
|
||||
private static final Set<Future<?>> ourHighlighterFutures = ContainerUtil.newConcurrentSet();
|
||||
private final Project myProject;
|
||||
private final Editor myEditor;
|
||||
private final VirtualFile myFile;
|
||||
|
||||
private AsyncHighlighterUpdater(Project project, Editor editor, VirtualFile file) {
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
myFile = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Continuation performInReadAction(@NotNull ProgressIndicator indicator) throws ProcessCanceledException {
|
||||
if (!isEverythingValid()) return null;
|
||||
|
||||
EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, myFile);
|
||||
return new Continuation(() -> ((EditorEx)myEditor).setHighlighter(highlighter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled(@NotNull ProgressIndicator indicator) {
|
||||
updateHighlighters(myProject, myEditor, myFile);
|
||||
}
|
||||
|
||||
private boolean isEverythingValid() {
|
||||
return !myProject.isDisposed() && !myEditor.isDisposed() && myFile.isValid();
|
||||
}
|
||||
|
||||
public static void updateHighlighters(@NotNull Project project, @NotNull Editor editor, @NotNull VirtualFile file) {
|
||||
AsyncHighlighterUpdater task = new AsyncHighlighterUpdater(project, editor, file);
|
||||
if (task.isEverythingValid()) {
|
||||
CompletableFuture<?> future = ProgressIndicatorUtils.scheduleWithWriteActionPriority(ourExecutor, task);
|
||||
ourHighlighterFutures.add(future);
|
||||
future.whenComplete((a, b) -> ourHighlighterFutures.remove(future));
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static void completeAsyncTasks() {
|
||||
assert !ApplicationManager.getApplication().isWriteAccessAllowed();
|
||||
for (Future<?> future : ourHighlighterFutures) {
|
||||
try {
|
||||
future.get();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
}
|
||||
}
|
||||
+1
-4
@@ -27,8 +27,6 @@ import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.EditorMarkupModel;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
@@ -239,8 +237,7 @@ class TextEditorComponent extends JBLoadingPanel implements DataProvider {
|
||||
*/
|
||||
private void updateHighlighters(){
|
||||
if (!myProject.isDisposed() && !myEditor.isDisposed()) {
|
||||
final EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, myFile);
|
||||
((EditorEx)myEditor).setHighlighter(highlighter);
|
||||
AsyncHighlighterUpdater.updateHighlighters(myProject, myEditor, myFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-7
@@ -34,7 +34,6 @@ import org.jetbrains.ide.PooledThreadExecutor;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
@@ -64,7 +63,7 @@ public class ProgressIndicatorUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Future<?> submitWithWriteActionPriority(@NotNull ReadTask task) {
|
||||
public static CompletableFuture<?> submitWithWriteActionPriority(@NotNull ReadTask task) {
|
||||
return scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task);
|
||||
}
|
||||
|
||||
@@ -73,12 +72,12 @@ public class ProgressIndicatorUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Future<?> scheduleWithWriteActionPriority(@NotNull ProgressIndicator progressIndicator, @NotNull ReadTask readTask) {
|
||||
public static CompletableFuture<?> scheduleWithWriteActionPriority(@NotNull ProgressIndicator progressIndicator, @NotNull ReadTask readTask) {
|
||||
return scheduleWithWriteActionPriority(progressIndicator, PooledThreadExecutor.INSTANCE, readTask);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Future<?> scheduleWithWriteActionPriority(@NotNull Executor executor, @NotNull ReadTask task) {
|
||||
public static CompletableFuture<?> scheduleWithWriteActionPriority(@NotNull Executor executor, @NotNull ReadTask task) {
|
||||
return scheduleWithWriteActionPriority(new ProgressIndicatorBase(), executor, task);
|
||||
}
|
||||
|
||||
@@ -159,9 +158,9 @@ public class ProgressIndicatorUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Future<?> scheduleWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator,
|
||||
@NotNull final Executor executor,
|
||||
@NotNull final ReadTask readTask) {
|
||||
public static CompletableFuture<?> scheduleWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator,
|
||||
@NotNull final Executor executor,
|
||||
@NotNull final ReadTask readTask) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
// invoke later even if on EDT
|
||||
// to avoid tasks eagerly restarting immediately, allocating many pooled threads
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.intellij.openapi.command.undo.DocumentReferenceManager;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.impl.text.AsyncHighlighterUpdater;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl;
|
||||
import com.intellij.openapi.module.EmptyModuleType;
|
||||
@@ -393,6 +394,8 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
((PsiManagerImpl)PsiManager.getInstance(defaultProject)).cleanupForNextTest();
|
||||
}
|
||||
|
||||
AsyncHighlighterUpdater.completeAsyncTasks();
|
||||
|
||||
((FileBasedIndexImpl) FileBasedIndex.getInstance()).cleanupForNextTest();
|
||||
|
||||
LocalFileSystemImpl localFileSystem = (LocalFileSystemImpl)LocalFileSystem.getInstance();
|
||||
|
||||
Reference in New Issue
Block a user