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