xref: /llvm-project/clang-tools-extra/clangd/SemanticHighlighting.h (revision e72baa76b91fbcb2b16747cb7d2088723478a754)
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   Modifier,
53   Operator,
54   Bracket,
55   Label,
56 
57   // This one is different from the other kinds as it's a line style
58   // rather than a token style.
59   InactiveCode,
60 
61   LastKind = InactiveCode
62 };
63 
64 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K);
65 std::optional<HighlightingKind>
66 highlightingKindFromString(llvm::StringRef Name);
67 
68 enum class HighlightingModifier {
69   Declaration,
70   Definition,
71   Deprecated,
72   Deduced,
73   Readonly,
74   Static,
75   Abstract,
76   Virtual,
77   DependentName,
78   DefaultLibrary,
79   UsedAsMutableReference,
80   UsedAsMutablePointer,
81   ConstructorOrDestructor,
82   UserDefined,
83 
84   FunctionScope,
85   ClassScope,
86   FileScope,
87   GlobalScope,
88 
89   LastModifier = GlobalScope
90 };
91 static_assert(static_cast<unsigned>(HighlightingModifier::LastModifier) < 32,
92               "Increase width of modifiers bitfield!");
93 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingModifier K);
94 std::optional<HighlightingModifier>
95 highlightingModifierFromString(llvm::StringRef Name);
96 
97 // Contains all information needed for the highlighting a token.
98 struct HighlightingToken {
99   HighlightingKind Kind;
100   uint32_t Modifiers = 0;
101   Range R;
102 
addModifierHighlightingToken103   HighlightingToken &addModifier(HighlightingModifier M) {
104     Modifiers |= 1 << static_cast<unsigned>(M);
105     return *this;
106   }
107 };
108 
109 bool operator==(const HighlightingToken &L, const HighlightingToken &R);
110 bool operator<(const HighlightingToken &L, const HighlightingToken &R);
111 
112 // Returns all HighlightingTokens from an AST. Only generates highlights for the
113 // main AST.
114 std::vector<HighlightingToken>
115 getSemanticHighlightings(ParsedAST &AST, bool IncludeInactiveRegionTokens);
116 
117 std::vector<SemanticToken> toSemanticTokens(llvm::ArrayRef<HighlightingToken>,
118                                             llvm::StringRef Code);
119 llvm::StringRef toSemanticTokenType(HighlightingKind Kind);
120 llvm::StringRef toSemanticTokenModifier(HighlightingModifier Modifier);
121 std::vector<SemanticTokensEdit> diffTokens(llvm::ArrayRef<SemanticToken> Before,
122                                            llvm::ArrayRef<SemanticToken> After);
123 
124 // Returns ranges of the file that are inside an inactive preprocessor branch.
125 // The preprocessor directives at the beginning and end of a branch themselves
126 // are not included.
127 std::vector<Range> getInactiveRegions(ParsedAST &AST);
128 
129 } // namespace clangd
130 } // namespace clang
131 
132 #endif
133