IDEA-CR-51959 fix OCRootsSynchronizerExcludingLibraryRootsWhenFilesMovedTest.testLibraryWithSourceSubfoldersMovedIntoAnotherLibrary

GitOrigin-RevId: 94613ea9f15d28e1046887a8ea82f9253bb6bc16
This commit is contained in:
Vladimir Krivosheev
2019-09-03 19:31:26 +00:00
committed by intellij-monorepo-bot
parent cedf229250
commit fad4a5ddd9
11 changed files with 113 additions and 135 deletions
@@ -789,7 +789,7 @@ class IndexTest extends JavaCodeInsightFixtureTestCase {
class RecordingVfsListener extends IndexedFilesListener {
RecordingVfsListener() {
super(ManagingFS.getInstance())
super()
}
@Override
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vfs.pointers;
import com.intellij.openapi.Disposable;
@@ -24,7 +10,7 @@ import org.jetbrains.annotations.Nullable;
public abstract class VirtualFilePointerManager extends SimpleModificationTracker {
public static VirtualFilePointerManager getInstance() {
return ApplicationManager.getApplication().getComponent(VirtualFilePointerManager.class);
return ApplicationManager.getApplication().getService(VirtualFilePointerManager.class);
}
@NotNull
@@ -37,7 +37,11 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.AsyncFileListener;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileWithId;
import com.intellij.openapi.vfs.newvfs.AsyncEventSupport;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
@@ -119,7 +123,8 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
private volatile boolean myExtensionsRelatedDataWasLoaded;
private final PerIndexDocumentVersionMap myLastIndexedDocStamps = new PerIndexDocumentVersionMap();
@NotNull private final ChangedFilesCollector myChangedFilesCollector;
@NotNull
private final NotNullLazyValue<ChangedFilesCollector> myChangedFilesCollector = NotNullLazyValue.createValue(() -> AsyncEventSupport.EP_NAME.findExtensionOrFail(ChangedFilesCollector.class));
private final List<IndexableFileSet> myIndexableSets = ContainerUtil.createLockFreeCopyOnWriteList();
private final Map<IndexableFileSet, Project> myIndexableSetToProjectMap = new THashMap<>();
@@ -258,11 +263,8 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
}
}, this);
myChangedFilesCollector = new ChangedFilesCollector(ManagingFS.getInstance());
myConnection = connection;
VirtualFileManager.getInstance().addAsyncFileListener(myChangedFilesCollector, this);
initComponent();
}
@@ -282,8 +284,8 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
boolean processChangedFiles(@NotNull Project project, @NotNull Processor<? super VirtualFile> processor) {
// avoid missing files when events are processed concurrently
return Stream.concat(myChangedFilesCollector.getEventMerger().getChangedFiles(),
myChangedFilesCollector.myFilesToUpdate.values().stream())
return Stream.concat(myChangedFilesCollector.getValue().getEventMerger().getChangedFiles(),
myChangedFilesCollector.getValue().myFilesToUpdate.values().stream())
.filter(filesToBeIndexedForProjectCondition(project))
.distinct()
.mapToInt(f -> processor.process(f) ? 1 : 0)
@@ -310,8 +312,11 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
// but it is more costly than current code, see IDEA-192192
//myChangedFilesCollector.invalidateIndicesRecursively(file, false);
//myChangedFilesCollector.buildIndicesForFileRecursively(file, false);
myChangedFilesCollector.invalidateIndicesRecursively(file, true, myChangedFilesCollector.getEventMerger());
if (myInitialized) myChangedFilesCollector.ensureUpToDateAsync();
ChangedFilesCollector changedFilesCollector = myChangedFilesCollector.getValue();
changedFilesCollector.invalidateIndicesRecursively(file, true, changedFilesCollector.getEventMerger());
if (myInitialized) {
changedFilesCollector.ensureUpToDateAsync();
}
}
private void initComponent() {
@@ -504,7 +509,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
try {
PersistentIndicesConfiguration.saveConfiguration();
for (VirtualFile file : myChangedFilesCollector.getAllFilesToUpdate()) {
for (VirtualFile file : myChangedFilesCollector.getValue().getAllFilesToUpdate()) {
if (!file.isValid()) {
removeDataFromIndicesForFile(Math.abs(getIdMaskingNonIdBasedFile(file)), file);
}
@@ -721,7 +726,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
@Nullable GlobalSearchScope filter,
@Nullable VirtualFile restrictedFile) {
ProgressManager.checkCanceled();
myChangedFilesCollector.ensureUpToDate();
myChangedFilesCollector.getValue().ensureUpToDate();
ApplicationManager.getApplication().assertReadAccessAllowed();
NoAccessDuringPsiEvents.checkCallContext();
@@ -998,7 +1003,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
@TestOnly
public void cleanupForNextTest() {
myChangedFilesCollector.ensureUpToDate();
myChangedFilesCollector.getValue().ensureUpToDate();
myTransactionMap = SmartFMap.emptyMap();
IndexConfiguration state = getState();
@@ -1011,7 +1016,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
@TestOnly
public IndexedFilesListener getChangedFilesCollector() {
return myChangedFilesCollector;
return myChangedFilesCollector.getValue();
}
public static final class ProjectIndexableFilesFilter extends IdFilter {
@@ -1053,7 +1058,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
}
void filesUpdateStarted(Project project) {
myChangedFilesCollector.ensureUpToDate();
myChangedFilesCollector.getValue().ensureUpToDate();
myProjectsBeingUpdated.add(project);
myFilesModCount.incrementAndGet();
}
@@ -1515,7 +1520,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
@NotNull
Collection<VirtualFile> getFilesToUpdate(final Project project) {
return ContainerUtil.filter(myChangedFilesCollector.getAllFilesToUpdate(), filesToBeIndexedForProjectCondition(project)::test);
return ContainerUtil.filter(myChangedFilesCollector.getValue().getAllFilesToUpdate(), filesToBeIndexedForProjectCondition(project)::test);
}
@NotNull
@@ -1539,14 +1544,14 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
}
public boolean isFileUpToDate(VirtualFile file) {
return !myChangedFilesCollector.isScheduledForUpdate(file);
return !myChangedFilesCollector.getValue().isScheduledForUpdate(file);
}
// caller is responsible to ensure no concurrent same document processing
void processRefreshedFile(@Nullable Project project, @NotNull final com.intellij.ide.caches.FileContent fileContent) {
// ProcessCanceledException will cause re-adding the file to processing list
final VirtualFile file = fileContent.getVirtualFile();
if (myChangedFilesCollector.isScheduledForUpdate(file)) {
if (myChangedFilesCollector.getValue().isScheduledForUpdate(file)) {
indexFileContent(project, fileContent);
}
}
@@ -1576,7 +1581,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
IndexingStamp.flushCache(fileId);
}
myChangedFilesCollector.removeFileIdFromFilesScheduledForUpdate(fileId);
myChangedFilesCollector.getValue().removeFileIdFromFilesScheduledForUpdate(fileId);
if (file instanceof VirtualFileSystemEntry && setIndexedStatus) ((VirtualFileSystemEntry)file).setFileIndexed(true);
}
@@ -1744,7 +1749,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
private volatile long myLastOtherProjectInclusionStamp;
private void forceUpdate(@Nullable Project project, @Nullable final GlobalSearchScope filter, @Nullable final VirtualFile restrictedTo) {
Collection<VirtualFile> allFilesToUpdate = myChangedFilesCollector.getAllFilesToUpdate();
Collection<VirtualFile> allFilesToUpdate = myChangedFilesCollector.getValue().getAllFilesToUpdate();
if (!allFilesToUpdate.isEmpty()) {
boolean includeFilesFromOtherProjects = restrictedTo == null && System.currentTimeMillis() - myLastOtherProjectInclusionStamp > 100;
@@ -1833,8 +1838,10 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
// the file is for sure not a dir and it was previously indexed by at least one index
if (file.isValid()) {
if(!isTooLarge(file)) myChangedFilesCollector.scheduleForUpdate(file);
else myChangedFilesCollector.scheduleForUpdate(new DeletedVirtualFileStub((VirtualFileWithId)file));
if (!isTooLarge(file)) {
myChangedFilesCollector.getValue().scheduleForUpdate(file);
}
else myChangedFilesCollector.getValue().scheduleForUpdate(new DeletedVirtualFileStub((VirtualFileWithId)file));
}
else {
LOG.info("Unexpected state in update:" + file);
@@ -1847,12 +1854,12 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
updateSingleIndex(indexId, null, fileId, null);
}
}
if(!fileIndexedStatesToUpdate.isEmpty()) {
if (!fileIndexedStatesToUpdate.isEmpty()) {
// its data should be (lazily) wiped for every index
myChangedFilesCollector.scheduleForUpdate(new DeletedVirtualFileStub((VirtualFileWithId)file));
myChangedFilesCollector.getValue().scheduleForUpdate(new DeletedVirtualFileStub((VirtualFileWithId)file));
}
else {
myChangedFilesCollector.removeScheduledFileFromUpdate(file); // no need to update it anymore
myChangedFilesCollector.getValue().removeScheduledFileFromUpdate(file); // no need to update it anymore
}
}
}
@@ -1878,7 +1885,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
if (!fileIsDirectory) {
if (!file.isValid() || isTooLarge(file)) {
// large file might be scheduled for update in before event when its size was not large
myChangedFilesCollector.removeScheduledFileFromUpdate(file);
myChangedFilesCollector.getValue().removeScheduledFileFromUpdate(file);
}
else {
myFileTypeManager.freezeFileTypeTemporarilyIn(file, () -> {
@@ -1897,8 +1904,9 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
if (scheduleForUpdate) {
IndexingStamp.flushCache(fileId);
myChangedFilesCollector.scheduleForUpdate(file);
} else if (file instanceof VirtualFileSystemEntry) {
myChangedFilesCollector.getValue().scheduleForUpdate(file);
}
else if (file instanceof VirtualFileSystemEntry) {
((VirtualFileSystemEntry)file).setFileIndexed(true);
}
});
@@ -1906,7 +1914,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
}
}
private final class ChangedFilesCollector extends IndexedFilesListener {
static final class ChangedFilesCollector extends IndexedFilesListener {
private final IntObjectMap<VirtualFile> myFilesToUpdate = ContainerUtil.createConcurrentIntObjectMap();
private final AtomicInteger myProcessedEventIndex = new AtomicInteger();
private final Phaser myWorkersFinishedSync = new Phaser() {
@@ -1918,30 +1926,31 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
private final Executor myVfsEventsExecutor = SequentialTaskExecutor.createSequentialApplicationPoolExecutor("FileBasedIndex Vfs Event Processor");
private final AtomicInteger myScheduledVfsEventsWorkers = new AtomicInteger();
private final FileBasedIndexImpl myManager;
ChangedFilesCollector(@NotNull ManagingFS managingFS) {
super(managingFS);
ChangedFilesCollector() {
myManager = (FileBasedIndexImpl)getInstance();
}
@Override
protected void buildIndicesForFileRecursively(@NotNull VirtualFile file, boolean contentChange) {
cleanProcessedFlag(file);
if (!contentChange) {
myUpdatingFiles.incrementAndGet();
myManager.myUpdatingFiles.incrementAndGet();
}
super.buildIndicesForFileRecursively(file, contentChange);
if (!contentChange) {
if (myUpdatingFiles.decrementAndGet() == 0) {
myFilesModCount.incrementAndGet();
if (myManager.myUpdatingFiles.decrementAndGet() == 0) {
myManager.myFilesModCount.incrementAndGet();
}
}
}
@Override
protected void iterateIndexableFiles(@NotNull VirtualFile file, @NotNull ContentIterator iterator) {
for (IndexableFileSet set : myIndexableSets) {
for (IndexableFileSet set : myManager.myIndexableSets) {
if (set.isInSet(file)) {
set.iterateIndexableFilesIn(file, iterator);
}
@@ -1950,7 +1959,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
void scheduleForUpdate(VirtualFile file) {
if (!(file instanceof DeletedVirtualFileStub)) {
IndexableFileSet setForFile = getIndexableSetForFile(file);
IndexableFileSet setForFile = myManager.getIndexableSetForFile(file);
if (setForFile == null) {
return;
}
@@ -1999,7 +2008,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
@Override
public void beforeVfsChange() {
if (shouldCleanup) {
cleanupMemoryStorage(false);
myManager.cleanupMemoryStorage(false);
}
superApplier.beforeVfsChange();
}
@@ -2007,7 +2016,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
@Override
public void afterVfsChange() {
superApplier.afterVfsChange();
if (myInitialized) ensureUpToDateAsync();
if (myManager.myInitialized) ensureUpToDateAsync();
}
};
}
@@ -2028,7 +2037,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
return;
}
//assert ApplicationManager.getApplication().isReadAccessAllowed() || ShutDownTracker.isShutdownHookRunning();
waitUntilIndicesAreInitialized();
myManager.waitUntilIndicesAreInitialized();
if (ApplicationManager.getApplication().isReadAccessAllowed()) {
processFilesInReadAction();
@@ -2080,16 +2089,16 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
int phase = myWorkersFinishedSync.getPhase();
try {
getEventMerger().processChanges(info ->
ConcurrencyUtil.withLock(myWriteLock, () -> {
ConcurrencyUtil.withLock(myManager.myWriteLock, () -> {
try {
ProgressManager.getInstance().executeNonCancelableSection(() -> {
int fileId = info.getFileId();
VirtualFile file = info.getFile();
if (info.isTransientStateChanged()) doTransientStateChangeForFile(fileId, file);
if (info.isBeforeContentChanged()) FileBasedIndexImpl.this.doInvalidateIndicesForFile(fileId, file, true);
if (info.isContentChanged()) scheduleFileForIndexing(fileId, file, true);
if (info.isFileRemoved()) FileBasedIndexImpl.this.doInvalidateIndicesForFile(fileId, file, false);
if (info.isFileAdded()) scheduleFileForIndexing(fileId, file, false);
if (info.isTransientStateChanged()) myManager.doTransientStateChangeForFile(fileId, file);
if (info.isBeforeContentChanged()) myManager.doInvalidateIndicesForFile(fileId, file, true);
if (info.isContentChanged()) myManager.scheduleFileForIndexing(fileId, file, true);
if (info.isFileRemoved()) myManager.doInvalidateIndicesForFile(fileId, file, false);
if (info.isFileAdded()) myManager.scheduleFileForIndexing(fileId, file, false);
});
}
finally {
@@ -2290,9 +2299,8 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
if (file != null) {
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile instanceof VirtualFileWithId) {
myChangedFilesCollector.getEventMerger().recordTransientStateChangeEvent(virtualFile);
myChangedFilesCollector.getValue().getEventMerger().recordTransientStateChangeEvent(virtualFile);
}
}
}
@@ -2314,7 +2322,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
}
}
if (wasIndexed) {
myChangedFilesCollector.scheduleForUpdate(virtualFile);
myChangedFilesCollector.getValue().scheduleForUpdate(virtualFile);
IndexingStamp.flushCache(fileId);
}
}
@@ -2326,14 +2334,15 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
myIndexableSets.remove(set);
myIndexableSetToProjectMap.remove(set);
for (VirtualFile file : myChangedFilesCollector.getAllFilesToUpdate()) {
ChangedFilesCollector changedFilesCollector = myChangedFilesCollector.getValue();
for (VirtualFile file : changedFilesCollector.getAllFilesToUpdate()) {
final int fileId = Math.abs(getIdMaskingNonIdBasedFile(file));
if (!file.isValid()) {
removeDataFromIndicesForFile(fileId, file);
myChangedFilesCollector.removeFileIdFromFilesScheduledForUpdate(fileId);
changedFilesCollector.removeFileIdFromFilesScheduledForUpdate(fileId);
}
else if (getIndexableSetForFile(file) == null) { // todo remove data from indices for removed
myChangedFilesCollector.removeFileIdFromFilesScheduledForUpdate(fileId);
changedFilesCollector.removeFileIdFromFilesScheduledForUpdate(fileId);
}
}
@@ -2536,7 +2545,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
});
myAllIndicesInitializedFuture = IndexInfrastructure.submitGenesisTask(() -> {
if (!myShutdownPerformed.get()) {
myChangedFilesCollector.ensureUpToDateAsync();
myChangedFilesCollector.getValue().ensureUpToDateAsync();
}
return null;
});
@@ -2564,7 +2573,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
long deadline = System.nanoTime() + unit.toNanos(timeout);
while (System.nanoTime() < deadline) {
try {
((BoundedTaskExecutor)myChangedFilesCollector.myVfsEventsExecutor).waitAllTasksExecuted(100, TimeUnit.MILLISECONDS);
((BoundedTaskExecutor)myChangedFilesCollector.getValue().myVfsEventsExecutor).waitAllTasksExecuted(100, TimeUnit.MILLISECONDS);
return;
}
catch (TimeoutException e) {
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.indexing;
import com.intellij.openapi.application.PathManager;
@@ -28,13 +14,8 @@ import java.io.File;
import java.util.List;
abstract class IndexedFilesListener implements AsyncFileListener {
private final ManagingFS myManagingFS;
private final VfsEventsMerger myEventMerger = new VfsEventsMerger();
IndexedFilesListener(@NotNull ManagingFS managingFS) {
myManagingFS = managingFS;
}
private static class ConfigHolder {
private static final VirtualFile myConfig = LocalFileSystem.getInstance().findFileByIoFile(new File(PathManager.getConfigPath()));
private static final VirtualFile myLog = LocalFileSystem.getInstance().findFileByIoFile(new File(PathManager.getLogPath()));
@@ -65,7 +46,7 @@ abstract class IndexedFilesListener implements AsyncFileListener {
}
ProgressManager.checkCanceled();
eventMerger.recordBeforeFileEvent(file, contentChange);
return !file.isDirectory() || FileBasedIndexImpl.isMock(file) || myManagingFS.wereChildrenAccessed(file);
return !file.isDirectory() || FileBasedIndexImpl.isMock(file) || ManagingFS.getInstance().wereChildrenAccessed(file);
}
protected abstract void iterateIndexableFiles(@NotNull VirtualFile file, @NotNull ContentIterator iterator);
@@ -10,11 +10,15 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.AsyncFileListener.ChangeApplier;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.openapi.vfs.newvfs.ArchiveFileSystem;
import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
@@ -32,7 +36,6 @@ import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.io.URLUtil;
import com.intellij.util.messages.MessageBus;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectIntHashMap;
@@ -44,7 +47,7 @@ import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager implements Disposable, AsyncFileListener {
public final class VirtualFilePointerManagerImpl extends VirtualFilePointerManager implements Disposable {
private static final Logger LOG = Logger.getInstance(VirtualFilePointerManagerImpl.class);
private static final Comparator<String> URL_COMPARATOR = SystemInfo.isFileSystemCaseSensitive ? String::compareTo : String::compareToIgnoreCase;
static final boolean IS_UNDER_UNIT_TEST = ApplicationManager.getApplication().isUnitTestMode();
@@ -64,20 +67,14 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
private final Map<VirtualFileSystem, Map<VirtualFilePointerListener, FilePointerPartNode>> myRoots = ContainerUtil.newIdentityTroveMap(); // guarded by this
// compare by identity because VirtualFilePointerContainer has too smart equals
private final Set<VirtualFilePointerContainerImpl> myContainers = ContainerUtil.newIdentityTroveSet(); // guarded by myContainers
@NotNull
private final VirtualFileManager myVirtualFileManager;
@NotNull
private final MessageBus myBus;
@NotNull
private final FileTypeManager myFileTypeManager;
private int myPointerSetModCount;
VirtualFilePointerManagerImpl(@NotNull MessageBus messageBus, VirtualFileManager virtualFileManager, @NotNull FileTypeManager fileTypeManager) {
myVirtualFileManager = virtualFileManager;
myBus = messageBus;
myFileTypeManager = fileTypeManager;
virtualFileManager.addAsyncFileListener(this, this);
static final class MyAsyncFileListener implements AsyncFileListener {
@Override
public ChangeApplier prepareChange(@NotNull List<? extends VFileEvent> events) {
return ((VirtualFilePointerManagerImpl)getInstance()).prepareChange(events);
}
}
@Override
@@ -183,7 +180,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
else {
protocol = url.substring(0, protocolEnd);
fileSystem = myVirtualFileManager.getFileSystem(protocol);
fileSystem = VirtualFileManager.getInstance().getFileSystem(protocol);
path = url.substring(protocolEnd + URLUtil.SCHEME_SEPARATOR.length());
}
if (fileSystem == null) {
@@ -203,13 +200,13 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
// but we have so many tests that create pointers, not dispose and leak them,
// so for now we create normal pointers only when there are listeners.
// maybe, later we'll fix all those tests
VirtualFile found = file == null ? myVirtualFileManager.findFileByUrl(url) : file;
VirtualFile found = file == null ? VirtualFileManager.getInstance().findFileByUrl(url) : file;
return found == null ? new LightFilePointer(url) : new LightFilePointer(found);
}
if (!(fileSystem instanceof VirtualFilePointerCapableFileSystem)) {
// we are unable to track alien file systems for now
VirtualFile found = file == null ? myVirtualFileManager.findFileByUrl(url) : file;
VirtualFile found = file == null ? VirtualFileManager.getInstance().findFileByUrl(url) : file;
// if file is null, this pointer will never be alive
if (url == null) {
url = file.getUrl();
@@ -227,7 +224,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
if (url.contains("..")) {
// the url of the form "/x/../y" should resolve to "/y" (or something else in the case of symlinks)
file = myVirtualFileManager.findFileByUrl(url);
file = VirtualFileManager.getInstance().findFileByUrl(url);
if (file != null) {
url = file.getUrl();
path = file.getPath();
@@ -431,7 +428,6 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
@NotNull
@Override
public ChangeApplier prepareChange(@NotNull List<? extends VFileEvent> events) {
long start = System.currentTimeMillis();
MultiMap<VirtualFilePointerListener, FilePointerPartNode> toFireEvents = MultiMap.create();
@@ -464,7 +460,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
else {
String createdFileName = createEvent.getChildName();
// if the .jar file created, there may be many files hiding inside
FileType fileType = myFileTypeManager.getFileTypeByExtension(FileUtilRt.getExtension(createdFileName));
FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(FileUtilRt.getExtension(createdFileName));
fireSubdirectoryPointers = fileType instanceof ArchiveFileType;
}
addRelevantPointers(createEvent.getParent(), createEvent.getChildNameId(), toFireEvents, fireSubdirectoryPointers, fs);
@@ -542,7 +538,8 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
if (allPointers.length != 0) {
myBus.syncPublisher(VirtualFilePointerListener.TOPIC).beforeValidityChanged(allPointers);
ApplicationManager.getApplication().getMessageBus()
.syncPublisher(VirtualFilePointerListener.TOPIC).beforeValidityChanged(allPointers);
}
assertConsistency();
@@ -600,6 +597,8 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
ApplicationManager.getApplication().assertIsDispatchThread(); // guarantees no attempts to get read action lock under "this" lock
incModificationCount();
VirtualFileManager virtualFileManager = VirtualFileManager.getInstance();
//noinspection SynchronizeOnThis
synchronized (this) {
for (FilePointerPartNode node : toUpdateUrls.values()) {
@@ -611,7 +610,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
String urlAfter = after.second;
VirtualFile fileAfter = after.first;
if (URL_COMPARATOR.compare(urlBefore, urlAfter) != 0 || !node.urlEndsWithName(urlAfter, fileAfter)) {
VirtualFileSystem fs = myVirtualFileManager.getFileSystem(VirtualFileManager.extractProtocol(urlAfter));
VirtualFileSystem fs = virtualFileManager.getFileSystem(VirtualFileManager.extractProtocol(urlAfter));
if (fs instanceof NewVirtualFileSystem) {
List<VirtualFilePointerImpl> myPointers = new SmartList<>();
node.addAllPointersTo(myPointers);
@@ -644,7 +643,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
if (allPointers.length != 0) {
myBus.syncPublisher(VirtualFilePointerListener.TOPIC).validityChanged(allPointers);
ApplicationManager.getApplication().getMessageBus().syncPublisher(VirtualFilePointerListener.TOPIC).validityChanged(allPointers);
}
assertConsistency();
@@ -24,9 +24,11 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
@ApiStatus.Internal
public class AsyncEventSupport {
public final class AsyncEventSupport {
private static final Logger LOG = Logger.getInstance(AsyncEventSupport.class);
private static final ExtensionPointName<AsyncFileListener> EP_NAME = ExtensionPointName.create("com.intellij.vfs.asyncListener");
@ApiStatus.Internal
public static final ExtensionPointName<AsyncFileListener> EP_NAME = ExtensionPointName.create("com.intellij.vfs.asyncListener");
private static boolean ourSuppressAppliers;
public static void startListening() {
@@ -14,6 +14,8 @@
<!-- FileBasedIndex / SerializationManager is quite important and in any case will be used, better to preload it -->
<applicationService serviceInterface="com.intellij.util.indexing.FileBasedIndex"
serviceImplementation="com.intellij.util.indexing.FileBasedIndexImpl" preload="true"/>
<vfs.asyncListener implementation="com.intellij.util.indexing.FileBasedIndexImpl$ChangedFilesCollector"/>
<applicationService serviceInterface="com.intellij.psi.stubs.SerializationManager"
serviceImplementation="com.intellij.psi.stubs.SerializationManagerImpl" preload="true"/>
<applicationService serviceInterface="com.intellij.psi.stubs.StubIndex"
@@ -22,6 +22,10 @@
<applicationService serviceInterface="com.intellij.history.LocalHistory"
serviceImplementation="com.intellij.history.integration.LocalHistoryImpl" preload="true"/>
<applicationService serviceInterface="com.intellij.openapi.vfs.pointers.VirtualFilePointerManager"
serviceImplementation="com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl"/>
<vfs.asyncListener implementation="com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl$MyAsyncFileListener"/>
<applicationService serviceImplementation="com.intellij.util.net.HttpConfigurable" preload="true"/>
<applicationService serviceImplementation="com.intellij.ide.ClipboardSynchronizer" preload="true"/>
<applicationService serviceInterface="com.intellij.openapi.keymap.KeymapManager" preload="true"
@@ -9,11 +9,6 @@
<implementation-class>com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl</implementation-class>
</component>
<component>
<interface-class>com.intellij.openapi.vfs.pointers.VirtualFilePointerManager</interface-class>
<implementation-class>com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl</implementation-class>
</component>
<component>
<interface-class>com.intellij.openapi.command.undo.UndoManager</interface-class>
<implementation-class>com.intellij.openapi.command.impl.UndoManagerImpl</implementation-class>
@@ -38,17 +38,15 @@ import org.jetbrains.annotations.NotNull;
import java.util.*;
class FileAssociationsManagerImpl extends FileAssociationsManager implements Disposable, JDOMExternalizable, NamedComponent {
final class FileAssociationsManagerImpl extends FileAssociationsManager implements Disposable, JDOMExternalizable, NamedComponent {
private static final Logger LOG = Logger.getInstance(FileAssociationsManagerImpl.class);
private final Project myProject;
private final VirtualFilePointerManager myFilePointerManager;
private final Map<VirtualFilePointer, VirtualFilePointerContainer> myAssociations;
private boolean myTempCopy;
FileAssociationsManagerImpl(Project project, VirtualFilePointerManager filePointerManager) {
FileAssociationsManagerImpl(Project project) {
myProject = project;
myFilePointerManager = filePointerManager;
myAssociations = new LinkedHashMap<>();
}
@@ -59,11 +57,12 @@ class FileAssociationsManagerImpl extends FileAssociationsManager implements Dis
@Override
public void readExternal(Element element) throws InvalidDataException {
final List<Element> children = element.getChildren("file");
VirtualFilePointerManager filePointerManager = VirtualFilePointerManager.getInstance();
for (Element child : children) {
final String url = child.getAttributeValue("url");
if (url != null) {
final VirtualFilePointer pointer = myFilePointerManager.create(url, myProject, null);
final VirtualFilePointerContainer container = myFilePointerManager.createContainer(myProject);
final VirtualFilePointer pointer = filePointerManager.create(url, myProject, null);
final VirtualFilePointerContainer container = filePointerManager.createContainer(myProject);
container.readExternal(child, "association", false);
myAssociations.put(pointer, container);
}
@@ -82,7 +81,7 @@ class FileAssociationsManagerImpl extends FileAssociationsManager implements Dis
}
public TransactionalManager getTempManager() {
return new TempManager(this, myProject, myFilePointerManager);
return new TempManager(this, myProject);
}
@Override
@@ -125,10 +124,11 @@ class FileAssociationsManagerImpl extends FileAssociationsManager implements Dis
final HashMap<VirtualFilePointer, VirtualFilePointerContainer> hashMap = new LinkedHashMap<>();
final Set<VirtualFilePointer> virtualFilePointers = other.myAssociations.keySet();
VirtualFilePointerManager filePointerManager = VirtualFilePointerManager.getInstance();
for (VirtualFilePointer pointer : virtualFilePointers) {
final VirtualFilePointerContainer container = other.myFilePointerManager.createContainer(other.myProject);
final VirtualFilePointerContainer container = filePointerManager.createContainer(other.myProject);
container.addAll(other.myAssociations.get(pointer));
hashMap.put(other.myFilePointerManager.duplicate(pointer, other.myProject, null), container);
hashMap.put(filePointerManager.duplicate(pointer, other.myProject, null), container);
}
return hashMap;
}
@@ -189,11 +189,12 @@ class FileAssociationsManagerImpl extends FileAssociationsManager implements Dis
return;
}
VirtualFilePointerManager filePointerManager = VirtualFilePointerManager.getInstance();
for (VirtualFilePointer pointer : myAssociations.keySet()) {
if (pointer.getUrl().equals(virtualFile.getUrl())) {
VirtualFilePointerContainer container = myAssociations.get(pointer);
if (container == null) {
container = myFilePointerManager.createContainer(myProject);
container = filePointerManager.createContainer(myProject);
myAssociations.put(pointer, container);
}
if (container.findByUrl(assoc.getUrl()) == null) {
@@ -203,9 +204,9 @@ class FileAssociationsManagerImpl extends FileAssociationsManager implements Dis
return;
}
}
final VirtualFilePointerContainer container = myFilePointerManager.createContainer(myProject);
final VirtualFilePointerContainer container = filePointerManager.createContainer(myProject);
container.add(assoc);
myAssociations.put(myFilePointerManager.create(virtualFile, myProject, null), container);
myAssociations.put(filePointerManager.create(virtualFile, myProject, null), container);
touch();
}
@@ -19,7 +19,6 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.psi.PsiFile;
import java.util.Map;
@@ -30,8 +29,8 @@ class TempManager extends TransactionalManager {
private long myStartModCount;
private long myImplModCount;
TempManager(FileAssociationsManagerImpl impl, Project project, VirtualFilePointerManager filePointerManager) {
myTmp = new FileAssociationsManagerImpl(project, filePointerManager);
TempManager(FileAssociationsManagerImpl impl, Project project) {
myTmp = new FileAssociationsManagerImpl(project);
myTmp.markAsTempCopy();
myTmp.copyFrom(impl);