• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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