| 1 | //===--- ClangdServer.h - Main clangd server code ----------------*- 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 | #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H |
| 10 | #define |
| 11 | |
| 12 | #include "CodeComplete.h" |
| 13 | #include "ConfigProvider.h" |
| 14 | #include "Diagnostics.h" |
| 15 | #include "DraftStore.h" |
| 16 | #include "FeatureModule.h" |
| 17 | #include "GlobalCompilationDatabase.h" |
| 18 | #include "Hover.h" |
| 19 | #include "ModulesBuilder.h" |
| 20 | #include "Protocol.h" |
| 21 | #include "SemanticHighlighting.h" |
| 22 | #include "TUScheduler.h" |
| 23 | #include "XRefs.h" |
| 24 | #include "index/Background.h" |
| 25 | #include "index/FileIndex.h" |
| 26 | #include "index/Index.h" |
| 27 | #include "refactor/Rename.h" |
| 28 | #include "refactor/Tweak.h" |
| 29 | #include "support/Function.h" |
| 30 | #include "support/MemoryTree.h" |
| 31 | #include "support/Path.h" |
| 32 | #include "support/ThreadsafeFS.h" |
| 33 | #include "clang/Tooling/Core/Replacement.h" |
| 34 | #include "llvm/ADT/ArrayRef.h" |
| 35 | #include "llvm/ADT/FunctionExtras.h" |
| 36 | #include "llvm/ADT/StringRef.h" |
| 37 | #include <functional> |
| 38 | #include <memory> |
| 39 | #include <optional> |
| 40 | #include <string> |
| 41 | #include <tuple> |
| 42 | #include <vector> |
| 43 | |
| 44 | namespace clang { |
| 45 | namespace clangd { |
| 46 | /// Manages a collection of source files and derived data (ASTs, indexes), |
| 47 | /// and provides language-aware features such as code completion. |
| 48 | /// |
| 49 | /// The primary client is ClangdLSPServer which exposes these features via |
| 50 | /// the Language Server protocol. ClangdServer may also be embedded directly, |
| 51 | /// though its API is not stable over time. |
| 52 | /// |
| 53 | /// ClangdServer should be used from a single thread. Many potentially-slow |
| 54 | /// operations have asynchronous APIs and deliver their results on another |
| 55 | /// thread. |
| 56 | /// Such operations support cancellation: if the caller sets up a cancelable |
| 57 | /// context, many operations will notice cancellation and fail early. |
| 58 | /// (ClangdLSPServer uses this to implement $/cancelRequest). |
| 59 | class ClangdServer { |
| 60 | public: |
| 61 | /// Interface with hooks for users of ClangdServer to be notified of events. |
| 62 | class Callbacks { |
| 63 | public: |
| 64 | virtual ~Callbacks() = default; |
| 65 | |
| 66 | /// Called by ClangdServer when \p Diagnostics for \p File are ready. |
| 67 | /// These pushed diagnostics might correspond to an older version of the |
| 68 | /// file, they do not interfere with "pull-based" ClangdServer::diagnostics. |
| 69 | /// May be called concurrently for separate files, not for a single file. |
| 70 | virtual void onDiagnosticsReady(PathRef File, llvm::StringRef Version, |
| 71 | llvm::ArrayRef<Diag> Diagnostics) {} |
| 72 | /// Called whenever the file status is updated. |
| 73 | /// May be called concurrently for separate files, not for a single file. |
| 74 | virtual void onFileUpdated(PathRef File, const TUStatus &Status) {} |
| 75 | |
| 76 | /// Called when background indexing tasks are enqueued/started/completed. |
| 77 | /// Not called concurrently. |
| 78 | virtual void |
| 79 | onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) {} |
| 80 | |
| 81 | /// Called when the meaning of a source code may have changed without an |
| 82 | /// edit. Usually clients assume that responses to requests are valid until |
| 83 | /// they next edit the file. If they're invalidated at other times, we |
| 84 | /// should tell the client. In particular, when an asynchronous preamble |
| 85 | /// build finishes, we can provide more accurate semantic tokens, so we |
| 86 | /// should tell the client to refresh. |
| 87 | virtual void onSemanticsMaybeChanged(PathRef File) {} |
| 88 | |
| 89 | /// Called by ClangdServer when some \p InactiveRegions for \p File are |
| 90 | /// ready. |
| 91 | virtual void onInactiveRegionsReady(PathRef File, |
| 92 | std::vector<Range> InactiveRegions) {} |
| 93 | }; |
| 94 | /// Creates a context provider that loads and installs config. |
| 95 | /// Errors in loading config are reported as diagnostics via Callbacks. |
| 96 | /// (This is typically used as ClangdServer::Options::ContextProvider). |
| 97 | static std::function<Context(PathRef)> |
| 98 | createConfiguredContextProvider(const config::Provider *Provider, |
| 99 | ClangdServer::Callbacks *); |
| 100 | |
| 101 | struct Options { |
| 102 | /// To process requests asynchronously, ClangdServer spawns worker threads. |
| 103 | /// If this is zero, no threads are spawned. All work is done on the calling |
| 104 | /// thread, and callbacks are invoked before "async" functions return. |
| 105 | unsigned AsyncThreadsCount = getDefaultAsyncThreadsCount(); |
| 106 | |
| 107 | /// AST caching policy. The default is to keep up to 3 ASTs in memory. |
| 108 | ASTRetentionPolicy RetentionPolicy; |
| 109 | |
| 110 | /// Cached preambles are potentially large. If false, store them on disk. |
| 111 | bool StorePreamblesInMemory = true; |
| 112 | |
| 113 | /// Call hierarchy's outgoing calls feature requires additional index |
| 114 | /// serving structures which increase memory usage. If false, these are |
| 115 | /// not created and the feature is not enabled. |
| 116 | bool EnableOutgoingCalls = true; |
| 117 | |
| 118 | /// This throttler controls which preambles may be built at a given time. |
| 119 | clangd::PreambleThrottler *PreambleThrottler = nullptr; |
| 120 | |
| 121 | /// Manages to build module files. |
| 122 | ModulesBuilder *ModulesManager = nullptr; |
| 123 | |
| 124 | /// If true, ClangdServer builds a dynamic in-memory index for symbols in |
| 125 | /// opened files and uses the index to augment code completion results. |
| 126 | bool BuildDynamicSymbolIndex = false; |
| 127 | /// If true, ClangdServer automatically indexes files in the current project |
| 128 | /// on background threads. The index is stored in the project root. |
| 129 | bool BackgroundIndex = false; |
| 130 | llvm::ThreadPriority BackgroundIndexPriority = llvm::ThreadPriority::Low; |
| 131 | |
| 132 | /// If set, use this index to augment code completion results. |
| 133 | SymbolIndex *StaticIndex = nullptr; |
| 134 | |
| 135 | /// If set, queried to derive a processing context for some work. |
| 136 | /// Usually used to inject Config (see createConfiguredContextProvider). |
| 137 | /// |
| 138 | /// When the provider is called, the active context will be that inherited |
| 139 | /// from the request (e.g. addDocument()), or from the ClangdServer |
| 140 | /// constructor if there is no such request (e.g. background indexing). |
| 141 | /// |
| 142 | /// The path is an absolute path of the file being processed. |
| 143 | /// If there is no particular file (e.g. project loading) then it is empty. |
| 144 | std::function<Context(PathRef)> ContextProvider; |
| 145 | |
| 146 | /// The Options provider to use when running clang-tidy. If null, clang-tidy |
| 147 | /// checks will be disabled. |
| 148 | TidyProviderRef ClangTidyProvider; |
| 149 | |
| 150 | /// Clangd's workspace root. Relevant for "workspace" operations not bound |
| 151 | /// to a particular file. |
| 152 | /// FIXME: If not set, should use the current working directory. |
| 153 | std::optional<std::string> WorkspaceRoot; |
| 154 | |
| 155 | /// The resource directory is used to find internal headers, overriding |
| 156 | /// defaults and -resource-dir compiler flag). |
| 157 | /// If std::nullopt, ClangdServer calls |
| 158 | /// CompilerInvocation::GetResourcePath() to obtain the standard resource |
| 159 | /// directory. |
| 160 | std::optional<std::string> ResourceDir; |
| 161 | |
| 162 | /// Time to wait after a new file version before computing diagnostics. |
| 163 | DebouncePolicy UpdateDebounce = DebouncePolicy{ |
| 164 | /*Min=*/.Min: std::chrono::milliseconds(50), |
| 165 | /*Max=*/.Max: std::chrono::milliseconds(500), |
| 166 | /*RebuildRatio=*/.RebuildRatio: 1, |
| 167 | }; |
| 168 | |
| 169 | /// Cancel certain requests if the file changes before they begin running. |
| 170 | /// This is useful for "transient" actions like enumerateTweaks that were |
| 171 | /// likely implicitly generated, and avoids redundant work if clients forget |
| 172 | /// to cancel. Clients that always cancel stale requests should clear this. |
| 173 | bool ImplicitCancellation = true; |
| 174 | |
| 175 | /// Clangd will execute compiler drivers matching one of these globs to |
| 176 | /// fetch system include path. |
| 177 | std::vector<std::string> QueryDriverGlobs; |
| 178 | |
| 179 | // Whether the client supports folding only complete lines. |
| 180 | bool LineFoldingOnly = false; |
| 181 | |
| 182 | FeatureModuleSet *FeatureModules = nullptr; |
| 183 | /// If true, use the dirty buffer contents when building Preambles. |
| 184 | bool = false; |
| 185 | |
| 186 | // If true, parse emplace-like functions in the preamble. |
| 187 | bool PreambleParseForwardingFunctions = true; |
| 188 | |
| 189 | /// Whether include fixer insertions for Objective-C code should use #import |
| 190 | /// instead of #include. |
| 191 | bool ImportInsertions = false; |
| 192 | |
| 193 | /// Whether to collect and publish information about inactive preprocessor |
| 194 | /// regions in the document. |
| 195 | bool PublishInactiveRegions = false; |
| 196 | |
| 197 | explicit operator TUScheduler::Options() const; |
| 198 | }; |
| 199 | // Sensible default options for use in tests. |
| 200 | // Features like indexing must be enabled if desired. |
| 201 | static Options optsForTest(); |
| 202 | |
| 203 | /// Creates a new ClangdServer instance. |
| 204 | /// |
| 205 | /// ClangdServer uses \p CDB to obtain compilation arguments for parsing. Note |
| 206 | /// that ClangdServer only obtains compilation arguments once for each newly |
| 207 | /// added file (i.e., when processing a first call to addDocument) and reuses |
| 208 | /// those arguments for subsequent reparses. However, ClangdServer will check |
| 209 | /// if compilation arguments changed on calls to forceReparse(). |
| 210 | ClangdServer(const GlobalCompilationDatabase &CDB, const ThreadsafeFS &TFS, |
| 211 | const Options &Opts, Callbacks *Callbacks = nullptr); |
| 212 | ~ClangdServer(); |
| 213 | |
| 214 | /// Gets the installed feature module of a given type, if any. |
| 215 | /// This exposes access the public interface of feature modules that have one. |
| 216 | template <typename Mod> Mod *featureModule() { |
| 217 | return FeatureModules ? FeatureModules->get<Mod>() : nullptr; |
| 218 | } |
| 219 | template <typename Mod> const Mod *featureModule() const { |
| 220 | return FeatureModules ? FeatureModules->get<Mod>() : nullptr; |
| 221 | } |
| 222 | |
| 223 | /// Add a \p File to the list of tracked C++ files or update the contents if |
| 224 | /// \p File is already tracked. Also schedules parsing of the AST for it on a |
| 225 | /// separate thread. When the parsing is complete, DiagConsumer passed in |
| 226 | /// constructor will receive onDiagnosticsReady callback. |
| 227 | /// Version identifies this snapshot and is propagated to ASTs, preambles, |
| 228 | /// diagnostics etc built from it. If empty, a version number is generated. |
| 229 | void addDocument(PathRef File, StringRef Contents, |
| 230 | llvm::StringRef Version = "null" , |
| 231 | WantDiagnostics WD = WantDiagnostics::Auto, |
| 232 | bool ForceRebuild = false); |
| 233 | |
| 234 | /// Remove \p File from list of tracked files, schedule a request to free |
| 235 | /// resources associated with it. Pending diagnostics for closed files may not |
| 236 | /// be delivered, even if requested with WantDiags::Auto or WantDiags::Yes. |
| 237 | /// An empty set of diagnostics will be delivered, with Version = "". |
| 238 | void removeDocument(PathRef File); |
| 239 | |
| 240 | /// Requests a reparse of currently opened files using their latest source. |
| 241 | /// This will typically only rebuild if something other than the source has |
| 242 | /// changed (e.g. the CDB yields different flags, or files included in the |
| 243 | /// preamble have been modified). |
| 244 | void reparseOpenFilesIfNeeded( |
| 245 | llvm::function_ref<bool(llvm::StringRef File)> Filter); |
| 246 | |
| 247 | /// Run code completion for \p File at \p Pos. |
| 248 | /// |
| 249 | /// This method should only be called for currently tracked files. |
| 250 | void codeComplete(PathRef File, Position Pos, |
| 251 | const clangd::CodeCompleteOptions &Opts, |
| 252 | Callback<CodeCompleteResult> CB); |
| 253 | |
| 254 | /// Provide signature help for \p File at \p Pos. This method should only be |
| 255 | /// called for tracked files. |
| 256 | void signatureHelp(PathRef File, Position Pos, MarkupKind DocumentationFormat, |
| 257 | Callback<SignatureHelp> CB); |
| 258 | |
| 259 | /// Find declaration/definition locations of symbol at a specified position. |
| 260 | void locateSymbolAt(PathRef File, Position Pos, |
| 261 | Callback<std::vector<LocatedSymbol>> CB); |
| 262 | |
| 263 | /// Switch to a corresponding source file when given a header file, and vice |
| 264 | /// versa. |
| 265 | void (PathRef Path, |
| 266 | Callback<std::optional<clangd::Path>> CB); |
| 267 | |
| 268 | /// Get document highlights for a given position. |
| 269 | void findDocumentHighlights(PathRef File, Position Pos, |
| 270 | Callback<std::vector<DocumentHighlight>> CB); |
| 271 | |
| 272 | /// Get code hover for a given position. |
| 273 | void findHover(PathRef File, Position Pos, |
| 274 | Callback<std::optional<HoverInfo>> CB); |
| 275 | |
| 276 | /// Get information about type hierarchy for a given position. |
| 277 | void typeHierarchy(PathRef File, Position Pos, int Resolve, |
| 278 | TypeHierarchyDirection Direction, |
| 279 | Callback<std::vector<TypeHierarchyItem>> CB); |
| 280 | /// Get direct parents of a type hierarchy item. |
| 281 | void superTypes(const TypeHierarchyItem &Item, |
| 282 | Callback<std::optional<std::vector<TypeHierarchyItem>>> CB); |
| 283 | /// Get direct children of a type hierarchy item. |
| 284 | void subTypes(const TypeHierarchyItem &Item, |
| 285 | Callback<std::vector<TypeHierarchyItem>> CB); |
| 286 | |
| 287 | /// Resolve type hierarchy item in the given direction. |
| 288 | void resolveTypeHierarchy(TypeHierarchyItem Item, int Resolve, |
| 289 | TypeHierarchyDirection Direction, |
| 290 | Callback<std::optional<TypeHierarchyItem>> CB); |
| 291 | |
| 292 | /// Get information about call hierarchy for a given position. |
| 293 | void prepareCallHierarchy(PathRef File, Position Pos, |
| 294 | Callback<std::vector<CallHierarchyItem>> CB); |
| 295 | |
| 296 | /// Resolve incoming calls for a given call hierarchy item. |
| 297 | void incomingCalls(const CallHierarchyItem &Item, |
| 298 | Callback<std::vector<CallHierarchyIncomingCall>>); |
| 299 | |
| 300 | /// Resolve outgoing calls for a given call hierarchy item. |
| 301 | void outgoingCalls(const CallHierarchyItem &Item, |
| 302 | Callback<std::vector<CallHierarchyOutgoingCall>>); |
| 303 | |
| 304 | /// Resolve inlay hints for a given document. |
| 305 | void inlayHints(PathRef File, std::optional<Range> RestrictRange, |
| 306 | Callback<std::vector<InlayHint>>); |
| 307 | |
| 308 | /// Retrieve the top symbols from the workspace matching a query. |
| 309 | void workspaceSymbols(StringRef Query, int Limit, |
| 310 | Callback<std::vector<SymbolInformation>> CB); |
| 311 | |
| 312 | /// Retrieve the symbols within the specified file. |
| 313 | void documentSymbols(StringRef File, |
| 314 | Callback<std::vector<DocumentSymbol>> CB); |
| 315 | |
| 316 | /// Retrieve ranges that can be used to fold code within the specified file. |
| 317 | void foldingRanges(StringRef File, Callback<std::vector<FoldingRange>> CB); |
| 318 | |
| 319 | /// Retrieve implementations for virtual method. |
| 320 | void findImplementations(PathRef File, Position Pos, |
| 321 | Callback<std::vector<LocatedSymbol>> CB); |
| 322 | |
| 323 | /// Retrieve symbols for types referenced at \p Pos. |
| 324 | void findType(PathRef File, Position Pos, |
| 325 | Callback<std::vector<LocatedSymbol>> CB); |
| 326 | |
| 327 | /// Retrieve locations for symbol references. |
| 328 | void findReferences(PathRef File, Position Pos, uint32_t Limit, |
| 329 | bool AddContainer, Callback<ReferencesResult> CB); |
| 330 | |
| 331 | /// Run formatting for the \p File with content \p Code. |
| 332 | /// If \p Rng is non-empty, formats only those regions. |
| 333 | void formatFile(PathRef File, const std::vector<Range> &Rngs, |
| 334 | Callback<tooling::Replacements> CB); |
| 335 | |
| 336 | /// Run formatting after \p TriggerText was typed at \p Pos in \p File with |
| 337 | /// content \p Code. |
| 338 | void formatOnType(PathRef File, Position Pos, StringRef TriggerText, |
| 339 | Callback<std::vector<TextEdit>> CB); |
| 340 | |
| 341 | /// Test the validity of a rename operation. |
| 342 | /// |
| 343 | /// If NewName is provided, it performs a name validation. |
| 344 | void prepareRename(PathRef File, Position Pos, |
| 345 | std::optional<std::string> NewName, |
| 346 | const RenameOptions &RenameOpts, |
| 347 | Callback<RenameResult> CB); |
| 348 | |
| 349 | /// Rename all occurrences of the symbol at the \p Pos in \p File to |
| 350 | /// \p NewName. |
| 351 | /// If WantFormat is false, the final TextEdit will be not formatted, |
| 352 | /// embedders could use this method to get all occurrences of the symbol (e.g. |
| 353 | /// highlighting them in prepare stage). |
| 354 | void rename(PathRef File, Position Pos, llvm::StringRef NewName, |
| 355 | const RenameOptions &Opts, Callback<RenameResult> CB); |
| 356 | |
| 357 | struct TweakRef { |
| 358 | std::string ID; /// ID to pass for applyTweak. |
| 359 | std::string Title; /// A single-line message to show in the UI. |
| 360 | llvm::StringLiteral Kind; |
| 361 | }; |
| 362 | |
| 363 | // Ref to the clangd::Diag. |
| 364 | struct DiagRef { |
| 365 | clangd::Range Range; |
| 366 | std::string Message; |
| 367 | bool operator==(const DiagRef &Other) const { |
| 368 | return std::tie(args: Range, args: Message) == std::tie(args: Other.Range, args: Other.Message); |
| 369 | } |
| 370 | bool operator<(const DiagRef &Other) const { |
| 371 | return std::tie(args: Range, args: Message) < std::tie(args: Other.Range, args: Other.Message); |
| 372 | } |
| 373 | }; |
| 374 | |
| 375 | struct CodeActionInputs { |
| 376 | std::string File; |
| 377 | Range Selection; |
| 378 | |
| 379 | /// Requested kind of actions to return. |
| 380 | std::vector<std::string> RequestedActionKinds; |
| 381 | |
| 382 | /// Diagnostics attached to the code action request. |
| 383 | std::vector<DiagRef> Diagnostics; |
| 384 | |
| 385 | /// Tweaks where Filter returns false will not be checked or included. |
| 386 | std::function<bool(const Tweak &)> TweakFilter; |
| 387 | }; |
| 388 | struct CodeActionResult { |
| 389 | std::string Version; |
| 390 | struct QuickFix { |
| 391 | DiagRef Diag; |
| 392 | Fix F; |
| 393 | }; |
| 394 | std::vector<QuickFix> QuickFixes; |
| 395 | std::vector<TweakRef> TweakRefs; |
| 396 | struct Rename { |
| 397 | DiagRef Diag; |
| 398 | std::string FixMessage; |
| 399 | std::string NewName; |
| 400 | }; |
| 401 | std::vector<Rename> Renames; |
| 402 | }; |
| 403 | /// Surface code actions (quick-fixes for diagnostics, or available code |
| 404 | /// tweaks) for a given range in a file. |
| 405 | void codeAction(const CodeActionInputs &Inputs, |
| 406 | Callback<CodeActionResult> CB); |
| 407 | |
| 408 | /// Apply the code tweak with a specified \p ID. |
| 409 | void applyTweak(PathRef File, Range Sel, StringRef ID, |
| 410 | Callback<Tweak::Effect> CB); |
| 411 | |
| 412 | /// Called when an event occurs for a watched file in the workspace. |
| 413 | void onFileEvent(const DidChangeWatchedFilesParams &Params); |
| 414 | |
| 415 | /// Get symbol info for given position. |
| 416 | /// Clangd extension - not part of official LSP. |
| 417 | void symbolInfo(PathRef File, Position Pos, |
| 418 | Callback<std::vector<SymbolDetails>> CB); |
| 419 | |
| 420 | /// Get semantic ranges around a specified position in a file. |
| 421 | void semanticRanges(PathRef File, const std::vector<Position> &Pos, |
| 422 | Callback<std::vector<SelectionRange>> CB); |
| 423 | |
| 424 | /// Get all document links in a file. |
| 425 | void documentLinks(PathRef File, Callback<std::vector<DocumentLink>> CB); |
| 426 | |
| 427 | void semanticHighlights(PathRef File, |
| 428 | Callback<std::vector<HighlightingToken>>); |
| 429 | |
| 430 | /// Describe the AST subtree for a piece of code. |
| 431 | void getAST(PathRef File, std::optional<Range> R, |
| 432 | Callback<std::optional<ASTNode>> CB); |
| 433 | |
| 434 | /// Runs an arbitrary action that has access to the AST of the specified file. |
| 435 | /// The action will execute on one of ClangdServer's internal threads. |
| 436 | /// The AST is only valid for the duration of the callback. |
| 437 | /// As with other actions, the file must have been opened. |
| 438 | void customAction(PathRef File, llvm::StringRef Name, |
| 439 | Callback<InputsAndAST> Action); |
| 440 | |
| 441 | /// Fetches diagnostics for current version of the \p File. This might fail if |
| 442 | /// server is busy (building a preamble) and would require a long time to |
| 443 | /// prepare diagnostics. If it fails, clients should wait for |
| 444 | /// onSemanticsMaybeChanged and then retry. |
| 445 | /// These 'pulled' diagnostics do not interfere with the diagnostics 'pushed' |
| 446 | /// to Callbacks::onDiagnosticsReady, and clients may use either or both. |
| 447 | void diagnostics(PathRef File, Callback<std::vector<Diag>> CB); |
| 448 | |
| 449 | /// Returns estimated memory usage and other statistics for each of the |
| 450 | /// currently open files. |
| 451 | /// Overall memory usage of clangd may be significantly more than reported |
| 452 | /// here, as this metric does not account (at least) for: |
| 453 | /// - memory occupied by static and dynamic index, |
| 454 | /// - memory required for in-flight requests, |
| 455 | /// FIXME: those metrics might be useful too, we should add them. |
| 456 | llvm::StringMap<TUScheduler::FileStats> fileStats() const; |
| 457 | |
| 458 | /// Gets the contents of a currently tracked file. Returns nullptr if the file |
| 459 | /// isn't being tracked. |
| 460 | std::shared_ptr<const std::string> getDraft(PathRef File) const; |
| 461 | |
| 462 | // Blocks the main thread until the server is idle. Only for use in tests. |
| 463 | // Returns false if the timeout expires. |
| 464 | // FIXME: various subcomponents each get the full timeout, so it's more of |
| 465 | // an order of magnitude than a hard deadline. |
| 466 | [[nodiscard]] bool |
| 467 | blockUntilIdleForTest(std::optional<double> TimeoutSeconds = 10); |
| 468 | |
| 469 | /// Builds a nested representation of memory used by components. |
| 470 | void profile(MemoryTree &MT) const; |
| 471 | |
| 472 | private: |
| 473 | FeatureModuleSet *FeatureModules; |
| 474 | const GlobalCompilationDatabase &CDB; |
| 475 | const ThreadsafeFS &() const { |
| 476 | return UseDirtyHeaders ? *DirtyFS : TFS; |
| 477 | } |
| 478 | const ThreadsafeFS &TFS; |
| 479 | |
| 480 | Path ResourceDir; |
| 481 | // The index used to look up symbols. This could be: |
| 482 | // - null (all index functionality is optional) |
| 483 | // - the dynamic index owned by ClangdServer (DynamicIdx) |
| 484 | // - the static index passed to the constructor |
| 485 | // - a merged view of a static and dynamic index (MergedIndex) |
| 486 | const SymbolIndex *Index = nullptr; |
| 487 | // If present, an index of symbols in open files. Read via *Index. |
| 488 | std::unique_ptr<FileIndex> DynamicIdx; |
| 489 | // If present, the new "auto-index" maintained in background threads. |
| 490 | std::unique_ptr<BackgroundIndex> BackgroundIdx; |
| 491 | // Storage for merged views of the various indexes. |
| 492 | std::vector<std::unique_ptr<SymbolIndex>> MergedIdx; |
| 493 | // Manage module files. |
| 494 | ModulesBuilder *ModulesManager = nullptr; |
| 495 | |
| 496 | // When set, provides clang-tidy options for a specific file. |
| 497 | TidyProviderRef ClangTidyProvider; |
| 498 | |
| 499 | bool = false; |
| 500 | |
| 501 | // Whether the client supports folding only complete lines. |
| 502 | bool LineFoldingOnly = false; |
| 503 | |
| 504 | bool PreambleParseForwardingFunctions = true; |
| 505 | |
| 506 | bool ImportInsertions = false; |
| 507 | |
| 508 | bool PublishInactiveRegions = false; |
| 509 | |
| 510 | // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex) |
| 511 | llvm::StringMap<std::optional<FuzzyFindRequest>> |
| 512 | CachedCompletionFuzzyFindRequestByFile; |
| 513 | mutable std::mutex CachedCompletionFuzzyFindRequestMutex; |
| 514 | |
| 515 | std::optional<std::string> WorkspaceRoot; |
| 516 | std::optional<AsyncTaskRunner> IndexTasks; // for stdlib indexing. |
| 517 | std::optional<TUScheduler> WorkScheduler; |
| 518 | // Invalidation policy used for actions that we assume are "transient". |
| 519 | TUScheduler::ASTActionInvalidation Transient; |
| 520 | |
| 521 | // Store of the current versions of the open documents. |
| 522 | // Only written from the main thread (despite being threadsafe). |
| 523 | DraftStore DraftMgr; |
| 524 | |
| 525 | std::unique_ptr<ThreadsafeFS> DirtyFS; |
| 526 | }; |
| 527 | |
| 528 | } // namespace clangd |
| 529 | } // namespace clang |
| 530 | |
| 531 | #endif |
| 532 | |