xref: /llvm-project/clang-tools-extra/clangd/CodeComplete.h (revision 18ca7ad3393241b9fc0d5f149247e10837c6f926)
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