clang-tools  14.0.0git
AnnotateHighlightings.cpp
Go to the documentation of this file.
1 //===--- AnnotateHighlightings.cpp -------------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "SemanticHighlighting.h"
9 #include "refactor/Tweak.h"
10 #include "llvm/ADT/StringRef.h"
11 #include "llvm/Support/ScopedPrinter.h"
12 
13 namespace clang {
14 namespace clangd {
15 namespace {
16 
17 /// Annotate all highlighting tokens in the current file. This is a hidden tweak
18 /// which is used to debug semantic highlightings.
19 /// Before:
20 /// void f() { int abc; }
21 /// ^^^^^^^^^^^^^^^^^^^^^
22 /// After:
23 /// void /* entity.name.function.cpp */ f() { int /* variable.cpp */ abc; }
24 class AnnotateHighlightings : public Tweak {
25 public:
26  const char *id() const override final;
27 
28  bool prepare(const Selection &Inputs) override { return true; }
29  Expected<Effect> apply(const Selection &Inputs) override;
30 
31  std::string title() const override { return "Annotate highlighting tokens"; }
32  llvm::StringLiteral kind() const override {
34  }
35  bool hidden() const override { return true; }
36 };
37 REGISTER_TWEAK(AnnotateHighlightings)
38 
39 Expected<Tweak::Effect> AnnotateHighlightings::apply(const Selection &Inputs) {
40  const Decl *CommonDecl = nullptr;
41  for (auto N = Inputs.ASTSelection.commonAncestor(); N && !CommonDecl;
42  N = N->Parent)
43  CommonDecl = N->ASTNode.get<Decl>();
44 
45  std::vector<HighlightingToken> HighlightingTokens;
46  if (!CommonDecl) {
47  // Now we hit the TUDecl case where commonAncestor() returns null
48  // intendedly. We only annotate tokens in the main file, so use the default
49  // traversal scope (which is the top level decls of the main file).
50  HighlightingTokens = getSemanticHighlightings(*Inputs.AST);
51  } else {
52  // Store the existing scopes.
53  const auto &BackupScopes = Inputs.AST->getASTContext().getTraversalScope();
54  // Narrow the traversal scope to the selected node.
55  Inputs.AST->getASTContext().setTraversalScope(
56  {const_cast<Decl *>(CommonDecl)});
57  HighlightingTokens = getSemanticHighlightings(*Inputs.AST);
58  // Restore the traversal scope.
59  Inputs.AST->getASTContext().setTraversalScope(BackupScopes);
60  }
61  auto &SM = Inputs.AST->getSourceManager();
62  tooling::Replacements Result;
63  llvm::StringRef FilePath = SM.getFilename(Inputs.Cursor);
64  for (const auto &Token : HighlightingTokens) {
65  assert(Token.R.start.line == Token.R.end.line &&
66  "Token must be at the same line");
67  auto InsertOffset = positionToOffset(Inputs.Code, Token.R.start);
68  if (!InsertOffset)
69  return InsertOffset.takeError();
70 
71  std::string Comment = "/* ";
72  Comment.append(llvm::to_string(Token.Kind));
73  for (unsigned I = 0;
74  I <= static_cast<unsigned>(HighlightingModifier::LastModifier); ++I) {
75  if (Token.Modifiers & (1 << I)) {
76  Comment.append(" [");
77  Comment.append(llvm::to_string(static_cast<HighlightingModifier>(I)));
78  Comment.push_back(']');
79  }
80  }
81  Comment.append(" */");
82  auto InsertReplacement =
83  tooling::Replacement(FilePath, *InsertOffset, 0, Comment);
84  if (auto Err = Result.add(InsertReplacement))
85  return std::move(Err);
86  }
87  return Effect::mainFileEdit(SM, std::move(Result));
88 }
89 
90 } // namespace
91 } // namespace clangd
92 } // namespace clang
clang::clangd::HighlightingModifier
HighlightingModifier
Definition: SemanticHighlighting.h:61
clang::clangd::HighlightingModifier::LastModifier
@ LastModifier
Inputs
ParseInputs Inputs
Definition: TUScheduler.cpp:457
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
Tweak.h
clang::clangd::positionToOffset
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
Definition: SourceCode.cpp:175
clang::clangd::getSemanticHighlightings
std::vector< HighlightingToken > getSemanticHighlightings(ParsedAST &AST)
Definition: SemanticHighlighting.cpp:787
SemanticHighlighting.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::CodeAction::REFACTOR_KIND
const static llvm::StringLiteral REFACTOR_KIND
Definition: Protocol.h:985
REGISTER_TWEAK
#define REGISTER_TWEAK(Subclass)
Definition: Tweak.h:132