diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index be9c80200e63..31df42e40c30 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.vfs.newvfs.impl; import com.intellij.openapi.application.ApplicationManager; @@ -349,10 +349,11 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { private void updateCaseSensitivityIfUnknown(@NotNull String childName) { VFilePropertyChangeEvent caseSensitivityEvent = generateCaseSensitivityChangedEventForUnknownCase(this, childName); if (caseSensitivityEvent != null) { - - changeCaseSensitivity(this, (FileAttributes.CaseSensitivity)caseSensitivityEvent.getNewValue()); + //TODO RC: inside generateCaseSensitivityChangedEventForUnknownCase() we update case-sensitivity if it is == FS.default, + // and here we update case-sensitivity if it is !=FS.default -- why such a separation? + owningPersistentFS().executeChangeCaseSensitivity(this, (FileAttributes.CaseSensitivity)caseSensitivityEvent.getNewValue()); // fire event asynchronously to avoid deadlocks with possibly currently held VFP/Refresh queue locks - RefreshQueue.getInstance().processEvents(true, List.of(caseSensitivityEvent)); + RefreshQueue.getInstance().processEvents(/*async: */true, List.of(caseSensitivityEvent)); // when the case-sensitivity changes, the "children must be sorted by name" invariant must be restored resortChildren(); } @@ -968,25 +969,21 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { @ApiStatus.Internal public static VFilePropertyChangeEvent generateCaseSensitivityChangedEvent(@NotNull VirtualFile dir, @NotNull FileAttributes.CaseSensitivity actualCaseSensitivity) { - if (actualCaseSensitivity != FileAttributes.CaseSensitivity.UNKNOWN) { - if (dir.getFileSystem().isCaseSensitive() != (actualCaseSensitivity == FileAttributes.CaseSensitivity.SENSITIVE)) { - // fire only when the new case sensitivity is different from the default FS sensitivity, - // because only in that case the file.isCaseSensitive() value could change - return new VFilePropertyChangeEvent(REFRESH_REQUESTOR, dir, VirtualFile.PROP_CHILDREN_CASE_SENSITIVITY, - FileAttributes.CaseSensitivity.UNKNOWN, actualCaseSensitivity); - } - else { - changeCaseSensitivity(dir, actualCaseSensitivity); - } + if (actualCaseSensitivity == FileAttributes.CaseSensitivity.UNKNOWN) { + return null; } + + if (dir.getFileSystem().isCaseSensitive() != (actualCaseSensitivity == FileAttributes.CaseSensitivity.SENSITIVE)) { + // fire only when the new case sensitivity is different from the default FS sensitivity, + // because only in that case the file.isCaseSensitive() value could change + return new VFilePropertyChangeEvent(REFRESH_REQUESTOR, dir, VirtualFile.PROP_CHILDREN_CASE_SENSITIVITY, + FileAttributes.CaseSensitivity.UNKNOWN, actualCaseSensitivity); + } + + //TODO RC: why we update the case-sensitivity only if it is == FS.default? + //TODO RC: why we update case-sensitivity in method that should be just generating an event? + PersistentFSImpl persistentFS = (PersistentFSImpl)PersistentFS.getInstance(); + persistentFS.executeChangeCaseSensitivity((VirtualDirectoryImpl)dir, actualCaseSensitivity); return null; } - - private static void changeCaseSensitivity(@NotNull VirtualFile vFile, - @NotNull FileAttributes.CaseSensitivity newValue) { - ((PersistentFSImpl)PersistentFS.getInstance()).executeChangeCaseSensitivity( - vFile, - newValue - ); - } } 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 763fcf6d14c6..feb8f07841d4 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 @@ -253,14 +253,14 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable { @Override public void dispose() { + //noinspection IncorrectCancellationExceptionHandling try { disconnect(); } catch (ProcessCanceledException e) { // Application may be closed before `LocalFileSystem` gets initialized() //noinspection IncorrectCancellationExceptionHandling - LOG.warn("Detected cancellation during dispose of PersistentFS. Application was likely closed before VFS got completely initialized", - e); + LOG.warn("Detected cancellation during dispose of PersistentFS. Application was likely closed before VFS got completely initialized", e); } } @@ -2138,7 +2138,7 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable { } case VirtualFile.PROP_HIDDEN -> executeSetHidden(file, ((Boolean)newValue).booleanValue()); case VirtualFile.PROP_SYMLINK_TARGET -> executeSetTarget(file, (String)newValue); - case VirtualFile.PROP_CHILDREN_CASE_SENSITIVITY -> executeChangeCaseSensitivity(file, (FileAttributes.CaseSensitivity)newValue); + case VirtualFile.PROP_CHILDREN_CASE_SENSITIVITY -> executeChangeCaseSensitivity((VirtualDirectoryImpl)file, (FileAttributes.CaseSensitivity)newValue); } } } @@ -2150,10 +2150,14 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable { } } + /** + * Update case-sensitivity of the directory, both in persistent VFS structure, and in in-memory cache. + * Change doesn't produce a modification event + */ @ApiStatus.Internal - public void executeChangeCaseSensitivity(@NotNull VirtualFile file, @NotNull FileAttributes.CaseSensitivity newCaseSensitivity) { - VirtualDirectoryImpl directory = (VirtualDirectoryImpl)file; - int fileId = fileId(file); + public void executeChangeCaseSensitivity(@NotNull VirtualDirectoryImpl directory, + @NotNull FileAttributes.CaseSensitivity newCaseSensitivity) { + int fileId = fileId(directory); vfsPeer.updateRecordFields(fileId, record -> { boolean sensitivityChanged = (newCaseSensitivity == FileAttributes.CaseSensitivity.SENSITIVE) ? record.addFlags(Flags.CHILDREN_CASE_SENSITIVE)