diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java index a65cc8cd1213..e9a1d6c5c480 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java @@ -712,7 +712,6 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent } private void unregisterFileTypeWithoutNotification(@NotNull FileType fileType) { - CachedFileType.remove(fileType); myPatternsTable.removeAllAssociations(fileType); myInitialAssociations.removeAllAssociations(fileType); mySchemeManager.removeScheme(fileType); @@ -809,6 +808,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent private void fireFileTypesChanged(@Nullable FileType addedFileType, @Nullable FileType removedFileType) { myDetectionService.clearCaches(); + CachedFileType.clearCache(); ApplicationManager.getApplication().getMessageBus().syncPublisher(TOPIC).fileTypesChanged(new FileTypeEvent(this, addedFileType, removedFileType)); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/CachedFileType.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/CachedFileType.java index 141da3f24e8e..1779d1ffb672 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/CachedFileType.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/CachedFileType.java @@ -1,6 +1,7 @@ // Copyright 2000-2020 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.newvfs.impl; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.psi.util.PsiModificationTracker; import org.jetbrains.annotations.ApiStatus; @@ -25,10 +26,12 @@ public final class CachedFileType { } static CachedFileType forType(@NotNull FileType fileType) { + ApplicationManager.getApplication().assertReadAccessAllowed(); return ourInterner.computeIfAbsent(fileType, CachedFileType::new); } public static void clearCache() { + ApplicationManager.getApplication().assertWriteAccessAllowed(); ourInterner.forEach((type, cachedType) -> { // clear references to file types to aid plugin unloading cachedType.fileType = null; @@ -36,13 +39,6 @@ public final class CachedFileType { ourInterner.clear(); } - public static void remove(@NotNull FileType type) { - CachedFileType cached = ourInterner.remove(type); - if (cached != null) { - cached.fileType = null; - } - } - static final class PsiListener implements PsiModificationTracker.Listener { @Override public void modificationCountChanged() { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java index ba2b39974433..200ce673a3ae 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java @@ -485,7 +485,9 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { FileType type = cache == null ? null : cache.getUpToDateOrNull(); if (type == null) { type = super.getFileType(); - myFileType = CachedFileType.forType(type); + if (ApplicationManager.getApplication().isReadAccessAllowed()) { + myFileType = CachedFileType.forType(type); + } } return type; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index 248304e47469..deaa9fe44974 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -1,8 +1,6 @@ // Copyright 2000-2020 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.newvfs.persistent; -import com.google.common.hash.HashFunction; -import com.google.common.hash.Hashing; import com.intellij.ide.IdeBundle; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; @@ -20,7 +18,6 @@ import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl; import com.intellij.openapi.vfs.newvfs.ChildInfoImpl; import com.intellij.openapi.vfs.newvfs.FileAttribute; import com.intellij.openapi.vfs.newvfs.events.ChildInfo; -import com.intellij.openapi.vfs.newvfs.impl.CachedFileType; import com.intellij.openapi.vfs.newvfs.impl.FileNameCache; import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry; @@ -1186,7 +1183,6 @@ public final class FSRecords { private static void incModCount(int id) { incLocalModCount(); - CachedFileType.clearCache(); final int count = doGetModCount() + 1; getRecords().putInt(HEADER_GLOBAL_MOD_COUNT_OFFSET, count); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index e7ce048b625b..ea269b59b185 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -1044,6 +1044,7 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable { } private static void fireAfterEvents(@NotNull BulkFileListener publisher, @NotNull List toSend) { + CachedFileType.clearCache(); ((BulkFileListener)VirtualFilePointerManager.getInstance()).after(toSend); publisher.after(toSend); } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java index 4cc577e58578..a70cce34cb10 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java @@ -930,7 +930,7 @@ public class FileTypesTest extends HeavyPlatformTestCase { bean.fileNames = ".prettierrc"; bean.implementationClass = MyTestFileType.class.getName(); Disposable disposable = registerFileType(bean); - CachedFileType.clearCache(); // normally this is done by PsiModificationTracker.Listener but it's not fired in this test + clearFileTypeCache(); assertEquals(MyTestFileType.NAME, FileTypeManager.getInstance().getFileTypeByFileName(".prettierrc").getName()); assertEquals(MyTestFileType.NAME, vFile.getFileType().getName()); @@ -939,6 +939,10 @@ public class FileTypesTest extends HeavyPlatformTestCase { assertNull(FileTypeManager.getInstance().findFileTypeByName(MyTestFileType.NAME)); } + private static void clearFileTypeCache() { + WriteAction.run(() -> CachedFileType.clearCache()); // normally this is done by PsiModificationTracker.Listener but it's not fired in this test + } + public void testRegisterAdditionalExtensionForExistingFileType() throws IOException { File tempFile = createTempFile(".prettierrc", "This is a text file"); VirtualFile vFile = getVirtualFile(tempFile); @@ -948,7 +952,7 @@ public class FileTypesTest extends HeavyPlatformTestCase { bean.name = "XML"; bean.fileNames = ".prettierrc"; Disposable disposable = registerFileType(bean); - CachedFileType.clearCache(); // normally this is done by PsiModificationTracker.Listener but it's not fired in this test + clearFileTypeCache(); assertEquals("XML", FileTypeManager.getInstance().getFileTypeByFileName(".prettierrc").getName()); assertEquals("XML", vFile.getFileType().getName());