comparison clang-tools-extra/clangd/ConfigFragment.h @ 221:79ff65ed7e25

LLVM12 Original
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:15:29 +0900
parents
children c4bab56944e8
comparison
equal deleted inserted replaced
220:42394fc6a535 221:79ff65ed7e25
1 //===--- ConfigFragment.h - Unit of user-specified configuration -*- 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 // The configuration system allows users to control this:
11 // - in a user config file, a project config file, via LSP, or via flags
12 // - specifying different settings for different files
13 //
14 // This file defines the config::Fragment structure which models one piece of
15 // configuration as obtained from a source like a file.
16 //
17 // This is distinct from how the config is interpreted (CompiledFragment),
18 // combined (Provider) and exposed to the rest of clangd (Config).
19 //
20 //===----------------------------------------------------------------------===//
21 //
22 // To add a new configuration option, you must:
23 // - add its syntactic form to Fragment
24 // - update ConfigYAML.cpp to parse it
25 // - add its semantic form to Config (in Config.h)
26 // - update ConfigCompile.cpp to map Fragment -> Config
27 // - make use of the option inside clangd
28 // - document the new option (config.md in the llvm/clangd-www repository)
29 //
30 //===----------------------------------------------------------------------===//
31
32 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGFRAGMENT_H
33 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGFRAGMENT_H
34
35 #include "ConfigProvider.h"
36 #include "llvm/ADT/Optional.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/Support/Error.h"
39 #include "llvm/Support/SMLoc.h"
40 #include "llvm/Support/SourceMgr.h"
41 #include <string>
42 #include <vector>
43
44 namespace clang {
45 namespace clangd {
46 namespace config {
47
48 /// An entity written in config along, with its optional location in the file.
49 template <typename T> struct Located {
50 Located(T Value, llvm::SMRange Range = {})
51 : Range(Range), Value(std::move(Value)) {}
52
53 llvm::SMRange Range;
54 T *operator->() { return &Value; }
55 const T *operator->() const { return &Value; }
56 T &operator*() { return Value; }
57 const T &operator*() const { return Value; }
58
59 private:
60 T Value;
61 };
62
63 /// A chunk of configuration obtained from a config file, LSP, or elsewhere.
64 struct Fragment {
65 /// Parses fragments from a YAML file (one from each --- delimited document).
66 /// Documents that contained fatal errors are omitted from the results.
67 /// BufferName is used for the SourceMgr and diagnostics.
68 static std::vector<Fragment> parseYAML(llvm::StringRef YAML,
69 llvm::StringRef BufferName,
70 DiagnosticCallback);
71
72 /// Analyzes and consumes this fragment, possibly yielding more diagnostics.
73 /// This always produces a usable result (errors are recovered).
74 ///
75 /// Typically, providers will compile a Fragment once when it's first loaded,
76 /// caching the result for reuse.
77 /// Like a compiled program, this is good for performance and also encourages
78 /// errors to be reported early and only once.
79 ///
80 /// The returned function is a cheap-copyable wrapper of refcounted internals.
81 CompiledFragment compile(DiagnosticCallback) &&;
82
83 /// These fields are not part of the user-specified configuration, but
84 /// instead are populated by the parser to describe the configuration source.
85 struct SourceInfo {
86 /// Retains a buffer of the original source this fragment was parsed from.
87 /// Locations within Located<T> objects point into this SourceMgr.
88 /// Shared because multiple fragments are often parsed from one (YAML) file.
89 /// May be null, then all locations should be ignored.
90 std::shared_ptr<llvm::SourceMgr> Manager;
91 /// The start of the original source for this fragment.
92 /// Only valid if SourceManager is set.
93 llvm::SMLoc Location;
94 /// Absolute path to directory the fragment is associated with. Relative
95 /// paths mentioned in the fragment are resolved against this.
96 std::string Directory;
97 /// Whether this fragment is allowed to make critical security/privacy
98 /// decisions.
99 bool Trusted = false;
100 };
101 SourceInfo Source;
102
103 /// Conditions in the If block restrict when a Fragment applies.
104 ///
105 /// Each separate condition must match (combined with AND).
106 /// When one condition has multiple values, any may match (combined with OR).
107 /// e.g. `PathMatch: [foo/.*, bar/.*]` matches files in either directory.
108 ///
109 /// Conditions based on a file's path use the following form:
110 /// - if the fragment came from a project directory, the path is relative
111 /// - if the fragment is global (e.g. user config), the path is absolute
112 /// - paths always use forward-slashes (UNIX-style)
113 /// If no file is being processed, these conditions will not match.
114 struct IfBlock {
115 /// The file being processed must fully match a regular expression.
116 std::vector<Located<std::string>> PathMatch;
117 /// The file being processed must *not* fully match a regular expression.
118 std::vector<Located<std::string>> PathExclude;
119
120 /// An unrecognized key was found while parsing the condition.
121 /// The condition will evaluate to false.
122 bool HasUnrecognizedCondition = false;
123 };
124 IfBlock If;
125
126 /// Conditions in the CompileFlags block affect how a file is parsed.
127 ///
128 /// clangd emulates how clang would interpret a file.
129 /// By default, it behaves roughly like `clang $FILENAME`, but real projects
130 /// usually require setting the include path (with the `-I` flag), defining
131 /// preprocessor symbols, configuring warnings etc.
132 /// Often, a compilation database specifies these compile commands. clangd
133 /// searches for compile_commands.json in parents of the source file.
134 ///
135 /// This section modifies how the compile command is constructed.
136 struct CompileFlagsBlock {
137 /// List of flags to append to the compile command.
138 std::vector<Located<std::string>> Add;
139 /// List of flags to remove from the compile command.
140 ///
141 /// - If the value is a recognized clang flag (like "-I") then it will be
142 /// removed along with any arguments. Synonyms like --include-dir= will
143 /// also be removed.
144 /// - Otherwise, if the value ends in * (like "-DFOO=*") then any argument
145 /// with the prefix will be removed.
146 /// - Otherwise any argument exactly matching the value is removed.
147 ///
148 /// In all cases, -Xclang is also removed where needed.
149 ///
150 /// Example:
151 /// Command: clang++ --include-directory=/usr/include -DFOO=42 foo.cc
152 /// Remove: [-I, -DFOO=*]
153 /// Result: clang++ foo.cc
154 ///
155 /// Flags added by the same CompileFlags entry will not be removed.
156 std::vector<Located<std::string>> Remove;
157
158 /// Directory to search for compilation database (compile_comands.json etc).
159 /// Valid values are:
160 /// - A single path to a directory (absolute, or relative to the fragment)
161 /// - Ancestors: search all parent directories (the default)
162 /// - None: do not use a compilation database, just default flags.
163 llvm::Optional<Located<std::string>> CompilationDatabase;
164 };
165 CompileFlagsBlock CompileFlags;
166
167 /// Controls how clangd understands code outside the current file.
168 /// clangd's indexes provide information about symbols that isn't available
169 /// to clang's parser, such as incoming references.
170 struct IndexBlock {
171 /// Whether files are built in the background to produce a project index.
172 /// This is checked for translation units only, not headers they include.
173 /// Legal values are "Build" or "Skip".
174 llvm::Optional<Located<std::string>> Background;
175 /// An external index uses data source outside of clangd itself. This is
176 /// usually prepared using clangd-indexer.
177 /// Exactly one source (File/Server) should be configured.
178 struct ExternalBlock {
179 /// Whether the block is explicitly set to `None`. Can be used to clear
180 /// any external index specified before.
181 Located<bool> IsNone = false;
182 /// Path to an index file generated by clangd-indexer. Relative paths may
183 /// be used, if config fragment is associated with a directory.
184 llvm::Optional<Located<std::string>> File;
185 /// Address and port number for a clangd-index-server. e.g.
186 /// `123.1.1.1:13337`.
187 llvm::Optional<Located<std::string>> Server;
188 /// Source root governed by this index. Default is the directory
189 /// associated with the config fragment. Absolute in case of user config
190 /// and relative otherwise. Should always use forward-slashes.
191 llvm::Optional<Located<std::string>> MountPoint;
192 };
193 llvm::Optional<Located<ExternalBlock>> External;
194 };
195 IndexBlock Index;
196
197 /// Controls behavior of diagnostics (errors and warnings).
198 struct DiagnosticsBlock {
199 /// Diagnostic codes that should be suppressed.
200 ///
201 /// Valid values are:
202 /// - *, to disable all diagnostics
203 /// - diagnostic codes exposed by clangd (e.g unknown_type, -Wunused-result)
204 /// - clang internal diagnostic codes (e.g. err_unknown_type)
205 /// - warning categories (e.g. unused-result)
206 /// - clang-tidy check names (e.g. bugprone-narrowing-conversions)
207 ///
208 /// This is a simple filter. Diagnostics can be controlled in other ways
209 /// (e.g. by disabling a clang-tidy check, or the -Wunused compile flag).
210 /// This often has other advantages, such as skipping some analysis.
211 std::vector<Located<std::string>> Suppress;
212
213 /// Controls how clang-tidy will run over the code base.
214 ///
215 /// The settings are merged with any settings found in .clang-tidy
216 /// configiration files with these ones taking precedence.
217 struct ClangTidyBlock {
218 std::vector<Located<std::string>> Add;
219 /// List of checks to disable.
220 /// Takes precedence over Add. To enable all llvm checks except include
221 /// order:
222 /// Add: llvm-*
223 /// Remove: llvm-include-onder
224 std::vector<Located<std::string>> Remove;
225
226 /// A Key-Value pair list of options to pass to clang-tidy checks
227 /// These take precedence over options specified in clang-tidy
228 /// configuration files. Example:
229 /// CheckOptions:
230 /// readability-braces-around-statements.ShortStatementLines: 2
231 std::vector<std::pair<Located<std::string>, Located<std::string>>>
232 CheckOptions;
233 };
234 ClangTidyBlock ClangTidy;
235 };
236 DiagnosticsBlock Diagnostics;
237
238 // Describes the style of the codebase, beyond formatting.
239 struct StyleBlock {
240 // Namespaces that should always be fully qualified, meaning no "using"
241 // declarations, always spell out the whole name (with or without leading
242 // ::). All nested namespaces are affected as well.
243 // Affects availability of the AddUsing tweak.
244 std::vector<Located<std::string>> FullyQualifiedNamespaces;
245 };
246 StyleBlock Style;
247
248 /// Describes code completion preferences.
249 struct CompletionBlock {
250 /// Whether code completion should include suggestions from scopes that are
251 /// not visible. The required scope prefix will be inserted.
252 llvm::Optional<Located<bool>> AllScopes;
253 };
254 CompletionBlock Completion;
255 };
256
257 } // namespace config
258 } // namespace clangd
259 } // namespace clang
260
261 #endif