mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
VFS: cache file type only if under read action, clear cache in write action, cleanup
to avoid races possibly leading to IDEA-245099 File type of unloaded plugin can be leaked due to file type caching GitOrigin-RevId: 3e746a89a0e57cc2c49fcb02951e00b214a281e5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
478e1d913d
commit
8d62fcfecb
+1
-1
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
+3
-1
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
+1
@@ -1044,6 +1044,7 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable {
|
||||
}
|
||||
|
||||
private static void fireAfterEvents(@NotNull BulkFileListener publisher, @NotNull List<? extends VFileEvent> toSend) {
|
||||
CachedFileType.clearCache();
|
||||
((BulkFileListener)VirtualFilePointerManager.getInstance()).after(toSend);
|
||||
publisher.after(toSend);
|
||||
}
|
||||
|
||||
+6
-2
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user