[clangd] Deduplicate inlay hints
authorNathan Ridge <zeratul976@hotmail.com>
Mon, 20 Sep 2021 06:29:02 +0000 (02:29 -0400)
committerNathan Ridge <zeratul976@hotmail.com>
Tue, 21 Sep 2021 07:23:04 +0000 (03:23 -0400)
Duplicates can sometimes appear due to e.g. explicit template
instantiations

Differential Revision: https://reviews.llvm.org/D110051

clang-tools-extra/clangd/InlayHints.cpp
clang-tools-extra/clangd/Protocol.cpp
clang-tools-extra/clangd/Protocol.h
clang-tools-extra/clangd/unittests/InlayHintTests.cpp

index 167f800..73864b7 100644 (file)
@@ -366,6 +366,12 @@ std::vector<InlayHint> inlayHints(ParsedAST &AST) {
   std::vector<InlayHint> Results;
   InlayHintVisitor Visitor(Results, AST);
   Visitor.TraverseAST(AST.getASTContext());
+
+  // De-duplicate hints. Duplicates can sometimes occur due to e.g. explicit
+  // template instantiations.
+  llvm::sort(Results);
+  Results.erase(std::unique(Results.begin(), Results.end()), Results.end());
+
   return Results;
 }
 
index c0e96f6..5fa2d21 100644 (file)
@@ -1326,6 +1326,14 @@ llvm::json::Value toJSON(const InlayHint &H) {
   return llvm::json::Object{
       {"range", H.range}, {"kind", H.kind}, {"label", H.label}};
 }
+bool operator==(const InlayHint &A, const InlayHint &B) {
+  return std::tie(A.kind, A.range, A.label) ==
+         std::tie(B.kind, B.range, B.label);
+}
+bool operator<(const InlayHint &A, const InlayHint &B) {
+  return std::tie(A.kind, A.range, A.label) <
+         std::tie(B.kind, B.range, B.label);
+}
 
 static const char *toString(OffsetEncoding OE) {
   switch (OE) {
index cd469c2..3a43a48 100644 (file)
@@ -1548,6 +1548,8 @@ struct InlayHint {
   std::string label;
 };
 llvm::json::Value toJSON(const InlayHint &);
+bool operator==(const InlayHint &, const InlayHint &);
+bool operator<(const InlayHint &, const InlayHint &);
 
 struct ReferenceContext {
   /// Include the declaration of the current symbol.
index cda2ba4..1c69d50 100644 (file)
@@ -612,6 +612,18 @@ TEST(TypeHints, DefaultTemplateArgs) {
                   ExpectedHint{": A<float>", "var"});
 }
 
+TEST(TypeHints, Deduplication) {
+  assertTypeHints(R"cpp(
+    template <typename T>
+    void foo() {
+      auto $var[[var]] = 42;
+    }
+    template void foo<int>();
+    template void foo<float>();
+  )cpp",
+                  ExpectedHint{": int", "var"});
+}
+
 // FIXME: Low-hanging fruit where we could omit a type hint:
 //  - auto x = TypeName(...);
 //  - auto x = (TypeName) (...);
@@ -625,4 +637,4 @@ TEST(TypeHints, DefaultTemplateArgs) {
 
 } // namespace
 } // namespace clangd
-} // namespace clang
\ No newline at end of file
+} // namespace clang