From 1b0519bcc2103a765874e5281334fc794ffef937 Mon Sep 17 00:00:00 2001 From: Ruslan Cheremin Date: Tue, 18 Mar 2025 22:25:51 +0100 Subject: [PATCH] [vfs] IJPL-176784: better account for FS case-sensitivity in VirtualFilePointer GitOrigin-RevId: a1b38b347025ca72c75a23c62a871149742df63c --- .../openapi/vfs/impl/FilePartNode.java | 18 ++++++++++++---- .../openapi/vfs/impl/FilePartNodeRoot.java | 1 + .../openapi/vfs/impl/UrlPartNode.java | 8 +++---- .../vfs/impl/VirtualFilePointerTest.java | 21 +++++++++++++++++++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePartNode.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePartNode.java index 59db701e07ba..aaf8b90d8511 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePartNode.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePartNode.java @@ -153,14 +153,14 @@ public class FilePartNode { @NotNull NewVirtualFileSystem childFs) { if (nameId <= 0 && nameId != JAR_SEPARATOR_NAME_ID) throw new IllegalArgumentException("invalid argument nameId: "+nameId); for (FilePartNode child : children) { - if (child.nameEqualTo(nameId)) return child; + if (child.nameEqualTo(nameId, childFs)) return child; } if (createIfNotFound) { CharSequence name = fromNameId(nameId); int index = children.length == 0 ? -1 : binarySearchChildByName(name); FilePartNode child; if (index >= 0) throw new AssertionError(index + " : child= '" + (child = children[index]) + "'" - + "; child.nameEqualTo(nameId)=" + child.nameEqualTo(nameId) + + "; child.nameEqualTo(nameId)=" + child.nameEqualTo(nameId, childFs) + "; child.getClass()=" + child.getClass() + "; child.nameId=" + child.nameId + "; child.getName()='" + child.getName() + "'" @@ -182,8 +182,18 @@ public class FilePartNode { return null; } - boolean nameEqualTo(int nameId) { - return this.nameId == nameId; + /** @return true if this part name is equal to the name denoted by nameId, with case-sensitivity from childFs */ + boolean nameEqualTo(int nameId, + @NotNull NewVirtualFileSystem childFs) { + if (this.nameId == nameId) { + return true; + } + boolean caseSensitive = childFs.isCaseSensitive(); + if (caseSensitive) { + return false; + } + + return StringUtilRt.equal(getName(), fromNameId(nameId), caseSensitive); } int binarySearchChildByName(@NotNull CharSequence name) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePartNodeRoot.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePartNodeRoot.java index 381dde00be40..5b0b29e784c0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePartNodeRoot.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePartNodeRoot.java @@ -137,6 +137,7 @@ public final class FilePartNodeRoot extends FilePartNode { return result; } + /** Find a pointer to the given path, taking into account case-sensitivity of fs, or create a new pointer, if existing not found */ @NotNull NodeToUpdate findOrCreateByPath(@NotNull String path, @NotNull NewVirtualFileSystem fs) { NewVirtualFileSystem currentFS; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/UrlPartNode.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/UrlPartNode.java index 093f765d2832..af421c6ccbad 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/UrlPartNode.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/UrlPartNode.java @@ -1,7 +1,6 @@ -// Copyright 2000-2023 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.impl; -import com.intellij.openapi.util.SystemInfoRt; import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; import org.jetbrains.annotations.NonNls; @@ -32,8 +31,9 @@ final class UrlPartNode extends FilePartNode { } @Override - boolean nameEqualTo(int nameId) { - return StringUtilRt.equal(getName(), fromNameId(nameId), SystemInfoRt.isFileSystemCaseSensitive); + boolean nameEqualTo(int nameId, + @NotNull NewVirtualFileSystem childFs) { + return StringUtilRt.equal(getName(), fromNameId(nameId), childFs.isCaseSensitive()); } @Override diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java index ef5be02e075c..b57704c3f9c7 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java @@ -165,6 +165,27 @@ public class VirtualFilePointerTest extends BareTestFixtureTestCase { assertEquals("[before:true, after:false]", fileToDeleteListener.log.toString()); } + @Test//IJPL-176784 + public void testDeleteFileAndRecreateWithAnotherCase() { + VirtualFilePointerListener pointersListener = new LoggingListener(); + + File fileToDelete = tempDir.newFile("lower-case.txt"); + VirtualFilePointer pointerToFileToDelete = createPointerByFile(fileToDelete, pointersListener); + assertTrue(pointerToFileToDelete.isValid()); + VfsTestUtil.deleteFile(getVirtualFile(fileToDelete)); + assertFalse(pointerToFileToDelete.isValid()); + + File fileToReCreate = tempDir.newFile("lower-case.txt"); + VirtualFilePointer pointerToFileToReCreate = createPointerByFile(fileToReCreate, pointersListener); + assertTrue(pointerToFileToReCreate.isValid()); + VfsTestUtil.deleteFile(getVirtualFile(fileToReCreate)); + assertFalse(pointerToFileToReCreate.isValid()); + + File fileToReCreateWithAnotherCase = tempDir.newFile("LOWER-CASE.txt"); + VirtualFilePointer pointerToFileToReCreateAnotherCase = createPointerByFile(fileToReCreateWithAnotherCase, pointersListener); + assertTrue(pointerToFileToReCreateAnotherCase.isValid()); + } + @IJIgnore(issue = "IJPL-149673") @Test public void testSwitchingVfs() {