1 | //===--- Config.h - User configuration of clangd behavior --------*- 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 | // Various clangd features have configurable behaviour (or can be disabled). |
10 | // This file defines "resolved" configuration seen by features within clangd. |
11 | // For example, settings may vary per-file, the resolved Config only contains |
12 | // settings that apply to the current file. |
13 | // |
14 | // This is distinct from how the config is specified by the user (Fragment) |
15 | // interpreted (CompiledFragment), and combined (Provider). |
16 | // ConfigFragment.h describes the steps to add a new configuration option. |
17 | // |
18 | // Because this structure is shared throughout clangd, it's a potential source |
19 | // of layering problems. Config should be expressed in terms of simple |
20 | // vocabulary types where possible. |
21 | // |
22 | //===----------------------------------------------------------------------===// |
23 | |
24 | #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H |
25 | #define |
26 | |
27 | #include "support/Context.h" |
28 | #include "llvm/ADT/FunctionExtras.h" |
29 | #include "llvm/ADT/StringMap.h" |
30 | #include "llvm/ADT/StringSet.h" |
31 | #include <functional> |
32 | #include <optional> |
33 | #include <string> |
34 | #include <vector> |
35 | |
36 | namespace clang { |
37 | namespace clangd { |
38 | |
39 | /// Settings that express user/project preferences and control clangd behavior. |
40 | /// |
41 | /// Generally, features should consume Config::current() and the caller is |
42 | /// responsible for setting it appropriately. In practice these callers are |
43 | /// ClangdServer, TUScheduler, and BackgroundQueue. |
44 | struct Config { |
45 | /// Returns the Config of the current Context, or an empty configuration. |
46 | static const Config ¤t(); |
47 | /// Context key which can be used to set the current Config. |
48 | static clangd::Key<Config> Key; |
49 | |
50 | Config() = default; |
51 | Config(const Config &) = delete; |
52 | Config &operator=(const Config &) = delete; |
53 | Config(Config &&) = default; |
54 | Config &operator=(Config &&) = default; |
55 | |
56 | struct CDBSearchSpec { |
57 | enum { Ancestors, FixedDir, NoCDBSearch } Policy = Ancestors; |
58 | // Absolute, native slashes, no trailing slash. |
59 | std::optional<std::string> FixedCDBPath; |
60 | }; |
61 | |
62 | enum class { , }; |
63 | /// Controls how the compile command for the current file is determined. |
64 | struct { |
65 | /// Edits to apply to the compile command, in sequence. |
66 | std::vector<llvm::unique_function<void(std::vector<std::string> &) const>> |
67 | Edits; |
68 | /// Where to search for compilation databases for this file's flags. |
69 | CDBSearchSpec CDBSearch = {.Policy: CDBSearchSpec::Ancestors, .FixedCDBPath: std::nullopt}; |
70 | |
71 | /// Whether to use clangd's own builtin headers, or ones from the system |
72 | /// include extractor, if available. |
73 | BuiltinHeaderPolicy = BuiltinHeaderPolicy::Clangd; |
74 | } CompileFlags; |
75 | |
76 | enum class BackgroundPolicy { Build, Skip }; |
77 | /// Describes an external index configuration. |
78 | struct ExternalIndexSpec { |
79 | enum { None, File, Server } Kind = None; |
80 | /// This is one of: |
81 | /// - Address of a clangd-index-server, in the form of "ip:port". |
82 | /// - Absolute path to an index produced by clangd-indexer. |
83 | std::string Location; |
84 | /// Absolute path to source root this index is associated with, uses |
85 | /// forward-slashes. |
86 | std::string MountPoint; |
87 | }; |
88 | /// Controls index behavior. |
89 | struct { |
90 | /// Whether this TU should be background-indexed. |
91 | BackgroundPolicy Background = BackgroundPolicy::Build; |
92 | ExternalIndexSpec External; |
93 | bool StandardLibrary = true; |
94 | } Index; |
95 | |
96 | enum class IncludesPolicy { |
97 | /// Diagnose missing and unused includes. |
98 | Strict, |
99 | None, |
100 | }; |
101 | enum class FastCheckPolicy { Strict, Loose, None }; |
102 | /// Controls warnings and errors when parsing code. |
103 | struct { |
104 | bool SuppressAll = false; |
105 | llvm::StringSet<> Suppress; |
106 | |
107 | /// Configures what clang-tidy checks to run and options to use with them. |
108 | struct { |
109 | // A comma-separated list of globs specify which clang-tidy checks to run. |
110 | std::string Checks; |
111 | llvm::StringMap<std::string> CheckOptions; |
112 | FastCheckPolicy FastCheckFilter = FastCheckPolicy::Strict; |
113 | } ClangTidy; |
114 | |
115 | IncludesPolicy UnusedIncludes = IncludesPolicy::Strict; |
116 | IncludesPolicy MissingIncludes = IncludesPolicy::None; |
117 | |
118 | struct { |
119 | /// IncludeCleaner will not diagnose usages of these headers matched by |
120 | /// these regexes. |
121 | std::vector<std::function<bool(llvm::StringRef)>> ; |
122 | bool AnalyzeAngledIncludes = false; |
123 | } Includes; |
124 | } Diagnostics; |
125 | |
126 | /// Style of the codebase. |
127 | struct { |
128 | // Namespaces that should always be fully qualified, meaning no "using" |
129 | // declarations, always spell out the whole name (with or without leading |
130 | // ::). All nested namespaces are affected as well. |
131 | std::vector<std::string> FullyQualifiedNamespaces; |
132 | |
133 | // List of matcher functions for inserting certain headers with <> or "". |
134 | std::vector<std::function<bool(llvm::StringRef)>> ; |
135 | std::vector<std::function<bool(llvm::StringRef)>> ; |
136 | } Style; |
137 | |
138 | /// controls the completion options for argument lists. |
139 | enum class ArgumentListsPolicy { |
140 | /// nothing, no argument list and also NO Delimiters "()" or "<>". |
141 | None, |
142 | /// open, only opening delimiter "(" or "<". |
143 | OpenDelimiter, |
144 | /// empty pair of delimiters "()" or "<>". |
145 | Delimiters, |
146 | /// full name of both type and variable. |
147 | FullPlaceholders, |
148 | }; |
149 | |
150 | enum class { |
151 | , // Include what you use |
152 | // Never insert headers as part of code completion |
153 | }; |
154 | |
155 | enum class CodePatternsPolicy { |
156 | All, // Suggest all code patterns and snippets |
157 | None // Suggest none of the code patterns and snippets |
158 | }; |
159 | |
160 | /// Configures code completion feature. |
161 | struct { |
162 | /// Whether code completion includes results that are not visible in current |
163 | /// scopes. |
164 | bool AllScopes = true; |
165 | /// controls the completion options for argument lists. |
166 | ArgumentListsPolicy ArgumentLists = ArgumentListsPolicy::FullPlaceholders; |
167 | /// Controls if headers should be inserted when completions are accepted |
168 | HeaderInsertionPolicy = HeaderInsertionPolicy::IWYU; |
169 | /// Enables code patterns & snippets suggestions |
170 | CodePatternsPolicy CodePatterns = CodePatternsPolicy::All; |
171 | } Completion; |
172 | |
173 | /// Configures hover feature. |
174 | struct { |
175 | /// Whether hover show a.k.a type. |
176 | bool ShowAKA = true; |
177 | } Hover; |
178 | |
179 | struct { |
180 | /// If false, inlay hints are completely disabled. |
181 | bool Enabled = true; |
182 | |
183 | // Whether specific categories of hints are enabled. |
184 | bool Parameters = true; |
185 | bool DeducedTypes = true; |
186 | bool Designators = true; |
187 | bool BlockEnd = false; |
188 | bool DefaultArguments = false; |
189 | // Limit the length of type names in inlay hints. (0 means no limit) |
190 | uint32_t TypeNameLimit = 32; |
191 | } InlayHints; |
192 | |
193 | struct { |
194 | /// Controls highlighting kinds that are disabled. |
195 | std::vector<std::string> DisabledKinds; |
196 | /// Controls highlighting modifiers that are disabled. |
197 | std::vector<std::string> DisabledModifiers; |
198 | } SemanticTokens; |
199 | }; |
200 | |
201 | } // namespace clangd |
202 | } // namespace clang |
203 | |
204 | namespace llvm { |
205 | template <> struct DenseMapInfo<clang::clangd::Config::ExternalIndexSpec> { |
206 | using ExternalIndexSpec = clang::clangd::Config::ExternalIndexSpec; |
207 | static inline ExternalIndexSpec getEmptyKey() { |
208 | return {.Kind: ExternalIndexSpec::File, .Location: "" , .MountPoint: "" }; |
209 | } |
210 | static inline ExternalIndexSpec getTombstoneKey() { |
211 | return {.Kind: ExternalIndexSpec::File, .Location: "TOMB" , .MountPoint: "STONE" }; |
212 | } |
213 | static unsigned getHashValue(const ExternalIndexSpec &Val) { |
214 | return llvm::hash_combine(args: Val.Kind, args: Val.Location, args: Val.MountPoint); |
215 | } |
216 | static bool isEqual(const ExternalIndexSpec &LHS, |
217 | const ExternalIndexSpec &RHS) { |
218 | return std::tie(args: LHS.Kind, args: LHS.Location, args: LHS.MountPoint) == |
219 | std::tie(args: RHS.Kind, args: RHS.Location, args: RHS.MountPoint); |
220 | } |
221 | }; |
222 | } // namespace llvm |
223 | |
224 | #endif |
225 | |