1 //===--- CodeComplete.h ------------------------------------------*- 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 // Code completion provides suggestions for what the user might type next. 10 // After "std::string S; S." we might suggest members of std::string. 11 // Signature help describes the parameters of a function as you type them. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H 16 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H 17 18 #include "ASTSignals.h" 19 #include "Compiler.h" 20 #include "Config.h" 21 #include "Protocol.h" 22 #include "Quality.h" 23 #include "index/Index.h" 24 #include "index/Symbol.h" 25 #include "index/SymbolOrigin.h" 26 #include "support/Markup.h" 27 #include "support/Path.h" 28 #include "clang/Sema/CodeCompleteConsumer.h" 29 #include "clang/Sema/CodeCompleteOptions.h" 30 #include "llvm/ADT/SmallVector.h" 31 #include "llvm/ADT/StringRef.h" 32 #include <functional> 33 #include <future> 34 #include <optional> 35 #include <utility> 36 37 namespace clang { 38 class NamedDecl; 39 namespace clangd { 40 struct PreambleData; 41 struct CodeCompletion; 42 43 struct CodeCompleteOptions { 44 /// Returns options that can be passed to clang's completion engine. 45 clang::CodeCompleteOptions getClangCompleteOpts() const; 46 47 /// When true, completion items will contain expandable code snippets in 48 /// completion (e.g. `return ${1:expression}` or `foo(${1:int a}, ${2:int 49 /// b})). 50 bool EnableSnippets = false; 51 52 /// Include results that are not legal completions in the current context. 53 /// For example, private members are usually inaccessible. 54 bool IncludeIneligibleResults = false; 55 56 /// Force sema to load decls from preamble even if an index is provided. 57 /// This is helpful for cases the index can't provide symbols, e.g. with 58 /// experimental c++20 modules 59 bool ForceLoadPreamble = false; 60 61 /// Combine overloads into a single completion item where possible. 62 /// If none, the implementation may choose an appropriate behavior. 63 /// (In practice, ClangdLSPServer enables bundling if the client claims 64 /// to supports signature help). 65 std::optional<bool> BundleOverloads; 66 67 /// Limit the number of results returned (0 means no limit). 68 /// If more results are available, we set CompletionList.isIncomplete. 69 size_t Limit = 0; 70 71 /// Whether to present doc comments as plain-text or markdown. 72 MarkupKind DocumentationFormat = MarkupKind::PlainText; 73 74 enum IncludeInsertion { 75 IWYU, 76 NeverInsert, 77 } InsertIncludes = IncludeInsertion::IWYU; 78 79 /// Whether include insertions for Objective-C code should use #import instead 80 /// of #include. 81 bool ImportInsertions = false; 82 83 /// A visual indicator to prepend to the completion label to indicate whether 84 /// completion result would trigger an #include insertion or not. 85 struct IncludeInsertionIndicator { 86 std::string Insert = "•"; 87 std::string NoInsert = " "; 88 } IncludeIndicator; 89 90 /// Expose origins of completion items in the label (for debugging). 91 bool ShowOrigins = false; 92 93 // Populated internally by clangd, do not set. 94 /// If `Index` is set, it is used to augment the code completion 95 /// results. 96 /// FIXME(ioeric): we might want a better way to pass the index around inside 97 /// clangd. 98 const SymbolIndex *Index = nullptr; 99 100 const ASTSignals *MainFileSignals = nullptr; 101 /// Include completions that require small corrections, e.g. change '.' to 102 /// '->' on member access etc. 103 bool IncludeFixIts = false; 104 105 /// Whether to include index symbols that are not defined in the scopes 106 /// visible from the code completion point. This applies in contexts without 107 /// explicit scope qualifiers. 108 /// 109 /// Such completions can insert scope qualifiers. 110 bool AllScopes = false; 111 112 /// The way argument list on calls '()' and generics '<>' are handled. 113 Config::ArgumentListsPolicy ArgumentLists = 114 Config::ArgumentListsPolicy::FullPlaceholders; 115 116 /// Whether to use the clang parser, or fallback to text-based completion 117 /// (using identifiers in the current file and symbol indexes). 118 enum CodeCompletionParse { 119 /// Block until we can run the parser (e.g. preamble is built). 120 /// Return an error if this fails. 121 AlwaysParse, 122 /// Run the parser if inputs (preamble) are ready. 123 /// Otherwise, use text-based completion. 124 ParseIfReady, 125 /// Always use text-based completion. 126 NeverParse, 127 } RunParser = ParseIfReady; 128 129 /// Callback invoked on all CompletionCandidate after they are scored and 130 /// before they are ranked (by -Score). Thus the results are yielded in 131 /// arbitrary order. 132 /// 133 /// This callbacks allows capturing various internal structures used by clangd 134 /// during code completion. Eg: Symbol quality and relevance signals. 135 std::function<void(const CodeCompletion &, const SymbolQualitySignals &, 136 const SymbolRelevanceSignals &, float Score)> 137 RecordCCResult; 138 139 /// Model to use for ranking code completion candidates. 140 enum CodeCompletionRankingModel { 141 Heuristics, 142 DecisionForest, 143 }; 144 static const CodeCompletionRankingModel DefaultRankingModel; 145 CodeCompletionRankingModel RankingModel = DefaultRankingModel; 146 147 /// Callback used to score a CompletionCandidate if DecisionForest ranking 148 /// model is enabled. 149 /// This allows us to inject experimental models and compare them with 150 /// baseline model using A/B testing. 151 std::function<DecisionForestScores( 152 const SymbolQualitySignals &, const SymbolRelevanceSignals &, float Base)> 153 DecisionForestScorer = &evaluateDecisionForest; 154 /// Weight for combining NameMatch and Prediction of DecisionForest. 155 /// CompletionScore is NameMatch * pow(Base, Prediction). 156 /// The optimal value of Base largely depends on the semantics of the model 157 /// and prediction score (e.g. algorithm used during training, number of 158 /// trees, etc.). Usually if the range of Prediction is [-20, 20] then a Base 159 /// in [1.2, 1.7] works fine. 160 /// Semantics: E.g. For Base = 1.3, if the Prediction score reduces by 2.6 161 /// points then completion score reduces by 50% or 1.3^(-2.6). 162 float DecisionForestBase = 1.3f; 163 }; 164 165 // Semi-structured representation of a code-complete suggestion for our C++ API. 166 // We don't use the LSP structures here (unlike most features) as we want 167 // to expose more data to allow for more precise testing and evaluation. 168 struct CodeCompletion { 169 // The unqualified name of the symbol or other completion item. 170 std::string Name; 171 // The name of the symbol for filtering and sorting purposes. Typically the 172 // same as `Name`, but may be different e.g. for ObjC methods, `Name` is the 173 // first selector fragment but the `FilterText` is the entire selector. 174 std::string FilterText; 175 // The scope qualifier for the symbol name. e.g. "ns1::ns2::" 176 // Empty for non-symbol completions. Not inserted, but may be displayed. 177 std::string Scope; 178 // Text that must be inserted before the name, and displayed (e.g. base::). 179 std::string RequiredQualifier; 180 // Details to be displayed following the name. Not inserted. 181 std::string Signature; 182 // Text to be inserted following the name, in snippet format. 183 std::string SnippetSuffix; 184 // Type to be displayed for this completion. 185 std::string ReturnType; 186 // The parsed documentation comment. 187 std::optional<markup::Document> Documentation; 188 CompletionItemKind Kind = CompletionItemKind::Missing; 189 // This completion item may represent several symbols that can be inserted in 190 // the same way, such as function overloads. In this case BundleSize > 1, and 191 // the following fields are summaries: 192 // - Signature is e.g. "(...)" for functions. 193 // - SnippetSuffix is similarly e.g. "(${0})". 194 // - ReturnType may be empty 195 // - Documentation may be from one symbol, or a combination of several 196 // Other fields should apply equally to all bundled completions. 197 unsigned BundleSize = 1; 198 SymbolOrigin Origin = SymbolOrigin::Unknown; 199 200 struct IncludeCandidate { 201 // The header through which this symbol could be included. 202 // Quoted string as expected by an #include directive, e.g. "<memory>". 203 // Empty for non-symbol completions, or when not known. 204 std::string Header; 205 // Present if Header should be inserted to use this item. 206 std::optional<TextEdit> Insertion; 207 }; 208 // All possible include headers ranked by preference. By default, the first 209 // include is used. 210 // If we've bundled together overloads that have different sets of includes, 211 // thse includes may not be accurate for all of them. 212 llvm::SmallVector<IncludeCandidate, 1> Includes; 213 214 /// Holds information about small corrections that needs to be done. Like 215 /// converting '->' to '.' on member access. 216 std::vector<TextEdit> FixIts; 217 218 /// Holds the range of the token we are going to replace with this completion. 219 Range CompletionTokenRange; 220 221 // Scores are used to rank completion items. 222 struct Scores { 223 // The score that items are ranked by. 224 float Total = 0.f; 225 226 // The finalScore with the fuzzy name match score excluded. 227 // When filtering client-side, editors should calculate the new fuzzy score, 228 // whose scale is 0-1 (with 1 = prefix match, special case 2 = exact match), 229 // and recompute finalScore = fuzzyScore * symbolScore. 230 float ExcludingName = 0.f; 231 232 // Component scores that contributed to the final score: 233 234 // Quality describes how important we think this candidate is, 235 // independent of the query. 236 // e.g. symbols with lots of incoming references have higher quality. 237 float Quality = 0.f; 238 // Relevance describes how well this candidate matched the query. 239 // e.g. symbols from nearby files have higher relevance. 240 float Relevance = 0.f; 241 }; 242 Scores Score; 243 244 /// Indicates if this item is deprecated. 245 bool Deprecated = false; 246 247 // Serialize this to an LSP completion item. This is a lossy operation. 248 CompletionItem render(const CodeCompleteOptions &) const; 249 }; 250 raw_ostream &operator<<(raw_ostream &, const CodeCompletion &); 251 struct CodeCompleteResult { 252 std::vector<CodeCompletion> Completions; 253 bool HasMore = false; 254 CodeCompletionContext::Kind Context = CodeCompletionContext::CCC_Other; 255 // The text that is being directly completed. 256 // Example: foo.pb^ -> foo.push_back() 257 // ~~ 258 // Typically matches the textEdit.range of Completions, but not guaranteed to. 259 std::optional<Range> CompletionRange; 260 // Usually the source will be parsed with a real C++ parser. 261 // But heuristics may be used instead if e.g. the preamble is not ready. 262 bool RanParser = true; 263 }; 264 raw_ostream &operator<<(raw_ostream &, const CodeCompleteResult &); 265 266 /// A speculative and asynchronous fuzzy find index request (based on cached 267 /// request) that can be sent before parsing sema. This would reduce completion 268 /// latency if the speculation succeeds. 269 struct SpeculativeFuzzyFind { 270 /// A cached request from past code completions. 271 /// Set by caller of `codeComplete()`. 272 std::optional<FuzzyFindRequest> CachedReq; 273 /// The actual request used by `codeComplete()`. 274 /// Set by `codeComplete()`. This can be used by callers to update cache. 275 std::optional<FuzzyFindRequest> NewReq; 276 /// The result is consumed by `codeComplete()` if speculation succeeded. 277 /// NOTE: the destructor will wait for the async call to finish. 278 std::future<std::pair<bool /*Incomplete*/, SymbolSlab>> Result; 279 }; 280 281 /// Gets code completions at a specified \p Pos in \p FileName. 282 /// 283 /// If \p Preamble is nullptr, this runs code completion without compiling the 284 /// code. 285 /// 286 /// If \p SpecFuzzyFind is set, a speculative and asynchronous fuzzy find index 287 /// request (based on cached request) will be run before parsing sema. In case 288 /// the speculative result is used by code completion (e.g. speculation failed), 289 /// the speculative result is not consumed, and `SpecFuzzyFind` is only 290 /// destroyed when the async request finishes. 291 CodeCompleteResult codeComplete(PathRef FileName, Position Pos, 292 const PreambleData *Preamble, 293 const ParseInputs &ParseInput, 294 CodeCompleteOptions Opts, 295 SpeculativeFuzzyFind *SpecFuzzyFind = nullptr); 296 297 /// Get signature help at a specified \p Pos in \p FileName. 298 SignatureHelp signatureHelp(PathRef FileName, Position Pos, 299 const PreambleData &Preamble, 300 const ParseInputs &ParseInput, 301 MarkupKind DocumentationFormat); 302 303 // For index-based completion, we only consider: 304 // * symbols in namespaces or translation unit scopes (e.g. no class 305 // members, no locals) 306 // * enum constants (both scoped and unscoped) 307 // * primary templates (no specializations) 308 // For the other cases, we let Clang do the completion because it does not 309 // need any non-local information and it will be much better at following 310 // lookup rules. Other symbols still appear in the index for other purposes, 311 // like workspace/symbols or textDocument/definition, but are not used for code 312 // completion. 313 bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx); 314 315 // Text immediately before the completion point that should be completed. 316 // This is heuristically derived from the source code, and is used when: 317 // - semantic analysis fails 318 // - semantic analysis may be slow, and we speculatively query the index 319 struct CompletionPrefix { 320 // The unqualified partial name. 321 // If there is none, begin() == end() == completion position. 322 llvm::StringRef Name; 323 // The spelled scope qualifier, such as Foo::. 324 // If there is none, begin() == end() == Name.begin(). 325 llvm::StringRef Qualifier; 326 }; 327 // Heuristically parses before Offset to determine what should be completed. 328 CompletionPrefix guessCompletionPrefix(llvm::StringRef Content, 329 unsigned Offset); 330 331 // Whether it makes sense to complete at the point based on typed characters. 332 // For instance, we implicitly trigger at `a->^` but not at `a>^`. 333 bool allowImplicitCompletion(llvm::StringRef Content, unsigned Offset); 334 335 } // namespace clangd 336 } // namespace clang 337 338 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H 339