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 = {CDBSearchSpec::Ancestors, 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 | /// Controls warnings and errors when parsing code. |
97 | struct { |
98 | bool SuppressAll = false; |
99 | llvm::StringSet<> Suppress; |
100 | |
101 | /// Configures what clang-tidy checks to run and options to use with them. |
102 | struct { |
103 | // A comma-separated list of globs specify which clang-tidy checks to run. |
104 | std::string Checks; |
105 | llvm::StringMap<std::string> CheckOptions; |
106 | } ClangTidy; |
107 | |
108 | IncludesPolicy UnusedIncludes = IncludesPolicy::Strict; |
109 | IncludesPolicy MissingIncludes = IncludesPolicy::None; |
110 | |
111 | /// IncludeCleaner will not diagnose usages of these headers matched by |
112 | /// these regexes. |
113 | struct { |
114 | std::vector<std::function<bool(llvm::StringRef)>> ; |
115 | } Includes; |
116 | } Diagnostics; |
117 | |
118 | /// Style of the codebase. |
119 | struct { |
120 | // Namespaces that should always be fully qualified, meaning no "using" |
121 | // declarations, always spell out the whole name (with or without leading |
122 | // ::). All nested namespaces are affected as well. |
123 | std::vector<std::string> FullyQualifiedNamespaces; |
124 | } Style; |
125 | |
126 | /// Configures code completion feature. |
127 | struct { |
128 | /// Whether code completion includes results that are not visible in current |
129 | /// scopes. |
130 | bool AllScopes = true; |
131 | } Completion; |
132 | |
133 | /// Configures hover feature. |
134 | struct { |
135 | /// Whether hover show a.k.a type. |
136 | bool ShowAKA = true; |
137 | } Hover; |
138 | |
139 | struct { |
140 | /// If false, inlay hints are completely disabled. |
141 | bool Enabled = true; |
142 | |
143 | // Whether specific categories of hints are enabled. |
144 | bool Parameters = true; |
145 | bool DeducedTypes = true; |
146 | bool Designators = true; |
147 | bool BlockEnd = false; |
148 | // Limit the length of type names in inlay hints. (0 means no limit) |
149 | uint32_t TypeNameLimit = 32; |
150 | } InlayHints; |
151 | |
152 | struct { |
153 | /// Controls highlighting kinds that are disabled. |
154 | std::vector<std::string> DisabledKinds; |
155 | /// Controls highlighting modifiers that are disabled. |
156 | std::vector<std::string> DisabledModifiers; |
157 | } SemanticTokens; |
158 | }; |
159 | |
160 | } // namespace clangd |
161 | } // namespace clang |
162 | |
163 | namespace llvm { |
164 | template <> struct DenseMapInfo<clang::clangd::Config::ExternalIndexSpec> { |
165 | using ExternalIndexSpec = clang::clangd::Config::ExternalIndexSpec; |
166 | static inline ExternalIndexSpec getEmptyKey() { |
167 | return {ExternalIndexSpec::File, "" , "" }; |
168 | } |
169 | static inline ExternalIndexSpec getTombstoneKey() { |
170 | return {ExternalIndexSpec::File, "TOMB" , "STONE" }; |
171 | } |
172 | static unsigned getHashValue(const ExternalIndexSpec &Val) { |
173 | return llvm::hash_combine(Val.Kind, Val.Location, Val.MountPoint); |
174 | } |
175 | static bool isEqual(const ExternalIndexSpec &LHS, |
176 | const ExternalIndexSpec &RHS) { |
177 | return std::tie(LHS.Kind, LHS.Location, LHS.MountPoint) == |
178 | std::tie(RHS.Kind, RHS.Location, RHS.MountPoint); |
179 | } |
180 | }; |
181 | } // namespace llvm |
182 | |
183 | #endif |
184 | |