150
|
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 //
|
173
|
9 // This file supports semantic highlighting: categorizing tokens in the file so
|
|
10 // that the editor can color/style them differently.
|
|
11 //
|
|
12 // This is particularly valuable for C++: its complex and context-dependent
|
|
13 // grammar is a challenge for simple syntax-highlighting techniques.
|
|
14 //
|
|
15 // We support two protocols for providing highlights to the client:
|
|
16 // - the `textDocument/semanticTokens` request from LSP 3.16
|
|
17 // https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.16.0-next.1/protocol/src/protocol.semanticTokens.proposed.ts
|
|
18 // - the earlier proposed `textDocument/semanticHighlighting` notification
|
|
19 // https://github.com/microsoft/vscode-languageserver-node/pull/367
|
|
20 // This is referred to as "Theia" semantic highlighting in the code.
|
|
21 // It was supported from clangd 9 but should be considered deprecated as of
|
|
22 // clangd 11 and eventually removed.
|
|
23 //
|
150
|
24 // Semantic highlightings are calculated for an AST by visiting every AST node
|
|
25 // and classifying nodes that are interesting to highlight (variables/function
|
|
26 // calls etc.).
|
|
27 //
|
|
28 //===----------------------------------------------------------------------===//
|
|
29
|
|
30 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHTING_H
|
|
31 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHTING_H
|
|
32
|
|
33 #include "Protocol.h"
|
|
34 #include "llvm/Support/raw_ostream.h"
|
|
35
|
|
36 namespace clang {
|
|
37 namespace clangd {
|
|
38 class ParsedAST;
|
|
39
|
|
40 enum class HighlightingKind {
|
|
41 Variable = 0,
|
|
42 LocalVariable,
|
|
43 Parameter,
|
|
44 Function,
|
|
45 Method,
|
|
46 StaticMethod,
|
|
47 Field,
|
|
48 StaticField,
|
|
49 Class,
|
|
50 Enum,
|
|
51 EnumConstant,
|
|
52 Typedef,
|
|
53 DependentType,
|
|
54 DependentName,
|
|
55 Namespace,
|
|
56 TemplateParameter,
|
|
57 Concept,
|
|
58 Primitive,
|
|
59 Macro,
|
|
60
|
|
61 // This one is different from the other kinds as it's a line style
|
|
62 // rather than a token style.
|
|
63 InactiveCode,
|
|
64
|
|
65 LastKind = InactiveCode
|
|
66 };
|
|
67 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K);
|
|
68
|
|
69 // Contains all information needed for the highlighting a token.
|
|
70 struct HighlightingToken {
|
|
71 HighlightingKind Kind;
|
|
72 Range R;
|
|
73 };
|
|
74
|
|
75 bool operator==(const HighlightingToken &L, const HighlightingToken &R);
|
|
76 bool operator<(const HighlightingToken &L, const HighlightingToken &R);
|
|
77
|
|
78 /// Contains all information about highlightings on a single line.
|
|
79 struct LineHighlightings {
|
|
80 int Line;
|
|
81 std::vector<HighlightingToken> Tokens;
|
|
82 bool IsInactive;
|
|
83 };
|
|
84
|
|
85 bool operator==(const LineHighlightings &L, const LineHighlightings &R);
|
|
86
|
|
87 // Returns all HighlightingTokens from an AST. Only generates highlights for the
|
|
88 // main AST.
|
|
89 std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST);
|
|
90
|
173
|
91 std::vector<SemanticToken> toSemanticTokens(llvm::ArrayRef<HighlightingToken>);
|
|
92 llvm::StringRef toSemanticTokenType(HighlightingKind Kind);
|
|
93 std::vector<SemanticTokensEdit> diffTokens(llvm::ArrayRef<SemanticToken> Before,
|
|
94 llvm::ArrayRef<SemanticToken> After);
|
|
95
|
150
|
96 /// Converts a HighlightingKind to a corresponding TextMate scope
|
|
97 /// (https://manual.macromates.com/en/language_grammars).
|
|
98 llvm::StringRef toTextMateScope(HighlightingKind Kind);
|
|
99
|
|
100 /// Convert to LSP's semantic highlighting information.
|
173
|
101 std::vector<TheiaSemanticHighlightingInformation>
|
|
102 toTheiaSemanticHighlightingInformation(
|
|
103 llvm::ArrayRef<LineHighlightings> Tokens);
|
150
|
104
|
|
105 /// Return a line-by-line diff between two highlightings.
|
|
106 /// - if the tokens on a line are the same in both highlightings, this line is
|
|
107 /// omitted.
|
|
108 /// - if a line exists in New but not in Old, the tokens on this line are
|
|
109 /// emitted.
|
|
110 /// - if a line does not exist in New but exists in Old, an empty line is
|
|
111 /// emitted (to tell client to clear the previous highlightings on this line).
|
|
112 ///
|
|
113 /// REQUIRED: Old and New are sorted.
|
|
114 std::vector<LineHighlightings>
|
|
115 diffHighlightings(ArrayRef<HighlightingToken> New,
|
|
116 ArrayRef<HighlightingToken> Old);
|
|
117
|
|
118 } // namespace clangd
|
|
119 } // namespace clang
|
|
120
|
|
121 #endif
|