clang-tools 20.0.0git
CodeComplete.cpp
Go to the documentation of this file.
1//===--- CodeComplete.cpp ----------------------------------------*- 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 has several moving parts:
10// - AST-based completions are provided using the completion hooks in Sema.
11// - external completions are retrieved from the index (using hints from Sema)
12// - the two sources overlap, and must be merged and overloads bundled
13// - results must be scored and ranked (see Quality.h) before rendering
14//
15// Signature help works in a similar way as code completion, but it is simpler:
16// it's purely AST-based, and there are few candidates.
17//
18//===----------------------------------------------------------------------===//
19
20#include "CodeComplete.h"
21#include "AST.h"
23#include "Compiler.h"
24#include "Config.h"
25#include "ExpectedTypes.h"
26#include "Feature.h"
27#include "FileDistance.h"
28#include "FuzzyMatch.h"
29#include "Headers.h"
30#include "Hover.h"
31#include "Preamble.h"
32#include "Protocol.h"
33#include "Quality.h"
34#include "SourceCode.h"
35#include "URI.h"
36#include "index/Index.h"
37#include "index/Symbol.h"
38#include "index/SymbolOrigin.h"
39#include "support/Logger.h"
40#include "support/Markup.h"
41#include "support/Threading.h"
43#include "support/Trace.h"
44#include "clang/AST/Decl.h"
45#include "clang/AST/DeclBase.h"
46#include "clang/Basic/CharInfo.h"
47#include "clang/Basic/LangOptions.h"
48#include "clang/Basic/SourceLocation.h"
49#include "clang/Basic/TokenKinds.h"
50#include "clang/Format/Format.h"
51#include "clang/Frontend/CompilerInstance.h"
52#include "clang/Frontend/FrontendActions.h"
53#include "clang/Lex/ExternalPreprocessorSource.h"
54#include "clang/Lex/Lexer.h"
55#include "clang/Lex/Preprocessor.h"
56#include "clang/Lex/PreprocessorOptions.h"
57#include "clang/Sema/CodeCompleteConsumer.h"
58#include "clang/Sema/DeclSpec.h"
59#include "clang/Sema/Sema.h"
60#include "llvm/ADT/ArrayRef.h"
61#include "llvm/ADT/SmallVector.h"
62#include "llvm/ADT/StringExtras.h"
63#include "llvm/ADT/StringRef.h"
64#include "llvm/Support/Casting.h"
65#include "llvm/Support/Compiler.h"
66#include "llvm/Support/Debug.h"
67#include "llvm/Support/Error.h"
68#include "llvm/Support/FormatVariadic.h"
69#include "llvm/Support/ScopedPrinter.h"
70#include <algorithm>
71#include <iterator>
72#include <limits>
73#include <optional>
74#include <utility>
75
76// We log detailed candidate here if you run with -debug-only=codecomplete.
77#define DEBUG_TYPE "CodeComplete"
78
79namespace clang {
80namespace clangd {
81
82#if CLANGD_DECISION_FOREST
86#else
89#endif
90
91namespace {
92
93// Note: changes to this function should also be reflected in the
94// CodeCompletionResult overload where appropriate.
96toCompletionItemKind(index::SymbolKind Kind,
97 const llvm::StringRef *Signature = nullptr) {
98 using SK = index::SymbolKind;
99 switch (Kind) {
100 case SK::Unknown:
102 case SK::Module:
103 case SK::Namespace:
104 case SK::NamespaceAlias:
106 case SK::Macro:
107 // Use macro signature (if provided) to tell apart function-like and
108 // object-like macros.
109 return Signature && Signature->contains('(') ? CompletionItemKind::Function
111 case SK::Enum:
113 case SK::Struct:
115 case SK::Class:
116 case SK::Extension:
117 case SK::Union:
119 case SK::Protocol:
120 // Use interface instead of class for differentiation of classes and
121 // protocols with the same name (e.g. @interface NSObject vs. @protocol
122 // NSObject).
124 case SK::TypeAlias:
125 // We use the same kind as the VSCode C++ extension.
126 // FIXME: pick a better option when we have one.
128 case SK::Using:
130 case SK::Function:
131 case SK::ConversionFunction:
133 case SK::Variable:
134 case SK::Parameter:
135 case SK::NonTypeTemplateParm:
137 case SK::Field:
139 case SK::EnumConstant:
141 case SK::InstanceMethod:
142 case SK::ClassMethod:
143 case SK::StaticMethod:
144 case SK::Destructor:
146 case SK::InstanceProperty:
147 case SK::ClassProperty:
148 case SK::StaticProperty:
150 case SK::Constructor:
152 case SK::TemplateTypeParm:
153 case SK::TemplateTemplateParm:
155 case SK::Concept:
157 }
158 llvm_unreachable("Unhandled clang::index::SymbolKind.");
159}
160
161// Note: changes to this function should also be reflected in the
162// index::SymbolKind overload where appropriate.
163CompletionItemKind toCompletionItemKind(const CodeCompletionResult &Res,
164 CodeCompletionContext::Kind CtxKind) {
165 if (Res.Declaration)
166 return toCompletionItemKind(index::getSymbolInfo(Res.Declaration).Kind);
167 if (CtxKind == CodeCompletionContext::CCC_IncludedFile)
169 switch (Res.Kind) {
170 case CodeCompletionResult::RK_Declaration:
171 llvm_unreachable("RK_Declaration without Decl");
172 case CodeCompletionResult::RK_Keyword:
174 case CodeCompletionResult::RK_Macro:
175 // There is no 'Macro' kind in LSP.
176 // Avoid using 'Text' to avoid confusion with client-side word-based
177 // completion proposals.
178 return Res.MacroDefInfo && Res.MacroDefInfo->isFunctionLike()
181 case CodeCompletionResult::RK_Pattern:
183 }
184 llvm_unreachable("Unhandled CodeCompletionResult::ResultKind.");
185}
186
187// FIXME: find a home for this (that can depend on both markup and Protocol).
188MarkupContent renderDoc(const markup::Document &Doc, MarkupKind Kind) {
189 MarkupContent Result;
190 Result.kind = Kind;
191 switch (Kind) {
193 Result.value.append(Doc.asPlainText());
194 break;
196 Result.value.append(Doc.asMarkdown());
197 break;
198 }
199 return Result;
200}
201
202Symbol::IncludeDirective insertionDirective(const CodeCompleteOptions &Opts) {
203 if (!Opts.ImportInsertions || !Opts.MainFileSignals)
206}
207
208// Identifier code completion result.
209struct RawIdentifier {
210 llvm::StringRef Name;
211 unsigned References; // # of usages in file.
212};
213
214/// A code completion result, in clang-native form.
215/// It may be promoted to a CompletionItem if it's among the top-ranked results.
216struct CompletionCandidate {
217 llvm::StringRef Name; // Used for filtering and sorting.
218 // We may have a result from Sema, from the index, or both.
219 const CodeCompletionResult *SemaResult = nullptr;
220 const Symbol *IndexResult = nullptr;
221 const RawIdentifier *IdentifierResult = nullptr;
222 llvm::SmallVector<SymbolInclude, 1> RankedIncludeHeaders;
223
224 // Returns a token identifying the overload set this is part of.
225 // 0 indicates it's not part of any overload set.
226 size_t overloadSet(const CodeCompleteOptions &Opts, llvm::StringRef FileName,
227 IncludeInserter *Inserter,
228 CodeCompletionContext::Kind CCContextKind) const {
229 if (!Opts.BundleOverloads.value_or(false))
230 return 0;
231
232 // Depending on the index implementation, we can see different header
233 // strings (literal or URI) mapping to the same file. We still want to
234 // bundle those, so we must resolve the header to be included here.
235 std::string HeaderForHash;
236 if (Inserter) {
237 if (auto Header = headerToInsertIfAllowed(Opts, CCContextKind)) {
238 if (auto HeaderFile = toHeaderFile(*Header, FileName)) {
239 if (auto Spelled =
240 Inserter->calculateIncludePath(*HeaderFile, FileName))
241 HeaderForHash = *Spelled;
242 } else {
243 vlog("Code completion header path manipulation failed {0}",
244 HeaderFile.takeError());
245 }
246 }
247 }
248
249 llvm::SmallString<256> Scratch;
250 if (IndexResult) {
251 switch (IndexResult->SymInfo.Kind) {
252 case index::SymbolKind::ClassMethod:
253 case index::SymbolKind::InstanceMethod:
254 case index::SymbolKind::StaticMethod:
255#ifndef NDEBUG
256 llvm_unreachable("Don't expect members from index in code completion");
257#else
258 [[fallthrough]];
259#endif
260 case index::SymbolKind::Function:
261 // We can't group overloads together that need different #includes.
262 // This could break #include insertion.
263 return llvm::hash_combine(
264 (IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
265 HeaderForHash);
266 default:
267 return 0;
268 }
269 }
270 if (SemaResult) {
271 // We need to make sure we're consistent with the IndexResult case!
272 const NamedDecl *D = SemaResult->Declaration;
273 if (!D || !D->isFunctionOrFunctionTemplate())
274 return 0;
275 {
276 llvm::raw_svector_ostream OS(Scratch);
277 D->printQualifiedName(OS);
278 }
279 return llvm::hash_combine(Scratch, HeaderForHash);
280 }
281 assert(IdentifierResult);
282 return 0;
283 }
284
285 bool contextAllowsHeaderInsertion(CodeCompletionContext::Kind Kind) const {
286 // Explicitly disable insertions for forward declarations since they don't
287 // reference the declaration.
288 if (Kind == CodeCompletionContext::CCC_ObjCClassForwardDecl)
289 return false;
290 return true;
291 }
292
293 // The best header to include if include insertion is allowed.
294 std::optional<llvm::StringRef>
295 headerToInsertIfAllowed(const CodeCompleteOptions &Opts,
296 CodeCompletionContext::Kind ContextKind) const {
297 if (Opts.InsertIncludes == CodeCompleteOptions::NeverInsert ||
298 RankedIncludeHeaders.empty() ||
299 !contextAllowsHeaderInsertion(ContextKind))
300 return std::nullopt;
301 if (SemaResult && SemaResult->Declaration) {
302 // Avoid inserting new #include if the declaration is found in the current
303 // file e.g. the symbol is forward declared.
304 auto &SM = SemaResult->Declaration->getASTContext().getSourceManager();
305 for (const Decl *RD : SemaResult->Declaration->redecls())
306 if (SM.isInMainFile(SM.getExpansionLoc(RD->getBeginLoc())))
307 return std::nullopt;
308 }
309 Symbol::IncludeDirective Directive = insertionDirective(Opts);
310 for (const auto &Inc : RankedIncludeHeaders)
311 if ((Inc.Directive & Directive) != 0)
312 return Inc.Header;
313 return std::nullopt;
314 }
315
316 using Bundle = llvm::SmallVector<CompletionCandidate, 4>;
317};
318using ScoredBundle =
319 std::pair<CompletionCandidate::Bundle, CodeCompletion::Scores>;
320struct ScoredBundleGreater {
321 bool operator()(const ScoredBundle &L, const ScoredBundle &R) {
322 if (L.second.Total != R.second.Total)
323 return L.second.Total > R.second.Total;
324 return L.first.front().Name <
325 R.first.front().Name; // Earlier name is better.
326 }
327};
328
329// Remove the first template argument from Signature.
330// If Signature only contains a single argument an empty string is returned.
331std::string removeFirstTemplateArg(llvm::StringRef Signature) {
332 auto Rest = Signature.split(",").second;
333 if (Rest.empty())
334 return "";
335 return ("<" + Rest.ltrim()).str();
336}
337
338// Assembles a code completion out of a bundle of >=1 completion candidates.
339// Many of the expensive strings are only computed at this point, once we know
340// the candidate bundle is going to be returned.
341//
342// Many fields are the same for all candidates in a bundle (e.g. name), and are
343// computed from the first candidate, in the constructor.
344// Others vary per candidate, so add() must be called for remaining candidates.
345struct CodeCompletionBuilder {
346 CodeCompletionBuilder(ASTContext *ASTCtx, const CompletionCandidate &C,
347 CodeCompletionString *SemaCCS,
348 llvm::ArrayRef<std::string> AccessibleScopes,
349 const IncludeInserter &Includes,
350 llvm::StringRef FileName,
351 CodeCompletionContext::Kind ContextKind,
352 const CodeCompleteOptions &Opts,
353 bool IsUsingDeclaration, tok::TokenKind NextTokenKind)
354 : ASTCtx(ASTCtx), ArgumentLists(Opts.ArgumentLists),
355 IsUsingDeclaration(IsUsingDeclaration), NextTokenKind(NextTokenKind) {
356 Completion.Deprecated = true; // cleared by any non-deprecated overload.
357 add(C, SemaCCS, ContextKind);
358 if (C.SemaResult) {
359 assert(ASTCtx);
360 Completion.Origin |= SymbolOrigin::AST;
361 Completion.Name = std::string(llvm::StringRef(SemaCCS->getTypedText()));
362 Completion.FilterText = SemaCCS->getAllTypedText();
363 if (Completion.Scope.empty()) {
364 if ((C.SemaResult->Kind == CodeCompletionResult::RK_Declaration) ||
365 (C.SemaResult->Kind == CodeCompletionResult::RK_Pattern))
366 if (const auto *D = C.SemaResult->getDeclaration())
367 if (const auto *ND = dyn_cast<NamedDecl>(D))
368 Completion.Scope = std::string(
370 }
371 Completion.Kind = toCompletionItemKind(*C.SemaResult, ContextKind);
372 // Sema could provide more info on whether the completion was a file or
373 // folder.
374 if (Completion.Kind == CompletionItemKind::File &&
375 Completion.Name.back() == '/')
376 Completion.Kind = CompletionItemKind::Folder;
377 for (const auto &FixIt : C.SemaResult->FixIts) {
378 Completion.FixIts.push_back(toTextEdit(
379 FixIt, ASTCtx->getSourceManager(), ASTCtx->getLangOpts()));
380 }
381 llvm::sort(Completion.FixIts, [](const TextEdit &X, const TextEdit &Y) {
382 return std::tie(X.range.start.line, X.range.start.character) <
383 std::tie(Y.range.start.line, Y.range.start.character);
384 });
385 }
386 if (C.IndexResult) {
387 Completion.Origin |= C.IndexResult->Origin;
388 if (Completion.Scope.empty())
389 Completion.Scope = std::string(C.IndexResult->Scope);
390 if (Completion.Kind == CompletionItemKind::Missing)
391 Completion.Kind = toCompletionItemKind(C.IndexResult->SymInfo.Kind,
392 &C.IndexResult->Signature);
393 if (Completion.Name.empty())
394 Completion.Name = std::string(C.IndexResult->Name);
395 if (Completion.FilterText.empty())
396 Completion.FilterText = Completion.Name;
397 // If the completion was visible to Sema, no qualifier is needed. This
398 // avoids unneeded qualifiers in cases like with `using ns::X`.
399 if (Completion.RequiredQualifier.empty() && !C.SemaResult) {
400 llvm::StringRef ShortestQualifier = C.IndexResult->Scope;
401 for (llvm::StringRef Scope : AccessibleScopes) {
402 llvm::StringRef Qualifier = C.IndexResult->Scope;
403 if (Qualifier.consume_front(Scope) &&
404 Qualifier.size() < ShortestQualifier.size())
405 ShortestQualifier = Qualifier;
406 }
407 Completion.RequiredQualifier = std::string(ShortestQualifier);
408 }
409 }
410 if (C.IdentifierResult) {
411 Completion.Origin |= SymbolOrigin::Identifier;
412 Completion.Kind = CompletionItemKind::Text;
413 Completion.Name = std::string(C.IdentifierResult->Name);
414 Completion.FilterText = Completion.Name;
415 }
416
417 // Turn absolute path into a literal string that can be #included.
418 auto Inserted = [&](llvm::StringRef Header)
419 -> llvm::Expected<std::pair<std::string, bool>> {
420 auto ResolvedDeclaring =
421 URI::resolve(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
422 if (!ResolvedDeclaring)
423 return ResolvedDeclaring.takeError();
424 auto ResolvedInserted = toHeaderFile(Header, FileName);
425 if (!ResolvedInserted)
426 return ResolvedInserted.takeError();
427 auto Spelled = Includes.calculateIncludePath(*ResolvedInserted, FileName);
428 if (!Spelled)
429 return error("Header not on include path");
430 return std::make_pair(
431 std::move(*Spelled),
432 Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
433 };
434 bool ShouldInsert =
435 C.headerToInsertIfAllowed(Opts, ContextKind).has_value();
436 Symbol::IncludeDirective Directive = insertionDirective(Opts);
437 // Calculate include paths and edits for all possible headers.
438 for (const auto &Inc : C.RankedIncludeHeaders) {
439 if ((Inc.Directive & Directive) == 0)
440 continue;
441
442 if (auto ToInclude = Inserted(Inc.Header)) {
443 CodeCompletion::IncludeCandidate Include;
444 Include.Header = ToInclude->first;
445 if (ToInclude->second && ShouldInsert)
446 Include.Insertion = Includes.insert(
447 ToInclude->first, Directive == Symbol::Import
448 ? tooling::IncludeDirective::Import
449 : tooling::IncludeDirective::Include);
450 Completion.Includes.push_back(std::move(Include));
451 } else
452 log("Failed to generate include insertion edits for adding header "
453 "(FileURI='{0}', IncludeHeader='{1}') into {2}: {3}",
454 C.IndexResult->CanonicalDeclaration.FileURI, Inc.Header, FileName,
455 ToInclude.takeError());
456 }
457 // Prefer includes that do not need edits (i.e. already exist).
458 std::stable_partition(Completion.Includes.begin(),
459 Completion.Includes.end(),
460 [](const CodeCompletion::IncludeCandidate &I) {
461 return !I.Insertion.has_value();
462 });
463 }
464
465 void add(const CompletionCandidate &C, CodeCompletionString *SemaCCS,
466 CodeCompletionContext::Kind ContextKind) {
467 assert(bool(C.SemaResult) == bool(SemaCCS));
468 Bundled.emplace_back();
469 BundledEntry &S = Bundled.back();
470 bool IsConcept = false;
471 if (C.SemaResult) {
472 getSignature(*SemaCCS, &S.Signature, &S.SnippetSuffix, C.SemaResult->Kind,
473 C.SemaResult->CursorKind,
474 /*IncludeFunctionArguments=*/C.SemaResult->FunctionCanBeCall,
475 /*RequiredQualifiers=*/&Completion.RequiredQualifier);
476 S.ReturnType = getReturnType(*SemaCCS);
477 if (C.SemaResult->Kind == CodeCompletionResult::RK_Declaration)
478 if (const auto *D = C.SemaResult->getDeclaration())
479 if (isa<ConceptDecl>(D))
480 IsConcept = true;
481 } else if (C.IndexResult) {
482 S.Signature = std::string(C.IndexResult->Signature);
483 S.SnippetSuffix = std::string(C.IndexResult->CompletionSnippetSuffix);
484 S.ReturnType = std::string(C.IndexResult->ReturnType);
485 if (C.IndexResult->SymInfo.Kind == index::SymbolKind::Concept)
486 IsConcept = true;
487 }
488
489 /// When a concept is used as a type-constraint (e.g. `Iterator auto x`),
490 /// and in some other contexts, its first type argument is not written.
491 /// Drop the parameter from the signature.
492 if (IsConcept && ContextKind == CodeCompletionContext::CCC_TopLevel) {
493 S.Signature = removeFirstTemplateArg(S.Signature);
494 // Dropping the first placeholder from the suffix will leave a $2
495 // with no $1.
496 S.SnippetSuffix = removeFirstTemplateArg(S.SnippetSuffix);
497 }
498
499 if (!Completion.Documentation) {
500 auto SetDoc = [&](llvm::StringRef Doc) {
501 if (!Doc.empty()) {
502 Completion.Documentation.emplace();
503 parseDocumentation(Doc, *Completion.Documentation);
504 }
505 };
506 if (C.IndexResult) {
507 SetDoc(C.IndexResult->Documentation);
508 } else if (C.SemaResult) {
509 const auto DocComment = getDocComment(*ASTCtx, *C.SemaResult,
510 /*CommentsFromHeaders=*/false);
511 SetDoc(formatDocumentation(*SemaCCS, DocComment));
512 }
513 }
514 if (Completion.Deprecated) {
515 if (C.SemaResult)
516 Completion.Deprecated &=
517 C.SemaResult->Availability == CXAvailability_Deprecated;
518 if (C.IndexResult)
519 Completion.Deprecated &=
520 bool(C.IndexResult->Flags & Symbol::Deprecated);
521 }
522 }
523
524 CodeCompletion build() {
525 Completion.ReturnType = summarizeReturnType();
526 Completion.Signature = summarizeSignature();
527 Completion.SnippetSuffix = summarizeSnippet();
528 Completion.BundleSize = Bundled.size();
529 return std::move(Completion);
530 }
531
532private:
533 struct BundledEntry {
534 std::string SnippetSuffix;
535 std::string Signature;
536 std::string ReturnType;
537 };
538
539 // If all BundledEntries have the same value for a property, return it.
540 template <std::string BundledEntry::*Member>
541 const std::string *onlyValue() const {
542 auto B = Bundled.begin(), E = Bundled.end();
543 for (auto *I = B + 1; I != E; ++I)
544 if (I->*Member != B->*Member)
545 return nullptr;
546 return &(B->*Member);
547 }
548
549 template <bool BundledEntry::*Member> const bool *onlyValue() const {
550 auto B = Bundled.begin(), E = Bundled.end();
551 for (auto *I = B + 1; I != E; ++I)
552 if (I->*Member != B->*Member)
553 return nullptr;
554 return &(B->*Member);
555 }
556
557 std::string summarizeReturnType() const {
558 if (auto *RT = onlyValue<&BundledEntry::ReturnType>())
559 return *RT;
560 return "";
561 }
562
563 std::string summarizeSnippet() const {
564 /// localize ArgumentLists tests for better readability
565 const bool None = ArgumentLists == Config::ArgumentListsPolicy::None;
566 const bool Open =
568 const bool Delim = ArgumentLists == Config::ArgumentListsPolicy::Delimiters;
569 const bool Full =
571 (!None && !Open && !Delim); // <-- failsafe: Full is default
572
573 if (IsUsingDeclaration)
574 return "";
575 auto *Snippet = onlyValue<&BundledEntry::SnippetSuffix>();
576 if (!Snippet)
577 // All bundles are function calls.
578 // FIXME(ibiryukov): sometimes add template arguments to a snippet, e.g.
579 // we need to complete 'forward<$1>($0)'.
580 return None ? "" : (Open ? "(" : "($0)");
581
582 if (Snippet->empty())
583 return "";
584
585 bool MayHaveArgList = Completion.Kind == CompletionItemKind::Function ||
586 Completion.Kind == CompletionItemKind::Method ||
587 Completion.Kind == CompletionItemKind::Constructor ||
588 Completion.Kind == CompletionItemKind::Text /*Macro*/;
589 // If likely arg list already exists, don't add new parens & placeholders.
590 // Snippet: function(int x, int y)
591 // func^(1,2) -> function(1, 2)
592 // NOT function(int x, int y)(1, 2)
593 if (MayHaveArgList) {
594 // Check for a template argument list in the code.
595 // Snippet: function<class T>(int x)
596 // fu^<int>(1) -> function<int>(1)
597 if (NextTokenKind == tok::less && Snippet->front() == '<')
598 return "";
599 // Potentially followed by regular argument list.
600 if (NextTokenKind == tok::l_paren) {
601 // Snippet: function<class T>(int x)
602 // fu^(1,2) -> function<class T>(1, 2)
603 if (Snippet->front() == '<') {
604 // Find matching '>', handling nested brackets.
605 int Balance = 0;
606 size_t I = 0;
607 do {
608 if (Snippet->at(I) == '>')
609 --Balance;
610 else if (Snippet->at(I) == '<')
611 ++Balance;
612 ++I;
613 } while (Balance > 0);
614 return Snippet->substr(0, I);
615 }
616 return "";
617 }
618 }
619 if (Full)
620 return *Snippet;
621
622 // Replace argument snippets with a simplified pattern.
623 if (MayHaveArgList) {
624 // Functions snippets can be of 2 types:
625 // - containing only function arguments, e.g.
626 // foo(${1:int p1}, ${2:int p2});
627 // We transform this pattern to '($0)' or '()'.
628 // - template arguments and function arguments, e.g.
629 // foo<${1:class}>(${2:int p1}).
630 // We transform this pattern to '<$1>()$0' or '<$0>()'.
631
632 bool EmptyArgs = llvm::StringRef(*Snippet).ends_with("()");
633 if (Snippet->front() == '<')
634 return None ? "" : (Open ? "<" : (EmptyArgs ? "<$1>()$0" : "<$1>($0)"));
635 if (Snippet->front() == '(')
636 return None ? "" : (Open ? "(" : (EmptyArgs ? "()" : "($0)"));
637 return *Snippet; // Not an arg snippet?
638 }
639 // 'CompletionItemKind::Interface' matches template type aliases.
640 if (Completion.Kind == CompletionItemKind::Interface ||
641 Completion.Kind == CompletionItemKind::Class ||
642 Completion.Kind == CompletionItemKind::Variable) {
643 if (Snippet->front() != '<')
644 return *Snippet; // Not an arg snippet?
645
646 // Classes and template using aliases can only have template arguments,
647 // e.g. Foo<${1:class}>.
648 if (llvm::StringRef(*Snippet).ends_with("<>"))
649 return "<>"; // can happen with defaulted template arguments.
650 return None ? "" : (Open ? "<" : "<$0>");
651 }
652 return *Snippet;
653 }
654
655 std::string summarizeSignature() const {
656 if (auto *Signature = onlyValue<&BundledEntry::Signature>())
657 return *Signature;
658 // All bundles are function calls.
659 return "(…)";
660 }
661
662 // ASTCtx can be nullptr if not run with sema.
663 ASTContext *ASTCtx;
664 CodeCompletion Completion;
665 llvm::SmallVector<BundledEntry, 1> Bundled;
666 /// the way argument lists are handled.
667 Config::ArgumentListsPolicy ArgumentLists;
668 // No snippets will be generated for using declarations and when the function
669 // arguments are already present.
670 bool IsUsingDeclaration;
671 tok::TokenKind NextTokenKind;
672};
673
674// Determine the symbol ID for a Sema code completion result, if possible.
675SymbolID getSymbolID(const CodeCompletionResult &R, const SourceManager &SM) {
676 switch (R.Kind) {
677 case CodeCompletionResult::RK_Declaration:
678 case CodeCompletionResult::RK_Pattern: {
679 // Computing USR caches linkage, which may change after code completion.
680 if (hasUnstableLinkage(R.Declaration))
681 return {};
682 return clang::clangd::getSymbolID(R.Declaration);
683 }
684 case CodeCompletionResult::RK_Macro:
685 return clang::clangd::getSymbolID(R.Macro->getName(), R.MacroDefInfo, SM);
686 case CodeCompletionResult::RK_Keyword:
687 return {};
688 }
689 llvm_unreachable("unknown CodeCompletionResult kind");
690}
691
692// Scopes of the partial identifier we're trying to complete.
693// It is used when we query the index for more completion results.
694struct SpecifiedScope {
695 // The scopes we should look in, determined by Sema.
696 //
697 // If the qualifier was fully resolved, we look for completions in these
698 // scopes; if there is an unresolved part of the qualifier, it should be
699 // resolved within these scopes.
700 //
701 // Examples of qualified completion:
702 //
703 // "::vec" => {""}
704 // "using namespace std; ::vec^" => {"", "std::"}
705 // "namespace ns {using namespace std;} ns::^" => {"ns::", "std::"}
706 // "std::vec^" => {""} // "std" unresolved
707 //
708 // Examples of unqualified completion:
709 //
710 // "vec^" => {""}
711 // "using namespace std; vec^" => {"", "std::"}
712 // "namespace ns {inline namespace ni { struct Foo {}}}
713 // using namespace ns::ni; Fo^ " => {"", "ns::ni::"}
714 // "using namespace std; namespace ns { vec^ }" => {"ns::", "std::", ""}
715 //
716 // "" for global namespace, "ns::" for normal namespace.
717 std::vector<std::string> AccessibleScopes;
718 // This is an overestimate of AccessibleScopes, e.g. it ignores inline
719 // namespaces, to fetch more relevant symbols from index.
720 std::vector<std::string> QueryScopes;
721 // The full scope qualifier as typed by the user (without the leading "::").
722 // Set if the qualifier is not fully resolved by Sema.
723 std::optional<std::string> UnresolvedQualifier;
724
725 std::optional<std::string> EnclosingNamespace;
726
727 bool AllowAllScopes = false;
728
729 // Scopes that are accessible from current context. Used for dropping
730 // unnecessary namespecifiers.
731 std::vector<std::string> scopesForQualification() {
732 std::set<std::string> Results;
733 for (llvm::StringRef AS : AccessibleScopes)
734 Results.insert(
735 (AS + (UnresolvedQualifier ? *UnresolvedQualifier : "")).str());
736 return {Results.begin(), Results.end()};
737 }
738
739 // Construct scopes being queried in indexes. The results are deduplicated.
740 // This method formats the scopes to match the index request representation.
741 std::vector<std::string> scopesForIndexQuery() {
742 // The enclosing namespace must be first, it gets a quality boost.
743 std::vector<std::string> EnclosingAtFront;
744 if (EnclosingNamespace.has_value())
745 EnclosingAtFront.push_back(*EnclosingNamespace);
746 std::set<std::string> Deduplicated;
747 for (llvm::StringRef S : QueryScopes)
748 if (S != EnclosingNamespace)
749 Deduplicated.insert((S + UnresolvedQualifier.value_or("")).str());
750
751 EnclosingAtFront.reserve(EnclosingAtFront.size() + Deduplicated.size());
752 llvm::copy(Deduplicated, std::back_inserter(EnclosingAtFront));
753
754 return EnclosingAtFront;
755 }
756};
757
758// Get all scopes that will be queried in indexes and whether symbols from
759// any scope is allowed. The first scope in the list is the preferred scope
760// (e.g. enclosing namespace).
761SpecifiedScope getQueryScopes(CodeCompletionContext &CCContext,
762 const Sema &CCSema,
763 const CompletionPrefix &HeuristicPrefix,
764 const CodeCompleteOptions &Opts) {
765 SpecifiedScope Scopes;
766 for (auto *Context : CCContext.getVisitedContexts()) {
767 if (isa<TranslationUnitDecl>(Context)) {
768 Scopes.QueryScopes.push_back("");
769 Scopes.AccessibleScopes.push_back("");
770 } else if (const auto *ND = dyn_cast<NamespaceDecl>(Context)) {
771 Scopes.QueryScopes.push_back(printNamespaceScope(*Context));
772 Scopes.AccessibleScopes.push_back(printQualifiedName(*ND) + "::");
773 }
774 }
775
776 const CXXScopeSpec *SemaSpecifier =
777 CCContext.getCXXScopeSpecifier().value_or(nullptr);
778 // Case 1: unqualified completion.
779 if (!SemaSpecifier) {
780 // Case 2 (exception): sema saw no qualifier, but there appears to be one!
781 // This can happen e.g. in incomplete macro expansions. Use heuristics.
782 if (!HeuristicPrefix.Qualifier.empty()) {
783 vlog("Sema said no scope specifier, but we saw {0} in the source code",
784 HeuristicPrefix.Qualifier);
785 StringRef SpelledSpecifier = HeuristicPrefix.Qualifier;
786 if (SpelledSpecifier.consume_front("::")) {
787 Scopes.AccessibleScopes = {""};
788 Scopes.QueryScopes = {""};
789 }
790 Scopes.UnresolvedQualifier = std::string(SpelledSpecifier);
791 return Scopes;
792 }
793 /// FIXME: When the enclosing namespace contains an inline namespace,
794 /// it's dropped here. This leads to a behavior similar to
795 /// https://github.com/clangd/clangd/issues/1451
796 Scopes.EnclosingNamespace = printNamespaceScope(*CCSema.CurContext);
797 // Allow AllScopes completion as there is no explicit scope qualifier.
798 Scopes.AllowAllScopes = Opts.AllScopes;
799 return Scopes;
800 }
801 // Case 3: sema saw and resolved a scope qualifier.
802 if (SemaSpecifier && SemaSpecifier->isValid())
803 return Scopes;
804
805 // Case 4: There was a qualifier, and Sema didn't resolve it.
806 Scopes.QueryScopes.push_back(""); // Make sure global scope is included.
807 llvm::StringRef SpelledSpecifier = Lexer::getSourceText(
808 CharSourceRange::getCharRange(SemaSpecifier->getRange()),
809 CCSema.SourceMgr, clang::LangOptions());
810 if (SpelledSpecifier.consume_front("::"))
811 Scopes.QueryScopes = {""};
812 Scopes.UnresolvedQualifier = std::string(SpelledSpecifier);
813 // Sema excludes the trailing "::".
814 if (!Scopes.UnresolvedQualifier->empty())
815 *Scopes.UnresolvedQualifier += "::";
816
817 Scopes.AccessibleScopes = Scopes.QueryScopes;
818
819 return Scopes;
820}
821
822// Should we perform index-based completion in a context of the specified kind?
823// FIXME: consider allowing completion, but restricting the result types.
824bool contextAllowsIndex(enum CodeCompletionContext::Kind K) {
825 switch (K) {
826 case CodeCompletionContext::CCC_TopLevel:
827 case CodeCompletionContext::CCC_ObjCInterface:
828 case CodeCompletionContext::CCC_ObjCImplementation:
829 case CodeCompletionContext::CCC_ObjCIvarList:
830 case CodeCompletionContext::CCC_ClassStructUnion:
831 case CodeCompletionContext::CCC_Statement:
832 case CodeCompletionContext::CCC_Expression:
833 case CodeCompletionContext::CCC_ObjCMessageReceiver:
834 case CodeCompletionContext::CCC_EnumTag:
835 case CodeCompletionContext::CCC_UnionTag:
836 case CodeCompletionContext::CCC_ClassOrStructTag:
837 case CodeCompletionContext::CCC_ObjCProtocolName:
838 case CodeCompletionContext::CCC_Namespace:
839 case CodeCompletionContext::CCC_Type:
840 case CodeCompletionContext::CCC_ParenthesizedExpression:
841 case CodeCompletionContext::CCC_ObjCInterfaceName:
842 case CodeCompletionContext::CCC_Symbol:
843 case CodeCompletionContext::CCC_SymbolOrNewName:
844 case CodeCompletionContext::CCC_ObjCClassForwardDecl:
845 case CodeCompletionContext::CCC_TopLevelOrExpression:
846 return true;
847 case CodeCompletionContext::CCC_OtherWithMacros:
848 case CodeCompletionContext::CCC_DotMemberAccess:
849 case CodeCompletionContext::CCC_ArrowMemberAccess:
850 case CodeCompletionContext::CCC_ObjCCategoryName:
851 case CodeCompletionContext::CCC_ObjCPropertyAccess:
852 case CodeCompletionContext::CCC_MacroName:
853 case CodeCompletionContext::CCC_MacroNameUse:
854 case CodeCompletionContext::CCC_PreprocessorExpression:
855 case CodeCompletionContext::CCC_PreprocessorDirective:
856 case CodeCompletionContext::CCC_SelectorName:
857 case CodeCompletionContext::CCC_TypeQualifiers:
858 case CodeCompletionContext::CCC_ObjCInstanceMessage:
859 case CodeCompletionContext::CCC_ObjCClassMessage:
860 case CodeCompletionContext::CCC_IncludedFile:
861 case CodeCompletionContext::CCC_Attribute:
862 // FIXME: Provide identifier based completions for the following contexts:
863 case CodeCompletionContext::CCC_Other: // Be conservative.
864 case CodeCompletionContext::CCC_NaturalLanguage:
865 case CodeCompletionContext::CCC_Recovery:
866 case CodeCompletionContext::CCC_NewName:
867 return false;
868 }
869 llvm_unreachable("unknown code completion context");
870}
871
872static bool isInjectedClass(const NamedDecl &D) {
873 if (auto *R = dyn_cast_or_null<RecordDecl>(&D))
874 if (R->isInjectedClassName())
875 return true;
876 return false;
877}
878
879// Some member calls are excluded because they're so rarely useful.
880static bool isExcludedMember(const NamedDecl &D) {
881 // Destructor completion is rarely useful, and works inconsistently.
882 // (s.^ completes ~string, but s.~st^ is an error).
883 if (D.getKind() == Decl::CXXDestructor)
884 return true;
885 // Injected name may be useful for A::foo(), but who writes A::A::foo()?
886 if (isInjectedClass(D))
887 return true;
888 // Explicit calls to operators are also rare.
889 auto NameKind = D.getDeclName().getNameKind();
890 if (NameKind == DeclarationName::CXXOperatorName ||
891 NameKind == DeclarationName::CXXLiteralOperatorName ||
892 NameKind == DeclarationName::CXXConversionFunctionName)
893 return true;
894 return false;
895}
896
897// The CompletionRecorder captures Sema code-complete output, including context.
898// It filters out ignored results (but doesn't apply fuzzy-filtering yet).
899// It doesn't do scoring or conversion to CompletionItem yet, as we want to
900// merge with index results first.
901// Generally the fields and methods of this object should only be used from
902// within the callback.
903struct CompletionRecorder : public CodeCompleteConsumer {
904 CompletionRecorder(const CodeCompleteOptions &Opts,
905 llvm::unique_function<void()> ResultsCallback)
906 : CodeCompleteConsumer(Opts.getClangCompleteOpts()),
907 CCContext(CodeCompletionContext::CCC_Other), Opts(Opts),
908 CCAllocator(std::make_shared<GlobalCodeCompletionAllocator>()),
909 CCTUInfo(CCAllocator), ResultsCallback(std::move(ResultsCallback)) {
910 assert(this->ResultsCallback);
911 }
912
913 std::vector<CodeCompletionResult> Results;
914 CodeCompletionContext CCContext;
915 Sema *CCSema = nullptr; // Sema that created the results.
916 // FIXME: Sema is scary. Can we store ASTContext and Preprocessor, instead?
917
918 void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context,
919 CodeCompletionResult *InResults,
920 unsigned NumResults) final {
921 // Results from recovery mode are generally useless, and the callback after
922 // recovery (if any) is usually more interesting. To make sure we handle the
923 // future callback from sema, we just ignore all callbacks in recovery mode,
924 // as taking only results from recovery mode results in poor completion
925 // results.
926 // FIXME: in case there is no future sema completion callback after the
927 // recovery mode, we might still want to provide some results (e.g. trivial
928 // identifier-based completion).
929 if (Context.getKind() == CodeCompletionContext::CCC_Recovery) {
930 log("Code complete: Ignoring sema code complete callback with Recovery "
931 "context.");
932 return;
933 }
934 // If a callback is called without any sema result and the context does not
935 // support index-based completion, we simply skip it to give way to
936 // potential future callbacks with results.
937 if (NumResults == 0 && !contextAllowsIndex(Context.getKind()))
938 return;
939 if (CCSema) {
940 log("Multiple code complete callbacks (parser backtracked?). "
941 "Dropping results from context {0}, keeping results from {1}.",
942 getCompletionKindString(Context.getKind()),
943 getCompletionKindString(this->CCContext.getKind()));
944 return;
945 }
946 // Record the completion context.
947 CCSema = &S;
948 CCContext = Context;
949
950 // Retain the results we might want.
951 for (unsigned I = 0; I < NumResults; ++I) {
952 auto &Result = InResults[I];
953 // Class members that are shadowed by subclasses are usually noise.
954 if (Result.Hidden && Result.Declaration &&
955 Result.Declaration->isCXXClassMember())
956 continue;
957 if (!Opts.IncludeIneligibleResults &&
958 (Result.Availability == CXAvailability_NotAvailable ||
959 Result.Availability == CXAvailability_NotAccessible))
960 continue;
961 if (Result.Declaration &&
962 !Context.getBaseType().isNull() // is this a member-access context?
963 && isExcludedMember(*Result.Declaration))
964 continue;
965 // Skip injected class name when no class scope is not explicitly set.
966 // E.g. show injected A::A in `using A::A^` but not in "A^".
967 if (Result.Declaration && !Context.getCXXScopeSpecifier() &&
968 isInjectedClass(*Result.Declaration))
969 continue;
970 // We choose to never append '::' to completion results in clangd.
971 Result.StartsNestedNameSpecifier = false;
972 Results.push_back(Result);
973 }
974 ResultsCallback();
975 }
976
977 CodeCompletionAllocator &getAllocator() override { return *CCAllocator; }
978 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
979
980 // Returns the filtering/sorting name for Result, which must be from Results.
981 // Returned string is owned by this recorder (or the AST).
982 llvm::StringRef getName(const CodeCompletionResult &Result) {
983 switch (Result.Kind) {
984 case CodeCompletionResult::RK_Declaration:
985 if (auto *ID = Result.Declaration->getIdentifier())
986 return ID->getName();
987 break;
988 case CodeCompletionResult::RK_Keyword:
989 return Result.Keyword;
990 case CodeCompletionResult::RK_Macro:
991 return Result.Macro->getName();
992 case CodeCompletionResult::RK_Pattern:
993 break;
994 }
995 auto *CCS = codeCompletionString(Result);
996 const CodeCompletionString::Chunk *OnlyText = nullptr;
997 for (auto &C : *CCS) {
998 if (C.Kind != CodeCompletionString::CK_TypedText)
999 continue;
1000 if (OnlyText)
1001 return CCAllocator->CopyString(CCS->getAllTypedText());
1002 OnlyText = &C;
1003 }
1004 return OnlyText ? OnlyText->Text : llvm::StringRef();
1005 }
1006
1007 // Build a CodeCompletion string for R, which must be from Results.
1008 // The CCS will be owned by this recorder.
1009 CodeCompletionString *codeCompletionString(const CodeCompletionResult &R) {
1010 // CodeCompletionResult doesn't seem to be const-correct. We own it, anyway.
1011 return const_cast<CodeCompletionResult &>(R).CreateCodeCompletionString(
1012 *CCSema, CCContext, *CCAllocator, CCTUInfo,
1013 /*IncludeBriefComments=*/false);
1014 }
1015
1016private:
1017 CodeCompleteOptions Opts;
1018 std::shared_ptr<GlobalCodeCompletionAllocator> CCAllocator;
1019 CodeCompletionTUInfo CCTUInfo;
1020 llvm::unique_function<void()> ResultsCallback;
1021};
1022
1023struct ScoredSignature {
1024 // When not null, requires documentation to be requested from the index with
1025 // this ID.
1026 SymbolID IDForDoc;
1027 SignatureInformation Signature;
1028 SignatureQualitySignals Quality;
1029};
1030
1031// Returns the index of the parameter matching argument number "Arg.
1032// This is usually just "Arg", except for variadic functions/templates, where
1033// "Arg" might be higher than the number of parameters. When that happens, we
1034// assume the last parameter is variadic and assume all further args are
1035// part of it.
1036int paramIndexForArg(const CodeCompleteConsumer::OverloadCandidate &Candidate,
1037 int Arg) {
1038 int NumParams = Candidate.getNumParams();
1039 if (auto *T = Candidate.getFunctionType()) {
1040 if (auto *Proto = T->getAs<FunctionProtoType>()) {
1041 if (Proto->isVariadic())
1042 ++NumParams;
1043 }
1044 }
1045 return std::min(Arg, std::max(NumParams - 1, 0));
1046}
1047
1048class SignatureHelpCollector final : public CodeCompleteConsumer {
1049public:
1050 SignatureHelpCollector(const clang::CodeCompleteOptions &CodeCompleteOpts,
1051 MarkupKind DocumentationFormat,
1052 const SymbolIndex *Index, SignatureHelp &SigHelp)
1053 : CodeCompleteConsumer(CodeCompleteOpts), SigHelp(SigHelp),
1054 Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
1055 CCTUInfo(Allocator), Index(Index),
1056 DocumentationFormat(DocumentationFormat) {}
1057
1058 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
1059 OverloadCandidate *Candidates,
1060 unsigned NumCandidates,
1061 SourceLocation OpenParLoc,
1062 bool Braced) override {
1063 assert(!OpenParLoc.isInvalid());
1064 SourceManager &SrcMgr = S.getSourceManager();
1065 OpenParLoc = SrcMgr.getFileLoc(OpenParLoc);
1066 if (SrcMgr.isInMainFile(OpenParLoc))
1067 SigHelp.argListStart = sourceLocToPosition(SrcMgr, OpenParLoc);
1068 else
1069 elog("Location oustide main file in signature help: {0}",
1070 OpenParLoc.printToString(SrcMgr));
1071
1072 std::vector<ScoredSignature> ScoredSignatures;
1073 SigHelp.signatures.reserve(NumCandidates);
1074 ScoredSignatures.reserve(NumCandidates);
1075 // FIXME(rwols): How can we determine the "active overload candidate"?
1076 // Right now the overloaded candidates seem to be provided in a "best fit"
1077 // order, so I'm not too worried about this.
1078 SigHelp.activeSignature = 0;
1079 assert(CurrentArg <= (unsigned)std::numeric_limits<int>::max() &&
1080 "too many arguments");
1081
1082 SigHelp.activeParameter = static_cast<int>(CurrentArg);
1083
1084 for (unsigned I = 0; I < NumCandidates; ++I) {
1085 OverloadCandidate Candidate = Candidates[I];
1086 // We want to avoid showing instantiated signatures, because they may be
1087 // long in some cases (e.g. when 'T' is substituted with 'std::string', we
1088 // would get 'std::basic_string<char>').
1089 if (auto *Func = Candidate.getFunction()) {
1090 if (auto *Pattern = Func->getTemplateInstantiationPattern())
1091 Candidate = OverloadCandidate(Pattern);
1092 }
1093 if (static_cast<int>(I) == SigHelp.activeSignature) {
1094 // The activeParameter in LSP relates to the activeSignature. There is
1095 // another, per-signature field, but we currently do not use it and not
1096 // all clients might support it.
1097 // FIXME: Add support for per-signature activeParameter field.
1098 SigHelp.activeParameter =
1099 paramIndexForArg(Candidate, SigHelp.activeParameter);
1100 }
1101
1102 const auto *CCS = Candidate.CreateSignatureString(
1103 CurrentArg, S, *Allocator, CCTUInfo,
1104 /*IncludeBriefComments=*/true, Braced);
1105 assert(CCS && "Expected the CodeCompletionString to be non-null");
1106 ScoredSignatures.push_back(processOverloadCandidate(
1107 Candidate, *CCS,
1108 Candidate.getFunction()
1109 ? getDeclComment(S.getASTContext(), *Candidate.getFunction())
1110 : ""));
1111 }
1112
1113 // Sema does not load the docs from the preamble, so we need to fetch extra
1114 // docs from the index instead.
1115 llvm::DenseMap<SymbolID, std::string> FetchedDocs;
1116 if (Index) {
1117 LookupRequest IndexRequest;
1118 for (const auto &S : ScoredSignatures) {
1119 if (!S.IDForDoc)
1120 continue;
1121 IndexRequest.IDs.insert(S.IDForDoc);
1122 }
1123 Index->lookup(IndexRequest, [&](const Symbol &S) {
1124 if (!S.Documentation.empty())
1125 FetchedDocs[S.ID] = std::string(S.Documentation);
1126 });
1127 vlog("SigHelp: requested docs for {0} symbols from the index, got {1} "
1128 "symbols with non-empty docs in the response",
1129 IndexRequest.IDs.size(), FetchedDocs.size());
1130 }
1131
1132 llvm::sort(ScoredSignatures, [](const ScoredSignature &L,
1133 const ScoredSignature &R) {
1134 // Ordering follows:
1135 // - Less number of parameters is better.
1136 // - Aggregate > Function > FunctionType > FunctionTemplate
1137 // - High score is better.
1138 // - Shorter signature is better.
1139 // - Alphabetically smaller is better.
1140 if (L.Quality.NumberOfParameters != R.Quality.NumberOfParameters)
1141 return L.Quality.NumberOfParameters < R.Quality.NumberOfParameters;
1142 if (L.Quality.NumberOfOptionalParameters !=
1143 R.Quality.NumberOfOptionalParameters)
1144 return L.Quality.NumberOfOptionalParameters <
1145 R.Quality.NumberOfOptionalParameters;
1146 if (L.Quality.Kind != R.Quality.Kind) {
1147 using OC = CodeCompleteConsumer::OverloadCandidate;
1148 auto KindPriority = [&](OC::CandidateKind K) {
1149 switch (K) {
1150 case OC::CK_Aggregate:
1151 return 0;
1152 case OC::CK_Function:
1153 return 1;
1154 case OC::CK_FunctionType:
1155 return 2;
1156 case OC::CK_FunctionProtoTypeLoc:
1157 return 3;
1158 case OC::CK_FunctionTemplate:
1159 return 4;
1160 case OC::CK_Template:
1161 return 5;
1162 }
1163 llvm_unreachable("Unknown overload candidate type.");
1164 };
1165 return KindPriority(L.Quality.Kind) < KindPriority(R.Quality.Kind);
1166 }
1167 if (L.Signature.label.size() != R.Signature.label.size())
1168 return L.Signature.label.size() < R.Signature.label.size();
1169 return L.Signature.label < R.Signature.label;
1170 });
1171
1172 for (auto &SS : ScoredSignatures) {
1173 auto IndexDocIt =
1174 SS.IDForDoc ? FetchedDocs.find(SS.IDForDoc) : FetchedDocs.end();
1175 if (IndexDocIt != FetchedDocs.end()) {
1176 markup::Document SignatureComment;
1177 parseDocumentation(IndexDocIt->second, SignatureComment);
1178 SS.Signature.documentation =
1179 renderDoc(SignatureComment, DocumentationFormat);
1180 }
1181
1182 SigHelp.signatures.push_back(std::move(SS.Signature));
1183 }
1184 }
1185
1186 GlobalCodeCompletionAllocator &getAllocator() override { return *Allocator; }
1187
1188 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
1189
1190private:
1191 void processParameterChunk(llvm::StringRef ChunkText,
1192 SignatureInformation &Signature) const {
1193 // (!) this is O(n), should still be fast compared to building ASTs.
1194 unsigned ParamStartOffset = lspLength(Signature.label);
1195 unsigned ParamEndOffset = ParamStartOffset + lspLength(ChunkText);
1196 // A piece of text that describes the parameter that corresponds to
1197 // the code-completion location within a function call, message send,
1198 // macro invocation, etc.
1199 Signature.label += ChunkText;
1200 ParameterInformation Info;
1201 Info.labelOffsets.emplace(ParamStartOffset, ParamEndOffset);
1202 // FIXME: only set 'labelOffsets' when all clients migrate out of it.
1203 Info.labelString = std::string(ChunkText);
1204
1205 Signature.parameters.push_back(std::move(Info));
1206 }
1207
1208 void processOptionalChunk(const CodeCompletionString &CCS,
1209 SignatureInformation &Signature,
1210 SignatureQualitySignals &Signal) const {
1211 for (const auto &Chunk : CCS) {
1212 switch (Chunk.Kind) {
1213 case CodeCompletionString::CK_Optional:
1214 assert(Chunk.Optional &&
1215 "Expected the optional code completion string to be non-null.");
1216 processOptionalChunk(*Chunk.Optional, Signature, Signal);
1217 break;
1218 case CodeCompletionString::CK_VerticalSpace:
1219 break;
1220 case CodeCompletionString::CK_CurrentParameter:
1221 case CodeCompletionString::CK_Placeholder:
1222 processParameterChunk(Chunk.Text, Signature);
1223 Signal.NumberOfOptionalParameters++;
1224 break;
1225 default:
1226 Signature.label += Chunk.Text;
1227 break;
1228 }
1229 }
1230 }
1231
1232 // FIXME(ioeric): consider moving CodeCompletionString logic here to
1233 // CompletionString.h.
1234 ScoredSignature processOverloadCandidate(const OverloadCandidate &Candidate,
1235 const CodeCompletionString &CCS,
1236 llvm::StringRef DocComment) const {
1237 SignatureInformation Signature;
1238 SignatureQualitySignals Signal;
1239 const char *ReturnType = nullptr;
1240
1241 markup::Document OverloadComment;
1242 parseDocumentation(formatDocumentation(CCS, DocComment), OverloadComment);
1243 Signature.documentation = renderDoc(OverloadComment, DocumentationFormat);
1244 Signal.Kind = Candidate.getKind();
1245
1246 for (const auto &Chunk : CCS) {
1247 switch (Chunk.Kind) {
1248 case CodeCompletionString::CK_ResultType:
1249 // A piece of text that describes the type of an entity or,
1250 // for functions and methods, the return type.
1251 assert(!ReturnType && "Unexpected CK_ResultType");
1252 ReturnType = Chunk.Text;
1253 break;
1254 case CodeCompletionString::CK_CurrentParameter:
1255 case CodeCompletionString::CK_Placeholder:
1256 processParameterChunk(Chunk.Text, Signature);
1257 Signal.NumberOfParameters++;
1258 break;
1259 case CodeCompletionString::CK_Optional: {
1260 // The rest of the parameters are defaulted/optional.
1261 assert(Chunk.Optional &&
1262 "Expected the optional code completion string to be non-null.");
1263 processOptionalChunk(*Chunk.Optional, Signature, Signal);
1264 break;
1265 }
1266 case CodeCompletionString::CK_VerticalSpace:
1267 break;
1268 default:
1269 Signature.label += Chunk.Text;
1270 break;
1271 }
1272 }
1273 if (ReturnType) {
1274 Signature.label += " -> ";
1275 Signature.label += ReturnType;
1276 }
1277 dlog("Signal for {0}: {1}", Signature, Signal);
1278 ScoredSignature Result;
1279 Result.Signature = std::move(Signature);
1280 Result.Quality = Signal;
1281 const FunctionDecl *Func = Candidate.getFunction();
1282 if (Func && Result.Signature.documentation.value.empty()) {
1283 // Computing USR caches linkage, which may change after code completion.
1284 if (!hasUnstableLinkage(Func))
1285 Result.IDForDoc = clangd::getSymbolID(Func);
1286 }
1287 return Result;
1288 }
1289
1290 SignatureHelp &SigHelp;
1291 std::shared_ptr<clang::GlobalCodeCompletionAllocator> Allocator;
1292 CodeCompletionTUInfo CCTUInfo;
1293 const SymbolIndex *Index;
1294 MarkupKind DocumentationFormat;
1295}; // SignatureHelpCollector
1296
1297// Used only for completion of C-style comments in function call (i.e.
1298// /*foo=*/7). Similar to SignatureHelpCollector, but needs to do less work.
1299class ParamNameCollector final : public CodeCompleteConsumer {
1300public:
1301 ParamNameCollector(const clang::CodeCompleteOptions &CodeCompleteOpts,
1302 std::set<std::string> &ParamNames)
1303 : CodeCompleteConsumer(CodeCompleteOpts),
1304 Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
1305 CCTUInfo(Allocator), ParamNames(ParamNames) {}
1306
1307 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
1308 OverloadCandidate *Candidates,
1309 unsigned NumCandidates,
1310 SourceLocation OpenParLoc,
1311 bool Braced) override {
1312 assert(CurrentArg <= (unsigned)std::numeric_limits<int>::max() &&
1313 "too many arguments");
1314
1315 for (unsigned I = 0; I < NumCandidates; ++I) {
1316 if (const NamedDecl *ND = Candidates[I].getParamDecl(CurrentArg))
1317 if (const auto *II = ND->getIdentifier())
1318 ParamNames.emplace(II->getName());
1319 }
1320 }
1321
1322private:
1323 GlobalCodeCompletionAllocator &getAllocator() override { return *Allocator; }
1324
1325 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
1326
1327 std::shared_ptr<clang::GlobalCodeCompletionAllocator> Allocator;
1328 CodeCompletionTUInfo CCTUInfo;
1329 std::set<std::string> &ParamNames;
1330};
1331
1332struct SemaCompleteInput {
1334 size_t Offset;
1335 const PreambleData &Preamble;
1336 const std::optional<PreamblePatch> Patch;
1337 const ParseInputs &ParseInput;
1338};
1339
1340void loadMainFilePreambleMacros(const Preprocessor &PP,
1341 const PreambleData &Preamble) {
1342 // The ExternalPreprocessorSource has our macros, if we know where to look.
1343 // We can read all the macros using PreambleMacros->ReadDefinedMacros(),
1344 // but this includes transitively included files, so may deserialize a lot.
1345 ExternalPreprocessorSource *PreambleMacros = PP.getExternalSource();
1346 // As we have the names of the macros, we can look up their IdentifierInfo
1347 // and then use this to load just the macros we want.
1348 const auto &ITable = PP.getIdentifierTable();
1349 IdentifierInfoLookup *PreambleIdentifiers =
1350 ITable.getExternalIdentifierLookup();
1351
1352 if (!PreambleIdentifiers || !PreambleMacros)
1353 return;
1354 for (const auto &MacroName : Preamble.Macros.Names) {
1355 if (ITable.find(MacroName.getKey()) != ITable.end())
1356 continue;
1357 if (auto *II = PreambleIdentifiers->get(MacroName.getKey()))
1358 if (II->isOutOfDate())
1359 PreambleMacros->updateOutOfDateIdentifier(*II);
1360 }
1361}
1362
1363// Invokes Sema code completion on a file.
1364// If \p Includes is set, it will be updated based on the compiler invocation.
1365bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
1366 const clang::CodeCompleteOptions &Options,
1367 const SemaCompleteInput &Input,
1368 IncludeStructure *Includes = nullptr) {
1369 trace::Span Tracer("Sema completion");
1370
1371 IgnoreDiagnostics IgnoreDiags;
1372 auto CI = buildCompilerInvocation(Input.ParseInput, IgnoreDiags);
1373 if (!CI) {
1374 elog("Couldn't create CompilerInvocation");
1375 return false;
1376 }
1377 auto &FrontendOpts = CI->getFrontendOpts();
1378 FrontendOpts.SkipFunctionBodies = true;
1379 // Disable typo correction in Sema.
1380 CI->getLangOpts().SpellChecking = false;
1381 // Code completion won't trigger in delayed template bodies.
1382 // This is on-by-default in windows to allow parsing SDK headers; we're only
1383 // disabling it for the main-file (not preamble).
1384 CI->getLangOpts().DelayedTemplateParsing = false;
1385 // Setup code completion.
1386 FrontendOpts.CodeCompleteOpts = Options;
1387 FrontendOpts.CodeCompletionAt.FileName = std::string(Input.FileName);
1388 std::tie(FrontendOpts.CodeCompletionAt.Line,
1389 FrontendOpts.CodeCompletionAt.Column) =
1390 offsetToClangLineColumn(Input.ParseInput.Contents, Input.Offset);
1391
1392 std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
1393 llvm::MemoryBuffer::getMemBuffer(Input.ParseInput.Contents,
1394 Input.FileName);
1395 // The diagnostic options must be set before creating a CompilerInstance.
1396 CI->getDiagnosticOpts().IgnoreWarnings = true;
1397 // We reuse the preamble whether it's valid or not. This is a
1398 // correctness/performance tradeoff: building without a preamble is slow, and
1399 // completion is latency-sensitive.
1400 // However, if we're completing *inside* the preamble section of the draft,
1401 // overriding the preamble will break sema completion. Fortunately we can just
1402 // skip all includes in this case; these completions are really simple.
1403 PreambleBounds PreambleRegion =
1404 ComputePreambleBounds(CI->getLangOpts(), *ContentsBuffer, 0);
1405 bool CompletingInPreamble = Input.Offset < PreambleRegion.Size ||
1406 (!PreambleRegion.PreambleEndsAtStartOfLine &&
1407 Input.Offset == PreambleRegion.Size);
1408 if (Input.Patch)
1409 Input.Patch->apply(*CI);
1410 // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise
1411 // the remapped buffers do not get freed.
1412 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1413 Input.ParseInput.TFS->view(Input.ParseInput.CompileCommand.Directory);
1414 if (Input.Preamble.StatCache)
1415 VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS));
1417 std::move(CI), !CompletingInPreamble ? &Input.Preamble.Preamble : nullptr,
1418 std::move(ContentsBuffer), std::move(VFS), IgnoreDiags);
1419 Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble;
1420 Clang->setCodeCompletionConsumer(Consumer.release());
1421
1422 if (Input.Preamble.RequiredModules)
1423 Input.Preamble.RequiredModules->adjustHeaderSearchOptions(Clang->getHeaderSearchOpts());
1424
1426 if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
1427 log("BeginSourceFile() failed when running codeComplete for {0}",
1428 Input.FileName);
1429 return false;
1430 }
1431 // Macros can be defined within the preamble region of the main file.
1432 // They don't fall nicely into our index/Sema dichotomy:
1433 // - they're not indexed for completion (they're not available across files)
1434 // - but Sema code complete won't see them: as part of the preamble, they're
1435 // deserialized only when mentioned.
1436 // Force them to be deserialized so SemaCodeComplete sees them.
1437 loadMainFilePreambleMacros(Clang->getPreprocessor(), Input.Preamble);
1438 if (Includes)
1439 Includes->collect(*Clang);
1440 if (llvm::Error Err = Action.Execute()) {
1441 log("Execute() failed when running codeComplete for {0}: {1}",
1442 Input.FileName, toString(std::move(Err)));
1443 return false;
1444 }
1445 Action.EndSourceFile();
1446
1447 return true;
1448}
1449
1450// Should we allow index completions in the specified context?
1451bool allowIndex(CodeCompletionContext &CC) {
1452 if (!contextAllowsIndex(CC.getKind()))
1453 return false;
1454 // We also avoid ClassName::bar (but allow namespace::bar).
1455 auto Scope = CC.getCXXScopeSpecifier();
1456 if (!Scope)
1457 return true;
1458 NestedNameSpecifier *NameSpec = (*Scope)->getScopeRep();
1459 if (!NameSpec)
1460 return true;
1461 // We only query the index when qualifier is a namespace.
1462 // If it's a class, we rely solely on sema completions.
1463 switch (NameSpec->getKind()) {
1464 case NestedNameSpecifier::Global:
1465 case NestedNameSpecifier::Namespace:
1466 case NestedNameSpecifier::NamespaceAlias:
1467 return true;
1468 case NestedNameSpecifier::Super:
1469 case NestedNameSpecifier::TypeSpec:
1470 case NestedNameSpecifier::TypeSpecWithTemplate:
1471 // Unresolved inside a template.
1472 case NestedNameSpecifier::Identifier:
1473 return false;
1474 }
1475 llvm_unreachable("invalid NestedNameSpecifier kind");
1476}
1477
1478// Should we include a symbol from the index given the completion kind?
1479// FIXME: Ideally we can filter in the fuzzy find request itself.
1480bool includeSymbolFromIndex(CodeCompletionContext::Kind Kind,
1481 const Symbol &Sym) {
1482 // Objective-C protocols are only useful in ObjC protocol completions,
1483 // in other places they're confusing, especially when they share the same
1484 // identifier with a class.
1485 if (Sym.SymInfo.Kind == index::SymbolKind::Protocol &&
1486 Sym.SymInfo.Lang == index::SymbolLanguage::ObjC)
1487 return Kind == CodeCompletionContext::CCC_ObjCProtocolName;
1488 else if (Kind == CodeCompletionContext::CCC_ObjCProtocolName)
1489 // Don't show anything else in ObjC protocol completions.
1490 return false;
1491
1492 if (Kind == CodeCompletionContext::CCC_ObjCClassForwardDecl)
1493 return Sym.SymInfo.Kind == index::SymbolKind::Class &&
1494 Sym.SymInfo.Lang == index::SymbolLanguage::ObjC;
1495 return true;
1496}
1497
1498std::future<std::pair<bool, SymbolSlab>>
1499startAsyncFuzzyFind(const SymbolIndex &Index, const FuzzyFindRequest &Req) {
1500 return runAsync<std::pair<bool, SymbolSlab>>([&Index, Req]() {
1501 trace::Span Tracer("Async fuzzyFind");
1502 SymbolSlab::Builder Syms;
1503 bool Incomplete =
1504 Index.fuzzyFind(Req, [&Syms](const Symbol &Sym) { Syms.insert(Sym); });
1505 return std::make_pair(Incomplete, std::move(Syms).build());
1506 });
1507}
1508
1509// Creates a `FuzzyFindRequest` based on the cached index request from the
1510// last completion, if any, and the speculated completion filter text in the
1511// source code.
1512FuzzyFindRequest speculativeFuzzyFindRequestForCompletion(
1513 FuzzyFindRequest CachedReq, const CompletionPrefix &HeuristicPrefix) {
1514 CachedReq.Query = std::string(HeuristicPrefix.Name);
1515 return CachedReq;
1516}
1517
1518// This function is similar to Lexer::findNextToken(), but assumes
1519// that the input SourceLocation is the completion point (which is
1520// a case findNextToken() does not handle).
1521std::optional<Token>
1522findTokenAfterCompletionPoint(SourceLocation CompletionPoint,
1523 const SourceManager &SM,
1524 const LangOptions &LangOpts) {
1525 SourceLocation Loc = CompletionPoint;
1526 if (Loc.isMacroID()) {
1527 if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
1528 return std::nullopt;
1529 }
1530
1531 // Advance to the next SourceLocation after the completion point.
1532 // Lexer::findNextToken() would call MeasureTokenLength() here,
1533 // which does not handle the completion point (and can't, because
1534 // the Lexer instance it constructs internally doesn't have a
1535 // Preprocessor and so doesn't know about the completion point).
1536 Loc = Loc.getLocWithOffset(1);
1537
1538 // Break down the source location.
1539 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
1540
1541 // Try to load the file buffer.
1542 bool InvalidTemp = false;
1543 StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
1544 if (InvalidTemp)
1545 return std::nullopt;
1546
1547 const char *TokenBegin = File.data() + LocInfo.second;
1548
1549 // Lex from the start of the given location.
1550 Lexer TheLexer(SM.getLocForStartOfFile(LocInfo.first), LangOpts, File.begin(),
1551 TokenBegin, File.end());
1552 // Find the token.
1553 Token Tok;
1554 TheLexer.LexFromRawLexer(Tok);
1555 return Tok;
1556}
1557
1558// Runs Sema-based (AST) and Index-based completion, returns merged results.
1559//
1560// There are a few tricky considerations:
1561// - the AST provides information needed for the index query (e.g. which
1562// namespaces to search in). So Sema must start first.
1563// - we only want to return the top results (Opts.Limit).
1564// Building CompletionItems for everything else is wasteful, so we want to
1565// preserve the "native" format until we're done with scoring.
1566// - the data underlying Sema completion items is owned by the AST and various
1567// other arenas, which must stay alive for us to build CompletionItems.
1568// - we may get duplicate results from Sema and the Index, we need to merge.
1569//
1570// So we start Sema completion first, and do all our work in its callback.
1571// We use the Sema context information to query the index.
1572// Then we merge the two result sets, producing items that are Sema/Index/Both.
1573// These items are scored, and the top N are synthesized into the LSP response.
1574// Finally, we can clean up the data structures created by Sema completion.
1575//
1576// Main collaborators are:
1577// - semaCodeComplete sets up the compiler machinery to run code completion.
1578// - CompletionRecorder captures Sema completion results, including context.
1579// - SymbolIndex (Opts.Index) provides index completion results as Symbols
1580// - CompletionCandidates are the result of merging Sema and Index results.
1581// Each candidate points to an underlying CodeCompletionResult (Sema), a
1582// Symbol (Index), or both. It computes the result quality score.
1583// CompletionCandidate also does conversion to CompletionItem (at the end).
1584// - FuzzyMatcher scores how the candidate matches the partial identifier.
1585// This score is combined with the result quality score for the final score.
1586// - TopN determines the results with the best score.
1587class CodeCompleteFlow {
1589 IncludeStructure Includes; // Complete once the compiler runs.
1590 SpeculativeFuzzyFind *SpecFuzzyFind; // Can be nullptr.
1591 const CodeCompleteOptions &Opts;
1592
1593 // Sema takes ownership of Recorder. Recorder is valid until Sema cleanup.
1594 CompletionRecorder *Recorder = nullptr;
1595 CodeCompletionContext::Kind CCContextKind = CodeCompletionContext::CCC_Other;
1596 bool IsUsingDeclaration = false;
1597 // The snippets will not be generated if the token following completion
1598 // location is an opening parenthesis (tok::l_paren) because this would add
1599 // extra parenthesis.
1600 tok::TokenKind NextTokenKind = tok::eof;
1601 // Counters for logging.
1602 int NSema = 0, NIndex = 0, NSemaAndIndex = 0, NIdent = 0;
1603 bool Incomplete = false; // Would more be available with a higher limit?
1604 CompletionPrefix HeuristicPrefix;
1605 std::optional<FuzzyMatcher> Filter; // Initialized once Sema runs.
1606 Range ReplacedRange;
1607 std::vector<std::string> QueryScopes; // Initialized once Sema runs.
1608 std::vector<std::string> AccessibleScopes; // Initialized once Sema runs.
1609 // Initialized once QueryScopes is initialized, if there are scopes.
1610 std::optional<ScopeDistance> ScopeProximity;
1611 std::optional<OpaqueType> PreferredType; // Initialized once Sema runs.
1612 // Whether to query symbols from any scope. Initialized once Sema runs.
1613 bool AllScopes = false;
1614 llvm::StringSet<> ContextWords;
1615 // Include-insertion and proximity scoring rely on the include structure.
1616 // This is available after Sema has run.
1617 std::optional<IncludeInserter> Inserter; // Available during runWithSema.
1618 std::optional<URIDistance> FileProximity; // Initialized once Sema runs.
1619 /// Speculative request based on the cached request and the filter text before
1620 /// the cursor.
1621 /// Initialized right before sema run. This is only set if `SpecFuzzyFind` is
1622 /// set and contains a cached request.
1623 std::optional<FuzzyFindRequest> SpecReq;
1624
1625public:
1626 // A CodeCompleteFlow object is only useful for calling run() exactly once.
1627 CodeCompleteFlow(PathRef FileName, const IncludeStructure &Includes,
1628 SpeculativeFuzzyFind *SpecFuzzyFind,
1629 const CodeCompleteOptions &Opts)
1630 : FileName(FileName), Includes(Includes), SpecFuzzyFind(SpecFuzzyFind),
1631 Opts(Opts) {}
1632
1633 CodeCompleteResult run(const SemaCompleteInput &SemaCCInput) && {
1634 trace::Span Tracer("CodeCompleteFlow");
1635 HeuristicPrefix = guessCompletionPrefix(SemaCCInput.ParseInput.Contents,
1636 SemaCCInput.Offset);
1637 populateContextWords(SemaCCInput.ParseInput.Contents);
1638 if (Opts.Index && SpecFuzzyFind && SpecFuzzyFind->CachedReq) {
1639 assert(!SpecFuzzyFind->Result.valid());
1640 SpecReq = speculativeFuzzyFindRequestForCompletion(
1641 *SpecFuzzyFind->CachedReq, HeuristicPrefix);
1642 SpecFuzzyFind->Result = startAsyncFuzzyFind(*Opts.Index, *SpecReq);
1643 }
1644
1645 // We run Sema code completion first. It builds an AST and calculates:
1646 // - completion results based on the AST.
1647 // - partial identifier and context. We need these for the index query.
1648 CodeCompleteResult Output;
1649 auto RecorderOwner = std::make_unique<CompletionRecorder>(Opts, [&]() {
1650 assert(Recorder && "Recorder is not set");
1651 CCContextKind = Recorder->CCContext.getKind();
1652 IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
1653 auto Style = getFormatStyleForFile(SemaCCInput.FileName,
1654 SemaCCInput.ParseInput.Contents,
1655 *SemaCCInput.ParseInput.TFS, false);
1656 const auto NextToken = findTokenAfterCompletionPoint(
1657 Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(),
1658 Recorder->CCSema->getSourceManager(), Recorder->CCSema->LangOpts);
1659 if (NextToken)
1660 NextTokenKind = NextToken->getKind();
1661 // If preprocessor was run, inclusions from preprocessor callback should
1662 // already be added to Includes.
1663 Inserter.emplace(
1664 SemaCCInput.FileName, SemaCCInput.ParseInput.Contents, Style,
1665 SemaCCInput.ParseInput.CompileCommand.Directory,
1666 &Recorder->CCSema->getPreprocessor().getHeaderSearchInfo(),
1669 for (const auto &Inc : Includes.MainFileIncludes)
1670 Inserter->addExisting(Inc);
1671
1672 // Most of the cost of file proximity is in initializing the FileDistance
1673 // structures based on the observed includes, once per query. Conceptually
1674 // that happens here (though the per-URI-scheme initialization is lazy).
1675 // The per-result proximity scoring is (amortized) very cheap.
1676 FileDistanceOptions ProxOpts{}; // Use defaults.
1677 const auto &SM = Recorder->CCSema->getSourceManager();
1678 llvm::StringMap<SourceParams> ProxSources;
1679 auto MainFileID =
1680 Includes.getID(SM.getFileEntryForID(SM.getMainFileID()));
1681 assert(MainFileID);
1682 for (auto &HeaderIDAndDepth : Includes.includeDepth(*MainFileID)) {
1683 auto &Source =
1684 ProxSources[Includes.getRealPath(HeaderIDAndDepth.getFirst())];
1685 Source.Cost = HeaderIDAndDepth.getSecond() * ProxOpts.IncludeCost;
1686 // Symbols near our transitive includes are good, but only consider
1687 // things in the same directory or below it. Otherwise there can be
1688 // many false positives.
1689 if (HeaderIDAndDepth.getSecond() > 0)
1690 Source.MaxUpTraversals = 1;
1691 }
1692 FileProximity.emplace(ProxSources, ProxOpts);
1693
1694 Output = runWithSema();
1695 Inserter.reset(); // Make sure this doesn't out-live Clang.
1696 SPAN_ATTACH(Tracer, "sema_completion_kind",
1697 getCompletionKindString(CCContextKind));
1698 log("Code complete: sema context {0}, query scopes [{1}] (AnyScope={2}), "
1699 "expected type {3}{4}",
1700 getCompletionKindString(CCContextKind),
1701 llvm::join(QueryScopes.begin(), QueryScopes.end(), ","), AllScopes,
1702 PreferredType ? Recorder->CCContext.getPreferredType().getAsString()
1703 : "<none>",
1704 IsUsingDeclaration ? ", inside using declaration" : "");
1705 });
1706
1707 Recorder = RecorderOwner.get();
1708
1709 semaCodeComplete(std::move(RecorderOwner), Opts.getClangCompleteOpts(),
1710 SemaCCInput, &Includes);
1711 logResults(Output, Tracer);
1712 return Output;
1713 }
1714
1715 void logResults(const CodeCompleteResult &Output, const trace::Span &Tracer) {
1716 SPAN_ATTACH(Tracer, "sema_results", NSema);
1717 SPAN_ATTACH(Tracer, "index_results", NIndex);
1718 SPAN_ATTACH(Tracer, "merged_results", NSemaAndIndex);
1719 SPAN_ATTACH(Tracer, "identifier_results", NIdent);
1720 SPAN_ATTACH(Tracer, "returned_results", int64_t(Output.Completions.size()));
1721 SPAN_ATTACH(Tracer, "incomplete", Output.HasMore);
1722 log("Code complete: {0} results from Sema, {1} from Index, "
1723 "{2} matched, {3} from identifiers, {4} returned{5}.",
1724 NSema, NIndex, NSemaAndIndex, NIdent, Output.Completions.size(),
1725 Output.HasMore ? " (incomplete)" : "");
1726 assert(!Opts.Limit || Output.Completions.size() <= Opts.Limit);
1727 // We don't assert that isIncomplete means we hit a limit.
1728 // Indexes may choose to impose their own limits even if we don't have one.
1729 }
1730
1731 CodeCompleteResult runWithoutSema(llvm::StringRef Content, size_t Offset,
1732 const ThreadsafeFS &TFS) && {
1733 trace::Span Tracer("CodeCompleteWithoutSema");
1734 // Fill in fields normally set by runWithSema()
1735 HeuristicPrefix = guessCompletionPrefix(Content, Offset);
1736 populateContextWords(Content);
1737 CCContextKind = CodeCompletionContext::CCC_Recovery;
1738 IsUsingDeclaration = false;
1739 Filter = FuzzyMatcher(HeuristicPrefix.Name);
1740 auto Pos = offsetToPosition(Content, Offset);
1741 ReplacedRange.start = ReplacedRange.end = Pos;
1742 ReplacedRange.start.character -= HeuristicPrefix.Name.size();
1743
1744 llvm::StringMap<SourceParams> ProxSources;
1745 ProxSources[FileName].Cost = 0;
1746 FileProximity.emplace(ProxSources);
1747
1748 auto Style = getFormatStyleForFile(FileName, Content, TFS, false);
1749 // This will only insert verbatim headers.
1750 Inserter.emplace(FileName, Content, Style,
1751 /*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr,
1752 Config::current().Style.QuotedHeaders,
1754
1755 auto Identifiers = collectIdentifiers(Content, Style);
1756 std::vector<RawIdentifier> IdentifierResults;
1757 for (const auto &IDAndCount : Identifiers) {
1758 RawIdentifier ID;
1759 ID.Name = IDAndCount.first();
1760 ID.References = IDAndCount.second;
1761 // Avoid treating typed filter as an identifier.
1762 if (ID.Name == HeuristicPrefix.Name)
1763 --ID.References;
1764 if (ID.References > 0)
1765 IdentifierResults.push_back(std::move(ID));
1766 }
1767
1768 // Simplified version of getQueryScopes():
1769 // - accessible scopes are determined heuristically.
1770 // - all-scopes query if no qualifier was typed (and it's allowed).
1771 SpecifiedScope Scopes;
1772 Scopes.QueryScopes = visibleNamespaces(
1773 Content.take_front(Offset), format::getFormattingLangOpts(Style));
1774 for (std::string &S : Scopes.QueryScopes)
1775 if (!S.empty())
1776 S.append("::"); // visibleNamespaces doesn't include trailing ::.
1777 if (HeuristicPrefix.Qualifier.empty())
1778 AllScopes = Opts.AllScopes;
1779 else if (HeuristicPrefix.Qualifier.starts_with("::")) {
1780 Scopes.QueryScopes = {""};
1781 Scopes.UnresolvedQualifier =
1782 std::string(HeuristicPrefix.Qualifier.drop_front(2));
1783 } else
1784 Scopes.UnresolvedQualifier = std::string(HeuristicPrefix.Qualifier);
1785 // First scope is the (modified) enclosing scope.
1786 QueryScopes = Scopes.scopesForIndexQuery();
1788 ScopeProximity.emplace(QueryScopes);
1789
1790 SymbolSlab IndexResults = Opts.Index ? queryIndex() : SymbolSlab();
1791
1792 CodeCompleteResult Output = toCodeCompleteResult(mergeResults(
1793 /*SemaResults=*/{}, IndexResults, IdentifierResults));
1794 Output.RanParser = false;
1795 logResults(Output, Tracer);
1796 return Output;
1797 }
1798
1799private:
1800 void populateContextWords(llvm::StringRef Content) {
1801 // Take last 3 lines before the completion point.
1802 unsigned RangeEnd = HeuristicPrefix.Qualifier.begin() - Content.data(),
1803 RangeBegin = RangeEnd;
1804 for (size_t I = 0; I < 3 && RangeBegin > 0; ++I) {
1805 auto PrevNL = Content.rfind('\n', RangeBegin);
1806 if (PrevNL == StringRef::npos) {
1807 RangeBegin = 0;
1808 break;
1809 }
1810 RangeBegin = PrevNL;
1811 }
1812
1813 ContextWords = collectWords(Content.slice(RangeBegin, RangeEnd));
1814 dlog("Completion context words: {0}",
1815 llvm::join(ContextWords.keys(), ", "));
1816 }
1817
1818 // This is called by run() once Sema code completion is done, but before the
1819 // Sema data structures are torn down. It does all the real work.
1820 CodeCompleteResult runWithSema() {
1821 const auto &CodeCompletionRange = CharSourceRange::getCharRange(
1822 Recorder->CCSema->getPreprocessor().getCodeCompletionTokenRange());
1823 // When we are getting completions with an empty identifier, for example
1824 // std::vector<int> asdf;
1825 // asdf.^;
1826 // Then the range will be invalid and we will be doing insertion, use
1827 // current cursor position in such cases as range.
1828 if (CodeCompletionRange.isValid()) {
1829 ReplacedRange = halfOpenToRange(Recorder->CCSema->getSourceManager(),
1830 CodeCompletionRange);
1831 } else {
1832 const auto &Pos = sourceLocToPosition(
1833 Recorder->CCSema->getSourceManager(),
1834 Recorder->CCSema->getPreprocessor().getCodeCompletionLoc());
1835 ReplacedRange.start = ReplacedRange.end = Pos;
1836 }
1837 Filter = FuzzyMatcher(
1838 Recorder->CCSema->getPreprocessor().getCodeCompletionFilter());
1839 auto SpecifiedScopes = getQueryScopes(
1840 Recorder->CCContext, *Recorder->CCSema, HeuristicPrefix, Opts);
1841
1842 QueryScopes = SpecifiedScopes.scopesForIndexQuery();
1843 AccessibleScopes = SpecifiedScopes.scopesForQualification();
1844 AllScopes = SpecifiedScopes.AllowAllScopes;
1845 if (!QueryScopes.empty())
1846 ScopeProximity.emplace(QueryScopes);
1847 PreferredType =
1848 OpaqueType::fromType(Recorder->CCSema->getASTContext(),
1849 Recorder->CCContext.getPreferredType());
1850 // Sema provides the needed context to query the index.
1851 // FIXME: in addition to querying for extra/overlapping symbols, we should
1852 // explicitly request symbols corresponding to Sema results.
1853 // We can use their signals even if the index can't suggest them.
1854 // We must copy index results to preserve them, but there are at most Limit.
1855 auto IndexResults = (Opts.Index && allowIndex(Recorder->CCContext))
1856 ? queryIndex()
1857 : SymbolSlab();
1858 trace::Span Tracer("Populate CodeCompleteResult");
1859 // Merge Sema and Index results, score them, and pick the winners.
1860 auto Top =
1861 mergeResults(Recorder->Results, IndexResults, /*Identifiers*/ {});
1862 return toCodeCompleteResult(Top);
1863 }
1864
1865 CodeCompleteResult
1866 toCodeCompleteResult(const std::vector<ScoredBundle> &Scored) {
1867 CodeCompleteResult Output;
1868
1869 // Convert the results to final form, assembling the expensive strings.
1870 for (auto &C : Scored) {
1871 Output.Completions.push_back(toCodeCompletion(C.first));
1872 Output.Completions.back().Score = C.second;
1873 Output.Completions.back().CompletionTokenRange = ReplacedRange;
1874 }
1875 Output.HasMore = Incomplete;
1876 Output.Context = CCContextKind;
1877 Output.CompletionRange = ReplacedRange;
1878 return Output;
1879 }
1880
1881 SymbolSlab queryIndex() {
1882 trace::Span Tracer("Query index");
1883 SPAN_ATTACH(Tracer, "limit", int64_t(Opts.Limit));
1884
1885 // Build the query.
1886 FuzzyFindRequest Req;
1887 if (Opts.Limit)
1888 Req.Limit = Opts.Limit;
1889 Req.Query = std::string(Filter->pattern());
1890 Req.RestrictForCodeCompletion = true;
1891 Req.Scopes = QueryScopes;
1892 Req.AnyScope = AllScopes;
1893 // FIXME: we should send multiple weighted paths here.
1894 Req.ProximityPaths.push_back(std::string(FileName));
1895 if (PreferredType)
1896 Req.PreferredTypes.push_back(std::string(PreferredType->raw()));
1897 vlog("Code complete: fuzzyFind({0:2})", toJSON(Req));
1898
1899 if (SpecFuzzyFind)
1900 SpecFuzzyFind->NewReq = Req;
1901 if (SpecFuzzyFind && SpecFuzzyFind->Result.valid() && (*SpecReq == Req)) {
1902 vlog("Code complete: speculative fuzzy request matches the actual index "
1903 "request. Waiting for the speculative index results.");
1904 SPAN_ATTACH(Tracer, "Speculative results", true);
1905
1906 trace::Span WaitSpec("Wait speculative results");
1907 auto SpecRes = SpecFuzzyFind->Result.get();
1908 Incomplete |= SpecRes.first;
1909 return std::move(SpecRes.second);
1910 }
1911
1912 SPAN_ATTACH(Tracer, "Speculative results", false);
1913
1914 // Run the query against the index.
1915 SymbolSlab::Builder ResultsBuilder;
1916 Incomplete |= Opts.Index->fuzzyFind(
1917 Req, [&](const Symbol &Sym) { ResultsBuilder.insert(Sym); });
1918 return std::move(ResultsBuilder).build();
1919 }
1920
1921 // Merges Sema and Index results where possible, to form CompletionCandidates.
1922 // \p Identifiers is raw identifiers that can also be completion candidates.
1923 // Identifiers are not merged with results from index or sema.
1924 // Groups overloads if desired, to form CompletionCandidate::Bundles. The
1925 // bundles are scored and top results are returned, best to worst.
1926 std::vector<ScoredBundle>
1927 mergeResults(const std::vector<CodeCompletionResult> &SemaResults,
1928 const SymbolSlab &IndexResults,
1929 const std::vector<RawIdentifier> &IdentifierResults) {
1930 trace::Span Tracer("Merge and score results");
1931 std::vector<CompletionCandidate::Bundle> Bundles;
1932 llvm::DenseMap<size_t, size_t> BundleLookup;
1933 auto AddToBundles = [&](const CodeCompletionResult *SemaResult,
1934 const Symbol *IndexResult,
1935 const RawIdentifier *IdentifierResult) {
1936 CompletionCandidate C;
1937 C.SemaResult = SemaResult;
1938 C.IndexResult = IndexResult;
1939 C.IdentifierResult = IdentifierResult;
1940 if (C.IndexResult) {
1941 C.Name = IndexResult->Name;
1942 C.RankedIncludeHeaders = getRankedIncludes(*C.IndexResult);
1943 } else if (C.SemaResult) {
1944 C.Name = Recorder->getName(*SemaResult);
1945 } else {
1946 assert(IdentifierResult);
1947 C.Name = IdentifierResult->Name;
1948 }
1949 if (auto OverloadSet = C.overloadSet(
1950 Opts, FileName, Inserter ? &*Inserter : nullptr, CCContextKind)) {
1951 auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
1952 if (Ret.second)
1953 Bundles.emplace_back();
1954 Bundles[Ret.first->second].push_back(std::move(C));
1955 } else {
1956 Bundles.emplace_back();
1957 Bundles.back().push_back(std::move(C));
1958 }
1959 };
1960 llvm::DenseSet<const Symbol *> UsedIndexResults;
1961 auto CorrespondingIndexResult =
1962 [&](const CodeCompletionResult &SemaResult) -> const Symbol * {
1963 if (auto SymID =
1964 getSymbolID(SemaResult, Recorder->CCSema->getSourceManager())) {
1965 auto I = IndexResults.find(SymID);
1966 if (I != IndexResults.end()) {
1967 UsedIndexResults.insert(&*I);
1968 return &*I;
1969 }
1970 }
1971 return nullptr;
1972 };
1973 // Emit all Sema results, merging them with Index results if possible.
1974 for (auto &SemaResult : SemaResults)
1975 AddToBundles(&SemaResult, CorrespondingIndexResult(SemaResult), nullptr);
1976 // Now emit any Index-only results.
1977 for (const auto &IndexResult : IndexResults) {
1978 if (UsedIndexResults.count(&IndexResult))
1979 continue;
1980 if (!includeSymbolFromIndex(CCContextKind, IndexResult))
1981 continue;
1982 AddToBundles(/*SemaResult=*/nullptr, &IndexResult, nullptr);
1983 }
1984 // Emit identifier results.
1985 for (const auto &Ident : IdentifierResults)
1986 AddToBundles(/*SemaResult=*/nullptr, /*IndexResult=*/nullptr, &Ident);
1987 // We only keep the best N results at any time, in "native" format.
1988 TopN<ScoredBundle, ScoredBundleGreater> Top(
1989 Opts.Limit == 0 ? std::numeric_limits<size_t>::max() : Opts.Limit);
1990 for (auto &Bundle : Bundles)
1991 addCandidate(Top, std::move(Bundle));
1992 return std::move(Top).items();
1993 }
1994
1995 std::optional<float> fuzzyScore(const CompletionCandidate &C) {
1996 // Macros can be very spammy, so we only support prefix completion.
1997 if (((C.SemaResult &&
1998 C.SemaResult->Kind == CodeCompletionResult::RK_Macro) ||
1999 (C.IndexResult &&
2000 C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro)) &&
2001 !C.Name.starts_with_insensitive(Filter->pattern()))
2002 return std::nullopt;
2003 return Filter->match(C.Name);
2004 }
2005
2006 CodeCompletion::Scores
2007 evaluateCompletion(const SymbolQualitySignals &Quality,
2008 const SymbolRelevanceSignals &Relevance) {
2010 CodeCompletion::Scores Scores;
2011 switch (Opts.RankingModel) {
2012 case RM::Heuristics:
2013 Scores.Quality = Quality.evaluateHeuristics();
2014 Scores.Relevance = Relevance.evaluateHeuristics();
2015 Scores.Total =
2016 evaluateSymbolAndRelevance(Scores.Quality, Scores.Relevance);
2017 // NameMatch is in fact a multiplier on total score, so rescoring is
2018 // sound.
2019 Scores.ExcludingName =
2020 Relevance.NameMatch > std::numeric_limits<float>::epsilon()
2021 ? Scores.Total / Relevance.NameMatch
2022 : Scores.Quality;
2023 return Scores;
2024
2025 case RM::DecisionForest:
2026 DecisionForestScores DFScores = Opts.DecisionForestScorer(
2027 Quality, Relevance, Opts.DecisionForestBase);
2028 Scores.ExcludingName = DFScores.ExcludingName;
2029 Scores.Total = DFScores.Total;
2030 return Scores;
2031 }
2032 llvm_unreachable("Unhandled CodeCompletion ranking model.");
2033 }
2034
2035 // Scores a candidate and adds it to the TopN structure.
2036 void addCandidate(TopN<ScoredBundle, ScoredBundleGreater> &Candidates,
2037 CompletionCandidate::Bundle Bundle) {
2038 SymbolQualitySignals Quality;
2039 SymbolRelevanceSignals Relevance;
2040 Relevance.Context = CCContextKind;
2041 Relevance.Name = Bundle.front().Name;
2042 Relevance.FilterLength = HeuristicPrefix.Name.size();
2043 Relevance.Query = SymbolRelevanceSignals::CodeComplete;
2044 Relevance.FileProximityMatch = &*FileProximity;
2045 if (ScopeProximity)
2046 Relevance.ScopeProximityMatch = &*ScopeProximity;
2047 if (PreferredType)
2048 Relevance.HadContextType = true;
2049 Relevance.ContextWords = &ContextWords;
2050 Relevance.MainFileSignals = Opts.MainFileSignals;
2051
2052 auto &First = Bundle.front();
2053 if (auto FuzzyScore = fuzzyScore(First))
2054 Relevance.NameMatch = *FuzzyScore;
2055 else
2056 return;
2058 bool FromIndex = false;
2059 for (const auto &Candidate : Bundle) {
2060 if (Candidate.IndexResult) {
2061 Quality.merge(*Candidate.IndexResult);
2062 Relevance.merge(*Candidate.IndexResult);
2063 Origin |= Candidate.IndexResult->Origin;
2064 FromIndex = true;
2065 if (!Candidate.IndexResult->Type.empty())
2066 Relevance.HadSymbolType |= true;
2067 if (PreferredType &&
2068 PreferredType->raw() == Candidate.IndexResult->Type) {
2069 Relevance.TypeMatchesPreferred = true;
2070 }
2071 }
2072 if (Candidate.SemaResult) {
2073 Quality.merge(*Candidate.SemaResult);
2074 Relevance.merge(*Candidate.SemaResult);
2075 if (PreferredType) {
2076 if (auto CompletionType = OpaqueType::fromCompletionResult(
2077 Recorder->CCSema->getASTContext(), *Candidate.SemaResult)) {
2078 Relevance.HadSymbolType |= true;
2079 if (PreferredType == CompletionType)
2080 Relevance.TypeMatchesPreferred = true;
2081 }
2082 }
2083 Origin |= SymbolOrigin::AST;
2084 }
2085 if (Candidate.IdentifierResult) {
2086 Quality.References = Candidate.IdentifierResult->References;
2087 Relevance.Scope = SymbolRelevanceSignals::FileScope;
2088 Origin |= SymbolOrigin::Identifier;
2089 }
2090 }
2091
2092 CodeCompletion::Scores Scores = evaluateCompletion(Quality, Relevance);
2093 if (Opts.RecordCCResult)
2094 Opts.RecordCCResult(toCodeCompletion(Bundle), Quality, Relevance,
2095 Scores.Total);
2096
2097 dlog("CodeComplete: {0} ({1}) = {2}\n{3}{4}\n", First.Name,
2098 llvm::to_string(Origin), Scores.Total, llvm::to_string(Quality),
2099 llvm::to_string(Relevance));
2100
2101 NSema += bool(Origin & SymbolOrigin::AST);
2102 NIndex += FromIndex;
2103 NSemaAndIndex += bool(Origin & SymbolOrigin::AST) && FromIndex;
2104 NIdent += bool(Origin & SymbolOrigin::Identifier);
2105 if (Candidates.push({std::move(Bundle), Scores}))
2106 Incomplete = true;
2107 }
2108
2109 CodeCompletion toCodeCompletion(const CompletionCandidate::Bundle &Bundle) {
2110 std::optional<CodeCompletionBuilder> Builder;
2111 for (const auto &Item : Bundle) {
2112 CodeCompletionString *SemaCCS =
2113 Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
2114 : nullptr;
2115 if (!Builder)
2116 Builder.emplace(Recorder ? &Recorder->CCSema->getASTContext() : nullptr,
2117 Item, SemaCCS, AccessibleScopes, *Inserter, FileName,
2118 CCContextKind, Opts, IsUsingDeclaration, NextTokenKind);
2119 else
2120 Builder->add(Item, SemaCCS, CCContextKind);
2121 }
2122 return Builder->build();
2123 }
2124};
2125
2126} // namespace
2127
2128clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
2129 clang::CodeCompleteOptions Result;
2130 Result.IncludeCodePatterns = EnableSnippets;
2131 Result.IncludeMacros = true;
2132 Result.IncludeGlobals = true;
2133 // We choose to include full comments and not do doxygen parsing in
2134 // completion.
2135 // FIXME: ideally, we should support doxygen in some form, e.g. do markdown
2136 // formatting of the comments.
2137 Result.IncludeBriefComments = false;
2138
2139 // When an is used, Sema is responsible for completing the main file,
2140 // the index can provide results from the preamble.
2141 // Tell Sema not to deserialize the preamble to look for results.
2142 Result.LoadExternal = ForceLoadPreamble || !Index;
2143 Result.IncludeFixIts = IncludeFixIts;
2144
2145 return Result;
2146}
2147
2149 unsigned Offset) {
2150 assert(Offset <= Content.size());
2151 StringRef Rest = Content.take_front(Offset);
2152 CompletionPrefix Result;
2153
2154 // Consume the unqualified name. We only handle ASCII characters.
2155 // isAsciiIdentifierContinue will let us match "0invalid", but we don't mind.
2156 while (!Rest.empty() && isAsciiIdentifierContinue(Rest.back()))
2157 Rest = Rest.drop_back();
2158 Result.Name = Content.slice(Rest.size(), Offset);
2159
2160 // Consume qualifiers.
2161 while (Rest.consume_back("::") && !Rest.ends_with(":")) // reject ::::
2162 while (!Rest.empty() && isAsciiIdentifierContinue(Rest.back()))
2163 Rest = Rest.drop_back();
2164 Result.Qualifier =
2165 Content.slice(Rest.size(), Result.Name.begin() - Content.begin());
2166
2167 return Result;
2168}
2169
2170// Code complete the argument name on "/*" inside function call.
2171// Offset should be pointing to the start of the comment, i.e.:
2172// foo(^/*, rather than foo(/*^) where the cursor probably is.
2174 llvm::StringRef Prefix,
2175 const PreambleData *Preamble,
2176 const ParseInputs &ParseInput) {
2177 if (Preamble == nullptr) // Can't run without Sema.
2178 return CodeCompleteResult();
2179
2180 clang::CodeCompleteOptions Options;
2181 Options.IncludeGlobals = false;
2182 Options.IncludeMacros = false;
2183 Options.IncludeCodePatterns = false;
2184 Options.IncludeBriefComments = false;
2185 std::set<std::string> ParamNames;
2186 // We want to see signatures coming from newly introduced includes, hence a
2187 // full patch.
2188 semaCodeComplete(
2189 std::make_unique<ParamNameCollector>(Options, ParamNames), Options,
2191 PreamblePatch::createFullPatch(FileName, ParseInput, *Preamble),
2192 ParseInput});
2193 if (ParamNames.empty())
2194 return CodeCompleteResult();
2195
2196 CodeCompleteResult Result;
2197 Range CompletionRange;
2198 // Skip /*
2199 Offset += 2;
2200 CompletionRange.start = offsetToPosition(ParseInput.Contents, Offset);
2201 CompletionRange.end =
2202 offsetToPosition(ParseInput.Contents, Offset + Prefix.size());
2203 Result.CompletionRange = CompletionRange;
2204 Result.Context = CodeCompletionContext::CCC_NaturalLanguage;
2205 for (llvm::StringRef Name : ParamNames) {
2206 if (!Name.starts_with(Prefix))
2207 continue;
2208 CodeCompletion Item;
2209 Item.Name = Name.str() + "=*/";
2210 Item.FilterText = Item.Name;
2211 Item.Kind = CompletionItemKind::Text;
2212 Item.CompletionTokenRange = CompletionRange;
2213 Item.Origin = SymbolOrigin::AST;
2214 Result.Completions.push_back(Item);
2215 }
2216
2217 return Result;
2218}
2219
2220// If Offset is inside what looks like argument comment (e.g.
2221// "/*^" or "/* foo^"), returns new offset pointing to the start of the /*
2222// (place where semaCodeComplete should run).
2223std::optional<unsigned>
2224maybeFunctionArgumentCommentStart(llvm::StringRef Content) {
2225 while (!Content.empty() && isAsciiIdentifierContinue(Content.back()))
2226 Content = Content.drop_back();
2227 Content = Content.rtrim();
2228 if (Content.ends_with("/*"))
2229 return Content.size() - 2;
2230 return std::nullopt;
2231}
2232
2234 const PreambleData *Preamble,
2235 const ParseInputs &ParseInput,
2237 SpeculativeFuzzyFind *SpecFuzzyFind) {
2238 auto Offset = positionToOffset(ParseInput.Contents, Pos);
2239 if (!Offset) {
2240 elog("Code completion position was invalid {0}", Offset.takeError());
2241 return CodeCompleteResult();
2242 }
2243
2244 auto Content = llvm::StringRef(ParseInput.Contents).take_front(*Offset);
2245 if (auto OffsetBeforeComment = maybeFunctionArgumentCommentStart(Content)) {
2246 // We are doing code completion of a comment, where we currently only
2247 // support completing param names in function calls. To do this, we
2248 // require information from Sema, but Sema's comment completion stops at
2249 // parsing, so we must move back the position before running it, extract
2250 // information we need and construct completion items ourselves.
2251 auto CommentPrefix = Content.substr(*OffsetBeforeComment + 2).trim();
2252 return codeCompleteComment(FileName, *OffsetBeforeComment, CommentPrefix,
2254 }
2255
2256 auto Flow = CodeCompleteFlow(
2257 FileName, Preamble ? Preamble->Includes : IncludeStructure(),
2258 SpecFuzzyFind, Opts);
2259 return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse)
2260 ? std::move(Flow).runWithoutSema(ParseInput.Contents, *Offset,
2261 *ParseInput.TFS)
2262 : std::move(Flow).run({FileName, *Offset, *Preamble,
2263 /*PreamblePatch=*/
2264 PreamblePatch::createMacroPatch(
2266 ParseInput});
2267}
2268
2270 const PreambleData &Preamble,
2271 const ParseInputs &ParseInput,
2272 MarkupKind DocumentationFormat) {
2273 auto Offset = positionToOffset(ParseInput.Contents, Pos);
2274 if (!Offset) {
2275 elog("Signature help position was invalid {0}", Offset.takeError());
2276 return SignatureHelp();
2277 }
2278 SignatureHelp Result;
2279 clang::CodeCompleteOptions Options;
2280 Options.IncludeGlobals = false;
2281 Options.IncludeMacros = false;
2282 Options.IncludeCodePatterns = false;
2283 Options.IncludeBriefComments = false;
2284 semaCodeComplete(
2285 std::make_unique<SignatureHelpCollector>(Options, DocumentationFormat,
2286 ParseInput.Index, Result),
2287 Options,
2288 {FileName, *Offset, Preamble,
2289 PreamblePatch::createFullPatch(FileName, ParseInput, Preamble),
2290 ParseInput});
2291 return Result;
2292}
2293
2294bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx) {
2295 auto InTopLevelScope = [](const NamedDecl &ND) {
2296 switch (ND.getDeclContext()->getDeclKind()) {
2297 case Decl::TranslationUnit:
2298 case Decl::Namespace:
2299 case Decl::LinkageSpec:
2300 return true;
2301 default:
2302 break;
2303 };
2304 return false;
2305 };
2306 auto InClassScope = [](const NamedDecl &ND) {
2307 return ND.getDeclContext()->getDeclKind() == Decl::CXXRecord;
2308 };
2309 // We only complete symbol's name, which is the same as the name of the
2310 // *primary* template in case of template specializations.
2312 return false;
2313
2314 // Category decls are not useful on their own outside the interface or
2315 // implementation blocks. Moreover, sema already provides completion for
2316 // these, even if it requires preamble deserialization. So by excluding them
2317 // from the index, we reduce the noise in all the other completion scopes.
2318 if (llvm::isa<ObjCCategoryDecl>(&ND) || llvm::isa<ObjCCategoryImplDecl>(&ND))
2319 return false;
2320
2321 if (InTopLevelScope(ND))
2322 return true;
2323
2324 // Always index enum constants, even if they're not in the top level scope:
2325 // when
2326 // --all-scopes-completion is set, we'll want to complete those as well.
2327 if (const auto *EnumDecl = dyn_cast<clang::EnumDecl>(ND.getDeclContext()))
2328 return (InTopLevelScope(*EnumDecl) || InClassScope(*EnumDecl));
2329
2330 return false;
2331}
2332
2333CompletionItem CodeCompletion::render(const CodeCompleteOptions &Opts) const {
2334 CompletionItem LSP;
2335 const auto *InsertInclude = Includes.empty() ? nullptr : &Includes[0];
2336 // We could move our indicators from label into labelDetails->description.
2337 // In VSCode there are rendering issues that prevent these being aligned.
2338 LSP.label = ((InsertInclude && InsertInclude->Insertion)
2339 ? Opts.IncludeIndicator.Insert
2340 : Opts.IncludeIndicator.NoInsert) +
2341 (Opts.ShowOrigins ? "[" + llvm::to_string(Origin) + "]" : "") +
2342 RequiredQualifier + Name;
2343 LSP.labelDetails.emplace();
2344 LSP.labelDetails->detail = Signature;
2345
2346 LSP.kind = Kind;
2347 LSP.detail = BundleSize > 1
2348 ? std::string(llvm::formatv("[{0} overloads]", BundleSize))
2349 : ReturnType;
2350 LSP.deprecated = Deprecated;
2351 // Combine header information and documentation in LSP `documentation` field.
2352 // This is not quite right semantically, but tends to display well in editors.
2353 if (InsertInclude || Documentation) {
2354 markup::Document Doc;
2355 if (InsertInclude)
2356 Doc.addParagraph().appendText("From ").appendCode(InsertInclude->Header);
2357 if (Documentation)
2358 Doc.append(*Documentation);
2359 LSP.documentation = renderDoc(Doc, Opts.DocumentationFormat);
2360 }
2361 LSP.sortText = sortText(Score.Total, FilterText);
2362 LSP.filterText = FilterText;
2363 LSP.textEdit = {CompletionTokenRange, RequiredQualifier + Name, ""};
2364 // Merge continuous additionalTextEdits into main edit. The main motivation
2365 // behind this is to help LSP clients, it seems most of them are confused when
2366 // they are provided with additionalTextEdits that are consecutive to main
2367 // edit.
2368 // Note that we store additional text edits from back to front in a line. That
2369 // is mainly to help LSP clients again, so that changes do not effect each
2370 // other.
2371 for (const auto &FixIt : FixIts) {
2372 if (FixIt.range.end == LSP.textEdit->range.start) {
2373 LSP.textEdit->newText = FixIt.newText + LSP.textEdit->newText;
2374 LSP.textEdit->range.start = FixIt.range.start;
2375 } else {
2376 LSP.additionalTextEdits.push_back(FixIt);
2377 }
2378 }
2379 if (Opts.EnableSnippets)
2380 LSP.textEdit->newText += SnippetSuffix;
2381
2382 // FIXME(kadircet): Do not even fill insertText after making sure textEdit is
2383 // compatible with most of the editors.
2384 LSP.insertText = LSP.textEdit->newText;
2385 // Some clients support snippets but work better with plaintext.
2386 // So if the snippet is trivial, let the client know.
2387 // https://github.com/clangd/clangd/issues/922
2388 LSP.insertTextFormat = (Opts.EnableSnippets && !SnippetSuffix.empty())
2389 ? InsertTextFormat::Snippet
2390 : InsertTextFormat::PlainText;
2391 if (InsertInclude && InsertInclude->Insertion)
2392 LSP.additionalTextEdits.push_back(*InsertInclude->Insertion);
2393
2394 LSP.score = Score.ExcludingName;
2395
2396 return LSP;
2397}
2398
2399llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const CodeCompletion &C) {
2400 // For now just lean on CompletionItem.
2401 return OS << C.render(CodeCompleteOptions());
2402}
2403
2404llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
2405 const CodeCompleteResult &R) {
2406 OS << "CodeCompleteResult: " << R.Completions.size() << (R.HasMore ? "+" : "")
2407 << " (" << getCompletionKindString(R.Context) << ")"
2408 << " items:\n";
2409 for (const auto &C : R.Completions)
2410 OS << C << "\n";
2411 return OS;
2412}
2413
2414// Heuristically detect whether the `Line` is an unterminated include filename.
2415bool isIncludeFile(llvm::StringRef Line) {
2416 Line = Line.ltrim();
2417 if (!Line.consume_front("#"))
2418 return false;
2419 Line = Line.ltrim();
2420 if (!(Line.consume_front("include_next") || Line.consume_front("include") ||
2421 Line.consume_front("import")))
2422 return false;
2423 Line = Line.ltrim();
2424 if (Line.consume_front("<"))
2425 return Line.count('>') == 0;
2426 if (Line.consume_front("\""))
2427 return Line.count('"') == 0;
2428 return false;
2429}
2430
2431bool allowImplicitCompletion(llvm::StringRef Content, unsigned Offset) {
2432 // Look at last line before completion point only.
2433 Content = Content.take_front(Offset);
2434 auto Pos = Content.rfind('\n');
2435 if (Pos != llvm::StringRef::npos)
2436 Content = Content.substr(Pos + 1);
2437
2438 // Complete after scope operators.
2439 if (Content.ends_with(".") || Content.ends_with("->") ||
2440 Content.ends_with("::") || Content.ends_with("/*"))
2441 return true;
2442 // Complete after `#include <` and #include `<foo/`.
2443 if ((Content.ends_with("<") || Content.ends_with("\"") ||
2444 Content.ends_with("/")) &&
2445 isIncludeFile(Content))
2446 return true;
2447
2448 // Complete words. Give non-ascii characters the benefit of the doubt.
2449 return !Content.empty() && (isAsciiIdentifierContinue(Content.back()) ||
2450 !llvm::isASCII(Content.back()));
2451}
2452
2453} // namespace clangd
2454} // namespace clang
const Expr * E
const FunctionDecl * Decl
BindArgumentKind Kind
unsigned Line
Definition: Bracket.cpp:77
llvm::SmallString< 256U > Name
unsigned References
const ParseInputs & ParseInput
std::string Signature
std::vector< std::string > AccessibleScopes
std::optional< std::string > UnresolvedQualifier
CodeCompletionContext CCContext
size_t Offset
llvm::SmallVector< SymbolInclude, 1 > RankedIncludeHeaders
const RawIdentifier * IdentifierResult
const Symbol * IndexResult
std::vector< std::string > QueryScopes
SymbolID IDForDoc
std::vector< CodeCompletionResult > Results
std::string ReturnType
Sema * CCSema
std::optional< std::string > EnclosingNamespace
const std::optional< PreamblePatch > Patch
bool AllowAllScopes
std::string SnippetSuffix
SignatureQualitySignals Quality
const PreambleData & Preamble
const CodeCompletionResult * SemaResult
CodeCompletionBuilder Builder
llvm::raw_ostream & OS
const Criteria C
CognitiveComplexity CC
ExpectedMatch Candidate
std::optional< float > Score
IgnoringDiagConsumer IgnoreDiags
std::unique_ptr< CompilerInstance > Clang
CharSourceRange Range
SourceRange for the file name.
StringRef FileName
SourceLocation Loc
int X
#define dlog(...)
Definition: Logger.h:101
const MacroDirective * Directive
FieldAction Action
size_t Pos
std::string MacroName
Definition: Preamble.cpp:240
Kind K
Definition: Rename.cpp:474
std::unique_ptr< CompilerInvocation > CI
std::string Output
Definition: TraceTests.cpp:159
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Definition: Trace.h:164
std::optional< FixItHint > FixIt
void collect(const CompilerInstance &CI)
Definition: Headers.cpp:178
static std::optional< OpaqueType > fromCompletionResult(ASTContext &Ctx, const CodeCompletionResult &R)
Create a type from a code completion result.
static std::optional< OpaqueType > fromType(ASTContext &Ctx, QualType Type)
Construct an instance from a clang::QualType.
static llvm::Expected< std::string > resolve(const URI &U, llvm::StringRef HintPath="")
Resolves the absolute path of U.
Definition: URI.cpp:244
A format-agnostic representation for structured text.
Definition: Markup.h:97
Paragraph & addParagraph()
Adds a semantical block that will be separate from others.
Definition: Markup.cpp:473
void append(Document Other)
Definition: Markup.cpp:468
Paragraph & appendText(llvm::StringRef Text)
Append plain text to the end of the string.
Definition: Markup.cpp:423
Paragraph & appendCode(llvm::StringRef Code, bool Preserve=false)
Append inline code, this translates to the ` block in markdown.
Definition: Markup.cpp:436
std::pair< StringRef, StringRef > splitQualifiedName(StringRef QName)
Definition: SourceCode.cpp:497
@ Info
An information message.
SymbolID getSymbolID(const Decl *D)
Gets the symbol ID for a declaration. Returned SymbolID might be null.
Definition: AST.cpp:331
std::string formatDocumentation(const CodeCompletionString &CCS, llvm::StringRef DocComment)
Assembles formatted documentation for a completion result.
Range halfOpenToRange(const SourceManager &SM, CharSourceRange R)
Definition: SourceCode.cpp:472
std::string sortText(float Score, llvm::StringRef Name)
Returns a string that sorts in the same order as (-Score, Tiebreak), for LSP.
Definition: Quality.cpp:549
std::string getDeclComment(const ASTContext &Ctx, const NamedDecl &Decl)
Similar to getDocComment, but returns the comment for a NamedDecl.
bool isIncludeFile(llvm::StringRef Line)
TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, const LangOptions &L)
Definition: SourceCode.cpp:556
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
Definition: SourceCode.cpp:202
size_t lspLength(llvm::StringRef Code)
Definition: SourceCode.cpp:149
CompletionPrefix guessCompletionPrefix(llvm::StringRef Content, unsigned Offset)
std::unique_ptr< CompilerInvocation > buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, std::vector< std::string > *CC1Args)
Builds compiler invocation that could be used to build AST or preamble.
Definition: Compiler.cpp:95
bool isExplicitTemplateSpecialization(const NamedDecl *D)
Indicates if D is an explicit template specialization, e.g.
Definition: AST.cpp:163
CompletionItemKind
The kind of a completion entry.
Definition: Protocol.h:338
bool allowImplicitCompletion(llvm::StringRef Content, unsigned Offset)
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:72
static const char * toString(OffsetEncoding OE)
Definition: Protocol.cpp:1595
CodeCompleteResult codeCompleteComment(PathRef FileName, unsigned Offset, llvm::StringRef Prefix, const PreambleData *Preamble, const ParseInputs &ParseInput)
llvm::Error error(std::error_code EC, const char *Fmt, Ts &&... Vals)
Definition: Logger.h:79
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
std::string getReturnType(const CodeCompletionString &CCS)
Gets detail to be used as the detail field in an LSP completion item.
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc)
Turn a SourceLocation into a [line, column] pair.
Definition: SourceCode.cpp:214
llvm::StringMap< unsigned > collectIdentifiers(llvm::StringRef Content, const format::FormatStyle &Style)
Collects identifiers with counts in the source code.
Definition: SourceCode.cpp:632
bool hasUnstableLinkage(const Decl *D)
Whether we must avoid computing linkage for D during code completion.
Definition: AST.cpp:699
llvm::json::Value toJSON(const FuzzyFindRequest &Request)
Definition: Index.cpp:45
std::vector< std::string > visibleNamespaces(llvm::StringRef Code, const LangOptions &LangOpts)
Heuristically determine namespaces visible at a point, without parsing Code.
Definition: SourceCode.cpp:823
llvm::Expected< HeaderFile > toHeaderFile(llvm::StringRef Header, llvm::StringRef HintPath)
Creates a HeaderFile from Header which can be either a URI or a literal include.
Definition: Headers.cpp:143
std::unique_ptr< CompilerInstance > prepareCompilerInstance(std::unique_ptr< clang::CompilerInvocation > CI, const PrecompiledPreamble *Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, DiagnosticConsumer &DiagsClient)
Definition: Compiler.cpp:129
void log(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:67
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
Definition: SourceCode.cpp:173
std::optional< unsigned > maybeFunctionArgumentCommentStart(llvm::StringRef Content)
llvm::StringSet collectWords(llvm::StringRef Content)
Collects words from the source code.
Definition: SourceCode.cpp:871
void getSignature(const CodeCompletionString &CCS, std::string *Signature, std::string *Snippet, CodeCompletionResult::ResultKind ResultKind, CXCursorKind CursorKind, bool IncludeFunctionArguments, std::string *RequiredQualifiers)
Formats the signature for an item, as a display string and snippet.
llvm::SmallVector< SymbolInclude, 1 > getRankedIncludes(const Symbol &Sym)
Definition: Headers.cpp:163
std::pair< size_t, size_t > offsetToClangLineColumn(llvm::StringRef Code, size_t Offset)
Definition: SourceCode.cpp:487
@ Deprecated
Deprecated or obsolete code.
Definition: Protocol.h:908
@ Full
Documents are synced by always sending the full content of the document.
void parseDocumentation(llvm::StringRef Input, markup::Document &Output)
Definition: Hover.cpp:1619
float evaluateSymbolAndRelevance(float SymbolQuality, float SymbolRelevance)
Combine symbol quality and relevance into a single score.
Definition: Quality.cpp:531
CodeCompleteResult codeComplete(PathRef FileName, Position Pos, const PreambleData *Preamble, const ParseInputs &ParseInput, CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind)
Gets code completions at a specified Pos in FileName.
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
Definition: AST.cpp:182
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:29
SignatureHelp signatureHelp(PathRef FileName, Position Pos, const PreambleData &Preamble, const ParseInputs &ParseInput, MarkupKind DocumentationFormat)
Get signature help at a specified Pos in FileName.
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:61
std::string getDocComment(const ASTContext &Ctx, const CodeCompletionResult &Result, bool CommentsFromHeaders)
Gets a minimally formatted documentation comment of Result, with comment markers stripped.
std::string printNamespaceScope(const DeclContext &DC)
Returns the first enclosing namespace scope starting from DC.
Definition: AST.cpp:280
bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx)
format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, const ThreadsafeFS &TFS, bool FormatFile)
Choose the clang-format style we should apply to a certain file.
Definition: SourceCode.cpp:583
std::array< uint8_t, 20 > SymbolID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
-clang-tidy
Symbol::IncludeDirective InsertionDirective
Preferred preprocessor directive to use for inclusions by the file.
Definition: ASTSignals.h:34
static const CodeCompletionRankingModel DefaultRankingModel
Definition: CodeComplete.h:144
CodeCompletionRankingModel
Model to use for ranking code completion candidates.
Definition: CodeComplete.h:140
const ASTSignals * MainFileSignals
Definition: CodeComplete.h:100
bool ImportInsertions
Whether include insertions for Objective-C code should use #import instead of #include.
Definition: CodeComplete.h:81
bool AllScopes
Whether to include index symbols that are not defined in the scopes visible from the code completion ...
Definition: CodeComplete.h:110
std::vector< CodeCompletion > Completions
Definition: CodeComplete.h:252
CodeCompletionContext::Kind Context
Definition: CodeComplete.h:254
Range CompletionTokenRange
Holds the range of the token we are going to replace with this completion.
Definition: CodeComplete.h:219
std::string sortText
A string that should be used when comparing this item with other items.
Definition: Protocol.h:1312
std::optional< TextEdit > textEdit
An edit which is applied to a document when selecting this completion.
Definition: Protocol.h:1331
std::string filterText
A string that should be used when filtering a set of completion items.
Definition: Protocol.h:1316
std::string detail
A human-readable string with additional information about this item, like type or symbol information.
Definition: Protocol.h:1305
InsertTextFormat insertTextFormat
The format of the insert text.
Definition: Protocol.h:1324
CompletionItemKind kind
The kind of this completion item.
Definition: Protocol.h:1301
std::vector< TextEdit > additionalTextEdits
An optional array of additional text edits that are applied when selecting this completion.
Definition: Protocol.h:1336
std::optional< MarkupContent > documentation
A human-readable string that represents a doc-comment.
Definition: Protocol.h:1308
std::string insertText
A string that should be inserted to a document when selecting this completion.
Definition: Protocol.h:1320
bool deprecated
Indicates if this item is deprecated.
Definition: Protocol.h:1339
std::optional< CompletionItemLabelDetails > labelDetails
Additional details for the label.
Definition: Protocol.h:1297
float score
The score that clangd calculates to rank the returned completions.
Definition: Protocol.h:1346
std::string label
The label of this completion item.
Definition: Protocol.h:1294
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
Definition: Config.cpp:17
ArgumentListsPolicy
controls the completion options for argument lists.
Definition: Config.h:134
@ None
nothing, no argument list and also NO Delimiters "()" or "<>".
@ Delimiters
empty pair of delimiters "()" or "<>".
@ OpenDelimiter
open, only opening delimiter "(" or "<".
@ FullPlaceholders
full name of both type and variable.
struct clang::clangd::Config::@5 Style
Style of the codebase.
std::vector< std::function< bool(llvm::StringRef)> > QuotedHeaders
Definition: Config.h:129
std::vector< std::function< bool(llvm::StringRef)> > AngledHeaders
Definition: Config.h:130
Information required to run clang, e.g. to parse AST or do code completion.
Definition: Compiler.h:49
The parsed preamble and associated data.
Definition: Preamble.h:97
Position start
The range's start position.
Definition: Protocol.h:187
Position end
The range's end position.
Definition: Protocol.h:190
Represents the signature of a callable.
Definition: Protocol.h:1410
A speculative and asynchronous fuzzy find index request (based on cached request) that can be sent be...
Definition: CodeComplete.h:269
@ Deprecated
Indicates if the symbol is deprecated.
Definition: Symbol.h:143
@ Include
#include "header.h"
Definition: Symbol.h:93
@ Import
#import "header.h"
Definition: Symbol.h:95