Fix crash when completing in the current directory.
authorZachary Turner <zturner@google.com>
Sat, 15 Apr 2017 02:44:53 +0000 (02:44 +0000)
committerZachary Turner <zturner@google.com>
Sat, 15 Apr 2017 02:44:53 +0000 (02:44 +0000)
llvm-svn: 300386

lldb/source/Commands/CommandCompletions.cpp
lldb/unittests/Interpreter/TestCompletion.cpp

index 5f0d494..fd84e1c 100644 (file)
@@ -176,7 +176,10 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
   if (PartialItem == ".")
     PartialItem = llvm::StringRef();
 
-  assert(!SearchDir.empty());
+  if (SearchDir.empty()) {
+    llvm::sys::fs::current_path(Storage);
+    SearchDir = Storage;
+  }
   assert(!PartialItem.contains(path::get_separator()));
 
   // SearchDir now contains the directory to search in, and Prefix contains the
index 4b06b7f..0548b93 100644 (file)
@@ -43,6 +43,8 @@ protected:
   /// be placed. It is removed at the end of the test suite.
   static SmallString<128> BaseDir;
 
+  static SmallString<128> OriginalWorkingDir;
+
   static SmallString<128> DirFoo;
   static SmallString<128> DirFooA;
   static SmallString<128> DirFooB;
@@ -58,7 +60,11 @@ protected:
   static SmallString<128> FileBar;
   static SmallString<128> FileBaz;
 
+  void SetUp() override { llvm::sys::fs::set_current_path(OriginalWorkingDir); }
+
   static void SetUpTestCase() {
+    llvm::sys::fs::current_path(OriginalWorkingDir);
+
     ASSERT_NO_ERROR(fs::createUniqueDirectory("FsCompletion", BaseDir));
     const char *DirNames[] = {"foo", "fooa", "foob",       "fooc",
                               "bar", "baz",  "test_folder"};
@@ -106,9 +112,33 @@ protected:
     }
     return false;
   }
+
+  void DoDirCompletions(const Twine &Prefix,
+                        StandardTildeExpressionResolver &Resolver,
+                        StringList &Results) {
+    // When a partial name matches, it returns all matches.  If it matches both
+    // a full name AND some partial names, it returns all of them.
+    uint32_t Count =
+        CommandCompletions::DiskDirectories(Prefix + "foo", Results, Resolver);
+    ASSERT_EQ(4u, Count);
+    ASSERT_EQ(Count, Results.GetSize());
+    EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
+    EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
+    EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
+    EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
+
+    // If it matches only partial names, it still works as expected.
+    Count = CommandCompletions::DiskDirectories(Twine(Prefix) + "b", Results,
+                                                Resolver);
+    ASSERT_EQ(2u, Count);
+    ASSERT_EQ(Count, Results.GetSize());
+    EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
+    EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
+  }
 };
 
 SmallString<128> CompletionTest::BaseDir;
+SmallString<128> CompletionTest::OriginalWorkingDir;
 
 SmallString<128> CompletionTest::DirFoo;
 SmallString<128> CompletionTest::DirFooA;
@@ -132,8 +162,11 @@ TEST_F(CompletionTest, DirCompletionAbsolute) {
   // by asserting an exact result count, and verifying against known
   // folders.
 
+  std::string Prefixes[] = {(Twine(BaseDir) + "/").str(), ""};
+
   StandardTildeExpressionResolver Resolver;
   StringList Results;
+
   // When a directory is specified that doesn't end in a slash, it searches
   // for that directory, not items under it.
   size_t Count =
@@ -143,8 +176,7 @@ TEST_F(CompletionTest, DirCompletionAbsolute) {
   EXPECT_TRUE(HasEquivalentFile(BaseDir, Results));
 
   // When the same directory ends with a slash, it finds all children.
-  Count = CommandCompletions::DiskDirectories(Twine(BaseDir) + "/", Results,
-                                              Resolver);
+  Count = CommandCompletions::DiskDirectories(Prefixes[0], Results, Resolver);
   ASSERT_EQ(7u, Count);
   ASSERT_EQ(Count, Results.GetSize());
   EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
@@ -155,24 +187,9 @@ TEST_F(CompletionTest, DirCompletionAbsolute) {
   EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
   EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results));
 
-  // When a partial name matches, it returns all matches.  If it matches both
-  // a full name AND some partial names, it returns all of them.
-  Count = CommandCompletions::DiskDirectories(Twine(BaseDir) + "/foo", Results,
-                                              Resolver);
-  ASSERT_EQ(4u, Count);
-  ASSERT_EQ(Count, Results.GetSize());
-  EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
-  EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
-  EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
-  EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
-
-  // If it matches only partial names, it still works as expected.
-  Count = CommandCompletions::DiskDirectories(Twine(BaseDir) + "/b", Results,
-                                              Resolver);
-  ASSERT_EQ(2u, Count);
-  ASSERT_EQ(Count, Results.GetSize());
-  EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
-  EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
+  DoDirCompletions(Twine(BaseDir) + "/", Resolver, Results);
+  llvm::sys::fs::set_current_path(BaseDir);
+  DoDirCompletions("", Resolver, Results);
 }
 
 TEST_F(CompletionTest, FileCompletionAbsolute) {