diff --git a/java/java-impl/src/com/intellij/ide/scopeView/ClassesScopeTreeStructureExpander.java b/java/java-impl/src/com/intellij/ide/scopeView/ClassesScopeTreeStructureExpander.java index 76038f999439..ef0105d641e5 100644 --- a/java/java-impl/src/com/intellij/ide/scopeView/ClassesScopeTreeStructureExpander.java +++ b/java/java-impl/src/com/intellij/ide/scopeView/ClassesScopeTreeStructureExpander.java @@ -20,14 +20,12 @@ import com.intellij.ide.projectView.PsiClassChildrenSource; import com.intellij.ide.scopeView.nodes.ClassNode; import com.intellij.ide.scopeView.nodes.FieldNode; import com.intellij.ide.scopeView.nodes.MethodNode; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packageDependencies.ui.DependencyNodeComparator; import com.intellij.packageDependencies.ui.DirectoryNode; import com.intellij.packageDependencies.ui.FileNode; -import com.intellij.packageDependencies.ui.PackageDependenciesNode; import com.intellij.psi.*; import com.intellij.util.ui.tree.TreeUtil; @@ -74,7 +72,7 @@ public class ClassesScopeTreeStructureExpander implements ScopeTreeStructureExpa if (classNodes == null) { classNodes = new HashSet<>(); } - commitDocument((PsiFile)file); + for (final PsiClass psiClass : psiClasses) { if (psiClass != null && psiClass.isValid()) { final ClassNode classNode = new ClassNode(psiClass); @@ -155,9 +153,4 @@ public class ClassesScopeTreeStructureExpander implements ScopeTreeStructureExpa return new DependencyNodeComparator(ProjectView.getInstance(myProject).isSortByType(ScopeViewPane.ID)); } - private void commitDocument(final PsiFile file) { - final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); - final Document document = documentManager.getDocument(file); - documentManager.commitDocument(document); - } } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java index 431e046fe308..13ca286944bf 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java @@ -61,7 +61,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations protected final PsiManager myPsiManager; - private final ConcurrentMap> myExternalAnnotations = ContainerUtil.createConcurrentSoftValueMap(); + private final ConcurrentMap> myExternalAnnotations = ContainerUtil.createConcurrentWeakKeySoftValueMap(); private final Map myAnnotationDataCache = new WeakKeyWeakValueHashMap(); private final ConcurrentMap, Long>> myAnnotationFileToDataAndModStamp = ContainerUtil.createConcurrentSoftMap(); diff --git a/java/java-tests/testSrc/com/intellij/psi/LightVirtualFileLeaksTest.java b/java/java-tests/testSrc/com/intellij/psi/LightVirtualFileLeaksTest.java new file mode 100644 index 000000000000..4d5111197f6c --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/LightVirtualFileLeaksTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2016 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.psi; + +import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.Key; +import com.intellij.testFramework.LeakHunter; +import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.testFramework.LightVirtualFile; +import com.intellij.testFramework.PsiTestUtil; +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.util.GCUtil; +import org.jetbrains.annotations.NotNull; + +/** + * @author peter + */ +public class LightVirtualFileLeaksTest extends LightCodeInsightFixtureTestCase { + private Key myKey; + private static final DefaultLightProjectDescriptor PROJECT_DESCRIPTOR = new DefaultLightProjectDescriptor() { + @Override + public Sdk getSdk() { + return PsiTestUtil.addJdkAnnotations(super.getSdk()); + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + myKey = Key.create(getName()); + } + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return PROJECT_DESCRIPTOR; + } + + public void testDoNotLeakViaDocument() { + createFileWithDocument(); + checkLeak(); + } + + private void createFileWithDocument() { + Document document = FileDocumentManager.getInstance().getDocument(createLightFile()); + assertNotNull(document); + PsiJavaFile psiFile = (PsiJavaFile)PsiDocumentManager.getInstance(getProject()).getPsiFile(document); + assertSame(document, PsiDocumentManager.getInstance(getProject()).getDocument(psiFile)); + } + + private void checkLeak() { + GCUtil.tryGcSoftlyReachableObjects(); + LeakHunter.checkLeak(getProject(), LightVirtualFile.class, vf -> vf.getUserData(myKey) == Boolean.TRUE); + } + + public void testDoNotLeakViaExternalAnnotations() { + queryExternalAnnotations(); + checkLeak(); + } + + private void queryExternalAnnotations() { + LightVirtualFile vFile = createLightFile(); + assertEmpty(AnnotationUtil.getAllAnnotations(((PsiJavaFile)getPsiManager().findFile(vFile)).getClasses()[0], true, null)); + } + + @NotNull + private LightVirtualFile createLightFile() { + LightVirtualFile vFile = new LightVirtualFile(getName() + ".java", JavaFileType.INSTANCE, "class Foo {}"); + vFile.putUserData(myKey, Boolean.TRUE); + return vFile; + } +} diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java index a115ef0aa2f6..5bdc230599db 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java @@ -220,8 +220,12 @@ public class FileManagerImpl implements FileManager { assert !file.isDirectory(); FileViewProvider viewProvider = findCachedViewProvider(file); if (viewProvider != null) return viewProvider; - viewProvider = ConcurrencyUtil.cacheOrGet(myVFileToViewProviderMap, file, createFileViewProvider(file, true)); - return viewProvider; + + viewProvider = createFileViewProvider(file, true); + if (file instanceof LightVirtualFile) { + return file.putUserDataIfAbsent(myPsiHardRefKey, viewProvider); + } + return ConcurrencyUtil.cacheOrGet(myVFileToViewProviderMap, file, viewProvider); } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 8bcc97ab568e..9f0101a5b551 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -1112,7 +1112,9 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - myManager.dropResolveCaches(); + if (!myManager.isDisposed()) { + myManager.dropResolveCaches(); + } final VirtualFile vFile = getVirtualFile(); if (vFile != null && vFile.isValid()) { diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java index 6c2d26242346..2249f0fe23d1 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.OptionAction; import com.intellij.openapi.ui.ValidationInfo; +import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.components.labels.ActionLink; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.components.BorderLayoutPanel; @@ -52,7 +53,8 @@ public class VcsPushDialog extends DialogWrapper { public VcsPushDialog(@NotNull Project project, @NotNull List selectedRepositories, @Nullable Repository currentRepo) { - super(project); + super(project, true, (Registry.is("ide.perProjectModality")) ? IdeModalityType.PROJECT : IdeModalityType.IDE); + myController = new PushController(project, this, selectedRepositories, currentRepo); myAdditionalPanels = myController.createAdditionalPanels(); myListPanel = myController.getPushPanelLog(); diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java index a6d381a73da9..63d408517103 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java @@ -31,7 +31,8 @@ import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.ResolveScopeManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.SearchScope; -import com.intellij.util.containers.ConcurrentFactoryMap; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.FactoryMap; import com.intellij.util.indexing.AdditionalIndexableFileSet; import org.jetbrains.annotations.NotNull; @@ -43,7 +44,13 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager { private final ProjectRootManager myProjectRootManager; private final PsiManager myManager; - private final Map myDefaultResolveScopesCache = new ConcurrentFactoryMap() { + private final Map myDefaultResolveScopesCache = new FactoryMap() { + + @Override + protected Map createMap() { + return ContainerUtil.createConcurrentWeakKeySoftValueMap(); + } + @Override protected GlobalSearchScope create(@NotNull VirtualFile key) { GlobalSearchScope scope = null; diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index 3ed2ae188039..5a1cefeae19e 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.EmptyAction; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.TransactionGuard; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.editor.*; @@ -108,7 +109,7 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons public void focusGained(Editor editor) { myCurrentEditor = (EditorEx)editor; if (GeneralSettings.getInstance().isSaveOnFrameDeactivation()) { - FileDocumentManager.getInstance().saveAllDocuments(); // PY-12487 + TransactionGuard.submitTransaction(LanguageConsoleImpl.this, () -> FileDocumentManager.getInstance().saveAllDocuments()); // PY-12487 } } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java index 56659a81074a..077630d4ea69 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java @@ -259,7 +259,6 @@ public class GotoActionModel implements ChooseByNameModel, Comparator, E public static AnActionEvent updateActionBeforeShow(@NotNull AnAction anAction, @NotNull DataContext dataContext) { AnActionEvent event = AnActionEvent.createFromDataContext(ActionPlaces.ACTION_SEARCH, null, dataContext); ActionUtil.performDumbAwareUpdate(anAction, event, false); - ActionUtil.performDumbAwareUpdate(anAction, event, true); return event; } diff --git a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java index 035135934acc..04ec2228340e 100644 --- a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java +++ b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java @@ -151,7 +151,7 @@ public class CommandLineProcessor { try { final String url = URLDecoder.decode(command, "UTF-8"); JetBrainsProtocolHandler.processJetBrainsLauncherParameters(url); - ApplicationManager.getApplication().invokeLater(() -> JBProtocolCommand.handleCurrentCommand(), ModalityState.any()); + ApplicationManager.getApplication().invokeLater(() -> JBProtocolCommand.handleCurrentCommand()); } catch (UnsupportedEncodingException e) { LOG.error(e); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/CommandProcessor.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/CommandProcessor.java index 476ff706b325..13276cc1f59a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/CommandProcessor.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/CommandProcessor.java @@ -80,7 +80,7 @@ public final class CommandProcessor implements Runnable { // definitely have some since runnables in command list may (and do) request some PSI activity final boolean queueNext = myCommandCount > 0; Application application = ApplicationManager.getApplication(); - ModalityState modalityState = Registry.is("ide.perProjectModality") ? ModalityState.defaultModalityState() : ModalityState.NON_MODAL; + ModalityState modalityState = ModalityState.NON_MODAL; application.getInvokator().invokeLater(command, modalityState, expire == null ? application.getDisposed() : expire).doWhenDone(() -> { if (queueNext) { this.run(); diff --git a/platform/platform-impl/src/com/intellij/reporting/Reporter.kt b/platform/platform-impl/src/com/intellij/reporting/Reporter.kt index 728f1bed7ca3..10117bd1d4d8 100644 --- a/platform/platform-impl/src/com/intellij/reporting/Reporter.kt +++ b/platform/platform-impl/src/com/intellij/reporting/Reporter.kt @@ -22,7 +22,7 @@ import org.apache.http.client.fluent.Request import org.apache.http.entity.ContentType -private class StatsServerInfo(var status: String, var url: String) { +private class StatsServerInfo(@JvmField var status: String, @JvmField var url: String) { fun isServiceAlive() = "ok" == status } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java index a299a0ee2092..19de6eb510c9 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java @@ -271,7 +271,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj final boolean isAlien, final String comment, @Nullable CommitResultHandler customResultHandler) { - super(project, true); + super(project, true, (Registry.is("ide.perProjectModality")) ? IdeModalityType.PROJECT : IdeModalityType.IDE); myCommitContext = new CommitContext(); myProject = project; myVcsConfiguration = ObjectUtils.assertNotNull(VcsConfiguration.getInstance(myProject)); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java index 32a5024fe858..3f39e50df904 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java @@ -93,7 +93,7 @@ public class VcsLogData implements Disposable, VcsLogDataProvider { if (!(e instanceof ProcessCanceledException)) { LOG.error(e); } - }, RECENT_COMMITS_COUNT); + }, RECENT_COMMITS_COUNT, this); myContainingBranchesGetter = new ContainingBranchesGetter(this, this); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogProgress.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogProgress.java index b208e68f6088..fb8f9f0a704b 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogProgress.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogProgress.java @@ -26,12 +26,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Set; import java.util.function.Consumer; -public class VcsLogProgress { +public class VcsLogProgress implements Disposable { @NotNull private final Object myLock = new Object(); @NotNull private final List myListeners = ContainerUtil.newArrayList(); - private int myRunningTasksCount = 0; + @NotNull private Set myRunningTasks = ContainerUtil.newHashSet(); @NotNull public ProgressIndicator createProgressIndicator() { @@ -59,21 +60,21 @@ public class VcsLogProgress { public boolean isRunning() { synchronized (myLock) { - return myRunningTasksCount > 0; + return !myRunningTasks.isEmpty(); } } - private void started() { + private void started(@NotNull ProgressIndicator indicator) { synchronized (myLock) { - myRunningTasksCount++; - if (myRunningTasksCount == 1) fireNotification(ProgressListener::progressStarted); + myRunningTasks.add(indicator); + if (myRunningTasks.size() == 1) fireNotification(ProgressListener::progressStarted); } } - private void stopped() { + private void stopped(@NotNull ProgressIndicator indicator) { synchronized (myLock) { - myRunningTasksCount--; - if (myRunningTasksCount == 0) fireNotification(ProgressListener::progressStopped); + myRunningTasks.remove(indicator); + if (myRunningTasks.isEmpty()) fireNotification(ProgressListener::progressStopped); } } @@ -84,17 +85,26 @@ public class VcsLogProgress { } } + @Override + public void dispose() { + synchronized (myLock) { + for (ProgressIndicator indicator : myRunningTasks) { + indicator.cancel(); + } + } + } + private class VcsLogProgressIndicator extends AbstractProgressIndicatorBase { @Override public synchronized void start() { super.start(); - started(); + started(this); } @Override public synchronized void stop() { super.stop(); - stopped(); + stopped(this); } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java index 01666e67682e..8dbbf2562d4c 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java @@ -15,11 +15,13 @@ */ package com.intellij.vcs.log.data; +import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; @@ -65,7 +67,8 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { @NotNull TopCommitsCache topCommitsDetailsCache, @NotNull Consumer dataPackUpdateHandler, @NotNull Consumer exceptionHandler, - int recentCommitsCount) { + int recentCommitsCount, + @NotNull Disposable parentDisposable) { myProject = project; myHashMap = hashMap; myProviders = providers; @@ -74,6 +77,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { myExceptionHandler = exceptionHandler; myRecentCommitCount = recentCommitsCount; myProgress = new VcsLogProgress(); + Disposer.register(parentDisposable, myProgress); mySingleTaskController = new SingleTaskController(dataPack -> { myDataPack = dataPack; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java index 507a646184a3..a1921a9fda7b 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java @@ -17,6 +17,7 @@ package com.intellij.vcs.log.data; import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; @@ -60,6 +61,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { @NotNull private final PersistentEnumeratorBase myCommitIdEnumerator; @NotNull private final PersistentEnumeratorBase myRefsEnumerator; @NotNull private final Consumer myExceptionReporter; + private volatile boolean myDisposed = false; public VcsLogStorageImpl(@NotNull Project project, @NotNull Map logProviders, @@ -94,6 +96,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { @Override public int getCommitIndex(@NotNull Hash hash, @NotNull VirtualFile root) { + checkDisposed(); try { return getOrPut(hash, root); } @@ -106,6 +109,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { @Override @Nullable public CommitId getCommitId(int commitIndex) { + checkDisposed(); try { CommitId commitId = doGetCommitId(commitIndex); if (commitId == null) { @@ -122,6 +126,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { @Override @Nullable public CommitId findCommitId(@NotNull final Condition condition) { + checkDisposed(); try { final Ref hashRef = Ref.create(); myCommitIdEnumerator.iterateData(new CommonProcessors.FindProcessor() { @@ -144,6 +149,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { @Override public int getRefIndex(@NotNull VcsRef ref) { + checkDisposed(); try { return myRefsEnumerator.enumerate(ref); } @@ -156,6 +162,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { @Nullable @Override public VcsRef getVcsRef(int refIndex) { + checkDisposed(); try { return myRefsEnumerator.valueOf(refIndex); } @@ -166,6 +173,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { } public void flush() { + checkDisposed(); myCommitIdEnumerator.force(); myRefsEnumerator.force(); } @@ -173,6 +181,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { @Override public void dispose() { try { + myDisposed = true; myCommitIdEnumerator.close(); myRefsEnumerator.close(); } @@ -181,6 +190,10 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage { } } + private void checkDisposed() { + if (myDisposed) throw new ProcessCanceledException(); + } + private static class MyCommitIdKeyDescriptor implements KeyDescriptor { @NotNull private final List myRoots; @NotNull private final TObjectIntHashMap myRootsReversed; diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java index 65da9a2516e3..780e1f55b759 100644 --- a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java +++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java @@ -202,7 +202,8 @@ public class VcsLogRefresherTest extends VcsPlatformTest { myLogData = new VcsLogData(myProject, myLogProviders, LOG::error); Disposer.register(myProject, myLogData); return new VcsLogRefresherImpl(myProject, myLogData.getHashMap(), myLogProviders, myLogData.getUserRegistry(), - myLogData.getTopCommitsCache(), dataPackConsumer, FAILING_EXCEPTION_HANDLER, RECENT_COMMITS_COUNT) { + myLogData.getTopCommitsCache(), dataPackConsumer, FAILING_EXCEPTION_HANDLER, RECENT_COMMITS_COUNT, + myLogData) { @Override protected void startNewBackgroundTask(@NotNull final Task.Backgroundable refreshTask) { LOG.debug("Starting a background task..."); diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index 55bcec425a19..0352361fde03 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -130,7 +130,7 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState updateStateStorage(changedComponentNames, changed, false) updateStateStorage(changedComponentNames, deleted, true) @@ -178,7 +179,7 @@ internal fun updateStoragesFromStreamProvider(store: ComponentStoreImpl, updateR } if (changedComponentNames.isEmpty()) { - return@Computable false + return@Runnable } notReloadableComponents = store.getNotReloadableComponents(changedComponentNames) @@ -189,8 +190,9 @@ internal fun updateStoragesFromStreamProvider(store: ComponentStoreImpl, updateR store.reinitComponents(changedComponentNames, changedStorageSet, notReloadableComponents) } - !notReloadableComponents.isEmpty() && askToRestart(store, notReloadableComponents, null, true) - }) + result.set(!notReloadableComponents.isEmpty() && askToRestart(store, notReloadableComponents, null, true)) + }, ModalityState.defaultModalityState()) + return result.get() } private fun updateStateStorage(changedComponentNames: MutableSet, stateStorages: Collection, deleted: Boolean) { diff --git a/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py b/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py index 9d612005e9f3..4ad420baea9a 100644 --- a/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py +++ b/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py @@ -70,9 +70,6 @@ class BaseStdIn: # which is not something we want. return '\n' - def isatty(self): - return False # not really a file - def write(self, *args, **kwargs): pass # not available StdIn (but it can be expected to be in the stream interface)