From 6b20885666201934c41b7969a5548c4c6d7a310a Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 31 Aug 2011 16:02:24 +0400 Subject: [PATCH] run injections in background upon commit document + closure friendly API --- .../impl/analysis/HighlightVisitorImpl.java | 4 +- .../com/intellij/openapi/vfs/VfsUtilTest.java | 4 +- .../openapi/vfs/VirtualFilePointerTest.java | 4 +- .../daemon/impl/GeneralHighlightingPass.java | 10 +- .../daemon/impl/LineMarkersPass.java | 4 +- .../daemon/impl/LocalInspectionsPass.java | 14 +-- .../daemon/impl/PassExecutorService.java | 2 +- .../BraceHighlightingHandler.java | 4 +- .../ex/GlobalInspectionContextImpl.java | 4 +- .../ContributorsBasedGotoByModel.java | 8 +- .../psi/impl/DocumentCommitThread.java | 112 ++++++++---------- .../psi/impl/PsiDocumentManagerImpl.java | 85 +++++++------ .../psi/impl/search/PsiSearchHelperImpl.java | 8 +- .../InjectedSelfElementInfo.java | 4 +- .../source/PostprocessReformattingAspect.java | 15 +-- .../injected/InjectedFileViewProvider.java | 4 +- .../injected/InjectedLanguageManagerImpl.java | 108 +++++++++++++++-- .../tree/injected/InjectedLanguageUtil.java | 16 +-- .../src/com/intellij/ui/DeferredIconImpl.java | 4 +- .../src/com/intellij/concurrency/JobUtil.java | 23 ++-- .../DuplicatePropertyInspection.java | 4 +- 21 files changed, 262 insertions(+), 179 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 590814e2f9c3..014b08a4774e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -113,11 +113,11 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } private void registerReferencesFromInjectedFragments(final PsiElement element) { - InjectedLanguageUtil.enumerate(element, myFile, new PsiLanguageInjectionHost.InjectedPsiVisitor() { + InjectedLanguageUtil.enumerate(element, myFile, false, new PsiLanguageInjectionHost.InjectedPsiVisitor() { public void visit(@NotNull final PsiFile injectedPsi, @NotNull final List places) { injectedPsi.accept(REGISTER_REFERENCES_VISITOR); } - }, false); + }); } public boolean analyze(@NotNull final Runnable action, final boolean updateWholeFile, @NotNull final PsiFile file) { diff --git a/java/java-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java b/java/java-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java index 74faaf1ee5e1..c19c44973bba 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java @@ -131,7 +131,7 @@ public class VfsUtilTest extends IdeaTestCase { public void testAsyncRefresh() throws Throwable { final Throwable[] ex = {null}; - JobUtil.invokeConcurrentlyUnderProgress(Arrays.asList(new Object[8]), new Processor() { + JobUtil.invokeConcurrentlyUnderProgress(Arrays.asList(new Object[8]), ProgressManager.getInstance().getProgressIndicator(), false, new Processor() { @Override public boolean process(Object o) { try { @@ -142,7 +142,7 @@ public class VfsUtilTest extends IdeaTestCase { } return true; } - }, false, ProgressManager.getInstance().getProgressIndicator()); + }); if (ex[0] != null) throw ex[0]; } diff --git a/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java b/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java index c916eff11e11..1ce381a69ecc 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java @@ -467,7 +467,7 @@ public class VirtualFilePointerTest extends IdeaTestCase { private static void doit(final VirtualFilePointer pointer) { if (((VirtualFilePointerImpl)pointer).isDisposed()) return; - boolean b = JobUtil.invokeConcurrentlyUnderProgress(Collections.nCopies(10, null), new Processor() { + boolean b = JobUtil.invokeConcurrentlyUnderProgress(Collections.nCopies(10, null), null, false, new Processor() { @Override public boolean process(Object o) { ApplicationManager.getApplication().runReadAction(new Runnable() { @@ -481,7 +481,7 @@ public class VirtualFilePointerTest extends IdeaTestCase { return true; } - }, false, null); + }); assertTrue(b); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java index eb6071c8032d..9a1735cc8973 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java @@ -314,14 +314,14 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP } } }; - if (!JobUtil.invokeConcurrentlyUnderProgress(new ArrayList(hosts), new Processor() { + if (!JobUtil.invokeConcurrentlyUnderProgress(new ArrayList(hosts), progress, false, new Processor() { @Override public boolean process(PsiElement element) { progress.checkCanceled(); - InjectedLanguageUtil.enumerate(element, myFile, visitor, false); + InjectedLanguageUtil.enumerate(element, myFile, false, visitor); return true; } - }, false, progress)) throw new ProcessCanceledException(); + })) throw new ProcessCanceledException(); } // returns false if canceled @@ -332,7 +332,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(myProject); final TextAttributes injectedAttributes = myGlobalScheme.getAttributes(EditorColors.INJECTED_LANGUAGE_FRAGMENT); - return JobUtil.invokeConcurrentlyUnderProgress(new ArrayList(injectedFiles), new Processor() { + return JobUtil.invokeConcurrentlyUnderProgress(new ArrayList(injectedFiles), progress, myFailFastOnAcquireReadAction, new Processor() { public boolean process(final PsiFile injectedPsi) { DocumentWindow documentWindow = (DocumentWindow)PsiDocumentManager.getInstance(myProject).getCachedDocument(injectedPsi); if (documentWindow == null) return true; @@ -383,7 +383,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP } return true; } - }, myFailFastOnAcquireReadAction, progress); + }); } private static TextRange getFixedTextRange(@NotNull DocumentWindow documentWindow, int startOffset) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java index 98f659346fe0..bed7a7534a96 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java @@ -148,11 +148,11 @@ public class LineMarkersPass extends ProgressableTextEditorHighlightingPass impl final Set injectedFiles = new THashSet(); for (PsiElement element : elements) { - InjectedLanguageUtil.enumerate(element, file, new PsiLanguageInjectionHost.InjectedPsiVisitor() { + InjectedLanguageUtil.enumerate(element, file, false, new PsiLanguageInjectionHost.InjectedPsiVisitor() { public void visit(@NotNull final PsiFile injectedPsi, @NotNull List places) { injectedFiles.add(injectedPsi); } - }, false); + }); } for (PsiFile injectedPsi : injectedFiles) { final Project project = injectedPsi.getProject(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index c2c42eabd146..1182317ef41f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -239,7 +239,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass @NotNull final List elements, @NotNull final LocalInspectionToolSession session, @NotNull final List> init) { - boolean result = JobUtil.invokeConcurrentlyUnderProgress(tools, new Processor() { + boolean result = JobUtil.invokeConcurrentlyUnderProgress(tools, indicator, myFailFastOnAcquireReadAction, new Processor() { public boolean process(final LocalInspectionTool tool) { indicator.checkCanceled(); @@ -268,7 +268,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass applyIncrementally[0] = false; // do not apply incrementally outside visible range return true; } - }, myFailFastOnAcquireReadAction, indicator); + }); if (!result) throw new ProcessCanceledException(); inspectInjectedPsi(elements, tools, isOnTheFly, indicator, iManager, true); } @@ -321,7 +321,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass return true; } }; - boolean result = JobUtil.invokeConcurrentlyUnderProgress(init, processor, myFailFastOnAcquireReadAction, indicator); + boolean result = JobUtil.invokeConcurrentlyUnderProgress(init, indicator, myFailFastOnAcquireReadAction, processor); if (!result) { throw new ProcessCanceledException(); } @@ -345,19 +345,19 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass final boolean inVisibleRange) { final Set injected = new THashSet(); for (PsiElement element : elements) { - InjectedLanguageUtil.enumerate(element, myFile, new PsiLanguageInjectionHost.InjectedPsiVisitor() { + InjectedLanguageUtil.enumerate(element, myFile, false, new PsiLanguageInjectionHost.InjectedPsiVisitor() { public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { injected.add(injectedPsi); } - }, false); + }); } if (injected.isEmpty()) return; - if (!JobUtil.invokeConcurrentlyUnderProgress(new ArrayList(injected), new Processor() { + if (!JobUtil.invokeConcurrentlyUnderProgress(new ArrayList(injected), indicator, myFailFastOnAcquireReadAction, new Processor() { public boolean process(final PsiFile injectedPsi) { doInspectInjectedPsi(injectedPsi, tools, onTheFly, indicator, iManager, inVisibleRange); return true; } - }, myFailFastOnAcquireReadAction, indicator)) throw new ProcessCanceledException(); + })) throw new ProcessCanceledException(); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java index fd1810134afa..43a72ed6ac51 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java @@ -267,7 +267,7 @@ public abstract class PassExecutorService implements Disposable { private void submit(final ScheduledPass pass) { if (!pass.myUpdateProgress.isCanceled()) { - Job job = JobUtil.submitToJobThread(pass, pass.myJobPriority, new Consumer() { + Job job = JobUtil.submitToJobThread(pass.myJobPriority, pass, new Consumer() { @Override public void consume(Future future) { try { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java index e2aad53fe08e..663f64451494 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java @@ -107,7 +107,7 @@ public class BraceHighlightingHandler { final Project project = editor.getProject(); if (project == null) return; final int offset = editor.getCaretModel().getOffset(); - JobUtil.submitToJobThread(new Runnable() { + JobUtil.submitToJobThread(Job.DEFAULT_PRIORITY, new Runnable() { public void run() { final PsiFile injected; try { @@ -145,7 +145,7 @@ public class BraceHighlightingHandler { } }, ModalityState.stateForComponent(editor.getComponent())); } - }, Job.DEFAULT_PRIORITY); + }); } private static boolean isReallyDisposed(Editor editor, Project project) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index 936c1fd3ddb5..163884d50f79 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -546,7 +546,7 @@ public class GlobalInspectionContextImpl extends UserDataHolderBase implements G } pass.doInspectInBatch((InspectionManagerEx)manager, lTools); - JobUtil.invokeConcurrentlyUnderProgress(globalSimpleTools, new Processor() { + JobUtil.invokeConcurrentlyUnderProgress(globalSimpleTools, myProgressIndicator, false, new Processor() { @Override public boolean process(Tools tools) { GlobalInspectionToolWrapper toolWrapper = (GlobalInspectionToolWrapper)tools.getTool(); @@ -557,7 +557,7 @@ public class GlobalInspectionContextImpl extends UserDataHolderBase implements G CONVERT, toolWrapper); return true; } - }, false, myProgressIndicator); + }); } catch (ProcessCanceledException e) { throw e; diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java index 3d72f7725be4..b11f59dc1b8e 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java @@ -54,7 +54,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModel public String[] getNames(final boolean checkBoxState) { final Set names = new ConcurrentHashSet(); - JobUtil.invokeConcurrentlyUnderProgress(filterDumb(myContributors), new Processor() { + JobUtil.invokeConcurrentlyUnderProgress(filterDumb(myContributors), ProgressManager.getInstance().getProgressIndicator(), false, new Processor() { @Override public boolean process(ChooseByNameContributor contributor) { try { @@ -71,7 +71,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModel } return true; } - }, false, ProgressManager.getInstance().getProgressIndicator()); + }); return ArrayUtil.toStringArray(names); } @@ -101,7 +101,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModel public Object[] getElementsByName(final String name, final boolean checkBoxState, final String pattern) { final List items = Collections.synchronizedList(new ArrayList()); - JobUtil.invokeConcurrentlyUnderProgress(filterDumb(myContributors), new Processor() { + JobUtil.invokeConcurrentlyUnderProgress(filterDumb(myContributors), ProgressManager.getInstance().getProgressIndicator(), false, new Processor() { @Override public boolean process(ChooseByNameContributor contributor) { try { @@ -124,7 +124,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModel } return true; } - }, false, ProgressManager.getInstance().getProgressIndicator()); + }); return ArrayUtil.toObjectArray(items); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java index ff19a3e904f0..2cf5ec9dbec7 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java @@ -22,7 +22,6 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -44,6 +43,7 @@ import com.intellij.psi.impl.source.tree.FileElement; import com.intellij.psi.text.BlockSupport; import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; +import com.intellij.util.SmartList; import com.intellij.util.containers.Queue; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -52,7 +52,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import javax.swing.*; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -127,20 +126,23 @@ public class DocumentCommitThread implements Runnable, Disposable { useIndicator(null); } - public boolean queueCommit(@NonNls @NotNull String reason, @NotNull Document document, @NotNull Project project, @Nullable DocumentEvent event) { - log("queueCommit called", document, false, reason, event); + public boolean queueCommit(@NotNull Project project, @NotNull Document document, @NonNls @NotNull Object reason) { + log("queueCommit called", document, false, reason); assert !isDisposed : "already disposed"; if (!project.isInitialized()) return false; PsiFile psiFile = PsiDocumentManager.getInstance(project).getCachedPsiFile(document); if (psiFile == null) return false; - boolean added = doQueue(document, project, getCommitStage(document), reason, event); + boolean added = doQueue(document, project, getCommitStage(document), reason); log("doQueue called", document, false, added); return added; } - private boolean doQueue(@NotNull Document document, @NotNull Project project, CommitStage start, @NonNls @NotNull String reason, @Nullable DocumentEvent event) { + private boolean doQueue(@NotNull Document document, + @NotNull Project project, + CommitStage start, + @NonNls @NotNull Object reason) { synchronized (documentsToCommit) { if (!changeCommitStage(document, start, CommitStage.QUEUED_TO_COMMIT, false)) return false; @@ -163,7 +165,7 @@ public class DocumentCommitThread implements Runnable, Disposable { } ProgressIndicator indicator = new ProgressIndicatorBase(); indicator.start(); - documentsToCommit.addLast(new CommitTask(document, project, indicator, reason, event)); + documentsToCommit.addLast(new CommitTask(document, project, indicator, reason)); log("Queued", document, false, reason); return true; } @@ -172,6 +174,7 @@ public class DocumentCommitThread implements Runnable, Disposable { private final StringBuilder log = new StringBuilder(); void log(@NonNls String msg, Document document, boolean synchronously, @NonNls Object... args) { if (debug()) { + @NonNls String s = (SwingUtilities.isEventDispatchThread() ? " " : "") + msg + (synchronously ? " (sync)" : "") + (document == null ? "" : "; Document: " + System.identityHashCode(document) + @@ -218,19 +221,16 @@ public class DocumentCommitThread implements Runnable, Disposable { // running = false means document was removed from the queue, should ignore. // canceled = true means commit was canceled, should reschedule for later. private final ProgressIndicator indicator; // progress to commit this doc under. - private final String reason; - @Nullable private final DocumentEvent event; + private final Object reason; private CommitTask(@NotNull Document document, @NotNull Project project, @NotNull ProgressIndicator indicator, - @NotNull String reason, - @Nullable DocumentEvent event) { + @NotNull Object reason) { this.document = document; this.project = project; this.indicator = indicator; this.reason = reason; - this.event = event; } } @@ -275,7 +275,7 @@ public class DocumentCommitThread implements Runnable, Disposable { CommitStage commitStage = getCommitStage(document); Document[] uncommitted = null; if (commitStage != CommitStage.QUEUED_TO_COMMIT - || project.isDisposed() || !ArrayUtil.contains(document,(uncommitted = PsiDocumentManager.getInstance(project).getUncommittedDocuments()))) { + || project.isDisposed() || !ArrayUtil.contains(document, uncommitted = PsiDocumentManager.getInstance(project).getUncommittedDocuments())) { List documents = uncommitted == null ? null : Arrays.asList(uncommitted); log("Abandon and proceeding to next",document, false, commitStage, documents); continue; @@ -292,7 +292,7 @@ public class DocumentCommitThread implements Runnable, Disposable { Runnable finishRunnable = null; if (!success && !indicator.isCanceled()) { try { - finishRunnable = commit(document, project, null, indicator, false, task.reason, task.event); + finishRunnable = commit(document, project, null, indicator, false, task.reason); success = finishRunnable != null; log("DCT.commit returned", document, false, finishRunnable, indicator); } @@ -312,8 +312,7 @@ public class DocumentCommitThread implements Runnable, Disposable { } } catch (ProcessCanceledException e) { - int i = 0; // leave queue unchanged - cancel(e); + cancel(e); // leave queue unchanged log("PCE", document, false, e); success = false; } @@ -332,7 +331,7 @@ public class DocumentCommitThread implements Runnable, Disposable { // reset status for queue back successfully changeCommitStage(document, CommitStage.WAITING_FOR_PSI_APPLY, CommitStage.QUEUED_TO_COMMIT, false); changeCommitStage(document, CommitStage.COMMITTED, CommitStage.QUEUED_TO_COMMIT, false); - doQueue(document, project, CommitStage.QUEUED_TO_COMMIT, "re-added on failure", null); + doQueue(document, project, CommitStage.QUEUED_TO_COMMIT, "re-added on failure"); } } } @@ -371,7 +370,7 @@ public class DocumentCommitThread implements Runnable, Disposable { ProgressIndicatorBase indicator = new ProgressIndicatorBase(); indicator.start(); log("About to commit sync", document, true, indicator); - Runnable finish = commit(document, project, excludeFile, indicator, true, "Sync commit", null); + Runnable finish = commit(document, project, excludeFile, indicator, true, "Sync commit"); log("Committed sync", document, true, finish, indicator); assert finish != null; @@ -383,13 +382,12 @@ public class DocumentCommitThread implements Runnable, Disposable { final PsiFile excludeFile, @NotNull final ProgressIndicator indicator, final boolean synchronously, - @NotNull final String reason, - @Nullable final DocumentEvent event) { + @NotNull final Object reason) { final Runnable[] success = new Runnable[1]; ((ProgressManagerImpl)ProgressManager.getInstance()).executeProcessUnderProgress(new Runnable() { @Override public void run() { - success[0] = commitUnderProgress(document, project, excludeFile, indicator, synchronously, reason, event); + success[0] = commitUnderProgress(document, project, excludeFile, indicator, synchronously, reason); } }, indicator); return success[0]; @@ -411,9 +409,8 @@ public class DocumentCommitThread implements Runnable, Disposable { final PsiFile excludeFile, @NotNull final ProgressIndicator indicator, final boolean synchronously, - @NotNull final String reason, - @Nullable final DocumentEvent event) { - final List> finishRunnables = new ArrayList>(); + @NotNull final Object reason) { + final List> finishRunnables = new SmartList>(); Runnable runnable = new Runnable() { public void run() { if (project.isDisposed()) return; @@ -432,7 +429,7 @@ public class DocumentCommitThread implements Runnable, Disposable { } }; if (synchronously) { - ApplicationManager.getApplication().assertIsDispatchThread(); + ApplicationManager.getApplication().assertWriteAccessAllowed(); runnable.run(); } else { @@ -458,45 +455,38 @@ public class DocumentCommitThread implements Runnable, Disposable { @Override public void run() { if (project.isDisposed()) return; - ApplicationManager.getApplication().runWriteAction(new CommitToPsiFileAction(document, project) { - public void run() { - if (project.isDisposed()) return; - PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(project); - CommitStage stage = getCommitStage(document); - log("Finish", document, synchronously, project); - if (stage != (synchronously ? CommitStage.ABOUT_TO_BE_SYNC_COMMITTED : CommitStage.WAITING_FOR_PSI_APPLY)) { - return; // there must be a synchronous commit sneaked in between queued commit and finish commit, or just document changed meanwhile - } + PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(project); - boolean success = false; - try { - success = documentManager.finishCommit(document, finishRunnables, synchronously, reason, event); - log("Finished", document, synchronously, success, Arrays.asList(documentManager.getUncommittedDocuments())); - if (synchronously) { - assert success; - } - } - finally { - if (success) { - CommitStage before = getCommitStage(document); - boolean changed = synchronously || changeCommitStage(document, CommitStage.WAITING_FOR_PSI_APPLY, CommitStage.COMMITTED, false); - assert changed : "Before: " + before + "; after: " + getCommitStage(document); - } - } - List unc = Arrays.asList(documentManager.getUncommittedDocuments()); - log("after call finish commit",document, synchronously, unc, success); - if (synchronously || success) { - assert !unc.contains(document) : unc; - } - if (!success) { - // add document back to the queue - log("Re-adding back", document, synchronously, success, documentManager.isCommitted(document), Arrays.asList(documentManager.getUncommittedDocuments())); - boolean addedBack = queueCommit("Re-added back", document, project, null); - assert addedBack; - } + CommitStage stage = getCommitStage(document); + log("Finish", document, synchronously, project); + if (stage != (synchronously ? CommitStage.ABOUT_TO_BE_SYNC_COMMITTED : CommitStage.WAITING_FOR_PSI_APPLY)) { + return; // there must be a synchronous commit sneaked in between queued commit and finish commit, or just document changed meanwhile + } + + boolean success = false; + try { + success = documentManager.finishCommit(document, finishRunnables, synchronously, reason); + log("Finished", document, synchronously, success, Arrays.asList(documentManager.getUncommittedDocuments())); + if (synchronously) { + assert success; } - }); + } + finally { + if (success) { + success = synchronously || changeCommitStage(document, CommitStage.WAITING_FOR_PSI_APPLY, CommitStage.COMMITTED, false); + } + } + List unc = Arrays.asList(documentManager.getUncommittedDocuments()); + log("after call finish commit",document, synchronously, unc, success); + if (synchronously || success) { + assert !unc.contains(document) : unc; + } + if (!success) { + // add document back to the queue + boolean addedBack = queueCommit(project, document, "Re-added back"); + assert addedBack; + } } }; return finishRunnable; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java index 7fdec94600f1..993d4643d00c 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java @@ -18,7 +18,9 @@ package com.intellij.psi.impl; import com.intellij.AppTopics; import com.intellij.injected.editor.DocumentWindow; +import com.intellij.injected.editor.EditorWindow; import com.intellij.lang.ASTNode; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationAdapter; import com.intellij.openapi.application.ApplicationManager; @@ -46,7 +48,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.PsiFileImpl; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; import com.intellij.psi.text.BlockSupport; import com.intellij.util.Processor; import com.intellij.util.SmartList; @@ -312,59 +314,66 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec } boolean finishCommit(@NotNull final Document document, - @NotNull List> finishRunnables, - boolean synchronously, - @NotNull String reason, - @Nullable DocumentEvent event) { + @NotNull final List> finishRunnables, + final boolean synchronously, + @NotNull Object reason) { if (myProject.isDisposed()) return false; - ApplicationManager.getApplication().assertWriteAccessAllowed(); - - assert !(document instanceof DocumentWindow); - myIsCommitInProgress = true; - boolean success = true; - try { - final FileViewProvider viewProvider = getCachedViewProvider(document); - if (viewProvider != null) { - for (Processor finishRunnable : finishRunnables) { - success = finishRunnable.process(document); - if (synchronously) { - assert success; - } - if (!success) { - break; + final boolean[] ok = {true}; + ApplicationManager.getApplication().runWriteAction(new CommitToPsiFileAction(document, myProject) { + @Override + public void run() { + if (myProject.isDisposed()) return; + EditorWindow.disposeInvalidEditors(); // in write action + assert !(document instanceof DocumentWindow); + myIsCommitInProgress = true; + boolean success = true; + try { + final FileViewProvider viewProvider = getCachedViewProvider(document); + if (viewProvider != null) { + for (Processor finishRunnable : finishRunnables) { + success = finishRunnable.process(document); + if (synchronously) { + assert success; + } + if (!success) { + break; + } + } + viewProvider.contentsSynchronized(); } + ok[0] = success; + } + finally { + myDocumentCommitThread.log("in PDI.finishDoc: ", document, synchronously, success, myUncommittedDocuments); + if (success) { + myUncommittedDocuments.remove(document); + myDocumentCommitThread.log("in PDI.finishDoc: removed doc", document, synchronously, success, myUncommittedDocuments); + } + myIsCommitInProgress = false; + myDocumentCommitThread.log("in PDI.finishDoc: exit", document, synchronously, success, myUncommittedDocuments); } - viewProvider.contentsSynchronized(); } - } - finally { - myDocumentCommitThread.log("in PDI.finishDoc: ",document, synchronously, success, myUncommittedDocuments); - if (success) { - myUncommittedDocuments.remove(document); - myDocumentCommitThread.log("in PDI.finishDoc: removed doc",document, synchronously, success, myUncommittedDocuments); - InjectedLanguageUtil.commitAllInjectedDocuments(document, myProject); - } - myIsCommitInProgress = false; - myDocumentCommitThread.log("in PDI.finishDoc: exit",document, synchronously, success, myUncommittedDocuments); - } + }); - if (success) { + if (ok[0]) { + ((InjectedLanguageManagerImpl)InjectedLanguageManager.getInstance(myProject)).startRunInjectors(document, synchronously); + // run after commit actions outside write action runAfterCommitActions(document); if (DebugUtil.DO_EXPENSIVE_CHECKS) { - checkAllElementsValid(document, reason, event); + checkAllElementsValid(document, reason); } } - return success; + return ok[0]; } - private void checkAllElementsValid(@NotNull Document document, @NotNull final String reason, @Nullable final DocumentEvent event) { + private void checkAllElementsValid(@NotNull Document document, @NotNull final Object reason) { final PsiFile psiFile = getCachedPsiFile(document); if (psiFile != null) { psiFile.accept(new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { if (!element.isValid()) { - LOG.error("Commit to '"+psiFile.getVirtualFile()+"' lead to invalid element: "+element+ "; Reason: '"+reason+"'; Doc change event: "+event); + LOG.error("Commit to '"+psiFile.getVirtualFile()+"' lead to invalid element: "+element+ "; Reason: '"+reason+"'"); } } }); @@ -616,7 +625,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec if (commitNecessary) { myUncommittedDocuments.add(document); - myDocumentCommitThread.queueCommit("Document changed", document, myProject, event); + myDocumentCommitThread.queueCommit(myProject, document, event); } // Consider that it's worth to perform complete re-parse instead of merge if the whole document text is replaced and diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index cb8f6c61d01e..b37f17ae8907 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -184,11 +184,11 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { PsiElement[] scopeElements = scope.getScope(); final boolean ignoreInjectedPsi = scope.isIgnoreInjectedPsi(); - return JobUtil.invokeConcurrentlyUnderProgress(Arrays.asList(scopeElements), new Processor() { + return JobUtil.invokeConcurrentlyUnderProgress(Arrays.asList(scopeElements), progress, false, new Processor() { public boolean process(PsiElement scopeElement) { return processElementsWithWordInScopeElement(scopeElement, processor, text, caseSensitively, ignoreInjectedPsi, progress); } - }, false, progress); + }); } } @@ -250,7 +250,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final AtomicBoolean pceThrown = new AtomicBoolean(false); final int size = files.size(); - boolean completed = JobUtil.invokeConcurrentlyUnderProgress(files, new Processor() { + boolean completed = JobUtil.invokeConcurrentlyUnderProgress(files, progress, false, new Processor() { public boolean process(final VirtualFile vfile) { final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable() { public PsiFile compute() { @@ -288,7 +288,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { } return !canceled.get(); } - }, false, progress); + }); if (pceThrown.get()) { throw new ProcessCanceledException(); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java index 79661277555a..2fe466980254 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java @@ -65,7 +65,7 @@ class InjectedSelfElementInfo extends SelfElementInfo { final Ref result = new Ref(); final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(getProject()); - InjectedLanguageUtil.enumerate(hostContext, hostContext.getContainingFile(), new PsiLanguageInjectionHost.InjectedPsiVisitor() { + InjectedLanguageUtil.enumerate(hostContext, hostContext.getContainingFile(), true, new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { if (result.get() != null) return; @@ -78,7 +78,7 @@ class InjectedSelfElementInfo extends SelfElementInfo { result.set(element); } } - }, true); + }); return result.get(); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java index dc2c9d6fcdfe..3b72de04bc08 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java @@ -143,26 +143,21 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable private void decrementPostponedCounter() { if (--myPostponedCounter == 0) { - if (!ApplicationManager.getApplication().isWriteAccessAllowed()) { + if (ApplicationManager.getApplication().isWriteAccessAllowed()) { + doPostponedFormatting(); + } + else { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { doPostponedFormatting(); } }); } - else { - doPostponedFormatting(); - } - //myDisabled = true; } } - private final Object LOCK = new Object(); - private void atomic(Runnable r) { - synchronized (LOCK) { - ProgressManager.getInstance().executeNonCancelableSection(r); - } + ProgressManager.getInstance().executeNonCancelableSection(r); } public void update(final PomModelEvent event) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java index 240be2f40dce..25737705aa14 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java @@ -98,14 +98,14 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider { PsiElement elementCopy = hostPsiFileCopy.getViewProvider().findElementAt(firstTextRange.getStartOffset(), hostFileLanguage); assert elementCopy != null; final Ref provider = new Ref(); - InjectedLanguageUtil.enumerate(elementCopy, hostPsiFileCopy, new PsiLanguageInjectionHost.InjectedPsiVisitor() { + InjectedLanguageUtil.enumerate(elementCopy, hostPsiFileCopy, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() { public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { Document document = documentManager.getCachedDocument(injectedPsi); if (document instanceof DocumentWindowImpl && oldDocumentWindow.areRangesEqual((DocumentWindowImpl)document)) { provider.set(injectedPsi.getViewProvider()); } } - }, true); + }); return provider.get(); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java index 8463342eed93..15c50a24be90 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java @@ -16,6 +16,11 @@ package com.intellij.psi.impl.source.tree.injected; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator; +import com.intellij.concurrency.Job; +import com.intellij.concurrency.JobUtil; +import com.intellij.injected.editor.DocumentWindow; import com.intellij.injected.editor.DocumentWindowImpl; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.Language; @@ -23,21 +28,24 @@ import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.lang.injection.MultiHostInjector; import com.intellij.lang.injection.MultiHostRegistrar; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.ExtensionPointListener; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.extensions.PluginDescriptor; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.ProperTextRange; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.impl.PsiDocumentManagerImpl; import com.intellij.util.ArrayUtil; +import com.intellij.util.Processor; import com.intellij.util.containers.ConcurrentHashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -51,11 +59,12 @@ import java.util.concurrent.atomic.AtomicReference; /** * @author cdr */ -public class InjectedLanguageManagerImpl extends InjectedLanguageManager { +public class InjectedLanguageManagerImpl extends InjectedLanguageManager implements Disposable{ private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl"); private final Project myProject; private final DumbService myDumbService; private final AtomicReference myPsiManagerRegisteredInjectorsAdapter = new AtomicReference(); + private volatile DaemonProgressIndicator myProgress; public static InjectedLanguageManagerImpl getInstanceImpl(Project project) { return (InjectedLanguageManagerImpl)InjectedLanguageManager.getInstance(project); @@ -74,7 +83,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager { public void extensionRemoved(@NotNull MultiHostInjector injector, @Nullable PluginDescriptor pluginDescriptor) { unregisterMultiHostInjector(injector); } - }); + },this); final ExtensionPointListener myListener = new ExtensionPointListener() { public void extensionAdded(@NotNull LanguageInjector extension, @Nullable PluginDescriptor pluginDescriptor) { psiManagerInjectorsChanged(); @@ -85,14 +94,91 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager { } }; final ExtensionPoint psiManagerPoint = Extensions.getRootArea().getExtensionPoint(LanguageInjector.EXTENSION_POINT_NAME); - psiManagerPoint.addExtensionPointListener(myListener); - Disposer.register(project, new Disposable() { - public void dispose() { - psiManagerPoint.removeExtensionPointListener(myListener); + psiManagerPoint.addExtensionPointListener(myListener,this); + myProgress = new DaemonProgressIndicator(); + project.getMessageBus().connect(this).subscribe(DaemonCodeAnalyzer.DAEMON_EVENT_TOPIC, new DaemonCodeAnalyzer.DaemonListener() { + @Override + public void daemonFinished() { + } + + @Override + public void daemonCancelEventOccurred() { + myProgress.cancel(); } }); } + @Override + public void dispose() { + } + + public boolean startRunInjectors(@NotNull Document hostDocument, final boolean synchronously) { + if (myProject.isDisposed()) return true; + assert synchronously || !ApplicationManager.getApplication().isWriteAccessAllowed(); + // use cached to avoid recreate PSI in alien project + final PsiFile hostPsiFile = PsiDocumentManager.getInstance(myProject).getCachedPsiFile(hostDocument); + if (hostPsiFile == null) return true; + + final List injected = InjectedLanguageUtil.getCachedInjectedDocuments(hostPsiFile); + if (injected.isEmpty()) return true; + + if (myProgress.isCanceled()) { + myProgress = new DaemonProgressIndicator(); + } + + final Computable commitRunnable = new Computable() { + @Override + public Boolean compute() { + return JobUtil.invokeConcurrentlyUnderProgress(injected, myProgress, !synchronously, new Processor() { + @Override + public boolean process(DocumentWindow documentWindow) { + ProgressManager.checkCanceled(); + RangeMarker rangeMarker = documentWindow.getHostRanges()[0]; + PsiElement element = rangeMarker.isValid() ? hostPsiFile.findElementAt(rangeMarker.getStartOffset()) : null; + if (element == null) { + injected.remove(documentWindow); + return true; + } + final DocumentWindow[] stillInjectedDocument = {null}; + // it is here where the reparse happens and old file contents replaced + InjectedLanguageUtil.enumerate(element, hostPsiFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() { + public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { + stillInjectedDocument[0] = (DocumentWindow)injectedPsi.getViewProvider().getDocument(); + PsiDocumentManagerImpl.checkConsistency(injectedPsi, stillInjectedDocument[0]); + } + }); + if (stillInjectedDocument[0] == null) { + injected.remove(documentWindow); + } + else if (stillInjectedDocument[0] != documentWindow) { + injected.remove(documentWindow); + injected.add(stillInjectedDocument[0]); + } + + return true; + } + }); + } + }; + + if (synchronously) { + return commitRunnable.compute(); + } + else { + JobUtil.submitToJobThread(Job.DEFAULT_PRIORITY, new Runnable() { + @Override + public void run() { + ApplicationManagerEx.getApplicationEx().tryRunReadAction(new Runnable() { + public void run() { + commitRunnable.compute(); + } + }); + } + }); + return true; + } + } + public void psiManagerInjectorsChanged() { LanguageInjector[] extensions = Extensions.getExtensions(LanguageInjector.EXTENSION_POINT_NAME); if (extensions.length == 0) { @@ -210,7 +296,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager { * @param rangeToEdit range in encoded(raw) PSI * @return list of ranges in encoded (raw) PSI */ - @SuppressWarnings({"ConstantConditions"}) + @SuppressWarnings({"ConstantConditions", "unchecked"}) @NotNull public List intersectWithAllEditableFragments(@NotNull PsiFile injectedPsi, @NotNull TextRange rangeToEdit) { Place shreds = InjectedLanguageUtil.getShreds(injectedPsi); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java index 42262afee0fe..a6b006d35d28 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java @@ -104,10 +104,13 @@ public class InjectedLanguageUtil { public static void enumerate(@NotNull PsiElement host, @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) { PsiFile containingFile = host.getContainingFile(); - enumerate(host, containingFile, visitor, true); + enumerate(host, containingFile, true, visitor); } - public static void enumerate(@NotNull PsiElement host, @NotNull PsiFile containingFile, @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor, boolean probeUp) { + public static void enumerate(@NotNull PsiElement host, + @NotNull PsiFile containingFile, + boolean probeUp, + @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) { //do not inject into nonphysical files except during completion if (!containingFile.isPhysical() && containingFile.getOriginalFile() == containingFile) { final PsiElement context = containingFile.getContext(); @@ -193,7 +196,6 @@ public class InjectedLanguageUtil { final Project project = psiManager.getProject(); InjectedLanguageManagerImpl injectedManager = InjectedLanguageManagerImpl.getInstanceImpl(project); if (injectedManager == null) return null; //for tests - long modificationCount = psiManager.getModificationTracker().getModificationCount(); MultiHostRegistrarImpl registrar = null; PsiElement current = element; nextParent: @@ -290,7 +292,7 @@ public class InjectedLanguageUtil { private static PsiElement findInside(@NotNull PsiElement element, @NotNull PsiFile hostFile, final int hostOffset, @NotNull final PsiDocumentManager documentManager) { final Ref out = new Ref(); - enumerate(element, hostFile, new PsiLanguageInjectionHost.InjectedPsiVisitor() { + enumerate(element, hostFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() { public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { for (PsiLanguageInjectionHost.Shred place : places) { TextRange hostRange = place.host.getTextRange(); @@ -303,7 +305,7 @@ public class InjectedLanguageUtil { } } } - }, true); + }); return out.get(); } @@ -340,12 +342,12 @@ public class InjectedLanguageUtil { } final DocumentWindow[] stillInjectedDocument = {null}; // it is here where the reparse happens and old file contents replaced - enumerate(element, hostPsiFile, new PsiLanguageInjectionHost.InjectedPsiVisitor() { + enumerate(element, hostPsiFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() { public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { stillInjectedDocument[0] = (DocumentWindow)injectedPsi.getViewProvider().getDocument(); PsiDocumentManagerImpl.checkConsistency(injectedPsi, stillInjectedDocument[0]); } - }, true); + }); if (stillInjectedDocument[0] == null) { injected.remove(i); } diff --git a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java index cd86d79f50e0..01cfef76fde2 100644 --- a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java @@ -106,7 +106,7 @@ public class DeferredIconImpl implements DeferredIcon { paintingParentRec.set(((PaintingParent)pp).getChildRec(c)); } - JobUtil.submitToJobThread(new Runnable() { + JobUtil.submitToJobThread(Job.DEFAULT_PRIORITY, new Runnable() { public void run() { int oldWidth = myDelegateIcon.getIconWidth(); myDelegateIcon = evaluate(); @@ -153,7 +153,7 @@ public class DeferredIconImpl implements DeferredIcon { } }); } - }, Job.DEFAULT_PRIORITY); + }); } } diff --git a/platform/platform-impl/src/com/intellij/concurrency/JobUtil.java b/platform/platform-impl/src/com/intellij/concurrency/JobUtil.java index 6751ed4fdf4c..eea654bf9d0e 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/JobUtil.java +++ b/platform/platform-impl/src/com/intellij/concurrency/JobUtil.java @@ -41,8 +41,8 @@ public class JobUtil { } private static boolean invokeConcurrentlyForAll(@NotNull final List things, - @NotNull final Processor thingProcessor, - boolean failFastOnAcquireReadAction) throws ProcessCanceledException { + boolean failFastOnAcquireReadAction, + @NotNull final Processor thingProcessor) throws ProcessCanceledException { final Job job = new JobImpl(Job.DEFAULT_PRIORITY, failFastOnAcquireReadAction); final int chunkSize = Math.max(1, things.size() / JobSchedulerImpl.CORES_COUNT / 20); @@ -84,10 +84,11 @@ public class JobUtil { /** * Schedules concurrent execution of #thingProcessor over each element of #things and waits for completion * With checkCanceled in each thread delegated to our current progress + * * @param things to process concurrently - * @param thingProcessor to be invoked concurrently on each element from the collection - * @param failFastOnAcquireReadAction if true, returns false when failed to acquire read action * @param progress + * @param failFastOnAcquireReadAction if true, returns false when failed to acquire read action + * @param thingProcessor to be invoked concurrently on each element from the collection * @return false if tasks have been canceled * or at least one processor returned false * or threw exception @@ -95,9 +96,9 @@ public class JobUtil { * @throws ProcessCanceledException if at least one task has thrown ProcessCanceledException */ public static boolean invokeConcurrentlyUnderProgress(@NotNull List things, - @NotNull final Processor thingProcessor, + ProgressIndicator progress, boolean failFastOnAcquireReadAction, - ProgressIndicator progress) throws ProcessCanceledException { + @NotNull final Processor thingProcessor) throws ProcessCanceledException { if (things.isEmpty()) { return true; } @@ -108,7 +109,7 @@ public class JobUtil { // can be already wrapped final ProgressWrapper wrapper = progress instanceof ProgressWrapper ? (ProgressWrapper)progress : ProgressWrapper.wrap(progress); - return invokeConcurrentlyForAll(things, new Processor() { + return invokeConcurrentlyForAll(things, failFastOnAcquireReadAction, new Processor() { public boolean process(final T t) { final boolean[] result = new boolean[1]; ((ProgressManagerImpl)ProgressManager.getInstance()).executeProcessUnderProgress(new Runnable() { @@ -118,14 +119,14 @@ public class JobUtil { }, wrapper); return result[0]; } - }, failFastOnAcquireReadAction); + }); } - public static Job submitToJobThread(@NotNull final Runnable action, int priority) { - return submitToJobThread(action, priority, null); + public static Job submitToJobThread(int priority, @NotNull final Runnable action) { + return submitToJobThread(priority, action, null); } - public static Job submitToJobThread(@NotNull final Runnable action, int priority, Consumer onDoneCallback) { + public static Job submitToJobThread(int priority, @NotNull final Runnable action, Consumer onDoneCallback) { final JobImpl job = new JobImpl(priority, false); Callable callable = new Callable() { public Void call() throws Exception { diff --git a/plugins/properties/src/com/intellij/codeInspection/duplicatePropertyInspection/DuplicatePropertyInspection.java b/plugins/properties/src/com/intellij/codeInspection/duplicatePropertyInspection/DuplicatePropertyInspection.java index dd68cb49cc96..40b90f3a8649 100644 --- a/plugins/properties/src/com/intellij/codeInspection/duplicatePropertyInspection/DuplicatePropertyInspection.java +++ b/plugins/properties/src/com/intellij/codeInspection/duplicatePropertyInspection/DuplicatePropertyInspection.java @@ -163,7 +163,7 @@ public class DuplicatePropertyInspection extends GlobalSimpleInspectionTool { final ProgressIndicator progress = ProgressWrapper.wrap(original); ProgressManager.getInstance().runProcess(new Runnable() { public void run() { - if (!JobUtil.invokeConcurrentlyUnderProgress(properties, new Processor() { + if (!JobUtil.invokeConcurrentlyUnderProgress(properties, progress, false, new Processor() { public boolean process(final IProperty property) { if (original != null) { if (original.isCanceled()) return false; @@ -173,7 +173,7 @@ public class DuplicatePropertyInspection extends GlobalSimpleInspectionTool { processTextUsages(processedKeyToFiles, property.getUnescapedKey(), processedValueToFiles, searchHelper, scope); return true; } - }, false, progress)) throw new ProcessCanceledException(); + })) throw new ProcessCanceledException(); List problemDescriptors = new ArrayList(); Map> keyToDifferentValues = new HashMap>();