1 //==-- SemanticHighlighting.h - Generating highlights from the AST-- 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 //
9 // This file supports semantic highlighting: categorizing tokens in the file so
10 // that the editor can color/style them differently.
11 // This is particularly valuable for C++: its complex and context-dependent
12 // grammar is a challenge for simple syntax-highlighting techniques.
13 //
14 // Semantic highlightings are calculated for an AST by visiting every AST node
15 // and classifying nodes that are interesting to highlight (variables/function
16 // calls etc.).
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHTING_H
21 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHTING_H
22 
23 #include "Protocol.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/Support/raw_ostream.h"
26 
27 namespace clang {
28 namespace clangd {
29 class ParsedAST;
30 
31 enum class HighlightingKind {
32   Variable = 0,
33   LocalVariable,
34   Parameter,
35   Function,
36   Method,
37   StaticMethod,
38   Field,
39   StaticField,
40   Class,
41   Interface,
42   Enum,
43   EnumConstant,
44   Typedef,
45   Type,
46   Unknown,
47   Namespace,
48   TemplateParameter,
49   Concept,
50   Primitive,
51   Macro,
52 
53   // This one is different from the other kinds as it's a line style
54   // rather than a token style.
55   InactiveCode,
56 
57   LastKind = InactiveCode
58 };
59 
60 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K);
61 
62 enum class HighlightingModifier {
63   Declaration,
64   // FIXME: Definition (needs findExplicitReferences support)
65   Deprecated,
66   Deduced,
67   Readonly,
68   Static,
69   Abstract,
70   Virtual,
71   DependentName,
72   DefaultLibrary,
73   UsedAsMutableReference,
74 
75   FunctionScope,
76   ClassScope,
77   FileScope,
78   GlobalScope,
79 
80   LastModifier = GlobalScope
81 };
82 static_assert(static_cast<unsigned>(HighlightingModifier::LastModifier) < 32,
83               "Increase width of modifiers bitfield!");
84 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingModifier K);
85 
86 // Contains all information needed for the highlighting a token.
87 struct HighlightingToken {
88   HighlightingKind Kind;
89   uint32_t Modifiers = 0;
90   Range R;
91 
addModifierHighlightingToken92   HighlightingToken &addModifier(HighlightingModifier M) {
93     Modifiers |= 1 << static_cast<unsigned>(M);
94     return *this;
95   }
96 };
97 
98 bool operator==(const HighlightingToken &L, const HighlightingToken &R);
99 bool operator<(const HighlightingToken &L, const HighlightingToken &R);
100 
101 // Returns all HighlightingTokens from an AST. Only generates highlights for the
102 // main AST.
103 std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST);
104 
105 std::vector<SemanticToken> toSemanticTokens(llvm::ArrayRef<HighlightingToken>,
106                                             llvm::StringRef Code);
107 llvm::StringRef toSemanticTokenType(HighlightingKind Kind);
108 llvm::StringRef toSemanticTokenModifier(HighlightingModifier Modifier);
109 std::vector<SemanticTokensEdit> diffTokens(llvm::ArrayRef<SemanticToken> Before,
110                                            llvm::ArrayRef<SemanticToken> After);
111 
112 } // namespace clangd
113 } // namespace clang
114 
115 #endif
116