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