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