jvikstrom updated this revision to Diff 206630.
jvikstrom marked 6 inline comments as done.
jvikstrom added a comment.

Renamed types to follow LSP. Also renamed files.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63559/new/

https://reviews.llvm.org/D63559

Files:
  clang-tools-extra/clangd/CMakeLists.txt
  clang-tools-extra/clangd/SemanticHighlighting.cpp
  clang-tools-extra/clangd/SemanticHighlighting.h
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Index: clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -0,0 +1,69 @@
+//==- SemanticHighlightingTest.cpp - SemanticHighlightTest 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
Index: clang-tools-extra/clangd/unittests/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/unittests/CMakeLists.txt
+++ clang-tools-extra/clangd/unittests/CMakeLists.txt
@@ -53,6 +53,7 @@
   RenameTests.cpp
   RIFFTests.cpp
   SelectionTests.cpp
+  SemanticHighlightingTests.cpp
   SerializationTests.cpp
   SourceCodeTests.cpp
   SymbolCollectorTests.cpp
Index: clang-tools-extra/clangd/SemanticHighlighting.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/SemanticHighlighting.h
@@ -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
Index: clang-tools-extra/clangd/SemanticHighlighting.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -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
Index: clang-tools-extra/clangd/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/CMakeLists.txt
+++ clang-tools-extra/clangd/CMakeLists.txt
@@ -62,6 +62,7 @@
   Quality.cpp
   RIFF.cpp
   Selection.cpp
+  SemanticHighlighting.cpp
   SourceCode.cpp
   Threading.cpp
   Trace.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to