forked from OSchip/llvm-project
[VirtualFileSystem] Support creating directories then adding files inside
Summary: In https://reviews.llvm.org/D39572 , I added support for specifying `Type` when invoking `InMemoryFileSystem::addFile()`. However, I didn't account for the fact that when `Type` is `directory_file`, we need to construct an `InMemoryDirectory`, not an `InMemoryFile`, or else clients cannot create files inside that directory. This diff fixes the bug and adds a test. Test Plan: New test added. Ran test with: % make -j12 check-clang-tools Reviewers: bkramer, hokein Reviewed By: bkramer Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D40140 llvm-svn: 318445
This commit is contained in:
parent
4ca69bdac6
commit
7838101678
|
@ -319,19 +319,23 @@ public:
|
|||
explicit InMemoryFileSystem(bool UseNormalizedPaths = true);
|
||||
~InMemoryFileSystem() override;
|
||||
|
||||
/// Add a buffer to the VFS with a path. The VFS owns the buffer.
|
||||
/// If present, User, Group, Type and Perms apply to the newly-created file.
|
||||
/// \return true if the file was successfully added, false if the file already
|
||||
/// exists in the file system with different contents.
|
||||
/// Add a file containing a buffer or a directory to the VFS with a
|
||||
/// path. The VFS owns the buffer. If present, User, Group, Type
|
||||
/// and Perms apply to the newly-created file or directory.
|
||||
/// \return true if the file or directory was successfully added,
|
||||
/// false if the file or directory already exists in the file system with
|
||||
/// different contents.
|
||||
bool addFile(const Twine &Path, time_t ModificationTime,
|
||||
std::unique_ptr<llvm::MemoryBuffer> Buffer,
|
||||
Optional<uint32_t> User = None, Optional<uint32_t> Group = None,
|
||||
Optional<llvm::sys::fs::file_type> Type = None,
|
||||
Optional<llvm::sys::fs::perms> Perms = None);
|
||||
/// Add a buffer to the VFS with a path. The VFS does not own the buffer.
|
||||
/// If present, User, Group, Type and Perms apply to the newly-created file.
|
||||
/// \return true if the file was successfully added, false if the file already
|
||||
/// exists in the file system with different contents.
|
||||
/// If present, User, Group, Type and Perms apply to the newly-created file
|
||||
/// or directory.
|
||||
/// \return true if the file or directory was successfully added,
|
||||
/// false if the file or directory already exists in the file system with
|
||||
/// different contents.
|
||||
bool addFileNoOwn(const Twine &Path, time_t ModificationTime,
|
||||
llvm::MemoryBuffer *Buffer,
|
||||
Optional<uint32_t> User = None,
|
||||
|
|
|
@ -527,13 +527,19 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
|
|||
++I;
|
||||
if (!Node) {
|
||||
if (I == E) {
|
||||
// End of the path, create a new file.
|
||||
// End of the path, create a new file or directory.
|
||||
Status Stat(P.str(), getNextVirtualUniqueID(),
|
||||
llvm::sys::toTimePoint(ModificationTime), ResolvedUser,
|
||||
ResolvedGroup, Buffer->getBufferSize(), ResolvedType,
|
||||
ResolvedPerms);
|
||||
Dir->addChild(Name, llvm::make_unique<detail::InMemoryFile>(
|
||||
std::move(Stat), std::move(Buffer)));
|
||||
std::unique_ptr<detail::InMemoryNode> Child;
|
||||
if (ResolvedType == sys::fs::file_type::directory_file) {
|
||||
Child.reset(new detail::InMemoryDirectory(std::move(Stat)));
|
||||
} else {
|
||||
Child.reset(new detail::InMemoryFile(std::move(Stat),
|
||||
std::move(Buffer)));
|
||||
}
|
||||
Dir->addChild(Name, std::move(Child));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -829,6 +829,19 @@ TEST_F(InMemoryFileSystemTest, AddFileWithPerms) {
|
|||
Stat->getPermissions());
|
||||
}
|
||||
|
||||
TEST_F(InMemoryFileSystemTest, AddDirectoryThenAddChild) {
|
||||
FS.addFile("/a", 0, MemoryBuffer::getMemBuffer(""), /*User=*/None,
|
||||
/*Group=*/None, sys::fs::file_type::directory_file);
|
||||
FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer("abc"), /*User=*/None,
|
||||
/*Group=*/None, sys::fs::file_type::regular_file);
|
||||
auto Stat = FS.status("/a");
|
||||
ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
|
||||
ASSERT_TRUE(Stat->isDirectory());
|
||||
Stat = FS.status("/a/b");
|
||||
ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
|
||||
ASSERT_TRUE(Stat->isRegularFile());
|
||||
}
|
||||
|
||||
// NOTE: in the tests below, we use '//root/' as our root directory, since it is
|
||||
// a legal *absolute* path on Windows as well as *nix.
|
||||
class VFSFromYAMLTest : public ::testing::Test {
|
||||
|
|
Loading…
Reference in New Issue