[FileSystem] Migrate CommandCompletions
authorJonas Devlieghere <jonas@devlieghere.com>
Tue, 4 Dec 2018 17:58:21 +0000 (17:58 +0000)
committerJonas Devlieghere <jonas@devlieghere.com>
Tue, 4 Dec 2018 17:58:21 +0000 (17:58 +0000)
Make use of the convenience helpers from FileSystem.

Differential revision: https://reviews.llvm.org/D55240

llvm-svn: 348287

lldb/include/lldb/Host/FileSystem.h
lldb/source/Commands/CommandCompletions.cpp
lldb/source/Host/common/FileSystem.cpp
lldb/unittests/Interpreter/TestCompletion.cpp

index 2122860..9e36649 100644 (file)
@@ -34,6 +34,9 @@ public:
   FileSystem() : m_fs(llvm::vfs::getRealFileSystem()) {}
   FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs) : m_fs(fs) {}
 
+  FileSystem(const FileSystem &fs) = delete;
+  FileSystem &operator=(const FileSystem &fs) = delete;
+
   static FileSystem &Instance();
 
   static void Initialize();
@@ -54,6 +57,20 @@ public:
   Status Open(File &File, const FileSpec &file_spec, uint32_t options,
               uint32_t permissions = lldb::eFilePermissionsFileDefault);
 
+  /// Get a directory iterator.
+  /// @{
+  llvm::vfs::directory_iterator DirBegin(const FileSpec &file_spec,
+                                         std::error_code &ec);
+  llvm::vfs::directory_iterator DirBegin(const llvm::Twine &dir,
+                                         std::error_code &ec);
+  /// @}
+
+  /// Returns the Status object for the given file.
+  /// @{
+  llvm::ErrorOr<llvm::vfs::Status> GetStatus(const FileSpec &file_spec) const;
+  llvm::ErrorOr<llvm::vfs::Status> GetStatus(const llvm::Twine &path) const;
+  /// @}
+
   /// Returns the modification time of the given file.
   /// @{
   llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec) const;
index 37f7bdf..7524c56 100644 (file)
@@ -101,7 +101,6 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
   if (CompletionBuffer.size() >= PATH_MAX)
     return matches.GetSize();
 
-  namespace fs = llvm::sys::fs;
   namespace path = llvm::sys::path;
 
   llvm::StringRef SearchDir;
@@ -178,11 +177,16 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
   // SearchDir now contains the directory to search in, and Prefix contains the
   // text we want to match against items in that directory.
 
+  FileSystem &fs = FileSystem::Instance();
   std::error_code EC;
-  fs::directory_iterator Iter(SearchDir, EC, false);
-  fs::directory_iterator End;
+  llvm::vfs::directory_iterator Iter = fs.DirBegin(SearchDir, EC);
+  llvm::vfs::directory_iterator End;
   for (; Iter != End && !EC; Iter.increment(EC)) {
     auto &Entry = *Iter;
+    llvm::ErrorOr<llvm::vfs::Status> Status = fs.GetStatus(Entry.path());
+
+    if (!Status)
+      continue;
 
     auto Name = path::filename(Entry.path());
 
@@ -190,20 +194,18 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
     if (Name == "." || Name == ".." || !Name.startswith(PartialItem))
       continue;
 
-    // We have a match.
-
-    llvm::ErrorOr<fs::basic_file_status> st = Entry.status();
-    if (!st)
-      continue;
+    bool is_dir = Status->isDirectory();
 
     // If it's a symlink, then we treat it as a directory as long as the target
     // is a directory.
-    bool is_dir = fs::is_directory(*st);
-    if (fs::is_symlink_file(*st)) {
-      fs::file_status target_st;
-      if (!fs::status(Entry.path(), target_st))
-        is_dir = fs::is_directory(target_st);
+    if (Status->isSymlink()) {
+      FileSpec symlink_filespec(Entry.path());
+      FileSpec resolved_filespec;
+      auto error = fs.ResolveSymbolicLink(symlink_filespec, resolved_filespec);
+      if (error.Success())
+        is_dir = fs.IsDirectory(symlink_filespec);
     }
+
     if (only_directories && !is_dir)
       continue;
 
index a010599..7191c9d 100644 (file)
@@ -63,6 +63,25 @@ Optional<FileSystem> &FileSystem::InstanceImpl() {
   return g_fs;
 }
 
+vfs::directory_iterator FileSystem::DirBegin(const FileSpec &file_spec,
+                                             std::error_code &ec) {
+  return DirBegin(file_spec.GetPath(), ec);
+}
+
+vfs::directory_iterator FileSystem::DirBegin(const Twine &dir,
+                                             std::error_code &ec) {
+  return m_fs->dir_begin(dir, ec);
+}
+
+llvm::ErrorOr<vfs::Status>
+FileSystem::GetStatus(const FileSpec &file_spec) const {
+  return GetStatus(file_spec.GetPath());
+}
+
+llvm::ErrorOr<vfs::Status> FileSystem::GetStatus(const Twine &path) const {
+  return m_fs->status(path);
+}
+
 sys::TimePoint<>
 FileSystem::GetModificationTime(const FileSpec &file_spec) const {
   return GetModificationTime(file_spec.GetPath());
index e781de0..6cd4f68 100644 (file)
@@ -7,9 +7,11 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Interpreter/CommandCompletions.h"
 #include "lldb/Utility/StringList.h"
 #include "lldb/Utility/TildeExpressionResolver.h"
+
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -65,6 +67,8 @@ protected:
   SmallString<128> FileBaz;
 
   void SetUp() override {
+    FileSystem::Initialize();
+
     // chdir back into the original working dir this test binary started with.
     // A previous test may have have changed the working dir.
     ASSERT_NO_ERROR(fs::set_current_path(OriginalWorkingDir));
@@ -105,7 +109,10 @@ protected:
     ASSERT_NO_ERROR(fs::current_path(OriginalWorkingDir));
   }
 
-  void TearDown() override { ASSERT_NO_ERROR(fs::remove_directories(BaseDir)); }
+  void TearDown() override {
+    ASSERT_NO_ERROR(fs::remove_directories(BaseDir));
+    FileSystem::Terminate();
+  }
 
   static bool HasEquivalentFile(const Twine &Path, const StringList &Paths) {
     for (size_t I = 0; I < Paths.GetSize(); ++I) {
@@ -140,7 +147,7 @@ protected:
 };
 
 SmallString<128> CompletionTest::OriginalWorkingDir;
-}
+} // namespace
 
 static std::vector<std::string> toVector(const StringList &SL) {
   std::vector<std::string> Result;
@@ -170,8 +177,8 @@ TEST_F(CompletionTest, DirCompletionAbsolute) {
   ASSERT_EQ(Count, Results.GetSize());
   EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
 
-  Count =
-    CommandCompletions::DiskDirectories(Twine(BaseDir) + "/.", Results, Resolver);
+  Count = CommandCompletions::DiskDirectories(Twine(BaseDir) + "/.", Results,
+                                              Resolver);
   ASSERT_EQ(0u, Count);
   ASSERT_EQ(Count, Results.GetSize());