| 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 | |