diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h --- a/clang-tools-extra/clangd/SemanticHighlighting.h +++ b/clang-tools-extra/clangd/SemanticHighlighting.h @@ -40,6 +40,7 @@ }; bool operator==(const HighlightingToken &Lhs, const HighlightingToken &Rhs); +bool operator<(const HighlightingToken &Lhs, const HighlightingToken &Rhs); // Returns all HighlightingTokens from an AST. Only generates highlights for the // main AST. diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -31,6 +31,16 @@ std::vector collectTokens() { Tokens.clear(); TraverseAST(Ctx); + // Initializer lists can give duplicates of tokens, therefore all tokens + // must be deduplicated. + std::sort(Tokens.begin(), Tokens.end()); + for (unsigned I = 1; I < Tokens.size(); ++I) { + if (Tokens[I] == Tokens[I - 1]) { + Tokens.erase(Tokens.begin() + I); + --I; + } + } + return Tokens; } @@ -70,7 +80,6 @@ DeclarationName::Identifier) // Only want to highlight identifiers. return true; - addToken(Ref->getLocation(), Ref->getDecl()); return true; } @@ -201,6 +210,10 @@ return Lhs.Kind == Rhs.Kind && Lhs.R == Rhs.R; } +bool operator<(const HighlightingToken &Lhs, const HighlightingToken &Rhs) { + return Lhs.R.start < Rhs.R.start; +} + std::vector getSemanticHighlightings(ParsedAST &AST) { return HighlightingTokenCollector(AST).collectTokens(); } diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -132,6 +132,13 @@ $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]]::Hi; ::$Namespace[[vwz]]::$Class[[A]] $Variable[[B]]; ::$Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable[[BB]]; + )cpp", + R"cpp( + struct $Class[[AA]] { + int A; + } + int $Variable[[B]]; + $Class[[AA]] $Variable[[A]]{$Variable[[B]]}; )cpp"}; for (const auto &TestCase : TestCases) { checkHighlightings(TestCase);