jvikstrom updated this revision to Diff 206178.
jvikstrom marked 18 inline comments as done.
jvikstrom added a comment.

Removed LSP specific stuff. Changed a bunch of types and names. Added fixme for 
macro expansion.


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/SemanticHighlight.cpp
  clang-tools-extra/clangd/SemanticHighlight.h
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/clangd/unittests/SemanticHighlightTests.cpp

Index: clang-tools-extra/clangd/unittests/SemanticHighlightTests.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/unittests/SemanticHighlightTests.cpp
@@ -0,0 +1,55 @@
+//===- SemanticHighlightTest.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 "ClangdUnit.h"
+#include "Protocol.h"
+#include "SemanticHighlight.h"
+#include "SourceCode.h"
+#include "TestTU.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using ::testing::ElementsAreArray;
+
+TEST(SemanticSymbolASTCollector, GetBeginningOfIdentifier) {
+  std::string Preamble = R"cpp(
+    struct A {
+      double SomeMember;
+    };
+    void $foo[[foo]](int $a[[a]]) {
+      auto $vlvn[[VeryLongVariableName]] = 12312;
+      A     $aa[[aa]];
+    }
+  )cpp";
+
+  Annotations Test(Preamble);
+  auto Foo = Test.range("foo");
+  auto A = Test.range("a");
+  auto VeryLong = Test.range("vlvn");
+  auto AA = Test.range("aa");
+  std::vector<SemanticToken> CorrectTokens = std::vector<SemanticToken>{
+      SemanticToken(SemanticHighlightKind::Function, Foo),
+      SemanticToken(SemanticHighlightKind::Variable, A),
+      SemanticToken(SemanticHighlightKind::Variable, VeryLong),
+      SemanticToken(SemanticHighlightKind::Variable, AA)};
+
+  auto AST = TestTU::withCode(Test.code()).build();
+  auto Tokens = getSemanticHighlights(AST);
+
+  EXPECT_THAT(Tokens, ElementsAreArray(CorrectTokens));
+}
+
+} // 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
+  SemanticHighlightTests.cpp
   SerializationTests.cpp
   SourceCodeTests.cpp
   SymbolCollectorTests.cpp
Index: clang-tools-extra/clangd/SemanticHighlight.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/SemanticHighlight.h
@@ -0,0 +1,46 @@
+//==-- SemanticHighlight.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Code for collecting semantic symbols from the C++ AST using the
+// RecursiveASTVisitor
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHT_H
+
+#include "ClangdUnit.h"
+#include "Protocol.h"
+
+namespace clang {
+namespace clangd {
+
+enum class SemanticHighlightKind : int {
+  Variable = 0,
+  Function = 1,
+};
+
+// Contains all information needed for the highlighting a symbol.
+struct SemanticToken {
+  SemanticToken() = default;
+  SemanticToken(SemanticHighlightKind Kind, Range R) : Kind(Kind), R(R) {}
+  SemanticHighlightKind Kind;
+  Range R;
+};
+
+bool operator==(const SemanticToken &Lhs, const SemanticToken &Rhs);
+bool operator!=(const SemanticToken &Lhs, const SemanticToken &Rhs);
+
+// Returns semantic highlights for the AST. The vector is ordered in ascending
+// order by the line number. Every symbol in LineHighlight is ordered in
+// ascending order by their coumn number.
+std::vector<SemanticToken> getSemanticHighlights(ParsedAST &AST);
+
+} // namespace clangd
+} // namespace clang
+
+#endif
Index: clang-tools-extra/clangd/SemanticHighlight.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/SemanticHighlight.cpp
@@ -0,0 +1,79 @@
+#include "SemanticHighlight.h"
+#include "SourceCode.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Lex/Lexer.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+// Collects all semantic symbols in an ASTContext. Symbols on line i are always
+// in front of symbols on line i+1
+class SemanticSymbolASTCollector
+    : public RecursiveASTVisitor<SemanticSymbolASTCollector> {
+  std::vector<SemanticToken> Symbols;
+  const ASTContext &AST;
+  const SourceManager &SM;
+
+public:
+  SemanticSymbolASTCollector(const ASTContext &AST)
+      : AST(AST), SM(AST.getSourceManager()) {}
+
+  std::vector<SemanticToken> getSymbols() { return Symbols; }
+
+  bool VisitVarDecl(VarDecl *Var) {
+    addSymbol(Var, SemanticHighlightKind::Variable);
+    return true;
+  }
+
+  bool VisitFunctionDecl(FunctionDecl *Func) {
+    addSymbol(Func, SemanticHighlightKind::Function);
+    return true;
+  }
+
+private:
+  void addSymbol(Decl *D, SemanticHighlightKind Kind) {
+    unsigned int Len = clang::Lexer::MeasureTokenLength(D->getLocation(), SM,
+                                                        AST.getLangOpts());
+    if (Len == 0) {
+      // Don't add symbols that don't have any length.
+      return;
+    }
+
+    if (D->getLocation().isMacroID()) {
+      // FIXME; This is inside a macro. For now skip the token
+      return;
+    }
+
+    Position LSPLoc = sourceLocToPosition(SM, D->getLocation());
+
+    SemanticToken S;
+    S.R.start.character = LSPLoc.character;
+    S.R.start.line = LSPLoc.line;
+    S.R.end.character = LSPLoc.character + Len;
+    S.R.end.line = LSPLoc.line;
+    S.Kind = Kind;
+
+    Symbols.push_back(S);
+  }
+};
+
+} // namespace
+
+bool operator==(const SemanticToken &Lhs, const SemanticToken &Rhs) {
+  return Lhs.Kind == Rhs.Kind && Lhs.R == Rhs.R;
+}
+bool operator!=(const SemanticToken &Lhs, const SemanticToken &Rhs) {
+  return !(Lhs == Rhs);
+}
+
+std::vector<SemanticToken> getSemanticHighlights(ParsedAST &AST) {
+  ASTContext &Ctx = AST.getASTContext();
+  Ctx.setTraversalScope(AST.getLocalTopLevelDecls());
+  SemanticSymbolASTCollector Collector(Ctx);
+  Collector.TraverseAST(Ctx);
+  return Collector.getSymbols();
+}
+} // 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
+  SemanticHighlight.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