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