From 64bbfe17e0dc58e677c88304fecb6a1df3e14f19 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 16 Sep 2014 17:59:02 +0400 Subject: [PATCH 01/12] read action --- .../ui/impl/watch/CompilingEvaluator.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java index 4f556f4e0d66..e228ec45719a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java @@ -111,7 +111,12 @@ public class CompilingEvaluator implements ExpressionEvaluator { try { // invoke base evaluator on call code - final Project project = myPsiContext.getProject(); + final Project project = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Project compute() { + return myPsiContext.getProject(); + } + }); ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(project, new EvaluatingComputable() { @Override @@ -156,7 +161,7 @@ public class CompilingEvaluator implements ExpressionEvaluator { DebugProcess process, ThreadReference threadReference, ClassLoaderReference classLoader) - throws EvaluateException, InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { + throws EvaluateException, InvalidTypeException, ClassNotLoadedException { VirtualMachineProxyImpl proxy = (VirtualMachineProxyImpl)process.getVirtualMachineProxy(); for (OutputFileObject cls : classes) { @@ -259,11 +264,17 @@ public class CompilingEvaluator implements ExpressionEvaluator { ///////////////// Compiler stuff + @NotNull private Collection compile() throws EvaluateException { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); MemoryFileManager manager = new MemoryFileManager(compiler); DiagnosticCollector diagnostic = new DiagnosticCollector(); - Module module = ModuleUtilCore.findModuleForPsiElement(myPsiContext); + Module module = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Module compute() { + return ModuleUtilCore.findModuleForPsiElement(myPsiContext); + } + }); PathsList cp = null; if (module != null) { cp = ModuleRootManager.getInstance(module).orderEntries().compileOnly().recursively().exportedOnly().withoutSdk().getPathsList(); From d1d85166687d88e5a265893249df47b660ba16f2 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 16 Sep 2014 20:20:17 +0400 Subject: [PATCH 02/12] removed unused classes --- .../intellij/openapi/vcs/ConcurrentTasks.java | 119 ------------------ 1 file changed, 119 deletions(-) delete mode 100644 platform/vcs-api/src/com/intellij/openapi/vcs/ConcurrentTasks.java diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ConcurrentTasks.java b/platform/vcs-api/src/com/intellij/openapi/vcs/ConcurrentTasks.java deleted file mode 100644 index c045561561a3..000000000000 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/ConcurrentTasks.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2000-2014 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.vcs; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.progress.EmptyProgressIndicator; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.util.Consumer; -import com.intellij.util.concurrency.Semaphore; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; - -// competes to calculate The Result -public class ConcurrentTasks { - private volatile boolean myResultKnown; - private final Semaphore mySemaphore; - private volatile T myResult; - private AtomicInteger myCntAlive; - private final ProgressIndicator myParentIndicator; - private final List>> myTasks; - - public void compute() { - final EmptyProgressIndicator pi = new EmptyProgressIndicator() { - @Override - public void checkCanceled() { - if (myResultKnown || (myParentIndicator != null) && myParentIndicator.isCanceled()) { - super.cancel(); - } - super.checkCanceled(); - } - }; - myCntAlive = new AtomicInteger(myTasks.size()); - mySemaphore.down(); - - final List> futures = new LinkedList>(); - for (final Consumer> task : myTasks) { - if (myResultKnown) { - final int decremented = myCntAlive.decrementAndGet(); - continue; - } - final Runnable computableProxy = new Runnable() { - public void run() { - try { - task.consume(new Consumer() { - public void consume(T t) { - if (myResultKnown) return; - myResult = t; - myResultKnown = true; - } - }); - } - finally { - final int decremented = myCntAlive.decrementAndGet(); - if (decremented == 0 || myResultKnown) { - mySemaphore.up(); - } - } - } - }; - final Future future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - public void run() { - ProgressManager.getInstance().runProcess(computableProxy, pi); - } - }); - futures.add(future); - } - - while (true) { - if (myResultKnown) break; - if (myCntAlive.get() <= 0) break; - pi.checkCanceled(); - mySemaphore.waitFor(300); - } - // in it possible to even interrupt() threads involved, but at the moment it's better for tasks themselves to check cancel status - for (Future future : futures) { - if ((! future.isCancelled() && (! future.isDone()))) { - future.cancel(true); - } - } - } - - public boolean isResultKnown() { - return myResultKnown; - } - - public T getResult() { - return myResult; - } - - public ConcurrentTasks(final ProgressIndicator parentIndicator, final Consumer>... tasks) { - myParentIndicator = parentIndicator; - myTasks = Arrays.asList(tasks); - mySemaphore = new Semaphore(); - } - - public ConcurrentTasks(final ProgressIndicator parentIndicator, final List>> tasks) { - myParentIndicator = parentIndicator; - myTasks = tasks; - mySemaphore = new Semaphore(); - } -} From c5695fe3d57680ebdbd464d372e62d7966bc1dde Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 17 Sep 2014 14:11:06 +0400 Subject: [PATCH 03/12] commit documents in tests --- .../fixtures/impl/HeavyIdeaTestFixtureImpl.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index 72bbff443dfa..bcf5dd335ed9 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -45,10 +45,7 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; +import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; import com.intellij.testFramework.EditorListenerTracker; import com.intellij.testFramework.LightPlatformTestCase; @@ -245,6 +242,7 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu protected void run() throws Throwable { virtualFile[0] = dir.createChildData(this, StringUtil.getShortName(relativePath, '/')); VfsUtil.saveText(virtualFile[0], fileText); + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); } }.execute(); return ApplicationManager.getApplication().runReadAction(new Computable() { From c16cdcc0901a2475d0f3fd4b47bf60edc4b7e823 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 17 Sep 2014 14:51:49 +0400 Subject: [PATCH 04/12] leak hunting tests fixed --- .../core-impl/src/com/intellij/psi/impl/EmptyFileManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/EmptyFileManager.java b/platform/core-impl/src/com/intellij/psi/impl/EmptyFileManager.java index 8479be924ee7..cf0f93cd7891 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/EmptyFileManager.java +++ b/platform/core-impl/src/com/intellij/psi/impl/EmptyFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -64,6 +64,7 @@ class EmptyFileManager implements FileManager { @Override public void cleanupForNextTest() { + myVFileToViewProviderMap.clear(); } @Override From a8f1e94f2fe8dace9196559558f5c80977e0f7d4 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 17 Sep 2014 17:09:09 +0400 Subject: [PATCH 05/12] restored line deleted accidentally --- .../src/com/intellij/openapi/editor/impl/EditorImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index f7f41d0ae656..99fe2fb6148a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -2789,6 +2789,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (extensions != null && !extensions.isEmpty()) { for (LineExtensionInfo info : extensions) { final String text = info.getText(); + additionalText += text; drawStringWithSoftWraps(g, text, 0, text.length(), position, clip, info.getEffectColor() == null ? effectColor : info.getEffectColor(), info.getEffectType() == null ? effectType : info.getEffectType(), From c58f7955e5ff6e84f899305b83770c3c5cf7f4eb Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 17 Sep 2014 17:22:01 +0400 Subject: [PATCH 06/12] commit documents in tests --- .../src/com/intellij/codeInsight/CodeInsightTestCase.java | 2 +- .../testFramework/LightPlatformCodeInsightTestCase.java | 1 + .../testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java index 631738835371..7f3a6990311c 100644 --- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java @@ -74,7 +74,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase { final FileEditorManager instance = FileEditorManager.getInstance(myProject); if (file.getFileType().isBinary()) return null; - + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); Editor editor = instance.openTextEditor(new OpenFileDescriptor(myProject, file, 0), false); ((EditorImpl)editor).setCaretActive(); PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java index 9dedcc6d47a8..3808e7d0e8ce 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java @@ -178,6 +178,7 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest } protected static Editor createEditor(@NotNull VirtualFile file) { + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); Editor editor = FileEditorManager.getInstance(getProject()).openTextEditor(new OpenFileDescriptor(getProject(), file, 0), false); ((EditorImpl)editor).setCaretActive(); return editor; diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index ff5e2020a2b9..9625030a8483 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1468,6 +1468,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig private Editor createEditor(@NotNull VirtualFile file) { final Project project = getProject(); final FileEditorManager instance = FileEditorManager.getInstance(project); + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + Editor editor = instance.openTextEditor(new OpenFileDescriptor(project, file), false); if (editor != null) { editor.getCaretModel().moveToOffset(0); From 1ff1c5978100de2fb3fa604fba51243c7118b59f Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 17 Sep 2014 19:14:41 +0400 Subject: [PATCH 07/12] restart daemon in case someone calls configureFile() for the same file twice --- .../src/com/intellij/codeInsight/CodeInsightTestCase.java | 2 ++ .../testFramework/LightPlatformCodeInsightTestCase.java | 3 +++ .../fixtures/impl/CodeInsightTestFixtureImpl.java | 1 + 3 files changed, 6 insertions(+) diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java index 7f3a6990311c..cedfe2d04aa9 100644 --- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.highlighting.HighlightUsagesHandler; import com.intellij.ide.DataManager; import com.intellij.injected.editor.EditorWindow; @@ -78,6 +79,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase { Editor editor = instance.openTextEditor(new OpenFileDescriptor(myProject, file, 0), false); ((EditorImpl)editor).setCaretActive(); PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + DaemonCodeAnalyzer.getInstance(getProject()).restart(); return editor; } diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java index 3808e7d0e8ce..524b9dc31a4b 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java @@ -15,6 +15,7 @@ */ package com.intellij.testFramework; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.generation.actions.CommentByLineCommentAction; import com.intellij.ide.DataManager; import com.intellij.injected.editor.DocumentWindow; @@ -180,6 +181,8 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest protected static Editor createEditor(@NotNull VirtualFile file) { PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); Editor editor = FileEditorManager.getInstance(getProject()).openTextEditor(new OpenFileDescriptor(getProject(), file, 0), false); + DaemonCodeAnalyzer.getInstance(getProject()).restart(); + ((EditorImpl)editor).setCaretActive(); return editor; } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 9625030a8483..b860131d285b 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1473,6 +1473,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig Editor editor = instance.openTextEditor(new OpenFileDescriptor(project, file), false); if (editor != null) { editor.getCaretModel().moveToOffset(0); + DaemonCodeAnalyzer.getInstance(getProject()).restart(); } return editor; } From a2ea75ef848e82c26aae5831339d4752eda2f93d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 17 Sep 2014 19:24:04 +0400 Subject: [PATCH 08/12] leak hunting tests really fixed --- .../src/com/intellij/testFramework/PlatformTestCase.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 41b41fb5f62e..36d63ebb17dc 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -43,6 +43,7 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.impl.ModuleManagerImpl; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.project.impl.ProjectManagerImpl; import com.intellij.openapi.project.impl.TooManyProjectLeakedException; @@ -341,6 +342,12 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro ((PsiManagerEx)PsiManager.getInstance(project)).getFileManager().cleanupForNextTest(); } + ProjectManagerImpl projectManager = (ProjectManagerImpl)ProjectManager.getInstance(); + if (projectManager.isDefaultProjectInitialized()) { + Project defaultProject = projectManager.getDefaultProject(); + ((PsiManagerEx)PsiManager.getInstance(defaultProject)).getFileManager().cleanupForNextTest(); + } + LocalFileSystemImpl localFileSystem = (LocalFileSystemImpl)LocalFileSystem.getInstance(); if (localFileSystem != null) { localFileSystem.cleanupForNextTest(); From 6942f20f0e77da8d26ff8812d7a1c27b216fb498 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 17 Sep 2014 19:46:11 +0400 Subject: [PATCH 09/12] read action --- .../usages/impl/SearchForUsagesRunnable.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java index 6e5e93f3ed96..680e621a8f16 100644 --- a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java +++ b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java @@ -138,6 +138,7 @@ class SearchForUsagesRunnable implements Runnable { resultLines.add(shortMessage); resultListener = addHrefHandling(resultListener, LARGE_FILES_HREF_TARGET, new Runnable() { + @Override public void run() { String detailedMessage = detailedLargeFilesMessage(largeFiles); List strings = new ArrayList(lines); @@ -247,9 +248,15 @@ class SearchForUsagesRunnable implements Runnable { }; } - private static PsiElement getPsiElement(UsageTarget[] searchFor) { - if (!(searchFor[0] instanceof PsiElementUsageTarget)) return null; - return ((PsiElementUsageTarget)searchFor[0]).getElement(); + private static PsiElement getPsiElement(@NotNull UsageTarget[] searchFor) { + final UsageTarget target = searchFor[0]; + if (!(target instanceof PsiElementUsageTarget)) return null; + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiElement compute() { + return ((PsiElementUsageTarget)target).getElement(); + } + }); } private static void flashUsageScriptaculously(@NotNull final Usage usage) { @@ -321,6 +328,7 @@ class SearchForUsagesRunnable implements Runnable { private void searchUsages(@NotNull final AtomicBoolean findStartedBalloonShown) { ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator()); + assert indicator != null : "must run find usages under progress"; TooManyUsagesStatus.createFor(indicator); Alarm findUsagesStartedBalloon = new Alarm(); findUsagesStartedBalloon.addRequest(new Runnable() { @@ -337,7 +345,8 @@ class SearchForUsagesRunnable implements Runnable { @Override public boolean process(final Usage usage) { ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator()); - if (indicator != null && indicator.isCanceled()) return false; + assert indicator != null : "must run find usages under progress"; + if (indicator.isCanceled()) return false; if (!UsageViewManagerImpl.isInScope(usage, mySearchScopeToWarnOfFallingOutOf)) { myOutOfScopeUsages.incrementAndGet(); @@ -368,7 +377,7 @@ class SearchForUsagesRunnable implements Runnable { }); } } - return indicator == null || !indicator.isCanceled(); + return !indicator.isCanceled(); } }); if (getUsageView(indicator) != null) { From bc348ff3beecaae2794c3204c2ff4d4872683fe0 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 18 Sep 2014 13:24:22 +0400 Subject: [PATCH 10/12] introduced StandardProgressIndicator, made cancellation methods final where possible --- .../compiler/progress/CompilerTask.java | 4 +- .../debugger/ui/HotSwapProgressImpl.java | 11 +- .../daemon/impl/DaemonProgressIndicator.java | 15 +- .../progress/EmptyProgressIndicator.java | 20 +- .../progress/StandardProgressIndicator.java | 26 ++ .../progress/util/ProgressWrapper.java | 29 +- .../util/ExternalSystemUtil.java | 6 +- .../CompletionProgressIndicator.java | 5 - .../actions/ShowImplementationsAction.java | 43 ++- .../ide/hierarchy/HierarchyBrowserBaseEx.java | 18 +- .../ide/hierarchy/HierarchyTreeBuilder.java | 22 +- .../util/scopeChooser/ScopeEditorPanel.java | 15 +- .../impl/UsageContextCallHierarchyPanel.java | 9 - .../download/impl/FileDownloaderImpl.java | 24 +- .../ide/util/DelegatingProgressIndicator.java | 8 +- .../ide/util/treeView/AbstractTreeUi.java | 10 +- .../concurrency/SensitiveProgressWrapper.java | 8 +- .../CustomizeFeaturedPluginsStepPanel.java | 5 +- .../progress/impl/NonCancelableIndicator.java | 154 ++++++++ .../progress/impl/ProgressManagerImpl.java | 38 +- .../util/AbstractProgressIndicatorExBase.java | 350 ++++++++++++++++++ .../util/BlockingProgressIndicator.java | 8 +- .../progress/util/ProgressIndicatorBase.java | 330 +---------------- .../openapi/progress/util/ProgressWindow.java | 19 +- .../util/ProgressWindowWithNotification.java | 38 +- .../progress/util/SmoothProgressAdapter.java | 48 ++- .../wm/impl/status/InfoAndProgressPanel.java | 14 +- .../plugin/ui/SearchDialog.java | 9 +- .../vcs/changes/ChangeListManagerImpl.java | 113 ++++-- 29 files changed, 833 insertions(+), 566 deletions(-) create mode 100644 platform/core-api/src/com/intellij/openapi/progress/StandardProgressIndicator.java create mode 100644 platform/platform-impl/src/com/intellij/openapi/progress/impl/NonCancelableIndicator.java create mode 100644 platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java index 2f9f023bc52a..ad73000a113a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java +++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java @@ -35,7 +35,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; -import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase; import com.intellij.openapi.project.DumbModeAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; @@ -244,7 +244,7 @@ public class CompilerTask extends Task.Backgroundable { if (!(indicator instanceof ProgressIndicatorEx)) { return; } - ((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() { + ((ProgressIndicatorEx)indicator).addStateDelegate(new AbstractProgressIndicatorExBase() { @Override public void cancel() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java index 601ec7957849..1f3d8e959634 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -25,6 +25,7 @@ import com.intellij.notification.NotificationType; import com.intellij.openapi.progress.PerformInBackgroundOption; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase; import com.intellij.openapi.progress.util.ProgressWindow; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; @@ -54,12 +55,14 @@ public class HotSwapProgressImpl extends HotSwapProgress{ public void processSentToBackground() { } - }, null, null, true) { + }, null, null, true); + myProgressWindow.addStateDelegate(new AbstractProgressIndicatorExBase(){ + @Override public void cancel() { - HotSwapProgressImpl.this.cancel(); super.cancel(); + HotSwapProgressImpl.this.cancel(); } - }; + }); } public void finished() { diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/DaemonProgressIndicator.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/DaemonProgressIndicator.java index 5c23a2dd7247..c5dd343a9e84 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/DaemonProgressIndicator.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/DaemonProgressIndicator.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.daemon.impl; +import com.intellij.openapi.progress.StandardProgressIndicator; import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase; import com.intellij.openapi.util.TraceableDisposable; import org.jetbrains.annotations.NotNull; @@ -24,7 +25,7 @@ import org.jetbrains.annotations.TestOnly; /** * @author cdr */ -public class DaemonProgressIndicator extends AbstractProgressIndicatorBase { +public class DaemonProgressIndicator extends AbstractProgressIndicatorBase implements StandardProgressIndicator { private static boolean debug; private final TraceableDisposable myTraceableDisposable = new TraceableDisposable(debug ? new Throwable() : null); @@ -44,11 +45,21 @@ public class DaemonProgressIndicator extends AbstractProgressIndicatorBase { } @Override - public void cancel() { + public final void cancel() { myTraceableDisposable.kill("Daemon Progress Canceled"); super.cancel(); } + @Override + public final boolean isCanceled() { + return super.isCanceled(); + } + + @Override + public final void checkCanceled() { + super.checkCanceled(); + } + public void cancel(@NotNull Throwable cause) { myTraceableDisposable.kill("Daemon Progress Canceled because of "+cause); super.cancel(); diff --git a/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java b/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java index 81e71a800192..4f68f1d25f25 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java +++ b/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java @@ -19,7 +19,7 @@ package com.intellij.openapi.progress; import com.intellij.openapi.application.ModalityState; import org.jetbrains.annotations.NotNull; -public class EmptyProgressIndicator implements ProgressIndicator { +public class EmptyProgressIndicator implements StandardProgressIndicator { private volatile boolean myIsRunning = false; private volatile boolean myIsCanceled = false; @@ -40,16 +40,23 @@ public class EmptyProgressIndicator implements ProgressIndicator { } @Override - public void cancel() { + public final void cancel() { myIsCanceled = true; ProgressManager.canceled(this); } @Override - public boolean isCanceled() { + public final boolean isCanceled() { return myIsCanceled; } + @Override + public final void checkCanceled() { + if (myIsCanceled) { + throw new ProcessCanceledException(); + } + } + @Override public void setText(String text) { } @@ -117,13 +124,6 @@ public class EmptyProgressIndicator implements ProgressIndicator { public void setIndeterminate(boolean indeterminate) { } - @Override - public void checkCanceled() { - if (myIsCanceled) { - throw new ProcessCanceledException(); - } - } - @Override public boolean isPopupWasShown() { return false; diff --git a/platform/core-api/src/com/intellij/openapi/progress/StandardProgressIndicator.java b/platform/core-api/src/com/intellij/openapi/progress/StandardProgressIndicator.java new file mode 100644 index 000000000000..b25c1dc54591 --- /dev/null +++ b/platform/core-api/src/com/intellij/openapi/progress/StandardProgressIndicator.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 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.progress; + +/** + * Marker interface which means this indicator cancellation behaves in a standard way: + * - checkCanceled() checks for isCanceled() and throws PCE if returned true + * - cancel() sets the corresponding flag + * - isCanceled() is true after cancel() call + * - all methods above are final + */ +public interface StandardProgressIndicator extends ProgressIndicator { +} diff --git a/platform/core-impl/src/com/intellij/openapi/progress/util/ProgressWrapper.java b/platform/core-impl/src/com/intellij/openapi/progress/util/ProgressWrapper.java index b0a88840a541..ae268dbc996b 100644 --- a/platform/core-impl/src/com/intellij/openapi/progress/util/ProgressWrapper.java +++ b/platform/core-impl/src/com/intellij/openapi/progress/util/ProgressWrapper.java @@ -23,20 +23,40 @@ package com.intellij.openapi.progress.util; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.StandardProgressIndicator; import com.intellij.openapi.progress.WrappedProgressIndicator; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ProgressWrapper extends AbstractProgressIndicatorBase implements WrappedProgressIndicator { +public class ProgressWrapper extends AbstractProgressIndicatorBase implements WrappedProgressIndicator, StandardProgressIndicator { private final ProgressIndicator myOriginal; + private final boolean myCheckCanceledForMe; protected ProgressWrapper(@NotNull ProgressIndicator original) { + this(original, false); + } + + protected ProgressWrapper(@NotNull ProgressIndicator original, boolean checkCanceledForMe) { myOriginal = original; + myCheckCanceledForMe = checkCanceledForMe; + } + + + @Override + public final void cancel() { + super.cancel(); + } + + + @Override + public final boolean isCanceled() { + return myOriginal.isCanceled() || myCheckCanceledForMe && super.isCanceled(); } @Override - public boolean isCanceled() { - return myOriginal.isCanceled(); + public final void checkCanceled() { + super.checkCanceled(); } @Override @@ -45,11 +65,12 @@ public class ProgressWrapper extends AbstractProgressIndicatorBase implements Wr return myOriginal; } - @Nullable + @Contract(value = "null -> null; !null -> !null", pure = true) public static ProgressWrapper wrap(@Nullable ProgressIndicator indicator) { return indicator == null || indicator instanceof ProgressWrapper ? (ProgressWrapper)indicator : new ProgressWrapper(indicator); } + @Contract(value = "null -> null; !null -> !null", pure = true) public static ProgressIndicator unwrap(ProgressIndicator indicator) { return indicator instanceof ProgressWrapper ? ((ProgressWrapper)indicator).getOriginalProgressIndicator() : indicator; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java index 7d360d7442ff..762ec55cd685 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -67,7 +67,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.progress.PerformInBackgroundOption; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; -import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.roots.libraries.Library; @@ -441,7 +441,7 @@ public class ExternalSystemUtil { if(project.isDisposed()) return; if (indicator instanceof ProgressIndicatorEx) { - ((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() { + ((ProgressIndicatorEx)indicator).addStateDelegate(new AbstractProgressIndicatorExBase() { @Override public void cancel() { super.cancel(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 4f02d6bc5e54..6a1bcd963213 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -273,11 +273,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } - @Override - public void cancel() { - super.cancel(); - } - private boolean isOutdated() { return CompletionServiceImpl.getCompletionPhase().indicator != this; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java index 376c24289617..6fce9f27a393 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java @@ -56,6 +56,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.*; @@ -65,8 +66,8 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { private static final Logger LOG = Logger.getInstance("#" + ShowImplementationsAction.class.getName()); - private WeakReference myPopupRef; - private WeakReference myTaskRef; + private Reference myPopupRef; + private Reference myTaskRef; public ShowImplementationsAction() { setEnabledInModalContext(true); @@ -284,7 +285,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { @Override public boolean process(JBPopup popup) { usageView.set(component.showInUsageView()); - myTaskRef = new WeakReference(null); + myTaskRef = null; popup.cancel(); return false; } @@ -292,10 +293,8 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { .setCancelCallback(new Computable() { @Override public Boolean compute() { - final BackgroundUpdaterTask task = SoftReference.dereference(myTaskRef); - if (task != null) { - task.setCanceled(); - } + ImplementationsUpdaterTask task = SoftReference.dereference(myTaskRef); + cancelTask(task); return Boolean.TRUE; } }) @@ -310,27 +309,31 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { } } + private static boolean cancelTask(ImplementationsUpdaterTask task) { + if (task != null) { + ProgressIndicator indicator = task.myIndicator; + if (indicator != null) { + indicator.cancel(); + } + return task.setCanceled(); + } + return false; + } + private void updateInBackground(Editor editor, @Nullable PsiElement element, ImplementationViewComponent component, String title, AbstractPopup popup, Ref usageView) { - final BackgroundUpdaterTask updaterTask = SoftReference.dereference(myTaskRef); - if (updaterTask != null) { - updaterTask.setCanceled(); - } + final ImplementationsUpdaterTask updaterTask = SoftReference.dereference(myTaskRef); + cancelTask(updaterTask); if (element == null) return; //already found final ImplementationsUpdaterTask task = new ImplementationsUpdaterTask(element, editor, title, isIncludeAlwaysSelf()); task.init(popup, component, usageView); - myTaskRef = new WeakReference(task); - ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, new BackgroundableProcessIndicator(task) { - @Override - public boolean isCanceled() { - return super.isCanceled() || task.isCanceled(); - } - }); + myTaskRef = new WeakReference(task); + ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, new BackgroundableProcessIndicator(task)); } protected boolean isIncludeAlwaysSelf() { @@ -402,6 +405,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { private final PsiElement myElement; private final boolean myIncludeSelf; private PsiElement[] myElements; + private volatile ProgressIndicator myIndicator; public ImplementationsUpdaterTask(final PsiElement element, final Editor editor, final String caption, boolean includeSelf) { super(element.getProject(), ImplementationSearcher.SEARCHING_FOR_IMPLEMENTATIONS); @@ -434,6 +438,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { @Override public void run(@NotNull final ProgressIndicator indicator) { + myIndicator = indicator; super.run(indicator); final ImplementationSearcher.BackgroundableImplementationSearcher implementationSearcher = new ImplementationSearcher.BackgroundableImplementationSearcher() { @@ -465,7 +470,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { @Override public void onSuccess() { - if (!setCanceled()) { + if (!cancelTask(this)) { myComponent.update(myElements, myComponent.getIndex()); } super.onSuccess(); diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java index 982904c9c629..85240f16d868 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -21,13 +21,9 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.OccurenceNavigator; import com.intellij.ide.OccurenceNavigatorSupport; import com.intellij.ide.PsiCopyPasteManager; -import com.intellij.ide.dnd.DnDAction; -import com.intellij.ide.dnd.DnDDragStartBean; -import com.intellij.ide.dnd.DnDManager; -import com.intellij.ide.dnd.DnDSource; +import com.intellij.ide.dnd.*; import com.intellij.ide.dnd.aware.DnDAwareTree; import com.intellij.ide.projectView.impl.ProjectViewTree; -import com.intellij.ide.dnd.TransferableWrapper; import com.intellij.ide.util.scopeChooser.EditScopesDialog; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.actionSystem.*; @@ -35,7 +31,6 @@ import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.OpenFileDescriptor; -import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; @@ -82,7 +77,7 @@ public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implem private boolean myCachedIsValidBase = false; - private final HashMap myOccurrenceNavigators = new HashMap(); + private final Map myOccurrenceNavigators = new HashMap(); private static final OccurenceNavigator EMPTY_NAVIGATOR = new OccurenceNavigator() { @Override @@ -745,11 +740,4 @@ public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implem } } } - - // will throw PCE during update when canceled - public void setProgressIndicator(@NotNull ProgressIndicator indicator) { - for (HierarchyTreeBuilder builder : myBuilders.values()) { - builder.setProgressIndicator(indicator); - } - } } diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java index 22e05a53c02a..15c7440e15f1 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyTreeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -84,28 +84,10 @@ public class HierarchyTreeBuilder extends AbstractTreeBuilder { } - private MyStatusBarProgress myProgress; @Override @NotNull protected ProgressIndicator createProgressIndicator() { - return myProgress = new MyStatusBarProgress(); - } - - public void setProgressIndicator(@NotNull ProgressIndicator indicator) { - myProgress.setSecondaryIndicator(indicator); - } - - private static class MyStatusBarProgress extends StatusBarProgress { - private ProgressIndicator mySecondaryIndicator; - - public void setSecondaryIndicator(ProgressIndicator indicator) { - mySecondaryIndicator = indicator; - } - - @Override - public boolean isCanceled() { - return super.isCanceled() || mySecondaryIndicator != null && mySecondaryIndicator.isCanceled(); - } + return new StatusBarProgress(); } private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java index 001c21e5f8da..de74e6530cf2 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -78,7 +78,6 @@ public class ScopeEditorPanel { private JLabel myCaretPositionLabel; private int myCaretPosition = 0; - private boolean myTextChanged = false; private JPanel myMatchingCountPanel; private JPanel myPositionPanel; private JLabel myRecursivelyIncluded; @@ -187,7 +186,7 @@ public class ScopeEditorPanel { private void onTextChange() { if (!myIsInUpdate) { myUpdateAlarm.cancelAllRequests(); - myTextChanged = true; + cancelCurrentProgress(); final String text = myPatternField.getText(); myCurrentScope = new InvalidPackageSet(text); try { @@ -602,12 +601,12 @@ public class ScopeEditorPanel { ProgressManager.getInstance().runProcess(updateModel, progress); } - protected PanelProgressIndicator createProgressIndicator(final boolean requestFocus) { + private PanelProgressIndicator createProgressIndicator(final boolean requestFocus) { return new MyPanelProgressIndicator(requestFocus); } public void cancelCurrentProgress(){ - if (myCurrentProgress != null && myCurrentProgress.isRunning()){ + if (myCurrentProgress != null){ myCurrentProgress.cancel(); } } @@ -748,12 +747,6 @@ public class ScopeEditorPanel { } }); myRequestFocus = requestFocus; - myTextChanged = false; - } - - @Override - public boolean isCanceled() { - return super.isCanceled() || myTextChanged; } @Override diff --git a/platform/lang-impl/src/com/intellij/usageView/impl/UsageContextCallHierarchyPanel.java b/platform/lang-impl/src/com/intellij/usageView/impl/UsageContextCallHierarchyPanel.java index ed41617db47c..5469e8986daf 100644 --- a/platform/lang-impl/src/com/intellij/usageView/impl/UsageContextCallHierarchyPanel.java +++ b/platform/lang-impl/src/com/intellij/usageView/impl/UsageContextCallHierarchyPanel.java @@ -22,7 +22,6 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.impl.SimpleDataContext; -import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.psi.PsiElement; @@ -124,14 +123,6 @@ public class UsageContextCallHierarchyPanel extends UsageContextPanelBase { if (browser instanceof HierarchyBrowserBaseEx) { HierarchyBrowserBaseEx browserEx = (HierarchyBrowserBaseEx)browser; browserEx.changeView(CallHierarchyBrowserBase.CALLER_TYPE); - final ProgressIndicatorBase indicator = new ProgressIndicatorBase(); - Disposer.register(browserEx, new Disposable() { - @Override - public void dispose() { - indicator.cancel(); - } - }); - browserEx.setProgressIndicator(indicator); } return browser; } diff --git a/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java b/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java index 20d889d1edfa..f192ab314865 100644 --- a/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java +++ b/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -18,6 +18,7 @@ package com.intellij.util.download.impl; import com.google.common.base.Throwables; import com.google.common.util.concurrent.AtomicDouble; +import com.intellij.concurrency.SensitiveProgressWrapper; import com.intellij.ide.IdeBundle; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.Result; @@ -30,7 +31,6 @@ import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; @@ -71,13 +71,13 @@ public class FileDownloaderImpl implements FileDownloader { @NonNls private static final String LIB_SCHEMA = "lib://"; private final List myFileDescriptions; - private JComponent myParentComponent; - private @Nullable Project myProject; + private final JComponent myParentComponent; + @Nullable private final Project myProject; private String myDirectoryForDownloadedFilesPath; private final String myDialogTitle; public FileDownloaderImpl(@NotNull List fileDescriptions, - final @Nullable Project project, + @Nullable final Project project, @Nullable JComponent parentComponent, @NotNull String presentableDownloadName) { myProject = project; @@ -305,8 +305,8 @@ public class FileDownloaderImpl implements FileDownloader { } @NotNull - private static File downloadFile(final @NotNull DownloadableFileDescription fileDescription, final @NotNull File existingFile, - final @NotNull ProgressIndicator indicator) throws IOException { + private static File downloadFile(@NotNull final DownloadableFileDescription fileDescription, @NotNull final File existingFile, + @NotNull final ProgressIndicator indicator) throws IOException { final String presentableUrl = fileDescription.getPresentableDownloadUrl(); indicator.setText2(IdeBundle.message("progress.connecting.to.download.file.text", presentableUrl)); indicator.setIndeterminate(true); @@ -380,7 +380,7 @@ public class FileDownloaderImpl implements FileDownloader { private final int myTasksCount; private final AtomicDouble myTotalFraction; private final Object myLock = new Object(); - private LinkedHashMap myText2Stack = new LinkedHashMap(); + private final LinkedHashMap myText2Stack = new LinkedHashMap(); private ConcurrentTasksProgressManager(ProgressIndicator parent, int tasksCount) { myParent = parent; @@ -417,11 +417,12 @@ public class FileDownloaderImpl implements FileDownloader { } } - private static class SubTaskProgressIndicator extends AbstractProgressIndicatorBase { + private static class SubTaskProgressIndicator extends SensitiveProgressWrapper { private final AtomicDouble myFraction; private final ConcurrentTasksProgressManager myProgressManager; private SubTaskProgressIndicator(ConcurrentTasksProgressManager progressManager) { + super(progressManager.myParent); myProgressManager = progressManager; myFraction = new AtomicDouble(); } @@ -452,10 +453,5 @@ public class FileDownloaderImpl implements FileDownloader { setFraction(1); myProgressManager.setText2(this, null); } - - @Override - public boolean isCanceled() { - return super.isCanceled() || myProgressManager.myParent.isCanceled(); - } } } diff --git a/platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java b/platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java index c8db3b7b6d4d..0783c2ccfb51 100644 --- a/platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java +++ b/platform/platform-api/src/com/intellij/ide/util/DelegatingProgressIndicator.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull; * @author Eugene Zhuravlev * Date: Jul 12, 2007 */ -public class DelegatingProgressIndicator implements WrappedProgressIndicator { +public class DelegatingProgressIndicator implements WrappedProgressIndicator, StandardProgressIndicator { private final ProgressIndicator myIndicator; public DelegatingProgressIndicator(@NotNull ProgressIndicator indicator) { @@ -51,12 +51,12 @@ public class DelegatingProgressIndicator implements WrappedProgressIndicator { } @Override - public void cancel() { + public final void cancel() { myIndicator.cancel(); } @Override - public boolean isCanceled() { + public final boolean isCanceled() { return myIndicator.isCanceled(); } @@ -137,7 +137,7 @@ public class DelegatingProgressIndicator implements WrappedProgressIndicator { } @Override - public void checkCanceled() throws ProcessCanceledException { + public final void checkCanceled() throws ProcessCanceledException { myIndicator.checkCanceled(); } diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index cd8499850430..17a80de39e72 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -18,6 +18,7 @@ package com.intellij.ide.util.treeView; import com.intellij.ide.IdeBundle; import com.intellij.ide.UiActivity; import com.intellij.ide.UiActivityMonitor; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -238,6 +239,14 @@ public class AbstractTreeUi { setUpdater(getBuilder().createUpdater()); myProgress = getBuilder().createProgressIndicator(); Disposer.register(getBuilder(), getUpdater()); + if (myProgress != null) { + Disposer.register(getBuilder(), new Disposable() { + @Override + public void dispose() { + myProgress.cancel(); + } + }); + } final UiNotifyConnector uiNotify = new UiNotifyConnector(tree, new Activatable() { @Override @@ -5111,5 +5120,4 @@ public class AbstractTreeUi { } }); } - } diff --git a/platform/platform-impl/src/com/intellij/concurrency/SensitiveProgressWrapper.java b/platform/platform-impl/src/com/intellij/concurrency/SensitiveProgressWrapper.java index e471f68a58c8..ae1164b8bc77 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/SensitiveProgressWrapper.java +++ b/platform/platform-impl/src/com/intellij/concurrency/SensitiveProgressWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -24,11 +24,7 @@ import org.jetbrains.annotations.NotNull; */ public class SensitiveProgressWrapper extends ProgressWrapper { public SensitiveProgressWrapper(@NotNull ProgressIndicator indicator) { - super(indicator); + super(indicator, true); } - @Override - public boolean isCanceled() { - return super.isCanceled() || getOriginalProgressIndicator().isCanceled(); - } } diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java index 498391b8e971..4371c3c991cf 100644 --- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java +++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java @@ -21,9 +21,10 @@ import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.ide.plugins.PluginNode; import com.intellij.openapi.options.OptionsBundle; -import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase; import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.openapi.updateSettings.impl.PluginDownloader; +import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.ui.ColorUtil; import com.intellij.ui.JBColor; import com.intellij.ui.border.CustomLineBorder; @@ -121,7 +122,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt wrapperLayout.show(buttonWrapper, "button"); - final ProgressIndicatorBase indicator = new ProgressIndicatorBase(true) { + final ProgressIndicatorEx indicator = new AbstractProgressIndicatorExBase(true) { @Override public void start() { diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/NonCancelableIndicator.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/NonCancelableIndicator.java new file mode 100644 index 000000000000..1d5b6b48bbb1 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/NonCancelableIndicator.java @@ -0,0 +1,154 @@ +/* + * Copyright 2000-2014 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.progress.impl; + +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.progress.NonCancelableSection; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.StandardProgressIndicator; +import org.jetbrains.annotations.NotNull; + +class NonCancelableIndicator implements NonCancelableSection, StandardProgressIndicator { + protected final ProgressIndicator myOld; + + NonCancelableIndicator() { + myOld = ProgressManager.getInstance().getProgressIndicator(); + } + + @Override + public void done() { + ProgressIndicator currentIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (currentIndicator != this) { + throw new AssertionError("Trying do .done() NonCancelableSection, which is already done"); + } + } + + @Override + public final void checkCanceled() { + } + + @Override + public void start() { + + } + + @Override + public void stop() { + + } + + @Override + public boolean isRunning() { + return true; + } + + @Override + public final void cancel() { + + } + + @Override + public final boolean isCanceled() { + return false; + } + + @Override + public void setText(String text) { + + } + + @Override + public String getText() { + return null; + } + + @Override + public void setText2(String text) { + + } + + @Override + public String getText2() { + return null; + } + + @Override + public double getFraction() { + return 0; + } + + @Override + public void setFraction(double fraction) { + + } + + @Override + public void pushState() { + + } + + @Override + public void popState() { + + } + + @Override + public void startNonCancelableSection() { + + } + + @Override + public void finishNonCancelableSection() { + + } + + @Override + public boolean isModal() { + return false; + } + + @NotNull + @Override + public ModalityState getModalityState() { + return ModalityState.NON_MODAL; + } + + @Override + public void setModalityProgress(ProgressIndicator modalityProgress) { + + } + + @Override + public boolean isIndeterminate() { + return false; + } + + @Override + public void setIndeterminate(boolean indeterminate) { + + } + + @Override + public boolean isPopupWasShown() { + return false; + } + + @Override + public boolean isShowing() { + return false; + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java index a728179a0f24..c166ccae50a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java @@ -76,39 +76,27 @@ public class ProgressManagerImpl extends ProgressManager { } } - private static class NonCancelableIndicator extends EmptyProgressIndicator implements NonCancelableSection { - private final ProgressIndicator myOld; - - private NonCancelableIndicator() { - myOld = myThreadIndicator.get(); - } - - @Override - public void done() { - ProgressIndicator currentIndicator = myThreadIndicator.get(); - if (currentIndicator != this) { - throw new AssertionError("Trying do .done() NonCancelableSection, which is already done"); - } - - myThreadIndicator.set(myOld); - } - - @Override - public void checkCanceled() { - } - } - @NotNull @Override public final NonCancelableSection startNonCancelableSection() { - NonCancelableIndicator nonCancelor = new NonCancelableIndicator(); + NonCancelableIndicator nonCancelor = createNonCancelableIndicator(); myThreadIndicator.set(nonCancelor); return nonCancelor; } @Override public void executeNonCancelableSection(@NotNull Runnable runnable) { - executeProcessUnderProgress(runnable, new NonCancelableIndicator()); + executeProcessUnderProgress(runnable, createNonCancelableIndicator()); + } + + @NotNull + private static NonCancelableIndicator createNonCancelableIndicator() { + return new NonCancelableIndicator(){ + @Override + public void done() { + myThreadIndicator.set(myOld); + } + }; } @Override @@ -116,7 +104,7 @@ public class ProgressManagerImpl extends ProgressManager { ProgressIndicator progressIndicator = getProgressIndicator(); if (progressIndicator != null) { if (progressIndicator instanceof SmoothProgressAdapter && cancelButtonText != null) { - ProgressIndicator original = ((SmoothProgressAdapter)progressIndicator).getOriginal(); + ProgressIndicator original = ((SmoothProgressAdapter)progressIndicator).getOriginalProgressIndicator(); if (original instanceof ProgressWindow) { ((ProgressWindow)original).setCancelButtonText(cancelButtonText); } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java new file mode 100644 index 000000000000..3a4bb05c173d --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java @@ -0,0 +1,350 @@ +/* + * Copyright 2000-2014 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.progress.util; + +import com.intellij.openapi.application.impl.LaterInvocator; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.TaskInfo; +import com.intellij.openapi.wm.ex.ProgressIndicatorEx; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.WeakList; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class AbstractProgressIndicatorExBase extends AbstractProgressIndicatorBase implements ProgressIndicatorEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressIndicatorBase"); + private static final IndicatorAction CHECK_CANCELED_ACTION = new IndicatorAction() { + @Override + public void execute(@NotNull ProgressIndicatorEx each) { + each.checkCanceled(); + } + }; + private static final IndicatorAction STOP_ACTION = new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.stop(); + } + }; + private static final IndicatorAction START_ACTION = new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.start(); + } + }; + private static final IndicatorAction CANCEL_ACTION = new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.cancel(); + } + }; + private static final IndicatorAction PUSH_ACTION = new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.pushState(); + } + }; + private static final IndicatorAction POP_ACTION = new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.popState(); + } + }; + private static final IndicatorAction STARTNC_ACTION = new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.startNonCancelableSection(); + } + }; + private static final IndicatorAction FINISHNC_ACTION = new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.finishNonCancelableSection(); + } + }; + protected final boolean myReusable; + private volatile boolean myModalityEntered; + private volatile List myStateDelegates; + private volatile WeakList myFinished; + private volatile boolean myWasStarted; + private TaskInfo myOwnerTask; + + public AbstractProgressIndicatorExBase(boolean reusable) { + myReusable = reusable; + } + + public AbstractProgressIndicatorExBase() { + this(false); + } + + @Override + public void start() { + synchronized (this) { + super.start(); + delegateRunningChange(START_ACTION); + } + myWasStarted = true; + + enterModality(); + } + + protected final void enterModality() { + if (myModalityProgress == this) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + doEnterModality(); + } + }); + } + } + + private void doEnterModality() { + if (!myModalityEntered) { + LaterInvocator.enterModal(this); + myModalityEntered = true; + } + } + + @Override + public void stop() { + super.stop(); + delegateRunningChange(STOP_ACTION); + exitModality(); + } + + protected final void exitModality() { + if (myModalityProgress == this) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + doExitModality(); + } + }); + } + } + + private void doExitModality() { + if (myModalityEntered) { + LaterInvocator.leaveModal(this); + myModalityEntered = false; + } + } + + @Override + public void cancel() { + super.cancel(); + delegateRunningChange(CANCEL_ACTION); + } + + @Override + public boolean isCanceled() { + return super.isCanceled(); + } + + @Override + public void finish(@NotNull final TaskInfo task) { + WeakList finished = myFinished; + if (finished == null) { + synchronized (this) { + finished = myFinished; + if (finished == null) { + myFinished = finished = new WeakList(); + } + } + } + if (!finished.addIfAbsent(task)) return; + + delegateRunningChange(new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.finish(task); + } + }); + } + + @Override + public boolean isFinished(@NotNull final TaskInfo task) { + List list = myFinished; + return list != null && list.contains(task); + } + + protected void setOwnerTask(TaskInfo owner) { + myOwnerTask = owner; + } + + @Override + public void processFinish() { + if (myOwnerTask != null) { + finish(myOwnerTask); + myOwnerTask = null; + } + } + + @Override + public final void checkCanceled() { + super.checkCanceled(); + + delegate(CHECK_CANCELED_ACTION); + } + + @Override + public void setText(final String text) { + super.setText(text); + + delegateProgressChange(new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.setText(text); + } + }); + } + + @Override + public void setText2(final String text) { + super.setText2(text); + + delegateProgressChange(new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.setText2(text); + } + }); + } + + @Override + public void setFraction(final double fraction) { + super.setFraction(fraction); + + delegateProgressChange(new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.setFraction(fraction); + } + }); + } + + @Override + public synchronized void pushState() { + super.pushState(); + + delegateProgressChange(PUSH_ACTION); + } + + @Override + public synchronized void popState() { + super.popState(); + + delegateProgressChange(POP_ACTION); + } + + @Override + public void startNonCancelableSection() { + super.startNonCancelableSection(); + + delegateProgressChange(STARTNC_ACTION); + } + + @Override + public void finishNonCancelableSection() { + super.finishNonCancelableSection(); + + delegateProgressChange(FINISHNC_ACTION); + } + + @Override + protected boolean isReuseable() { + return myReusable; + } + + @Override + public void setIndeterminate(final boolean indeterminate) { + super.setIndeterminate(indeterminate); + + delegateProgressChange(new IndicatorAction() { + @Override + public void execute(@NotNull final ProgressIndicatorEx each) { + each.setIndeterminate(indeterminate); + } + }); + } + + @Override + public final void addStateDelegate(@NotNull ProgressIndicatorEx delegate) { + delegate.initStateFrom(this); + synchronized (this) { + List stateDelegates = myStateDelegates; + if (stateDelegates == null) { + myStateDelegates = stateDelegates = ContainerUtil.createLockFreeCopyOnWriteList(); + } + else { + LOG.assertTrue(!stateDelegates.contains(delegate), "Already registered: " + delegate); + } + stateDelegates.add(delegate); + } + } + + private void delegateProgressChange(@NotNull IndicatorAction action) { + delegate(action); + onProgressChange(); + } + + private void delegateRunningChange(@NotNull IndicatorAction action) { + delegate(action); + onRunningChange(); + } + + private void delegate(@NotNull IndicatorAction action) { + List list = myStateDelegates; + if (list != null && !list.isEmpty()) { + for (ProgressIndicatorEx each : list) { + action.execute(each); + } + } + } + + protected void onProgressChange() { + + } + + protected void onRunningChange() { + + } + + @Override + public boolean isModalityEntered() { + return myModalityEntered; + } + + @Override + public synchronized void initStateFrom(@NotNull final ProgressIndicator indicator) { + super.initStateFrom(indicator); + if (indicator instanceof ProgressIndicatorEx) { + myModalityEntered = ((ProgressIndicatorEx)indicator).isModalityEntered(); + } + } + + @Override + public boolean wasStarted() { + return myWasStarted; + } + + private interface IndicatorAction { + void execute(@NotNull ProgressIndicatorEx each); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/BlockingProgressIndicator.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/BlockingProgressIndicator.java index be8e628bbcb5..e8758dd12db4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/BlockingProgressIndicator.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/BlockingProgressIndicator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -15,6 +15,8 @@ */ package com.intellij.openapi.progress.util; -public abstract class BlockingProgressIndicator extends ProgressIndicatorBase { - public abstract void startBlocking(); +import com.intellij.openapi.wm.ex.ProgressIndicatorEx; + +public interface BlockingProgressIndicator extends ProgressIndicatorEx { + public void startBlocking(); } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java index b4821f52fddb..d71a1125af94 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java @@ -15,336 +15,24 @@ */ package com.intellij.openapi.progress.util; -import com.intellij.openapi.application.impl.LaterInvocator; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.TaskInfo; -import com.intellij.openapi.wm.ex.ProgressIndicatorEx; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.WeakList; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; +import com.intellij.openapi.progress.StandardProgressIndicator; -import java.util.List; +public class ProgressIndicatorBase extends AbstractProgressIndicatorExBase implements StandardProgressIndicator { + public ProgressIndicatorBase() { + this(false); + } -public class ProgressIndicatorBase extends AbstractProgressIndicatorBase implements ProgressIndicatorEx { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressIndicatorBase"); - private final boolean myReusable; - - private volatile boolean myModalityEntered; - - private volatile List myStateDelegates; - private volatile WeakList myFinished; - private volatile boolean myWasStarted; - - private TaskInfo myOwnerTask; - private static final IndicatorAction CHECK_CANCELED_ACTION = new IndicatorAction() { - @Override - public void execute(@NotNull ProgressIndicatorEx each) { - each.checkCanceled(); - } - }; - private static final IndicatorAction STOP_ACTION = new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.stop(); - } - }; - private static final IndicatorAction START_ACTION = new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.start(); - } - }; - private static final IndicatorAction CANCEL_ACTION = new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.cancel(); - } - }; - private static final IndicatorAction PUSH_ACTION = new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.pushState(); - } - }; - private static final IndicatorAction POP_ACTION = new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.popState(); - } - }; - private static final IndicatorAction STARTNC_ACTION = new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.startNonCancelableSection(); - } - }; - private static final IndicatorAction FINISHNC_ACTION = new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.finishNonCancelableSection(); - } - }; - - public ProgressIndicatorBase() { this(false); } public ProgressIndicatorBase(boolean reusable) { - myReusable = reusable; + super(reusable); } @Override - public void start() { - synchronized (this) { - super.start(); - delegateRunningChange(START_ACTION); - } - myWasStarted = true; - - enterModality(); - } - - protected final void enterModality() { - if (myModalityProgress == this) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - doEnterModality(); - } - }); - } - } - - private void doEnterModality() { - if (!myModalityEntered) { - LaterInvocator.enterModal(this); - myModalityEntered = true; - } - } - - @Override - public void stop() { - super.stop(); - delegateRunningChange(STOP_ACTION); - exitModality(); - } - - protected final void exitModality() { - if (myModalityProgress == this) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - doExitModality(); - } - }); - } - } - - private void doExitModality() { - if (myModalityEntered) { - LaterInvocator.leaveModal(this); - myModalityEntered = false; - } - } - - - @Override - public void cancel() { + public final void cancel() { super.cancel(); - delegateRunningChange(CANCEL_ACTION); } @Override - public void finish(@NotNull final TaskInfo task) { - WeakList finished = myFinished; - if (finished == null) { - synchronized (this) { - finished = myFinished; - if (finished == null) { - myFinished = finished = new WeakList(); - } - } - } - if (!finished.addIfAbsent(task)) return; - - delegateRunningChange(new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.finish(task); - } - }); - } - - @Override - public boolean isFinished(@NotNull final TaskInfo task) { - List list = myFinished; - return list != null && list.contains(task); - } - - protected void setOwnerTask(TaskInfo owner) { - myOwnerTask = owner; - } - - @Override - public void processFinish() { - if (myOwnerTask != null) { - finish(myOwnerTask); - myOwnerTask = null; - } - } - - @Override - public final void checkCanceled() { - super.checkCanceled(); - - delegate(CHECK_CANCELED_ACTION); - } - - @Override - public void setText(final String text) { - super.setText(text); - - delegateProgressChange(new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.setText(text); - } - }); - } - - - @Override - public void setText2(final String text) { - super.setText2(text); - - delegateProgressChange(new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.setText2(text); - } - }); - } - - - - @Override - public void setFraction(final double fraction) { - super.setFraction(fraction); - - delegateProgressChange(new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.setFraction(fraction); - } - }); - } - - @Override - public synchronized void pushState() { - super.pushState(); - - delegateProgressChange(PUSH_ACTION); - } - - @Override - public synchronized void popState() { - super.popState(); - - delegateProgressChange(POP_ACTION); - } - - @Override - public void startNonCancelableSection() { - super.startNonCancelableSection(); - - delegateProgressChange(STARTNC_ACTION); - } - - @Override - public void finishNonCancelableSection() { - super.finishNonCancelableSection(); - - delegateProgressChange(FINISHNC_ACTION); - } - - @Override - protected boolean isReuseable() { - return myReusable; - } - - @Override - public void setIndeterminate(final boolean indeterminate) { - super.setIndeterminate(indeterminate); - - delegateProgressChange(new IndicatorAction() { - @Override - public void execute(@NotNull final ProgressIndicatorEx each) { - each.setIndeterminate(indeterminate); - } - }); - } - - @Override - public final void addStateDelegate(@NotNull ProgressIndicatorEx delegate) { - delegate.initStateFrom(this); - synchronized (this) { - List stateDelegates = myStateDelegates; - if (stateDelegates == null) { - myStateDelegates = stateDelegates = ContainerUtil.createLockFreeCopyOnWriteList(); - } - else { - LOG.assertTrue(!stateDelegates.contains(delegate), "Already registered: " + delegate); - } - stateDelegates.add(delegate); - } - } - - private void delegateProgressChange(@NotNull IndicatorAction action) { - delegate(action); - onProgressChange(); - } - - private void delegateRunningChange(@NotNull IndicatorAction action) { - delegate(action); - onRunningChange(); - } - - private void delegate(@NotNull IndicatorAction action) { - List list = myStateDelegates; - if (list != null && !list.isEmpty()) { - for (ProgressIndicatorEx each : list) { - action.execute(each); - } - } - } - - private interface IndicatorAction { - void execute(@NotNull ProgressIndicatorEx each); - } - - - protected void onProgressChange() { - - } - - protected void onRunningChange() { - - } - - @Override - public boolean isModalityEntered() { - return myModalityEntered; - } - - @Override - public synchronized void initStateFrom(@NotNull final ProgressIndicator indicator) { - super.initStateFrom(indicator); - if (indicator instanceof ProgressIndicatorEx) { - myModalityEntered = ((ProgressIndicatorEx)indicator).isModalityEntered(); - } - } - - @Override - public boolean wasStarted() { - return myWasStarted; + public final boolean isCanceled() { + return super.isCanceled(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index fd6484747dec..439860e15f97 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -46,7 +46,7 @@ import java.awt.event.*; import java.io.File; @SuppressWarnings({"NonStaticInitializer"}) -public class ProgressWindow extends BlockingProgressIndicator implements Disposable { +public class ProgressWindow extends ProgressIndicatorBase implements BlockingProgressIndicator, Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressWindow"); /** @@ -114,6 +114,15 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa Disposer.register(this, myDialog); myFocusTrackback.registerFocusComponent(myDialog.getPanel()); + addStateDelegate(new AbstractProgressIndicatorExBase(){ + @Override + public void cancel() { + super.cancel(); + if (myDialog != null) { + myDialog.cancel(); + } + } + }); } @Override @@ -289,14 +298,6 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa return myDialog != null && myDialog.getPanel() != null && myDialog.getPanel().isShowing(); } - @Override - public void cancel() { - super.cancel(); - if (myDialog != null) { - myDialog.cancel(); - } - } - public void background() { final Runnable backgroundHandler = myBackgroundHandler; if (backgroundHandler != null) { diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java index 111d5957abe0..8d5be53460d1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindowWithNotification.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -18,14 +18,11 @@ package com.intellij.openapi.progress.util; import com.intellij.openapi.project.Project; import javax.swing.*; -import java.util.LinkedList; /** * @author lex */ public class ProgressWindowWithNotification extends ProgressWindow { - private final LinkedList myListeners = new LinkedList(); - public ProgressWindowWithNotification(boolean shouldShowCancel, Project project) { super(shouldShowCancel, project); } @@ -42,25 +39,20 @@ public class ProgressWindowWithNotification extends ProgressWindow { super(shouldShowCancel, shouldShowBackground, project, parentComponent, cancelText); } - public void cancel() { - super.cancel(); - for (final ProgressIndicatorListener progressIndicatorListener : myListeners) { - progressIndicatorListener.cancelled(); - } + public void addListener(final ProgressIndicatorListener listener) { + addStateDelegate(new AbstractProgressIndicatorExBase(){ + @Override + public void cancel() { + super.cancel(); + listener.cancelled(); + } + + @Override + public void stop() { + super.stop(); + listener.stopped(); + } + }); } - public synchronized void stop() { - for (final ProgressIndicatorListener progressIndicatorListener : myListeners) { - progressIndicatorListener.stopped(); - } - super.stop(); - } - - public void addListener(ProgressIndicatorListener listener) { - myListeners.addFirst(listener); - } - - public void removeListener(ProgressIndicatorListener listener) { - myListeners.remove(listener); - } } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/SmoothProgressAdapter.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/SmoothProgressAdapter.java index 950d6ea57978..fab82af60c83 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/SmoothProgressAdapter.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/SmoothProgressAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -18,15 +18,19 @@ package com.intellij.openapi.progress.util; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.StandardProgressIndicator; +import com.intellij.openapi.progress.WrappedProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Disposer; import com.intellij.util.Alarm; import com.intellij.util.concurrency.Semaphore; +import org.jetbrains.annotations.NotNull; import javax.swing.*; -public class SmoothProgressAdapter extends BlockingProgressIndicator { +public class SmoothProgressAdapter extends AbstractProgressIndicatorExBase implements BlockingProgressIndicator, WrappedProgressIndicator, + StandardProgressIndicator { private static final int SHOW_DELAY = 500; private final Alarm myStartupAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); @@ -34,11 +38,12 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { protected ProgressIndicator myOriginal; private final Project myProject; - private boolean myOriginalStarted; + private volatile boolean myOriginalStarted; private DialogWrapper myDialog; private final Runnable myShowRequest = new Runnable() { + @Override public void run() { synchronized(SmoothProgressAdapter.this){ if (!isRunning()) { @@ -55,24 +60,33 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { } }; - public SmoothProgressAdapter(ProgressIndicator original, Project project){ + public SmoothProgressAdapter(@NotNull ProgressIndicator original, @NotNull Project project){ myOriginal = original; myProject = project; if (myOriginal.isModal()) { myOriginal.setModalityProgress(this); - this.setModalityProgress(this); + setModalityProgress(this); } } + @NotNull + @Override + public ProgressIndicator getOriginalProgressIndicator() { + return myOriginal; + } + + @Override public void setIndeterminate(boolean indeterminate) { super.setIndeterminate(indeterminate); myOriginal.setIndeterminate(indeterminate); } + @Override public boolean isIndeterminate() { return myOriginal.isIndeterminate(); } + @Override public synchronized void start() { if (isRunning()) return; @@ -81,6 +95,7 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { myStartupAlarm.addRequest(myShowRequest, SHOW_DELAY); } + @Override public void startBlocking() { ApplicationManager.getApplication().assertIsDispatchThread(); start(); @@ -98,10 +113,12 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { setResizable(false); } + @Override protected boolean isProgressDialog() { return true; } + @Override protected JComponent createCenterPanel() { return null; } @@ -112,6 +129,7 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { } } + @Override public synchronized void stop() { if (myOriginal.isRunning()) { myOriginal.stop(); @@ -131,6 +149,7 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { SwingUtilities.invokeLater( new Runnable() { + @Override public void run() { semaphore.waitFor(); if (myDialog != null){ @@ -150,6 +169,7 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { } } + @Override public synchronized void setText(String text) { super.setText(text); if (myOriginal.isRunning()) { @@ -157,6 +177,7 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { } } + @Override public synchronized void setFraction(double fraction) { super.setFraction(fraction); if (myOriginal.isRunning()) { @@ -164,6 +185,7 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { } } + @Override public synchronized void setText2(String text) { super.setText2(text); if (myOriginal.isRunning()) { @@ -171,21 +193,15 @@ public class SmoothProgressAdapter extends BlockingProgressIndicator { } } - public void cancel() { + @Override + public final void cancel() { super.cancel(); myOriginal.cancel(); } - - - public boolean isCanceled() { + @Override + public final boolean isCanceled() { if (super.isCanceled()) return true; - if (!myOriginalStarted) return false; - return myOriginal.isCanceled(); + return myOriginalStarted && myOriginal.isCanceled(); } - - public ProgressIndicator getOriginal() { - return myOriginal; - } - } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java index fa9817c93786..9ac0f7ea2b08 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java @@ -26,6 +26,7 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorsSplitters; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.TaskInfo; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase; import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; @@ -609,12 +610,13 @@ public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidge super(compact, task); myOriginal = original; original.addStateDelegate(this); - } - - @Override - public void cancel() { - super.cancel(); - updateProgress(); + addStateDelegate(new AbstractProgressIndicatorExBase(){ + @Override + public void cancel() { + super.cancel(); + updateProgress(); + } + }); } @Override diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java index 3f89f11b9e6d..cf233b749fa8 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java @@ -24,6 +24,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.fileTypes.impl.FileTypeRenderer; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.DialogWrapper; @@ -509,13 +510,15 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator new Factory() { @Override public ProgressIndicator create() { - return new FindProgressIndicator(searchContext.getProject(), presentation.getScopeText()) { + FindProgressIndicator indicator = new FindProgressIndicator(searchContext.getProject(), presentation.getScopeText()); + indicator.addStateDelegate(new AbstractProgressIndicatorExBase(){ @Override public void cancel() { - context.getCommand().stopAsyncSearch(); super.cancel(); + context.getCommand().stopAsyncSearch(); } - }; + }); + return indicator; } } ); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index 5e01feada2f3..87d39a539254 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -46,10 +46,7 @@ import com.intellij.openapi.vcs.checkin.CheckinHandler; import com.intellij.openapi.vcs.impl.*; import com.intellij.openapi.vcs.readOnlyHandler.ReadonlyStatusHandlerImpl; import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.*; import com.intellij.ui.EditorNotifications; import com.intellij.util.*; import com.intellij.util.concurrency.Semaphore; @@ -110,25 +107,26 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec private final IgnoredFilesComponent myIgnoredIdeaLevel; private boolean myExcludedConvertedToIgnored; - private ProgressIndicator myUpdateChangesProgressIndicator; + private volatile ProgressIndicator myUpdateChangesProgressIndicator = createProgressIndicator(); public static final Topic LISTS_LOADED = new Topic( "LOCAL_CHANGE_LISTS_LOADED", LocalChangeListsLoadedListener.class); private boolean myShowLocalChangesInvalidated; - private AtomicReference myFreezeName; + private final AtomicReference myFreezeName; // notifies myListeners on the same thread that local changes update is done private final DelayedNotificator myDelayedNotificator; private final VcsListener myVcsListener = new VcsListener() { + @Override public void directoryMappingChanged() { VcsDirtyScopeManager.getInstance(myProject).markEverythingDirty(); } }; private final ChangelistConflictTracker myConflictTracker; private VcsDirtyScopeManager myDirtyScopeManager; - private VcsDirtyScopeVfsListener myVfsListener; + private final VcsDirtyScopeVfsListener myVfsListener; private boolean myModalNotificationsBlocked; @NotNull private final Collection myListsToBeDeleted = new HashSet(); @@ -170,6 +168,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec !oldList.isReadOnly()) { invokeAfterUpdate(new Runnable() { + @Override public void run() { if (getChangeList(oldList.getId()) == null) { return; // removed already @@ -224,10 +223,12 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } VcsConfirmationDialog dialog = new VcsConfirmationDialog(myProject, new VcsShowConfirmationOption() { + @Override public Value getValue() { return config.REMOVE_EMPTY_INACTIVE_CHANGELISTS; } + @Override public void setValue(Value value) { config.REMOVE_EMPTY_INACTIVE_CHANGELISTS = value; } @@ -262,6 +263,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myListsToBeDeleted.clear(); } + @Override public void projectOpened() { initializeForNewProject(); @@ -273,6 +275,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec else { ((ProjectLevelVcsManagerImpl)vcsManager).addInitializationRequest( VcsInitObject.CHANGE_LIST_MANAGER, new DumbAwareRunnable() { + @Override public void run() { myUpdater.initialized(); broadcastStateAfterLoad(); @@ -332,27 +335,29 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public void projectClosed() { ProjectLevelVcsManager.getInstance(myProject).removeVcsListener(myVcsListener); synchronized (myDataLock) { - if (myUpdateChangesProgressIndicator != null) { - myUpdateChangesProgressIndicator.cancel(); - } + myUpdateChangesProgressIndicator.cancel(); } myUpdater.stop(); myConflictTracker.stopTracking(); } + @Override @NotNull @NonNls public String getComponentName() { return "ChangeListManager"; } + @Override public void initComponent() { } + @Override public void disposeComponent() { } @@ -360,6 +365,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec * update itself might produce actions done on AWT thread (invoked-after), * so waiting for its completion on AWT thread is not good runnable is invoked on AWT thread */ + @Override public void invokeAfterUpdate(final Runnable afterUpdate, final InvokeAfterUpdateMode mode, @Nullable final String title, @@ -367,6 +373,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myUpdater.invokeAfterUpdate(afterUpdate, mode, title, null, state); } + @Override public void invokeAfterUpdate(final Runnable afterUpdate, final InvokeAfterUpdateMode mode, final String title, final Consumer dirtyScopeManagerFiller, final ModalityState state) { myUpdater.invokeAfterUpdate(afterUpdate, mode, title, dirtyScopeManagerFiller, state); @@ -374,6 +381,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec static class DisposedException extends RuntimeException {} + @Override public void freeze(final ContinuationPause context, final String reason) { myUpdater.setIgnoreBackgroundOperation(true); // this update is nessesary for git, to refresh local changes before @@ -391,6 +399,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec public void freezeImmediately(@Nullable String reason) { myUpdater.setIgnoreBackgroundOperation(false); myUpdater.pause(); + myUpdateChangesProgressIndicator.cancel(); myFreezeName.set(reason); } @@ -400,14 +409,17 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myFreezeName.set(null); } + @Override public String isFreezed() { return myFreezeName.get(); } + @Override public void scheduleUpdate() { myUpdater.schedule(); } + @Override public void scheduleUpdate(boolean updateUnversionedFiles) { myUpdater.schedule(); } @@ -471,8 +483,6 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } private void updateImmediately() { - final DataHolder dataHolder; - final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); if (!vcsManager.hasActiveVcss()) return; @@ -488,6 +498,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec // copy existsing data to objects that would be updated. // mark for "modifier" that update started (it would create duplicates of modification commands done by user during update; // after update of copies of objects is complete, it would apply the same modifications to copies.) + final DataHolder dataHolder; synchronized (myDataLock) { dataHolder = new DataHolder((FileHolderComposite)myComposite.copy(), myWorker.copy(), wasEverythingDirty); myModifier.enterUpdate(); @@ -519,6 +530,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec clearCurrentRevisionsCache(invalidated); // for the case of project being closed we need a read action here -> to be more consistent ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override public void run() { if (myProject.isDisposed()) { return; @@ -653,18 +665,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } - private EmptyProgressIndicator createProgressIndicator() { - return new EmptyProgressIndicator() { - @Override - public boolean isCanceled() { - return myUpdater.isStopped(); - } - - @Override - public void checkCanceled() { - checkIfDisposed(); - } - }; + @NotNull + private static ProgressIndicator createProgressIndicator() { + return new EmptyProgressIndicator(); } private class DataHolder { @@ -779,6 +782,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec return before != null && scope.belongsTo(before.getFile()) || after != null && scope.belongsTo(after.getFile()); } + @Override public List getChangeListsCopy() { synchronized (myDataLock) { return myWorker.getListsCopy(); @@ -789,6 +793,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec * @deprecated this method made equivalent to {@link #getChangeListsCopy()} so to don't be confused by method name, * better use {@link #getChangeListsCopy()} */ + @Override @NotNull public List getChangeLists() { synchronized (myDataLock) { @@ -796,12 +801,14 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public List getAffectedPaths() { synchronized (myDataLock) { return myWorker.getAffectedPaths(); } } + @Override @NotNull public List getAffectedFiles() { synchronized (myDataLock) { @@ -809,6 +816,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override @NotNull public Collection getAllChanges() { synchronized (myDataLock) { @@ -901,12 +909,14 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public boolean isFileAffected(final VirtualFile file) { synchronized (myDataLock) { return myWorker.getStatus(file) != null; } } + @Override @Nullable public LocalChangeList findChangeList(final String name) { synchronized (myDataLock) { @@ -921,6 +931,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public LocalChangeList addChangeList(@NotNull final String name, @Nullable final String comment) { return addChangeList(name, comment, null); } @@ -940,6 +951,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } + @Override public void removeChangeList(final String name) { ApplicationManager.getApplication().runReadAction(new Runnable() { @Override @@ -952,6 +964,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec }); } + @Override public void removeChangeList(LocalChangeList list) { removeChangeList(list.getName()); } @@ -959,6 +972,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec /** * does no modification to change lists, only notification is sent */ + @Override @NotNull public Runnable prepareForChangeDeletion(final Collection changes) { final Map lists = new HashMap(); @@ -967,6 +981,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec map = myWorker.listsForChanges(changes, lists); } return new Runnable() { + @Override public void run() { final ChangeListListener multicaster = myDelayedNotificator.getProxyDispatcher(); ApplicationManager.getApplication().runReadAction(new Runnable() { @@ -997,6 +1012,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec }; } + @Override public void setDefaultChangeList(@NotNull final LocalChangeList list) { ApplicationManager.getApplication().runReadAction(new Runnable() { @Override @@ -1009,6 +1025,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myChangesViewManager.scheduleRefresh(); } + @Override @Nullable public LocalChangeList getDefaultChangeList() { synchronized (myDataLock) { @@ -1021,6 +1038,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec return list instanceof LocalChangeList && myWorker.isDefaultList((LocalChangeList)list); } + @Override @NotNull public Collection getInvolvedListsFilterChanges(final Collection changes, final List validChanges) { synchronized (myDataLock) { @@ -1028,6 +1046,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override @Nullable public LocalChangeList getChangeList(@NotNull Change change) { synchronized (myDataLock) { @@ -1045,6 +1064,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec /** * @deprecated better use normal comparison, with equals */ + @Override @Nullable public LocalChangeList getIdentityChangeList(Change change) { synchronized (myDataLock) { @@ -1067,6 +1087,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override @Nullable public Change getChange(@NotNull VirtualFile file) { synchronized (myDataLock) { @@ -1097,6 +1118,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override @Nullable public Change getChange(final FilePath file) { synchronized (myDataLock) { @@ -1104,12 +1126,14 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public boolean isUnversioned(VirtualFile file) { synchronized (myDataLock) { return myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED).containsFile(file); } } + @Override @NotNull public FileStatus getStatus(VirtualFile file) { synchronized (myDataLock) { @@ -1127,6 +1151,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override @NotNull public Collection getChangesIn(VirtualFile dir) { return getChangesIn(new FilePathImpl(dir)); @@ -1141,6 +1166,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override @NotNull public Collection getChangesIn(final FilePath dirPath) { synchronized (myDataLock) { @@ -1148,6 +1174,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public void moveChangesTo(final LocalChangeList list, final Change... changes) { ApplicationManager.getApplication().runReadAction(new Runnable() { @Override @@ -1178,6 +1205,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec final List exceptions = new ArrayList(); final Set allProcessedFiles = new HashSet(); ChangesUtil.processVirtualFilesByVcs(myProject, files, new ChangesUtil.PerVcsProcessor() { + @Override public void process(final AbstractVcs vcs, final List items) { final CheckinEnvironment environment = vcs.getCheckinEnvironment(); if (environment != null) { @@ -1219,6 +1247,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec if (!list.isDefault()) { // find the changes for the added files and move them to the necessary changelist invokeAfterUpdate(new Runnable() { + @Override public void run() { ApplicationManager.getApplication().runReadAction(new Runnable() { @Override @@ -1252,23 +1281,28 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public Project getProject() { return myProject; } + @Override public void addChangeListListener(ChangeListListener listener) { myListeners.addListener(listener); } + @Override public void removeChangeListListener(ChangeListListener listener) { myListeners.removeListener(listener); } + @Override public void registerCommitExecutor(CommitExecutor executor) { myExecutors.add(executor); } + @Override public void commitChanges(LocalChangeList changeList, List changes) { doCommit(changeList, changes, false); } @@ -1277,17 +1311,20 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec FileDocumentManager.getInstance().saveAllDocuments(); return new CommitHelper(myProject, changeList, changes, changeList.getName(), StringUtil.isEmpty(changeList.getComment()) ? changeList.getName() : changeList.getComment(), - new ArrayList(), false, synchronously, NullableFunction.NULL, null).doCommit(); + new ArrayList(), false, synchronously, FunctionUtil.nullConstant(), null).doCommit(); } + @Override public void commitChangesSynchronously(LocalChangeList changeList, List changes) { doCommit(changeList, changes, true); } + @Override public boolean commitChangesSynchronouslyWithResult(final LocalChangeList changeList, final List changes) { return doCommit(changeList, changes, true); } + @Override @SuppressWarnings({"unchecked"}) public void readExternal(Element element) throws InvalidDataException { if (!myProject.isDefault()) { @@ -1303,6 +1340,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public void writeExternal(Element element) throws WriteExternalException { if (!myProject.isDefault()) { final IgnoredFilesComponent ignoredFilesComponent; @@ -1320,8 +1358,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } // used in TeamCity + @Override public void reopenFiles(List paths) { - final ReadonlyStatusHandlerImpl readonlyStatusHandler = (ReadonlyStatusHandlerImpl)ReadonlyStatusHandlerImpl.getInstance(myProject); + final ReadonlyStatusHandlerImpl readonlyStatusHandler = (ReadonlyStatusHandlerImpl)ReadonlyStatusHandler.getInstance(myProject); final boolean savedOption = readonlyStatusHandler.getState().SHOW_DIALOG; readonlyStatusHandler.getState().SHOW_DIALOG = false; try { @@ -1332,12 +1371,13 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public List getRegisteredExecutors() { return Collections.unmodifiableList(myExecutors); } private static class MyDirtyFilesScheduler { - private final static int ourPiecesLimit = 100; + private static final int ourPiecesLimit = 100; final List myFiles = new ArrayList(); final List myDirs = new ArrayList(); private boolean myEveryThing; @@ -1377,6 +1417,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public void addFilesToIgnore(final IgnoredFileBean... filesToIgnore) { myIgnoredIdeaLevel.add(filesToIgnore); scheduleUnversionedUpdate(); @@ -1405,6 +1446,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec scheduler.arise(); } + @Override public void setFilesToIgnore(final IgnoredFileBean... filesToIgnore) { myIgnoredIdeaLevel.set(filesToIgnore); scheduleUnversionedUpdate(); @@ -1429,14 +1471,17 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public IgnoredFileBean[] getFilesToIgnore() { return myIgnoredIdeaLevel.getFilesToIgnore(); } + @Override public boolean isIgnoredFile(@NotNull VirtualFile file) { return myIgnoredIdeaLevel.isIgnoredFile(file); } + @Override @Nullable public String getSwitchedBranch(final VirtualFile file) { synchronized (myDataLock) { @@ -1459,9 +1504,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } - return VfsUtil.toVirtualFileArray(result); + return VfsUtilCore.toVirtualFileArray(result); } + @Override public boolean setReadOnly(final String name, final boolean value) { return ApplicationManager.getApplication().runReadAction(new Computable() { @Override @@ -1475,6 +1521,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec }); } + @Override public boolean editName(@NotNull final String fromName, @NotNull final String toName) { return ApplicationManager.getApplication().runReadAction(new Computable() { @Override @@ -1488,6 +1535,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec }); } + @Override public String editComment(@NotNull final String fromName, final String newComment) { return ApplicationManager.getApplication().runReadAction(new Computable() { @Override @@ -1536,6 +1584,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec ourUpdateAlarm.get().execute(r); } + @Override @TestOnly public boolean ensureUpToDate(final boolean canBeCanceled) { if (ApplicationManager.getApplication().isDispatchThread()) { @@ -1571,7 +1620,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } private static class MyChangesDeltaForwarder implements PlusMinusModify { - private RemoteRevisionsCache myRevisionsCache; + private final RemoteRevisionsCache myRevisionsCache; private final ProjectLevelVcsManager myVcsManager; private final Project myProject; private final AtomicReference myService; @@ -1586,6 +1635,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec @Override public void modify(final BaseRevision was, final BaseRevision become) { myService.get().submit(new Runnable() { + @Override public void run() { final AbstractVcs vcs = getVcs(was); if (vcs != null) { @@ -1597,8 +1647,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec }); } + @Override public void plus(final BaseRevision baseRevision) { myService.get().submit(new Runnable() { + @Override public void run() { final AbstractVcs vcs = getVcs(baseRevision); if (vcs != null) { @@ -1609,8 +1661,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec }); } + @Override public void minus(final BaseRevision baseRevision) { myService.get().submit(new Runnable() { + @Override public void run() { final AbstractVcs vcs = getVcs(baseRevision); if (vcs != null) { @@ -1642,6 +1696,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @Override public boolean isFreezedWithNotification(String modalTitle) { final String freezeReason = isFreezed(); if (freezeReason != null) { From cbee02e14b4b9fd98bcba25ebd26d992b0a14dcf Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 18 Sep 2014 13:34:40 +0400 Subject: [PATCH 11/12] call checkCanceled() periodically for running non-standard indicators --- .../openapi/progress/ProgressManager.java | 19 ++ .../progress/impl/ProgressManagerImpl.java | 21 ++- .../progress/util/ProgressIndicatorTest.java | 178 ++++++++++++++++-- 3 files changed, 198 insertions(+), 20 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java index a8e82322c083..9b76fa68ee54 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java +++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.Collection; import java.util.Map; import java.util.Set; @@ -199,6 +200,19 @@ public abstract class ProgressManager extends ProgressIndicatorProvider { } } + private static final Collection nonStandardIndicators = new ConcurrentHashSet(); + protected static void callCheckCancelForNonStandardIndicators() { + for (ProgressIndicator indicator : nonStandardIndicators) { + try { + indicator.checkCanceled(); + } + catch (ProcessCanceledException e) { + indicator.cancel(); + } + } + } + + public void executeProcessUnderProgress(@NotNull Runnable process, @Nullable("null means reuse current progress") ProgressIndicator progress) throws ProcessCanceledException { @@ -221,6 +235,7 @@ public abstract class ProgressManager extends ProgressIndicatorProvider { private static void registerIndicatorAndRun(@NotNull ProgressIndicator progress, @NotNull Thread currentThread, @NotNull Runnable process) { Set underIndicator; boolean alreadyUnder; + boolean addedToPerverse; synchronized (threadsUnderIndicator) { underIndicator = threadsUnderIndicator.get(progress); if (underIndicator == null) { @@ -228,6 +243,7 @@ public abstract class ProgressManager extends ProgressIndicatorProvider { threadsUnderIndicator.put(progress, underIndicator); } alreadyUnder = !underIndicator.add(currentThread); + addedToPerverse = !(progress instanceof StandardProgressIndicator) && nonStandardIndicators.add(progress); } try { @@ -245,6 +261,9 @@ public abstract class ProgressManager extends ProgressIndicatorProvider { threadsUnderIndicator.remove(progress); } threadsUnderCanceledIndicator.remove(currentThread); + if (addedToPerverse) { + nonStandardIndicators.remove(progress); + } } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java index c166ccae50a8..26d789c85cc0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.progress.impl; +import com.intellij.concurrency.JobScheduler; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; @@ -40,9 +41,11 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.util.concurrent.Future; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -public class ProgressManagerImpl extends ProgressManager { +public class ProgressManagerImpl extends ProgressManager implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.impl.ProgressManagerImpl"); public static final int CHECK_CANCELED_DELAY_MILLIS = 10; private final AtomicInteger myCurrentUnsafeProgressCount = new AtomicInteger(0); @@ -50,6 +53,22 @@ public class ProgressManagerImpl extends ProgressManager { private static volatile int ourLockedCheckCounter = 0; private static final boolean DISABLED = "disabled".equals(System.getProperty("idea.ProcessCanceledException")); + private final ScheduledFuture myCheckCancelledFuture; + + public ProgressManagerImpl() { + myCheckCancelledFuture = JobScheduler.getScheduler().scheduleWithFixedDelay(new Runnable() { + @Override + public void run() { + callCheckCancelForNonStandardIndicators(); + } + }, 0, CHECK_CANCELED_DELAY_MILLIS, TimeUnit.MILLISECONDS); + + } + + @Override + public void dispose() { + myCheckCancelledFuture.cancel(true); + } @Override protected void doCheckCanceled() throws ProcessCanceledException { diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/progress/util/ProgressIndicatorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/progress/util/ProgressIndicatorTest.java index b2381dbe0fb6..fbd9b2ea8fe2 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/progress/util/ProgressIndicatorTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/progress/util/ProgressIndicatorTest.java @@ -16,6 +16,7 @@ package com.intellij.openapi.progress.util; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.progress.*; import com.intellij.openapi.progress.impl.ProgressManagerImpl; @@ -189,26 +190,13 @@ public class ProgressIndicatorTest extends LightPlatformTestCase { private volatile boolean checkCanceledCalled; private volatile boolean taskCanceled; private volatile boolean taskSucceeded; - private volatile boolean taskFinished; private volatile Throwable exception; public void testProgressManagerCheckCanceledDoesNotDelegateToProgressIndicatorIfThereAreNoCanceledIndicators() throws Throwable { final long warmupEnd = System.currentTimeMillis() + 1000; - final long end = warmupEnd + 1000; + final long end = warmupEnd + 10000; checkCanceledCalled = false; - final ProgressIndicator myIndicator = new ProgressIndicatorStub() { - @Override - public void checkCanceled() throws ProcessCanceledException { - checkCanceledCalled = true; - assertTrue(isCanceled()); - super.checkCanceled(); - } - - @Override - public void processFinish() { - taskFinished = true; - } - }; - taskCanceled = taskSucceeded = taskFinished = false; + final ProgressIndicatorBase myIndicator = new ProgressIndicatorBase(); + taskCanceled = taskSucceeded = false; exception = null; Future future = ProgressManagerImpl.runProcessWithProgressAsynchronously(new Task.Backgroundable(getProject(), "xxx") { @Override @@ -220,6 +208,11 @@ public class ProgressIndicatorTest extends LightPlatformTestCase { ProgressManager.checkCanceled(); } } + catch (ProcessCanceledException e) { + exception = e; + checkCanceledCalled = true; + throw e; + } catch (RuntimeException e) { exception = e; throw e; @@ -251,8 +244,6 @@ public class ProgressIndicatorTest extends LightPlatformTestCase { myIndicator.cancel(); } } - assertTrue(taskFinished); - // invokeLater in runProcessWithProgressAsynchronously UIUtil.dispatchAllInvocationEvents(); @@ -262,7 +253,39 @@ public class ProgressIndicatorTest extends LightPlatformTestCase { assertTrue(String.valueOf(exception), exception instanceof ProcessCanceledException); } - private static class ProgressIndicatorStub extends EmptyProgressIndicator implements ProgressIndicatorEx { + private volatile boolean myFlag; + public void testPerverseIndicator() { + checkCanceledCalled = false; + ProgressIndicator indicator = new ProgressIndicatorStub() { + @Override + public void checkCanceled() throws ProcessCanceledException { + checkCanceledCalled = true; + if (myFlag) throw new ProcessCanceledException(); + } + }; + myFlag = false; + Alarm alarm = new Alarm(myTestRootDisposable); + alarm.addRequest(new Runnable() { + @Override + public void run() { + myFlag = true; + } + }, 100); + final long start = System.currentTimeMillis(); + ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() { + @Override + public void run() { + while (System.currentTimeMillis() - start < 10000) { + ProgressManager.checkCanceled(); + } + } + }, indicator); + assertTrue(checkCanceledCalled); + } + + private static class ProgressIndicatorStub implements ProgressIndicatorEx { + private volatile boolean myCanceled; + @Override public void addStateDelegate(@NotNull ProgressIndicatorEx delegate) { throw new RuntimeException(); @@ -318,5 +341,122 @@ public class ProgressIndicatorTest extends LightPlatformTestCase { public int getNonCancelableCount() { throw new RuntimeException(); } + + @Override + public void start() { + + } + + @Override + public void stop() { + + } + + @Override + public void setText(String text) { + throw new RuntimeException(); + } + + @Override + public String getText() { + throw new RuntimeException(); + } + + @Override + public String getText2() { + throw new RuntimeException(); + } + + @Override + public void setText2(String text) { + throw new RuntimeException(); + } + + @Override + public double getFraction() { + throw new RuntimeException(); + } + + @Override + public void setFraction(double fraction) { + throw new RuntimeException(); + } + + @Override + public void pushState() { + throw new RuntimeException(); + } + + @Override + public void popState() { + throw new RuntimeException(); + } + + @Override + public void startNonCancelableSection() { + throw new RuntimeException(); + } + + @Override + public void finishNonCancelableSection() { + throw new RuntimeException(); + } + + @Override + public boolean isModal() { + return false; + } + + @NotNull + @Override + public ModalityState getModalityState() { + throw new RuntimeException(); + } + + @Override + public void setModalityProgress(ProgressIndicator modalityProgress) { + throw new RuntimeException(); + } + + @Override + public boolean isIndeterminate() { + throw new RuntimeException(); + } + + @Override + public void setIndeterminate(boolean indeterminate) { + throw new RuntimeException(); + } + + @Override + public boolean isPopupWasShown() { + throw new RuntimeException(); + } + + @Override + public boolean isShowing() { + throw new RuntimeException(); + } + + @Override + public boolean isRunning() { + return true; + } + + @Override + public void cancel() { + myCanceled = true; + ProgressManager.canceled(this); + } + + @Override + public boolean isCanceled() { + return myCanceled; + } + + @Override + public void checkCanceled() throws ProcessCanceledException { + if (myCanceled) throw new ProcessCanceledException(); + } } } From aa035e87ad39b0cb5e594d6a89c4993fa814f8b8 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 18 Sep 2014 13:35:00 +0400 Subject: [PATCH 12/12] cleanup --- .../roots/ui/configuration/JavaContentEntriesEditor.java | 9 +++++---- .../roots/ui/configuration/ModuleConfigurationState.java | 4 +++- .../module/impl/ModuleConfigurationStateImpl.java | 3 ++- .../roots/ui/configuration/ModuleElementsEditor.java | 8 +++++--- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java index 73f9f7f39807..1bb0d8d6911d 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java @@ -28,9 +28,10 @@ import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.concurrency.SwingWorker; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.java.JavaResourceRootType; import org.jetbrains.jps.model.java.JavaSourceRootType; @@ -72,14 +73,14 @@ public class JavaContentEntriesEditor extends CommonContentEntriesEditor { return contentEntries; } - private static void addSourceRoots(final Project project, final ContentEntry[] contentEntries, final Runnable finishRunnable) { + private static void addSourceRoots(@NotNull Project project, final ContentEntry[] contentEntries, final Runnable finishRunnable) { final HashMap> entryToRootMap = new HashMap>(); final Map fileToEntryMap = new HashMap(); for (final ContentEntry contentEntry : contentEntries) { final VirtualFile file = contentEntry.getFile(); if (file != null) { entryToRootMap.put(contentEntry, null); - fileToEntryMap.put(VfsUtil.virtualToIoFile(file), contentEntry); + fileToEntryMap.put(VfsUtilCore.virtualToIoFile(file), contentEntry); } } @@ -113,7 +114,7 @@ public class JavaContentEntriesEditor extends CommonContentEntriesEditor { for (final JavaModuleSourceRoot suggestedRoot : suggestedRoots) { final VirtualFile sourceRoot = LocalFileSystem.getInstance().findFileByIoFile(suggestedRoot.getDirectory()); final VirtualFile fileContent = contentEntry.getFile(); - if (sourceRoot != null && fileContent != null && VfsUtil.isAncestor(fileContent, sourceRoot, false)) { + if (sourceRoot != null && fileContent != null && VfsUtilCore.isAncestor(fileContent, sourceRoot, false)) { contentEntry.addSourceFolder(sourceRoot, false, suggestedRoot.getPackagePrefix()); } } diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ui/configuration/ModuleConfigurationState.java b/platform/lang-api/src/com/intellij/openapi/roots/ui/configuration/ModuleConfigurationState.java index 139c41d7e859..3ba95cd4aded 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/ui/configuration/ModuleConfigurationState.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/ui/configuration/ModuleConfigurationState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -18,10 +18,12 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.UserDataHolder; +import org.jetbrains.annotations.NotNull; public interface ModuleConfigurationState extends UserDataHolder { ModulesProvider getModulesProvider(); FacetsProvider getFacetsProvider(); ModifiableRootModel getRootModel(); + @NotNull Project getProject(); } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java index 2b7356bf7b26..dc8e4c61caef 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -50,6 +50,7 @@ public class ModuleConfigurationStateImpl extends UserDataHolderBase implements return null; } + @NotNull @Override public Project getProject() { return myProject; diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java index 518f2cec5907..e1d95d1fedec 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.Disposer; import com.intellij.ui.navigation.History; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -33,14 +34,14 @@ import javax.swing.*; * Time: 7:24:37 PM */ public abstract class ModuleElementsEditor implements ModuleConfigurationEditor { - protected final Project myProject; + @NotNull protected final Project myProject; protected JComponent myComponent; private final CompositeDisposable myDisposables = new CompositeDisposable(); protected History myHistory; private final ModuleConfigurationState myState; - protected ModuleElementsEditor(ModuleConfigurationState state) { + protected ModuleElementsEditor(@NotNull ModuleConfigurationState state) { myProject = state.getProject(); myState = state; } @@ -58,6 +59,7 @@ public abstract class ModuleElementsEditor implements ModuleConfigurationEditor return myState.getRootModel(); } + @NotNull protected ModuleConfigurationState getState() { return myState; }