[vfs] IJPL-176784: better account for FS case-sensitivity in VirtualFilePointer

GitOrigin-RevId: a1b38b347025ca72c75a23c62a871149742df63c
This commit is contained in:
Ruslan Cheremin
2025-03-20 00:13:52 +00:00
committed by intellij-monorepo-bot
parent bf249aef42
commit 1b0519bcc2
4 changed files with 40 additions and 8 deletions
@@ -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) {
@@ -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;
@@ -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
@@ -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() {