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 | /// Controls how the compile command for the current file is determined. |
63 | struct { |
64 | /// Edits to apply to the compile command, in sequence. |
65 | std::vector<llvm::unique_function<void(std::vector<std::string> &) const>> |
66 | Edits; |
67 | /// Where to search for compilation databases for this file's flags. |
68 | CDBSearchSpec CDBSearch = {.Policy: CDBSearchSpec::Ancestors, .FixedCDBPath: std::nullopt}; |
69 | } CompileFlags; |
70 | |
71 | enum class BackgroundPolicy { Build, Skip }; |
72 | /// Describes an external index configuration. |
73 | struct ExternalIndexSpec { |
74 | enum { None, File, Server } Kind = None; |
75 | /// This is one of: |
76 | /// - Address of a clangd-index-server, in the form of "ip:port". |
77 | /// - Absolute path to an index produced by clangd-indexer. |
78 | std::string Location; |
79 | /// Absolute path to source root this index is associated with, uses |
80 | /// forward-slashes. |
81 | std::string MountPoint; |
82 | }; |
83 | /// Controls index behavior. |
84 | struct { |
85 | /// Whether this TU should be background-indexed. |
86 | BackgroundPolicy Background = BackgroundPolicy::Build; |
87 | ExternalIndexSpec External; |
88 | bool StandardLibrary = true; |
89 | } Index; |
90 | |
91 | enum class IncludesPolicy { |
92 | /// Diagnose missing and unused includes. |
93 | Strict, |
94 | None, |
95 | }; |
96 | enum class FastCheckPolicy { Strict, Loose, None }; |
97 | /// Controls warnings and errors when parsing code. |
98 | struct { |
99 | bool SuppressAll = false; |
100 | llvm::StringSet<> Suppress; |
101 | |
102 | /// Configures what clang-tidy checks to run and options to use with them. |
103 | struct { |
104 | // A comma-separated list of globs specify which clang-tidy checks to run. |
105 | std::string Checks; |
106 | llvm::StringMap<std::string> CheckOptions; |
107 | FastCheckPolicy FastCheckFilter = FastCheckPolicy::Strict; |
108 | } ClangTidy; |
109 | |
110 | IncludesPolicy UnusedIncludes = IncludesPolicy::Strict; |
111 | IncludesPolicy MissingIncludes = IncludesPolicy::None; |
112 | |
113 | /// IncludeCleaner will not diagnose usages of these headers matched by |
114 | /// these regexes. |
115 | struct { |
116 | std::vector<std::function<bool(llvm::StringRef)>> ; |
117 | } Includes; |
118 | } Diagnostics; |
119 | |
120 | /// Style of the codebase. |
121 | struct { |
122 | // Namespaces that should always be fully qualified, meaning no "using" |
123 | // declarations, always spell out the whole name (with or without leading |
124 | // ::). All nested namespaces are affected as well. |
125 | std::vector<std::string> FullyQualifiedNamespaces; |
126 | } Style; |
127 | |
128 | /// Configures code completion feature. |
129 | struct { |
130 | /// Whether code completion includes results that are not visible in current |
131 | /// scopes. |
132 | bool AllScopes = true; |
133 | } Completion; |
134 | |
135 | /// Configures hover feature. |
136 | struct { |
137 | /// Whether hover show a.k.a type. |
138 | bool ShowAKA = true; |
139 | } Hover; |
140 | |
141 | struct { |
142 | /// If false, inlay hints are completely disabled. |
143 | bool Enabled = true; |
144 | |
145 | // Whether specific categories of hints are enabled. |
146 | bool Parameters = true; |
147 | bool DeducedTypes = true; |
148 | bool Designators = true; |
149 | bool BlockEnd = false; |
150 | // Limit the length of type names in inlay hints. (0 means no limit) |
151 | uint32_t TypeNameLimit = 32; |
152 | } InlayHints; |
153 | |
154 | struct { |
155 | /// Controls highlighting kinds that are disabled. |
156 | std::vector<std::string> DisabledKinds; |
157 | /// Controls highlighting modifiers that are disabled. |
158 | std::vector<std::string> DisabledModifiers; |
159 | } SemanticTokens; |
160 | }; |
161 | |
162 | } // namespace clangd |
163 | } // namespace clang |
164 | |
165 | namespace llvm { |
166 | template <> struct DenseMapInfo<clang::clangd::Config::ExternalIndexSpec> { |
167 | using ExternalIndexSpec = clang::clangd::Config::ExternalIndexSpec; |
168 | static inline ExternalIndexSpec getEmptyKey() { |
169 | return {.Kind: ExternalIndexSpec::File, .Location: "" , .MountPoint: "" }; |
170 | } |
171 | static inline ExternalIndexSpec getTombstoneKey() { |
172 | return {.Kind: ExternalIndexSpec::File, .Location: "TOMB" , .MountPoint: "STONE" }; |
173 | } |
174 | static unsigned getHashValue(const ExternalIndexSpec &Val) { |
175 | return llvm::hash_combine(args: Val.Kind, args: Val.Location, args: Val.MountPoint); |
176 | } |
177 | static bool isEqual(const ExternalIndexSpec &LHS, |
178 | const ExternalIndexSpec &RHS) { |
179 | return std::tie(args: LHS.Kind, args: LHS.Location, args: LHS.MountPoint) == |
180 | std::tie(args: RHS.Kind, args: RHS.Location, args: RHS.MountPoint); |
181 | } |
182 | }; |
183 | } // namespace llvm |
184 | |
185 | #endif |
186 | |