[lldb][NFC] Remove argument prefix checking boilerplate when adding completions
authorRaphael Isemann <teemperor@gmail.com>
Mon, 23 Sep 2019 08:59:21 +0000 (08:59 +0000)
committerRaphael Isemann <teemperor@gmail.com>
Mon, 23 Sep 2019 08:59:21 +0000 (08:59 +0000)
llvm-svn: 372561

lldb/include/lldb/Utility/CompletionRequest.h
lldb/source/Commands/CommandCompletions.cpp
lldb/source/Interpreter/OptionValueBoolean.cpp
lldb/source/Interpreter/OptionValueEnumeration.cpp
lldb/source/Interpreter/OptionValueUUID.cpp
lldb/source/Interpreter/Options.cpp
lldb/source/Utility/ArchSpec.cpp
lldb/unittests/Utility/CompletionRequestTest.cpp

index e10c1f7..a430519 100644 (file)
@@ -146,6 +146,24 @@ public:
     m_result.AddResult(completion, description, mode);
   }
 
+  /// Adds a possible completion string if the completion would complete the
+  /// current argument.
+  ///
+  /// \param match The suggested completion.
+  /// \param description An optional description of the completion string. The
+  ///     description will be displayed to the user alongside the completion.
+  template <CompletionMode M = CompletionMode::Normal>
+  void TryCompleteCurrentArg(llvm::StringRef completion,
+                             llvm::StringRef description = "") {
+    // Trying to rewrite the whole line while checking for the current
+    // argument never makes sense. Completion modes are always hardcoded, so
+    // this can be a static_assert.
+    static_assert(M != CompletionMode::RewriteLine,
+                  "Shouldn't rewrite line with this function");
+    if (completion.startswith(GetCursorArgumentPrefix()))
+      AddCompletion(completion, description, M);
+  }
+
   /// Adds multiple possible completion strings.
   ///
   /// \param completions The list of completions.
index f00a35d..00ba108 100644 (file)
@@ -308,10 +308,8 @@ void CommandCompletions::SettingsNames(CommandInterpreter &interpreter,
     }
   }
 
-  for (const std::string &s : g_property_names) {
-    if (llvm::StringRef(s).startswith(request.GetCursorArgumentPrefix()))
-      request.AddCompletion(s);
-  }
+  for (const std::string &s : g_property_names)
+    request.TryCompleteCurrentArg(s);
 }
 
 void CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter,
index bfc7760..4a08415 100644 (file)
@@ -82,8 +82,6 @@ void OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
   if (request.GetCursorArgumentPrefix().empty())
     entries = entries.take_front(2);
 
-  for (auto entry : entries) {
-    if (entry.startswith_lower(request.GetCursorArgumentPrefix()))
-      request.AddCompletion(entry);
-  }
+  for (auto entry : entries)
+    request.TryCompleteCurrentArg(entry);
 }
index 126a4f5..26933aa 100644 (file)
@@ -108,8 +108,7 @@ void OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
   if (!request.GetCursorArgumentPrefix().empty()) {
     for (size_t i = 0; i < num_enumerators; ++i) {
       llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef();
-      if (name.startswith(request.GetCursorArgumentPrefix()))
-        request.AddCompletion(name);
+      request.TryCompleteCurrentArg(name);
     }
     return;
   }
index 483c478..7a6bc65 100644 (file)
@@ -80,10 +80,6 @@ void OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
     const UUID &module_uuid = module_sp->GetUUID();
     if (!module_uuid.IsValid())
       continue;
-    llvm::ArrayRef<uint8_t> module_bytes = module_uuid.GetBytes();
-    if (module_bytes.size() >= uuid_bytes.size() &&
-        module_bytes.take_front(uuid_bytes.size()).equals(uuid_bytes)) {
-      request.AddCompletion(module_uuid.GetAsString());
-    }
+    request.TryCompleteCurrentArg(module_uuid.GetAsString());
   }
 }
index 09ecfed..1f63382 100644 (file)
@@ -759,10 +759,7 @@ void Options::HandleOptionArgumentCompletion(
             request.GetCursorCharPosition());
 
     for (const auto &enum_value : enum_values) {
-      if (strstr(enum_value.string_value, match_string.c_str()) ==
-          enum_value.string_value) {
-        request.AddCompletion(enum_value.string_value);
-      }
+      request.TryCompleteCurrentArg(enum_value.string_value);
     }
   }
 
index fc2d439..1f22265 100644 (file)
@@ -244,17 +244,8 @@ void ArchSpec::ListSupportedArchNames(StringList &list) {
 }
 
 void ArchSpec::AutoComplete(CompletionRequest &request) {
-  if (!request.GetCursorArgumentPrefix().empty()) {
-    for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
-      if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith,
-                      request.GetCursorArgumentPrefix()))
-        request.AddCompletion(g_core_definitions[i].name);
-    }
-  } else {
-    StringList matches;
-    ListSupportedArchNames(matches);
-    request.AddCompletions(matches);
-  }
+  for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+    request.TryCompleteCurrentArg(g_core_definitions[i].name);
 }
 
 #define CPU_ANY (UINT32_MAX)
index 469aad2..ad3c560 100644 (file)
@@ -31,6 +31,43 @@ TEST(CompletionRequest, Constructor) {
   EXPECT_STREQ(request.GetPartialParsedLine().GetArgumentAtIndex(1), "b");
 }
 
+TEST(CompletionRequest, TryCompleteCurrentArgGood) {
+  std::string command = "a bad c";
+  StringList matches, descriptions;
+  CompletionResult result;
+
+  CompletionRequest request(command, 3, result);
+  request.TryCompleteCurrentArg("boo", "car");
+  result.GetMatches(matches);
+  result.GetDescriptions(descriptions);
+
+  EXPECT_EQ(1U, result.GetResults().size());
+  EXPECT_STREQ("boo", matches.GetStringAtIndex(0U));
+  EXPECT_EQ(1U, descriptions.GetSize());
+  EXPECT_STREQ("car", descriptions.GetStringAtIndex(0U));
+}
+
+TEST(CompletionRequest, TryCompleteCurrentArgBad) {
+  std::string command = "a bad c";
+  CompletionResult result;
+
+  CompletionRequest request(command, 3, result);
+  request.TryCompleteCurrentArg("car", "card");
+
+  EXPECT_EQ(0U, result.GetResults().size());
+}
+
+TEST(CompletionRequest, TryCompleteCurrentArgMode) {
+  std::string command = "a bad c";
+  CompletionResult result;
+
+  CompletionRequest request(command, 3, result);
+  request.TryCompleteCurrentArg<CompletionMode::Partial>("bar", "bard");
+
+  EXPECT_EQ(1U, result.GetResults().size());
+  EXPECT_EQ(CompletionMode::Partial, result.GetResults()[0].GetMode());
+}
+
 TEST(CompletionRequest, ShiftArguments) {
   std::string command = "a bad c";
   const unsigned cursor_pos = 3;