From fad4a5ddd9a54cecdf685cf97fab0ee34904098e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 3 Sep 2019 20:35:27 +0200 Subject: [PATCH] IDEA-CR-51959 fix OCRootsSynchronizerExcludingLibraryRootsWhenFilesMovedTest.testLibraryWithSourceSubfoldersMovedIntoAnotherLibrary GitOrigin-RevId: 94613ea9f15d28e1046887a8ea82f9253bb6bc16 --- .../intellij/util/indexing/IndexTest.groovy | 2 +- .../pointers/VirtualFilePointerManager.java | 18 +-- .../util/indexing/FileBasedIndexImpl.java | 113 ++++++++++-------- .../util/indexing/IndexedFilesListener.java | 23 +--- .../impl/VirtualFilePointerManagerImpl.java | 45 ++++--- .../openapi/vfs/newvfs/AsyncEventSupport.java | 6 +- .../src/META-INF/LangExtensions.xml | 2 + .../src/META-INF/PlatformExtensions.xml | 4 + .../src/componentSets/Platform.xml | 5 - .../impl/FileAssociationsManagerImpl.java | 25 ++-- .../xslt/associations/impl/TempManager.java | 5 +- 11 files changed, 113 insertions(+), 135 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/util/indexing/IndexTest.groovy b/java/java-tests/testSrc/com/intellij/util/indexing/IndexTest.groovy index 6de60c296f3b..e9186154f329 100644 --- a/java/java-tests/testSrc/com/intellij/util/indexing/IndexTest.groovy +++ b/java/java-tests/testSrc/com/intellij/util/indexing/IndexTest.groovy @@ -789,7 +789,7 @@ class IndexTest extends JavaCodeInsightFixtureTestCase { class RecordingVfsListener extends IndexedFilesListener { RecordingVfsListener() { - super(ManagingFS.getInstance()) + super() } @Override diff --git a/platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java b/platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java index e40e5406a175..24be235193c0 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java @@ -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 diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index e54f4a4d2d15..841055e3d499 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -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 myChangedFilesCollector = NotNullLazyValue.createValue(() -> AsyncEventSupport.EP_NAME.findExtensionOrFail(ChangedFilesCollector.class)); private final List myIndexableSets = ContainerUtil.createLockFreeCopyOnWriteList(); private final Map 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 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 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 allFilesToUpdate = myChangedFilesCollector.getAllFilesToUpdate(); + Collection 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 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) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexedFilesListener.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexedFilesListener.java index 2bf38d7f6b57..4bd0ae2efeba 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexedFilesListener.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexedFilesListener.java @@ -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); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java index 313c6f351281..b3cfb7da696a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java @@ -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 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> myRoots = ContainerUtil.newIdentityTroveMap(); // guarded by this // compare by identity because VirtualFilePointerContainer has too smart equals private final Set 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 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 events) { long start = System.currentTimeMillis(); MultiMap 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 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(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/AsyncEventSupport.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/AsyncEventSupport.java index c3e14edfa662..b055092828e9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/AsyncEventSupport.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/AsyncEventSupport.java @@ -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 EP_NAME = ExtensionPointName.create("com.intellij.vfs.asyncListener"); + + @ApiStatus.Internal + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.vfs.asyncListener"); private static boolean ourSuppressAppliers; public static void startListening() { diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index f709ce2af54f..ac349aa8b5ed 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -14,6 +14,8 @@ + + + + + com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl - - com.intellij.openapi.vfs.pointers.VirtualFilePointerManager - com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl - - com.intellij.openapi.command.undo.UndoManager com.intellij.openapi.command.impl.UndoManagerImpl diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java index 6d07331fcb81..42269727ce47 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java @@ -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 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 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 hashMap = new LinkedHashMap<>(); final Set 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(); } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/TempManager.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/TempManager.java index 673b53322099..1990098901a1 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/TempManager.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/TempManager.java @@ -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);