use async events processing in DirtyScopeHolder

GitOrigin-RevId: ba507007817f4399472b965285bec1ddd919a5e8
This commit is contained in:
Valentin Fondaratov
2019-05-31 18:11:51 +03:00
committed by intellij-monorepo-bot
parent d9a12f4f72
commit cd8d1fa827
2 changed files with 41 additions and 10 deletions
@@ -94,7 +94,7 @@ public abstract class CompilerReferenceServiceBase<Reader extends CompilerRefere
@Override
public void projectOpened() {
if (CompilerReferenceService.isEnabled()) {
myDirtyScopeHolder.installVFSListener();
myDirtyScopeHolder.installVFSListener(myProject);
if (!ApplicationManager.getApplication().isUnitTestMode()) {
CompilerManager compilerManager = CompilerManager.getInstance(myProject);
@@ -5,6 +5,7 @@ import com.intellij.ProjectTopics;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerReferenceService;
import com.intellij.compiler.backwardRefs.view.DirtyScopeTestInfo;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.compiler.options.ExcludeEntryDescription;
import com.intellij.openapi.compiler.options.ExcludedEntriesListener;
@@ -15,14 +16,15 @@ import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.AsyncFileListener;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.*;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -34,14 +36,16 @@ import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import gnu.trove.THashSet;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
import java.util.function.BiConsumer;
@SuppressWarnings("WeakerAccess")
public class DirtyScopeHolder extends UserDataHolderBase implements BulkFileListener {
public class DirtyScopeHolder extends UserDataHolderBase implements AsyncFileListener {
private final CompilerReferenceServiceBase<?> myService;
private final FileDocumentManager myFileDocManager;
private final PsiDocumentManager myPsiDocManager;
@@ -200,8 +204,25 @@ public class DirtyScopeHolder extends UserDataHolderBase implements BulkFileList
return getDirtyScope().contains(file);
}
@Nullable
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
public ChangeApplier prepareChange(@NotNull List<? extends VFileEvent> events) {
final List<Module> modulesToBeMarkedDirty = getModulesToBeMarkedDirtyBefore(events);
return new ChangeApplier() {
@Override
public void beforeVfsChange() {
modulesToBeMarkedDirty.forEach(DirtyScopeHolder.this::addToDirtyModules);
}
@Override
public void afterVfsChange() {
after(events);
}
};
}
private void after(@NotNull List<? extends VFileEvent> events) {
for (VFileEvent event : events) {
if (event instanceof VFileCreateEvent || event instanceof VFileCopyEvent || event instanceof VFileMoveEvent) {
VirtualFile file = event.getFile();
@@ -219,12 +240,20 @@ public class DirtyScopeHolder extends UserDataHolderBase implements BulkFileList
}
}
@Override
public void before(@NotNull List<? extends VFileEvent> events) {
@Contract(pure=true)
@NotNull
private List<Module> getModulesToBeMarkedDirtyBefore(@NotNull List<? extends VFileEvent> events) {
final List<Module> modulesToBeMarkedDirty = new ArrayList<>();
for (VFileEvent event : events) {
ProgressManager.checkCanceled();
if (event instanceof VFileDeleteEvent || event instanceof VFileMoveEvent || event instanceof VFileContentChangeEvent) {
VirtualFile file = event.getFile();
fileChanged(file);
if (file != null) {
final Module module = getModuleForSourceContentFile(file);
ContainerUtil.addIfNotNull(modulesToBeMarkedDirty, module);
}
}
else if (event instanceof VFilePropertyChangeEvent) {
VFilePropertyChangeEvent pce = (VFilePropertyChangeEvent)event;
@@ -233,16 +262,17 @@ public class DirtyScopeHolder extends UserDataHolderBase implements BulkFileList
final String path = pce.getFile().getPath();
for (Module module : ModuleManager.getInstance(myService.getProject()).getModules()) {
if (FileUtil.isAncestor(path, module.getModuleFilePath(), true)) {
addToDirtyModules(module);
modulesToBeMarkedDirty.add(module);
}
}
}
}
}
return modulesToBeMarkedDirty;
}
public void installVFSListener() {
myService.getProject().getMessageBus().connect().subscribe(VirtualFileManager.VFS_CHANGES, this);
public void installVFSListener(@NotNull Disposable parentDisposable) {
VirtualFileManager.getInstance().addAsyncFileListener(this, parentDisposable);
}
private void fileChanged(@NotNull VirtualFile file) {
@@ -251,6 +281,7 @@ public class DirtyScopeHolder extends UserDataHolderBase implements BulkFileList
addToDirtyModules(module);
}
}
private void addToDirtyModules(@NotNull Module module) {
synchronized (myLock) {
if (myCompilationPhase) {