[clang-tools-extra] r364421 - [clangd] Added functionality for getting semantic highlights for variable and function declarations
Johan Vikstrom via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 26 06:08:36 PDT 2019
Author: jvikstrom
Date: Wed Jun 26 06:08:36 2019
New Revision: 364421
URL: http://llvm.org/viewvc/llvm-project?rev=364421&view=rev
Log:
[clangd] Added functionality for getting semantic highlights for variable and function declarations
Added:
clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp
clang-tools-extra/trunk/clangd/SemanticHighlighting.h
clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp
Modified:
clang-tools-extra/trunk/clangd/CMakeLists.txt
clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt
Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=364421&r1=364420&r2=364421&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt Wed Jun 26 06:08:36 2019
@@ -63,6 +63,7 @@ add_clang_library(clangDaemon
Quality.cpp
RIFF.cpp
Selection.cpp
+ SemanticHighlighting.cpp
SourceCode.cpp
QueryDriverDatabase.cpp
Threading.cpp
Added: clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp?rev=364421&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp (added)
+++ clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp Wed Jun 26 06:08:36 2019
@@ -0,0 +1,78 @@
+//===--- SemanticHighlighting.cpp - -------------------------- ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SemanticHighlighting.h"
+#include "Logger.h"
+#include "SourceCode.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+// Collects all semantic tokens in an ASTContext.
+class HighlightingTokenCollector
+ : public RecursiveASTVisitor<HighlightingTokenCollector> {
+ std::vector<HighlightingToken> Tokens;
+ ASTContext &Ctx;
+ const SourceManager &SM;
+
+public:
+ HighlightingTokenCollector(ParsedAST &AST)
+ : Ctx(AST.getASTContext()), SM(AST.getSourceManager()) {}
+
+ std::vector<HighlightingToken> collectTokens() {
+ Tokens.clear();
+ TraverseAST(Ctx);
+ return Tokens;
+ }
+
+ bool VisitVarDecl(VarDecl *Var) {
+ addToken(Var, HighlightingKind::Variable);
+ return true;
+ }
+ bool VisitFunctionDecl(FunctionDecl *Func) {
+ addToken(Func, HighlightingKind::Function);
+ return true;
+ }
+
+private:
+ void addToken(const NamedDecl *D, HighlightingKind Kind) {
+ if (D->getLocation().isMacroID())
+ // FIXME: skip tokens inside macros for now.
+ return;
+
+ if (D->getDeclName().isEmpty())
+ // Don't add symbols that don't have any length.
+ return;
+
+ auto R = getTokenRange(SM, Ctx.getLangOpts(), D->getLocation());
+ if (!R) {
+ // R should always have a value, if it doesn't something is very wrong.
+ elog("Tried to add semantic token with an invalid range");
+ return;
+ }
+
+ Tokens.push_back({Kind, R.getValue()});
+ }
+};
+
+} // namespace
+
+bool operator==(const HighlightingToken &Lhs, const HighlightingToken &Rhs) {
+ return Lhs.Kind == Rhs.Kind && Lhs.R == Rhs.R;
+}
+
+std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST) {
+ AST.getASTContext().setTraversalScope(AST.getLocalTopLevelDecls());
+ return HighlightingTokenCollector(AST).collectTokens();
+}
+
+} // namespace clangd
+} // namespace clang
Added: clang-tools-extra/trunk/clangd/SemanticHighlighting.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticHighlighting.h?rev=364421&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/SemanticHighlighting.h (added)
+++ clang-tools-extra/trunk/clangd/SemanticHighlighting.h Wed Jun 26 06:08:36 2019
@@ -0,0 +1,37 @@
+//==-- SemanticHighlighting.h - Generating highlights from the AST-- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHT_H
+
+#include "ClangdUnit.h"
+
+namespace clang {
+namespace clangd {
+
+enum class HighlightingKind {
+ Variable,
+ Function,
+};
+
+// Contains all information needed for the highlighting a token.
+struct HighlightingToken {
+ HighlightingKind Kind;
+ Range R;
+};
+
+bool operator==(const HighlightingToken &Lhs, const HighlightingToken &Rhs);
+
+// Returns all HighlightingTokens from an AST. Only generates highlights for the
+// main AST.
+std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST);
+
+} // namespace clangd
+} // namespace clang
+
+#endif
Modified: clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt?rev=364421&r1=364420&r2=364421&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt Wed Jun 26 06:08:36 2019
@@ -53,6 +53,7 @@ add_unittest(ClangdUnitTests ClangdTests
RenameTests.cpp
RIFFTests.cpp
SelectionTests.cpp
+ SemanticHighlightingTests.cpp
SerializationTests.cpp
SourceCodeTests.cpp
SymbolCollectorTests.cpp
Added: clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp?rev=364421&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp (added)
+++ clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp Wed Jun 26 06:08:36 2019
@@ -0,0 +1,69 @@
+//==- SemanticHighlightingTests.cpp - SemanticHighlighting tests-*- C++ -* -==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Annotations.h"
+#include "SemanticHighlighting.h"
+#include "TestTU.h"
+#include "gmock/gmock.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+std::vector<HighlightingToken>
+makeHighlightingTokens(llvm::ArrayRef<Range> Ranges, HighlightingKind Kind) {
+ std::vector<HighlightingToken> Tokens(Ranges.size());
+ for (int I = 0, End = Ranges.size(); I < End; ++I) {
+ Tokens[I].R = Ranges[I];
+ Tokens[I].Kind = Kind;
+ }
+
+ return Tokens;
+}
+
+void checkHighlightings(llvm::StringRef Code) {
+ Annotations Test(Code);
+ auto AST = TestTU::withCode(Test.code()).build();
+ static const std::map<HighlightingKind, std::string> KindToString{
+ {HighlightingKind::Variable, "Variable"},
+ {HighlightingKind::Function, "Function"}};
+ std::vector<HighlightingToken> ExpectedTokens;
+ for (const auto &KindString : KindToString) {
+ std::vector<HighlightingToken> Toks =
+ makeHighlightingTokens(Test.ranges(KindString.second), KindString.first);
+ ExpectedTokens.insert(ExpectedTokens.end(), Toks.begin(), Toks.end());
+ }
+
+ auto ActualTokens = getSemanticHighlightings(AST);
+ EXPECT_THAT(ActualTokens, testing::UnorderedElementsAreArray(ExpectedTokens));
+}
+
+TEST(SemanticHighlighting, GetsCorrectTokens) {
+ const char *TestCases[] = {
+ R"cpp(
+ struct A {
+ double SomeMember;
+ };
+ struct {
+ } $Variable[[HStruct]];
+ void $Function[[foo]](int $Variable[[a]]) {
+ auto $Variable[[VeryLongVariableName]] = 12312;
+ A $Variable[[aa]];
+ }
+ )cpp",
+ R"cpp(
+ void $Function[[foo]](int);
+ )cpp"};
+ for (const auto &TestCase : TestCases) {
+ checkHighlightings(TestCase);
+ }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
More information about the cfe-commits
mailing list