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 LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H 26 27 #include "support/Context.h" 28 #include "llvm/ADT/FunctionExtras.h" 29 #include "llvm/ADT/Optional.h" 30 #include "llvm/ADT/StringMap.h" 31 #include "llvm/ADT/StringSet.h" 32 #include <functional> 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 llvm::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, llvm::None}; 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 = false; 89 } Index; 90 91 enum UnusedIncludesPolicy { Strict, None }; 92 /// Controls warnings and errors when parsing code. 93 struct { 94 bool SuppressAll = false; 95 llvm::StringSet<> Suppress; 96 97 /// Configures what clang-tidy checks to run and options to use with them. 98 struct { 99 // A comma-seperated list of globs specify which clang-tidy checks to run. 100 std::string Checks; 101 llvm::StringMap<std::string> CheckOptions; 102 } ClangTidy; 103 104 UnusedIncludesPolicy UnusedIncludes = None; 105 106 /// IncludeCleaner will not diagnose usages of these headers matched by 107 /// these regexes. 108 struct { 109 std::vector<std::function<bool(llvm::StringRef)>> IgnoreHeader; 110 } Includes; 111 } Diagnostics; 112 113 /// Style of the codebase. 114 struct { 115 // Namespaces that should always be fully qualified, meaning no "using" 116 // declarations, always spell out the whole name (with or without leading 117 // ::). All nested namespaces are affected as well. 118 std::vector<std::string> FullyQualifiedNamespaces; 119 } Style; 120 121 /// Configures code completion feature. 122 struct { 123 /// Whether code completion includes results that are not visible in current 124 /// scopes. 125 bool AllScopes = true; 126 } Completion; 127 128 /// Configures hover feature. 129 struct { 130 /// Whether hover show a.k.a type. 131 bool ShowAKA = true; 132 } Hover; 133 134 struct { 135 /// If false, inlay hints are completely disabled. 136 bool Enabled = true; 137 138 // Whether specific categories of hints are enabled. 139 bool Parameters = true; 140 bool DeducedTypes = true; 141 bool Designators = true; 142 } InlayHints; 143 }; 144 145 } // namespace clangd 146 } // namespace clang 147 148 namespace llvm { 149 template <> struct DenseMapInfo<clang::clangd::Config::ExternalIndexSpec> { 150 using ExternalIndexSpec = clang::clangd::Config::ExternalIndexSpec; 151 static inline ExternalIndexSpec getEmptyKey() { 152 return {ExternalIndexSpec::File, "", ""}; 153 } 154 static inline ExternalIndexSpec getTombstoneKey() { 155 return {ExternalIndexSpec::File, "TOMB", "STONE"}; 156 } 157 static unsigned getHashValue(const ExternalIndexSpec &Val) { 158 return llvm::hash_combine(Val.Kind, Val.Location, Val.MountPoint); 159 } 160 static bool isEqual(const ExternalIndexSpec &LHS, 161 const ExternalIndexSpec &RHS) { 162 return std::tie(LHS.Kind, LHS.Location, LHS.MountPoint) == 163 std::tie(RHS.Kind, RHS.Location, RHS.MountPoint); 164 } 165 }; 166 } // namespace llvm 167 168 #endif 169