mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
notify BuildManager only if file events affect opened and watched projects (second part of IDEA-122685)
This commit is contained in:
+85
-111
@@ -25,7 +25,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
@@ -78,7 +77,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
void execute(VirtualFile file);
|
||||
}
|
||||
|
||||
private static void processRecursively(final VirtualFile fromFile, final boolean dbOnly, final boolean needReadAction, final FileProcessor processor) {
|
||||
private static void processRecursively(final VirtualFile fromFile, final boolean dbOnly, final FileProcessor processor) {
|
||||
if (!(fromFile.getFileSystem() instanceof LocalFileSystem)) {
|
||||
return;
|
||||
}
|
||||
@@ -103,77 +102,70 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
if (dbOnly) {
|
||||
return file.isDirectory()? ((NewVirtualFile)file).iterInDbChildren() : null;
|
||||
}
|
||||
if (file.equals(fromFile) || !file.isDirectory()) {
|
||||
return null; // skipping additional checks for the initial file and non-directory files
|
||||
}
|
||||
// optimization: for all files that are not under content of currently opened projects iterate over DB children
|
||||
return isInContentOfOpenedProject(file, needReadAction)? null : ((NewVirtualFile)file).iterInDbChildren();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isInContentOfOpenedProject(@NotNull final VirtualFile file, boolean needReadAction) {
|
||||
private static boolean isInContentOfOpenedProject(@NotNull final VirtualFile file) {
|
||||
// probably need a read action to ensure that the project was not disposed during the iteration over the project list
|
||||
final Computable<Boolean> computation = new Computable<Boolean>() {
|
||||
public Boolean compute() {
|
||||
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
|
||||
if (!project.isInitialized()) {
|
||||
continue;
|
||||
}
|
||||
if (ProjectRootManager.getInstance(project).getFileIndex().isInContent(file)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
|
||||
if (!project.isInitialized() || !BuildManager.getInstance().isProjectWatched(project)) {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
return needReadAction? ApplicationManager.getApplication().runReadAction(computation) : computation.compute();
|
||||
if (ProjectRootManager.getInstance(project).getFileIndex().isInContent(file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private class MyVfsListener extends VirtualFileAdapter {
|
||||
public void propertyChanged(@NotNull final VirtualFilePropertyEvent event) {
|
||||
if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) {
|
||||
final VirtualFile eventFile = event.getFile();
|
||||
final VirtualFile parent = event.getParent();
|
||||
if (parent != null) {
|
||||
final String oldName = (String)event.getOldValue();
|
||||
final String root = parent.getPath() + "/" + oldName;
|
||||
final Set<File> toMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
if (eventFile.isDirectory()) {
|
||||
VfsUtilCore.visitChildrenRecursively(eventFile, new VirtualFileVisitor() {
|
||||
private StringBuilder filePath = new StringBuilder(root);
|
||||
|
||||
@Override
|
||||
public boolean visitFile(@NotNull VirtualFile child) {
|
||||
if (child.isDirectory()) {
|
||||
if (!Comparing.equal(child, eventFile)) {
|
||||
filePath.append("/").append(child.getName());
|
||||
if (isInContentOfOpenedProject(eventFile)) {
|
||||
final VirtualFile parent = event.getParent();
|
||||
if (parent != null) {
|
||||
final String oldName = (String)event.getOldValue();
|
||||
final String root = parent.getPath() + "/" + oldName;
|
||||
final Set<File> toMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
if (eventFile.isDirectory()) {
|
||||
VfsUtilCore.visitChildrenRecursively(eventFile, new VirtualFileVisitor() {
|
||||
private StringBuilder filePath = new StringBuilder(root);
|
||||
|
||||
@Override
|
||||
public boolean visitFile(@NotNull VirtualFile child) {
|
||||
if (child.isDirectory()) {
|
||||
if (!Comparing.equal(child, eventFile)) {
|
||||
filePath.append("/").append(child.getName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
String childPath = filePath.toString();
|
||||
if (!Comparing.equal(child, eventFile)) {
|
||||
childPath += "/" + child.getName();
|
||||
}
|
||||
toMark.add(new File(childPath));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterChildrenVisited(@NotNull VirtualFile file) {
|
||||
if (file.isDirectory() && !Comparing.equal(file, eventFile)) {
|
||||
filePath.delete(filePath.length() - file.getName().length() - 1, filePath.length());
|
||||
}
|
||||
}
|
||||
else {
|
||||
String childPath = filePath.toString();
|
||||
if (!Comparing.equal(child, eventFile)) {
|
||||
childPath += "/" + child.getName();
|
||||
}
|
||||
toMark.add(new File(childPath));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterChildrenVisited(@NotNull VirtualFile file) {
|
||||
if (file.isDirectory() && !Comparing.equal(file, eventFile)) {
|
||||
filePath.delete(filePath.length() - file.getName().length() - 1, filePath.length());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
toMark.add(new File(root));
|
||||
}
|
||||
notifyFilesDeleted(toMark);
|
||||
}
|
||||
else {
|
||||
toMark.add(new File(root));
|
||||
}
|
||||
notifyFilesDeleted(toMark);
|
||||
markDirtyIfSource(eventFile, false);
|
||||
}
|
||||
markDirtyIfSource(eventFile, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,23 +187,25 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
|
||||
public void beforeFileDeletion(@NotNull final VirtualFileEvent event) {
|
||||
final VirtualFile eventFile = event.getFile();
|
||||
if ((LOG.isDebugEnabled() && eventFile.isDirectory()) || ourDebugMode) {
|
||||
final String message = "Processing file deletion: " + eventFile.getPresentableUrl();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
if (isInContentOfOpenedProject(eventFile)) {
|
||||
if ((LOG.isDebugEnabled() && eventFile.isDirectory()) || ourDebugMode) {
|
||||
final String message = "Processing file deletion: " + eventFile.getPresentableUrl();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
final Set<File> pathsToMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
|
||||
processRecursively(eventFile, true, new FileProcessor() {
|
||||
public void execute(final VirtualFile file) {
|
||||
pathsToMark.add(new File(file.getPath()));
|
||||
}
|
||||
});
|
||||
|
||||
notifyFilesDeleted(pathsToMark);
|
||||
}
|
||||
|
||||
final Set<File> pathsToMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
|
||||
processRecursively(eventFile, true, false, new FileProcessor() {
|
||||
public void execute(final VirtualFile file) {
|
||||
pathsToMark.add(new File(file.getPath()));
|
||||
}
|
||||
});
|
||||
|
||||
notifyFilesDeleted(pathsToMark);
|
||||
}
|
||||
|
||||
public void beforeFileMovement(@NotNull final VirtualFileMoveEvent event) {
|
||||
@@ -219,54 +213,34 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
}
|
||||
|
||||
private void markDirtyIfSource(final VirtualFile file, final boolean fromMove) {
|
||||
final Set<File> pathsToMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
processRecursively(file, false, false, new FileProcessor() {
|
||||
public void execute(final VirtualFile file) {
|
||||
pathsToMark.add(new File(file.getPath()));
|
||||
}
|
||||
});
|
||||
if (fromMove) {
|
||||
notifyFilesDeleted(pathsToMark);
|
||||
}
|
||||
else if (!isIgnoredOrUnderIgnoredDirectory(file)) {
|
||||
notifyFilesChanged(pathsToMark);
|
||||
}
|
||||
}
|
||||
|
||||
private void processNewFile(final VirtualFile file) {
|
||||
if (!isIgnoredOrUnderIgnoredDirectory(file)) { // todo: avoid duplicated isInContent check
|
||||
if (isInContentOfOpenedProject(file)) {
|
||||
final Set<File> pathsToMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
boolean dbOnly = !isInContentOfOpenedProject(file, false);
|
||||
processRecursively(file, dbOnly, false, new FileProcessor() {
|
||||
@Override
|
||||
public void execute(VirtualFile file) {
|
||||
processRecursively(file, false, new FileProcessor() {
|
||||
public void execute(final VirtualFile file) {
|
||||
pathsToMark.add(new File(file.getPath()));
|
||||
}
|
||||
});
|
||||
notifyFilesChanged(pathsToMark);
|
||||
if (fromMove) {
|
||||
notifyFilesDeleted(pathsToMark);
|
||||
}
|
||||
else {
|
||||
notifyFilesChanged(pathsToMark);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isIgnoredOrUnderIgnoredDirectory(final VirtualFile file) {
|
||||
final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
|
||||
if (fileTypeManager.isFileIgnored(file)) {
|
||||
return true;
|
||||
private static void processNewFile(final VirtualFile file) {
|
||||
if (isInContentOfOpenedProject(file)) {
|
||||
final Set<File> pathsToMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
processRecursively(file, false, new FileProcessor() {
|
||||
@Override
|
||||
public void execute(VirtualFile file) {
|
||||
pathsToMark.add(new File(file.getPath()));
|
||||
}
|
||||
});
|
||||
notifyFilesChanged(pathsToMark);
|
||||
}
|
||||
|
||||
//optimization: if file is in content of some project it's definitely not ignored
|
||||
if (isInContentOfOpenedProject(file, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VirtualFile current = file.getParent();
|
||||
while (current != null) {
|
||||
if (fileTypeManager.isFileIgnored(current)) {
|
||||
return true;
|
||||
}
|
||||
current = current.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void notifyFilesChanged(Collection<File> paths) {
|
||||
|
||||
@@ -91,7 +91,6 @@ import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
|
||||
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.ide.PooledThreadExecutor;
|
||||
import org.jetbrains.io.ChannelRegistrar;
|
||||
import org.jetbrains.io.NettyUtil;
|
||||
@@ -383,12 +382,8 @@ public class BuildManager implements ApplicationComponent{
|
||||
scheduleAutoMake();
|
||||
}
|
||||
|
||||
public boolean rescanRequired(Project project) {
|
||||
final String projectPath = getProjectPath(project);
|
||||
synchronized (myProjectDataMap) {
|
||||
final ProjectData data = myProjectDataMap.get(projectPath);
|
||||
return data == null || data.myNeedRescan;
|
||||
}
|
||||
public boolean isProjectWatched(Project project) {
|
||||
return myProjectDataMap.containsKey(getProjectPath(project));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -915,6 +910,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
cmdLine.addParameter("-D" + GlobalOptions.LOG_DIR_OPTION + "=" + FileUtil.toSystemIndependentName(getBuildLogDirectory().getAbsolutePath()));
|
||||
|
||||
final File workDirectory = getBuildSystemDirectory();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
workDirectory.mkdirs();
|
||||
cmdLine.addParameter("-Djava.io.tmpdir=" + FileUtil.toSystemIndependentName(workDirectory.getPath()) + "/" + TEMP_DIR_NAME);
|
||||
|
||||
@@ -1034,11 +1030,6 @@ public class BuildManager implements ApplicationComponent{
|
||||
return ((InetSocketAddress)serverChannel.localAddress()).getPort();
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void stopWatchingProject(Project project) {
|
||||
myProjectDataMap.remove(getProjectPath(project));
|
||||
}
|
||||
|
||||
private static String classpathToString(List<String> cp) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String file : cp) {
|
||||
|
||||
Reference in New Issue
Block a user