diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java index d3225ee1bcf1..54c72140f993 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java @@ -16,6 +16,7 @@ package com.intellij.openapi.roots.impl; import com.intellij.ProjectTopics; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationAdapter; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ProjectComponent; @@ -62,7 +63,7 @@ import java.util.Set; /** * ProjectRootManager extended with ability to watch events. */ -public class ProjectRootManagerComponent extends ProjectRootManagerImpl implements ProjectComponent { +public class ProjectRootManagerComponent extends ProjectRootManagerImpl implements ProjectComponent, Disposable { private static final Logger LOG = Logger.getInstance(ProjectRootManagerComponent.class); private boolean myPointerChangesDetected = false; @@ -307,6 +308,11 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen } } + @Override + public void dispose() { + assertListenersAreDisposed(); + } + private class AppListener extends ApplicationAdapter { @Override public void beforeWriteActionStart(@NotNull Object action) { diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java index 06300ac19461..b27745f936b2 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java @@ -629,6 +629,22 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Pers myJdkTableMultiListener.removeListener(jdkTableListener); } + protected void assertListenersAreDisposed() { + if (!myRegisteredRootProviders.isEmpty()) { + StringBuilder details = new StringBuilder(); + for (Map.Entry> entry : myRegisteredRootProviders.entrySet()) { + details.append(" ").append(entry.getKey()).append(" referenced by ").append(entry.getValue().size()).append(" order entries:\n"); + for (OrderEntry orderEntry : entry.getValue()) { + details.append(" ").append(orderEntry).append("\n"); + } + } + LOG.error("Listeners for " + myRegisteredRootProviders.size() + " root providers aren't disposed:" + details); + for (RootProvider provider : myRegisteredRootProviders.keySet()) { + provider.removeRootSetChangedListener(myRootProviderChangeListener); + } + } + } + private class RootProviderChangeListener implements RootProvider.RootSetChangedListener { private boolean myInsideRootsChange;