llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tools-extra

Author: Mythreya Kuricheti (MythreyaK)

<details>
<summary>Changes</summary>

Adds `MacroFilterPolicy` 

```yaml
Completion:
  MacroFilter: ExactPrefix (default), FuzzyMatch
```

Fix for clangd/clangd#<!-- -->1480

---
Full diff: https://github.com/llvm/llvm-project/pull/169880.diff


9 Files Affected:

- (modified) clang-tools-extra/clangd/ClangdServer.cpp (+1) 
- (modified) clang-tools-extra/clangd/CodeComplete.cpp (+28-7) 
- (modified) clang-tools-extra/clangd/CodeComplete.h (+5) 
- (modified) clang-tools-extra/clangd/Config.h (+8) 
- (modified) clang-tools-extra/clangd/ConfigCompile.cpp (+16-4) 
- (modified) clang-tools-extra/clangd/ConfigFragment.h (+6) 
- (modified) clang-tools-extra/clangd/ConfigYAML.cpp (+4) 
- (modified) clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp (+29) 
- (modified) clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp (+14) 


``````````diff
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index ac1e9aa5f0ff1..f1a87dd12d905 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -458,6 +458,7 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
     CodeCompleteOpts.InsertIncludes =
         Config::current().Completion.HeaderInsertion;
     CodeCompleteOpts.CodePatterns = Config::current().Completion.CodePatterns;
+    CodeCompleteOpts.MacroFilter = Config::current().Completion.MacroFilter;
     // FIXME(ibiryukov): even if Preamble is non-null, we may want to check
     // both the old and the new version in case only one of them matches.
     CodeCompleteResult Result = clangd::codeComplete(
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index e4df7581f1315..0358455ff1f75 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1435,7 +1435,8 @@ bool 
semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
   Clang->setCodeCompletionConsumer(Consumer.release());
 
   if (Input.Preamble.RequiredModules)
-    
Input.Preamble.RequiredModules->adjustHeaderSearchOptions(Clang->getHeaderSearchOpts());
+    Input.Preamble.RequiredModules->adjustHeaderSearchOptions(
+        Clang->getHeaderSearchOpts());
 
   SyntaxOnlyAction Action;
   if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
@@ -2037,14 +2038,34 @@ class CodeCompleteFlow {
   }
 
   std::optional<float> fuzzyScore(const CompletionCandidate &C) {
-    // Macros can be very spammy, so we only support prefix completion.
-    if (((C.SemaResult &&
+    using MacroFilterPolicy = Config::MacroFilterPolicy;
+
+    const auto IsMacroResult =
+        ((C.SemaResult &&
           C.SemaResult->Kind == CodeCompletionResult::RK_Macro) ||
          (C.IndexResult &&
-          C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro)) &&
-        !C.Name.starts_with_insensitive(Filter->pattern()))
-      return std::nullopt;
-    return Filter->match(C.Name);
+          C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro));
+
+    if (!IsMacroResult)
+      return Filter->match(C.Name);
+
+    // macros with leading and trailing underscore are probably spammy
+    switch (Opts.MacroFilter) {
+    case MacroFilterPolicy::ExactPrefix:
+      if (C.Name.starts_with_insensitive(Filter->pattern()))
+        return Filter->match(C.Name);
+      else
+        return std::nullopt;
+    case MacroFilterPolicy::FuzzyMatch:
+      if (!C.Name.starts_with_insensitive("_") &&
+          !C.Name.ends_with_insensitive("_"))
+        return Filter->match(C.Name);
+      else
+        return std::nullopt;
+    }
+    llvm_unreachable("Unhandled MacroFilter option in fuzzyScore.");
+
+    return std::nullopt;
   }
 
   CodeCompletion::Scores
diff --git a/clang-tools-extra/clangd/CodeComplete.h 
b/clang-tools-extra/clangd/CodeComplete.h
index 1cf3b41119043..cde22a8212e6a 100644
--- a/clang-tools-extra/clangd/CodeComplete.h
+++ b/clang-tools-extra/clangd/CodeComplete.h
@@ -114,6 +114,11 @@ struct CodeCompleteOptions {
   /// Whether to suggest code patterns & snippets or not in completion
   Config::CodePatternsPolicy CodePatterns = Config::CodePatternsPolicy::All;
 
+  /// Filter macros using an exact prefix, or with a fuzzy match. In both 
cases,
+  /// macros with leading or trailing underscores are strictly filtered
+  Config::MacroFilterPolicy MacroFilter =
+      Config::MacroFilterPolicy::ExactPrefix;
+
   /// Whether to use the clang parser, or fallback to text-based completion
   /// (using identifiers in the current file and symbol indexes).
   enum CodeCompletionParse {
diff --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index 01997cee08515..bc58c831e4e89 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -157,6 +157,12 @@ struct Config {
     None // Suggest none of the code patterns and snippets
   };
 
+  enum class MacroFilterPolicy {
+    ExactPrefix, // Suggest macros if the prefix matches exactly
+    FuzzyMatch,  // Fuzzy-match macros if they do not have "_" as prefix or
+                 // suffix
+  };
+
   /// Configures code completion feature.
   struct {
     /// Whether code completion includes results that are not visible in 
current
@@ -168,6 +174,8 @@ struct Config {
     HeaderInsertionPolicy HeaderInsertion = HeaderInsertionPolicy::IWYU;
     /// Enables code patterns & snippets suggestions
     CodePatternsPolicy CodePatterns = CodePatternsPolicy::All;
+    /// Controls how macros are filtered
+    MacroFilterPolicy MacroFilter = MacroFilterPolicy::ExactPrefix;
   } Completion;
 
   /// Configures hover feature.
diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 18e31809aa7c7..2b41949d6d05c 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -564,10 +564,10 @@ struct FragmentCompiler {
       auto Fast = isFastTidyCheck(Str);
       if (!Fast.has_value()) {
         diag(Warning,
-             llvm::formatv(
-                 "Latency of clang-tidy check '{0}' is not known. "
-                 "It will only run if ClangTidy.FastCheckFilter is Loose or 
None",
-                 Str)
+             llvm::formatv("Latency of clang-tidy check '{0}' is not known. "
+                           "It will only run if ClangTidy.FastCheckFilter is "
+                           "Loose or None",
+                           Str)
                  .str(),
              Arg.Range);
       } else if (!*Fast) {
@@ -719,6 +719,18 @@ struct FragmentCompiler {
           C.Completion.CodePatterns = *Val;
         });
     }
+
+    if (F.MacroFilter) {
+      if (auto Val =
+              compileEnum<Config::MacroFilterPolicy>("MacroFilter",
+                                                     *F.MacroFilter)
+                  .map("ExactPrefix", Config::MacroFilterPolicy::ExactPrefix)
+                  .map("FuzzyMatch", Config::MacroFilterPolicy::FuzzyMatch)
+                  .value())
+        Out.Apply.push_back([Val](const Params &, Config &C) {
+          C.Completion.MacroFilter = *Val;
+        });
+    }
   }
 
   void compile(Fragment::HoverBlock &&F) {
diff --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index 2afeb36574b21..7604fe4e24c97 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -354,6 +354,12 @@ struct Fragment {
     ///   All  => enable all code patterns and snippets suggestion
     ///   None => disable all code patterns and snippets suggestion
     std::optional<Located<std::string>> CodePatterns;
+    /// How to filter macros before offering them as suggestions
+    /// Values are Config::MacroFilterPolicy:
+    ///   ExactPrefix:  Suggest macros if the prefix matches exactly
+    ///   FuzzyMatch:   Fuzzy-match macros if they do not have "_" as prefix or
+    ///   suffix
+    std::optional<Located<std::string>> MacroFilter;
   };
   CompletionBlock Completion;
 
diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp 
b/clang-tools-extra/clangd/ConfigYAML.cpp
index 392cf19b05a55..7b6993620fb8c 100644
--- a/clang-tools-extra/clangd/ConfigYAML.cpp
+++ b/clang-tools-extra/clangd/ConfigYAML.cpp
@@ -255,6 +255,10 @@ class Parser {
       if (auto CodePatterns = scalarValue(N, "CodePatterns"))
         F.CodePatterns = *CodePatterns;
     });
+    Dict.handle("MacroFilter", [&](Node &N) {
+      if (auto MacroFilter = scalarValue(N, "MacroFilter"))
+        F.MacroFilter = *MacroFilter;
+    });
     Dict.parse(N);
   }
 
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index e2bdb0fe46e37..1bec601ef1d36 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -4692,6 +4692,35 @@ TEST(CompletionTest, ListExplicitObjectOverloads) {
   }
 }
 
+TEST(CompletionTest, FuzzyMatchMacro) {
+  const auto *const Code = R"cpp(
+  #define gl_foo() 42
+  #define _gl_foo() 42
+  int gl_frob();
+
+  int main() {
+    int x = glf^
+  }
+  )cpp";
+
+  {
+    CodeCompleteOptions Opts{};
+    EXPECT_EQ(Opts.MacroFilter, Config::MacroFilterPolicy::ExactPrefix);
+
+    auto Results = completions(Code, {}, Opts);
+    EXPECT_THAT(Results.Completions, ElementsAre(named("gl_frob")));
+  }
+
+  {
+    CodeCompleteOptions Opts{};
+    Opts.MacroFilter = Config::MacroFilterPolicy::FuzzyMatch;
+
+    auto Results = completions(Code, {}, Opts);
+    EXPECT_THAT(Results.Completions,
+                ElementsAre(named("gl_frob"), named("gl_foo")));
+  }
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp 
b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
index c332dcc417fe1..264cb453b413c 100644
--- a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
@@ -228,6 +228,20 @@ TEST(ParseYAML, CodePatterns) {
   EXPECT_THAT(Results[0].Completion.CodePatterns, llvm::ValueIs(val("None")));
 }
 
+TEST(ParseYAML, MacroFilter) {
+  CapturedDiags Diags;
+  Annotations YAML(R"yaml(
+    Completion:
+      MacroFilter: FuzzyMatch
+  )yaml");
+  auto Results =
+      Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback());
+  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
+  ASSERT_EQ(Results.size(), 1u);
+  EXPECT_THAT(Results[0].Completion.MacroFilter,
+              llvm::ValueIs(val("FuzzyMatch")));
+}
+
 TEST(ParseYAML, Hover) {
   CapturedDiags Diags;
   Annotations YAML(R"yaml(

``````````

</details>


https://github.com/llvm/llvm-project/pull/169880
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to