void (@NotNull List<? extends VFileEvent> events) { List<Runnable> syncTasks = new ArrayList<>(); List<Runnable> delayedTasks = new ArrayList<>(); List<FilePropertyPusher<?>> filePushers = getFilePushers(); // this is useful for debugging. Especially in integration tests: it is often clear why large file sets have changed // (e.g. imported modules or jdk), but it is often unclear why small file sets change and what these files are. if (LOG.isDebugEnabled() && events.size() < 20) { for (VFileEvent event : events) LOG.debug("File changed: " + event.getPath() + ".\nevent:" + event); } for (VFileEvent event : events) { if (event instanceof VFileCreateEvent) { boolean isDirectory = ((VFileCreateEvent)event).isDirectory(); List<FilePropertyPusher<?>> pushers = isDirectory ? FilePropertyPusher.EP_NAME.getExtensionList() : filePushers; if (!event.isFromRefresh()) { ContainerUtil.addIfNotNull(syncTasks, createRecursivePushTask(event, pushers)); } else { FileType fileType = FileTypeRegistry.getInstance().getFileTypeByFileName(((VFileCreateEvent)event).getChildName()); boolean isProjectOrWorkspaceFile = fileType instanceof InternalFileType || VfsUtilCore.findContainingDirectory(((VFileCreateEvent)event).getParent(), Project.DIRECTORY_STORE_FOLDER) != null; if (!isProjectOrWorkspaceFile) { ContainerUtil.addIfNotNull(delayedTasks, createRecursivePushTask(event, pushers)); } } } else if (event instanceof VFileMoveEvent || event instanceof VFileCopyEvent) { VirtualFile file = getFile(event); if (file == null) continue; boolean isDirectory = file.isDirectory(); List<FilePropertyPusher<?>> pushers = isDirectory ? FilePropertyPusher.EP_NAME.getExtensionList() : filePushers; ContainerUtil.addIfNotNull(syncTasks, createRecursivePushTask(event, pushers)); } } boolean pushingSomethingSynchronously = !syncTasks.isEmpty() && syncTasks.size() < FileBasedIndexProjectHandler.ourMinFilesToStartDumbMode; if (pushingSomethingSynchronously) { // push synchronously to avoid entering dumb mode in the middle of a meaningful write action // when only a few files are created/moved syncTasks.forEach(Runnable::run); } else { delayedTasks.addAll(syncTasks); } if (!delayedTasks.isEmpty()) { queueTasks(delayedTasks, "Push on VFS changes"); } if (pushingSomethingSynchronously) { Application app = ApplicationManager.getApplication(); if (app.isDispatchThread()) { scheduleDumbModeReindexingIfNeeded(); } else { app.invokeLater(this::scheduleDumbModeReindexingIfNeeded, myProject.getDisposed()); } } }