IDEA-168933 Moving source folder breaks project

This commit is contained in:
Vladimir Krivosheev
2017-03-06 15:55:03 +01:00
parent 5a8d878ea2
commit 6f5a94e083
3 changed files with 23 additions and 4 deletions
@@ -18,6 +18,8 @@ package com.intellij.openapi.module.impl
import com.intellij.openapi.components.StateStorage
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.impl.ModuleRootManagerImpl
import com.intellij.openapi.roots.impl.ProjectRootManagerComponent
import com.intellij.openapi.roots.impl.storage.ClasspathStorage
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
@@ -25,6 +27,8 @@ import com.intellij.openapi.vfs.newvfs.BulkFileListener
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent
import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent
import com.intellij.project.rootManager
import gnu.trove.THashSet
/**
* Why this class is required if we have StorageVirtualFileTracker?
@@ -50,7 +54,7 @@ internal class ModuleFileListener(private val moduleManager: ModuleManagerCompon
val parentPath = event.file.parent?.path ?: return
var someModulePathIsChanged = false
for (module in moduleManager.modules) {
if (!module.isLoaded) {
if (!module.isLoaded || module.isDisposed) {
continue
}
@@ -72,10 +76,13 @@ internal class ModuleFileListener(private val moduleManager: ModuleManagerCompon
return
}
val roots = THashSet<String>()
val dirName = event.file.nameSequence
val ancestorPath = "${event.oldParent.path}/$dirName"
val newAncestorPath = "${event.newParent.path}/$dirName"
for (module in moduleManager.modules) {
if (!module.isLoaded) {
if (!module.isLoaded || module.isDisposed) {
continue
}
@@ -83,6 +90,18 @@ internal class ModuleFileListener(private val moduleManager: ModuleManagerCompon
if (FileUtil.isAncestor(ancestorPath, moduleFilePath, true)) {
setModuleFilePath(module, "${event.newParent.path}/$dirName/${FileUtil.getRelativePath(ancestorPath, moduleFilePath, '/')}")
}
// https://youtrack.jetbrains.com/issue/IDEA-168933
roots.clear()
val moduleRootManager = module.rootManager as? ModuleRootManagerImpl ?: continue
ProjectRootManagerComponent.addRootsToTrack(moduleRootManager.contentRootUrls, roots, roots)
ProjectRootManagerComponent.addRootsToTrack(moduleRootManager.sourceRootUrls, roots, roots)
if (roots.contains(newAncestorPath)) {
moduleRootManager.stateChanged()
break
}
}
}
@@ -263,7 +263,7 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
return Pair.create(recursive, flat);
}
private static void addRootsToTrack(final String[] urls, final Collection<String> recursive, final Collection<String> flat) {
public static void addRootsToTrack(final String[] urls, final Collection<String> recursive, final Collection<String> flat) {
for (String url : urls) {
if (url != null) {
final String protocol = VirtualFileManager.extractProtocol(url);
@@ -368,7 +368,7 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements Disposab
}
}
void stateChanged() {
public void stateChanged() {
if (Registry.is("store.track.module.root.manager.changes", false)) {
LOG.error("ModelRootManager state changed");
}