clang-tools 10.0.0

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"
22 #include "CodeCompletionStrings.h"
23 #include "Compiler.h"
24 #include "Diagnostics.h"
25 #include "ExpectedTypes.h"
26 #include "FileDistance.h"
27 #include "FuzzyMatch.h"
28 #include "Headers.h"
29 #include "Logger.h"
30 #include "Preamble.h"
31 #include "Protocol.h"
32 #include "Quality.h"
33 #include "SourceCode.h"
34 #include "TUScheduler.h"
35 #include "Threading.h"
36 #include "Trace.h"
37 #include "URI.h"
38 #include "index/Index.h"
39 #include "index/Symbol.h"
40 #include "index/SymbolOrigin.h"
41 #include "clang/AST/Decl.h"
42 #include "clang/AST/DeclBase.h"
43 #include "clang/Basic/CharInfo.h"
44 #include "clang/Basic/LangOptions.h"
45 #include "clang/Basic/SourceLocation.h"
46 #include "clang/Format/Format.h"
47 #include "clang/Frontend/CompilerInstance.h"
48 #include "clang/Frontend/FrontendActions.h"
49 #include "clang/Lex/ExternalPreprocessorSource.h"
50 #include "clang/Lex/Preprocessor.h"
51 #include "clang/Lex/PreprocessorOptions.h"
52 #include "clang/Sema/CodeCompleteConsumer.h"
53 #include "clang/Sema/DeclSpec.h"
54 #include "clang/Sema/Sema.h"
55 #include "llvm/ADT/ArrayRef.h"
56 #include "llvm/ADT/None.h"
57 #include "llvm/ADT/Optional.h"
58 #include "llvm/ADT/SmallVector.h"
59 #include "llvm/ADT/StringExtras.h"
60 #include "llvm/ADT/StringRef.h"
61 #include "llvm/Support/Compiler.h"
62 #include "llvm/Support/Debug.h"
63 #include "llvm/Support/Error.h"
64 #include "llvm/Support/Format.h"
65 #include "llvm/Support/FormatVariadic.h"
66 #include "llvm/Support/ScopedPrinter.h"
67 #include <algorithm>
68 #include <iterator>
69
70 // We log detailed candidate here if you run with -debug-only=codecomplete.
71 #define DEBUG_TYPE "CodeComplete"
72
73 namespace clang {
74 namespace clangd {
75 namespace {
76
77 CompletionItemKind toCompletionItemKind(index::SymbolKind Kind) {
78 using SK = index::SymbolKind;
79 switch (Kind) {
80 case SK::Unknown:
81 return CompletionItemKind::Missing;
82 case SK::Module:
83 case SK::Namespace:
84 case SK::NamespaceAlias:
85 return CompletionItemKind::Module;
86 case SK::Macro:
87 return CompletionItemKind::Text;
88 case SK::Enum:
89 return CompletionItemKind::Enum;
90 // FIXME(ioeric): use LSP struct instead of class when it is suppoted in the
91 // protocol.
92 case SK::Struct:
93 case SK::Class:
94 case SK::Protocol:
95 case SK::Extension:
96 case SK::Union:
97 return CompletionItemKind::Class;
98 case SK::TypeAlias:
99 // We use the same kind as the VSCode C++ extension.
100 // FIXME: pick a better option when we have one.
101 return CompletionItemKind::Interface;
102 case SK::Using:
103 return CompletionItemKind::Reference;
104 case SK::Function:
105 // FIXME(ioeric): this should probably be an operator. This should be fixed
106 // when `Operator` is support type in the protocol.
107 case SK::ConversionFunction:
108 return CompletionItemKind::Function;
109 case SK::Variable:
110 case SK::Parameter:
111 return CompletionItemKind::Variable;
112 case SK::Field:
113 return CompletionItemKind::Field;
114 // FIXME(ioeric): use LSP enum constant when it is supported in the protocol.
115 case SK::EnumConstant:
116 return CompletionItemKind::Value;
117 case SK::InstanceMethod:
118 case SK::ClassMethod:
119 case SK::StaticMethod:
120 case SK::Destructor:
121 return CompletionItemKind::Method;
122 case SK::InstanceProperty:
123 case SK::ClassProperty:
124 case SK::StaticProperty:
125 return CompletionItemKind::Property;
126 case SK::Constructor:
127 return CompletionItemKind::Constructor;
128 }
129 llvm_unreachable("Unhandled clang::index::SymbolKind.");
130 }
131
132 CompletionItemKind
133 toCompletionItemKind(CodeCompletionResult::ResultKind ResKind,
134 const NamedDecl *Decl,
135 CodeCompletionContext::Kind CtxKind) {
136 if (Decl)
137 return toCompletionItemKind(index::getSymbolInfo(Decl).Kind);
138 if (CtxKind == CodeCompletionContext::CCC_IncludedFile)
139 return CompletionItemKind::File;
140 switch (ResKind) {
141 case CodeCompletionResult::RK_Declaration:
142 llvm_unreachable("RK_Declaration without Decl");
143 case CodeCompletionResult::RK_Keyword:
144 return CompletionItemKind::Keyword;
145 case CodeCompletionResult::RK_Macro:
146 return CompletionItemKind::Text; // unfortunately, there's no 'Macro'
147 // completion items in LSP.
148 case CodeCompletionResult::RK_Pattern:
149 return CompletionItemKind::Snippet;
150 }
151 llvm_unreachable("Unhandled CodeCompletionResult::ResultKind.");
152 }
153
154 // Identifier code completion result.
155 struct RawIdentifier {
156 llvm::StringRef Name;
157 unsigned References; // # of usages in file.
158 };
159
160 /// A code completion result, in clang-native form.
161 /// It may be promoted to a CompletionItem if it's among the top-ranked results.
162 struct CompletionCandidate {
163 llvm::StringRef Name; // Used for filtering and sorting.
164 // We may have a result from Sema, from the index, or both.
165 const CodeCompletionResult *SemaResult = nullptr;
166 const Symbol *IndexResult = nullptr;
167 const RawIdentifier *IdentifierResult = nullptr;
168 llvm::SmallVector<llvm::StringRef, 1> RankedIncludeHeaders;
169
170 // Returns a token identifying the overload set this is part of.
171 // 0 indicates it's not part of any overload set.
172 size_t overloadSet(const CodeCompleteOptions &Opts) const {
173 if (!Opts.BundleOverloads.getValueOr(false))
174 return 0;
175 llvm::SmallString<256> Scratch;
176 if (IndexResult) {
177 switch (IndexResult->SymInfo.Kind) {
178 case index::SymbolKind::ClassMethod:
179 case index::SymbolKind::InstanceMethod:
180 case index::SymbolKind::StaticMethod:
181 #ifndef NDEBUG
182 llvm_unreachable("Don't expect members from index in code completion");
183 #else
184 LLVM_FALLTHROUGH;
185 #endif
186 case index::SymbolKind::Function:
187 // We can't group overloads together that need different #includes.
188 // This could break #include insertion.
189 return llvm::hash_combine(
190 (IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
191 headerToInsertIfAllowed(Opts).getValueOr(""));
192 default:
193 return 0;
194 }
195 }
196 if (SemaResult) {
197 // We need to make sure we're consistent with the IndexResult case!
198 const NamedDecl *D = SemaResult->Declaration;
199 if (!D || !D->isFunctionOrFunctionTemplate())
200 return 0;
201 {
202 llvm::raw_svector_ostream OS(Scratch);
203 D->printQualifiedName(OS);
204 }
205 return llvm::hash_combine(Scratch,
206 headerToInsertIfAllowed(Opts).getValueOr(""));
207 }
208 assert(IdentifierResult);
209 return 0;
210 }
211
212 // The best header to include if include insertion is allowed.
213 llvm::Optional<llvm::StringRef>
214 headerToInsertIfAllowed(const CodeCompleteOptions &Opts) const {
215 if (Opts.InsertIncludes == CodeCompleteOptions::NeverInsert ||
216 RankedIncludeHeaders.empty())
217 return None;
218 if (SemaResult && SemaResult->Declaration) {
219 // Avoid inserting new #include if the declaration is found in the current
220 // file e.g. the symbol is forward declared.
221 auto &SM = SemaResult->Declaration->getASTContext().getSourceManager();
222 for (const Decl *RD : SemaResult->Declaration->redecls())
223 if (SM.isInMainFile(SM.getExpansionLoc(RD->getBeginLoc())))
224 return None;
225 }
226 return RankedIncludeHeaders[0];
227 }
228
229 using Bundle = llvm::SmallVector<CompletionCandidate, 4>;
230 };
231 using ScoredBundle =
232 std::pair<CompletionCandidate::Bundle, CodeCompletion::Scores>;
233 struct ScoredBundleGreater {
234 bool operator()(const ScoredBundle &L, const ScoredBundle &R) {
235 if (L.second.Total != R.second.Total)
236 return L.second.Total > R.second.Total;
237 return L.first.front().Name <
238 R.first.front().Name; // Earlier name is better.
239 }
240 };
241
242 // Assembles a code completion out of a bundle of >=1 completion candidates.
243 // Many of the expensive strings are only computed at this point, once we know
244 // the candidate bundle is going to be returned.
245 //
246 // Many fields are the same for all candidates in a bundle (e.g. name), and are
247 // computed from the first candidate, in the constructor.
248 // Others vary per candidate, so add() must be called for remaining candidates.
249 struct CodeCompletionBuilder {
250 CodeCompletionBuilder(ASTContext *ASTCtx, const CompletionCandidate &C,
251 CodeCompletionString *SemaCCS,
252 llvm::ArrayRef<std::string> QueryScopes,
253 const IncludeInserter &Includes,
254 llvm::StringRef FileName,
255 CodeCompletionContext::Kind ContextKind,
256 const CodeCompleteOptions &Opts, bool GenerateSnippets)
257 : ASTCtx(ASTCtx), ExtractDocumentation(Opts.IncludeComments),
258 EnableFunctionArgSnippets(Opts.EnableFunctionArgSnippets),
259 GenerateSnippets(GenerateSnippets) {
260 add(C, SemaCCS);
261 if (C.SemaResult) {
262 assert(ASTCtx);
263 Completion.Origin |= SymbolOrigin::AST;
264 Completion.Name = llvm::StringRef(SemaCCS->getTypedText());
265 if (Completion.Scope.empty()) {
266 if ((C.SemaResult->Kind == CodeCompletionResult::RK_Declaration) ||
267 (C.SemaResult->Kind == CodeCompletionResult::RK_Pattern))
268 if (const auto *D = C.SemaResult->getDeclaration())
269 if (const auto *ND = dyn_cast<NamedDecl>(D))
270 Completion.Scope =
271 splitQualifiedName(printQualifiedName(*ND)).first;
272 }
273 Completion.Kind = toCompletionItemKind(
274 C.SemaResult->Kind, C.SemaResult->Declaration, ContextKind);
275 // Sema could provide more info on whether the completion was a file or
276 // folder.
277 if (Completion.Kind == CompletionItemKind::File &&
278 Completion.Name.back() == '/')
279 Completion.Kind = CompletionItemKind::Folder;
280 for (const auto &FixIt : C.SemaResult->FixIts) {
281 Completion.FixIts.push_back(toTextEdit(
282 FixIt, ASTCtx->getSourceManager(), ASTCtx->getLangOpts()));
283 }
284 llvm::sort(Completion.FixIts, [](const TextEdit &X, const TextEdit &Y) {
285 return std::tie(X.range.start.line, X.range.start.character) <
286 std::tie(Y.range.start.line, Y.range.start.character);
287 });
288 Completion.Deprecated |=
289 (C.SemaResult->Availability == CXAvailability_Deprecated);
290 }
291 if (C.IndexResult) {
292 Completion.Origin |= C.IndexResult->Origin;
293 if (Completion.Scope.empty())
294 Completion.Scope = C.IndexResult->Scope;
295 if (Completion.Kind == CompletionItemKind::Missing)
296 Completion.Kind = toCompletionItemKind(C.IndexResult->SymInfo.Kind);
297 if (Completion.Name.empty())
298 Completion.Name = C.IndexResult->Name;
299 // If the completion was visible to Sema, no qualifier is needed. This
300 // avoids unneeded qualifiers in cases like with `using ns::X`.
301 if (Completion.RequiredQualifier.empty() && !C.SemaResult) {
302 llvm::StringRef ShortestQualifier = C.IndexResult->Scope;
303 for (llvm::StringRef Scope : QueryScopes) {
304 llvm::StringRef Qualifier = C.IndexResult->Scope;
305 if (Qualifier.consume_front(Scope) &&
306 Qualifier.size() < ShortestQualifier.size())
307 ShortestQualifier = Qualifier;
308 }
309 Completion.RequiredQualifier = ShortestQualifier;
310 }
311 Completion.Deprecated |= (C.IndexResult->Flags & Symbol::Deprecated);
312 }
313 if (C.IdentifierResult) {
314 Completion.Origin |= SymbolOrigin::Identifier;
315 Completion.Kind = CompletionItemKind::Text;
316 Completion.Name = C.IdentifierResult->Name;
317 }
318
319 // Turn absolute path into a literal string that can be #included.
320 auto Inserted = [&](llvm::StringRef Header)
321 -> llvm::Expected<std::pair<std::string, bool>> {
322 auto ResolvedDeclaring =
323 URI::resolve(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
324 if (!ResolvedDeclaring)
325 return ResolvedDeclaring.takeError();
326 auto ResolvedInserted = toHeaderFile(Header, FileName);
327 if (!ResolvedInserted)
328 return ResolvedInserted.takeError();
329 auto Spelled = Includes.calculateIncludePath(*ResolvedInserted, FileName);
330 if (!Spelled)
331 return llvm::createStringError(llvm::inconvertibleErrorCode(),
332 "Header not on include path");
333 return std::make_pair(
334 std::move(*Spelled),
335 Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
336 };
337 bool ShouldInsert = C.headerToInsertIfAllowed(Opts).hasValue();
338 // Calculate include paths and edits for all possible headers.
339 for (const auto &Inc : C.RankedIncludeHeaders) {
340 if (auto ToInclude = Inserted(Inc)) {
341 CodeCompletion::IncludeCandidate Include;
342 Include.Header = ToInclude->first;
343 if (ToInclude->second && ShouldInsert)
344 Include.Insertion = Includes.insert(ToInclude->first);
345 Completion.Includes.push_back(std::move(Include));
346 } else
347 log("Failed to generate include insertion edits for adding header "
348 "(FileURI='{0}', IncludeHeader='{1}') into {2}: {3}",
349 C.IndexResult->CanonicalDeclaration.FileURI, Inc, FileName,
350 ToInclude.takeError());
351 }
352 // Prefer includes that do not need edits (i.e. already exist).
353 std::stable_partition(Completion.Includes.begin(),
354 Completion.Includes.end(),
355 [](const CodeCompletion::IncludeCandidate &I) {
356 return !I.Insertion.hasValue();
357 });
358 }
359
360 void add(const CompletionCandidate &C, CodeCompletionString *SemaCCS) {
361 assert(bool(C.SemaResult) == bool(SemaCCS));
362 Bundled.emplace_back();
363 BundledEntry &S = Bundled.back();
364 if (C.SemaResult) {
365 bool IsPattern = C.SemaResult->Kind == CodeCompletionResult::RK_Pattern;
366 getSignature(*SemaCCS, &S.Signature, &S.SnippetSuffix,
367 &Completion.RequiredQualifier, IsPattern);
368 S.ReturnType = getReturnType(*SemaCCS);
369 } else if (C.IndexResult) {
370 S.Signature = C.IndexResult->Signature;
371 S.SnippetSuffix = C.IndexResult->CompletionSnippetSuffix;
372 S.ReturnType = C.IndexResult->ReturnType;
373 }
374 if (ExtractDocumentation && Completion.Documentation.empty()) {
375 if (C.IndexResult)
376 Completion.Documentation = C.IndexResult->Documentation;
377 else if (C.SemaResult)
378 Completion.Documentation = getDocComment(*ASTCtx, *C.SemaResult,
379 /*CommentsFromHeader=*/false);
380 }
381 }
382
383 CodeCompletion build() {
384 Completion.ReturnType = summarizeReturnType();
385 Completion.Signature = summarizeSignature();
386 Completion.SnippetSuffix = summarizeSnippet();
387 Completion.BundleSize = Bundled.size();
388 return std::move(Completion);
389 }
390
391 private:
392 struct BundledEntry {
393 std::string SnippetSuffix;
394 std::string Signature;
395 std::string ReturnType;
396 };
397
398 // If all BundledEntries have the same value for a property, return it.
399 template <std::string BundledEntry::*Member>
400 const std::string *onlyValue() const {
401 auto B = Bundled.begin(), E = Bundled.end();
402 for (auto I = B + 1; I != E; ++I)
403 if (I->*Member != B->*Member)
404 return nullptr;
405 return &(B->*Member);
406 }
407
408 template <bool BundledEntry::*Member> const bool *onlyValue() const {
409 auto B = Bundled.begin(), E = Bundled.end();
410 for (auto I = B + 1; I != E; ++I)
411 if (I->*Member != B->*Member)
412 return nullptr;
413 return &(B->*Member);
414 }
415
416 std::string summarizeReturnType() const {
417 if (auto *RT = onlyValue<&BundledEntry::ReturnType>())
418 return *RT;
419 return "";
420 }
421
422 std::string summarizeSnippet() const {
423 if (!GenerateSnippets)
424 return "";
425 auto *Snippet = onlyValue<&BundledEntry::SnippetSuffix>();
426 if (!Snippet)
427 // All bundles are function calls.
428 // FIXME(ibiryukov): sometimes add template arguments to a snippet, e.g.
429 // we need to complete 'forward<$1>($0)'.
430 return "($0)";
431 if (EnableFunctionArgSnippets)
432 return *Snippet;
433
434 // Replace argument snippets with a simplified pattern.
435 if (Snippet->empty())
436 return "";
437 if (Completion.Kind == CompletionItemKind::Function ||
438 Completion.Kind == CompletionItemKind::Method) {
439 // Functions snippets can be of 2 types:
440 // - containing only function arguments, e.g.
441 // foo(${1:int p1}, ${2:int p2});
442 // We transform this pattern to '($0)' or '()'.
443 // - template arguments and function arguments, e.g.
444 // foo<${1:class}>(${2:int p1}).
445 // We transform this pattern to '<$1>()$0' or '<$0>()'.
446
447 bool EmptyArgs = llvm::StringRef(*Snippet).endswith("()");
448 if (Snippet->front() == '<')
449 return EmptyArgs ? "<$1>()$0" : "<$1>($0)";
450 if (Snippet->front() == '(')
451 return EmptyArgs ? "()" : "($0)";
452 return *Snippet; // Not an arg snippet?
453 }
454 // 'CompletionItemKind::Interface' matches template type aliases.
455 if (Completion.Kind == CompletionItemKind::Interface ||
456 Completion.Kind == CompletionItemKind::Class) {
457 if (Snippet->front() != '<')
458 return *Snippet; // Not an arg snippet?
459
460 // Classes and template using aliases can only have template arguments,
461 // e.g. Foo<${1:class}>.
462 if (llvm::StringRef(*Snippet).endswith("<>"))
463 return "<>"; // can happen with defaulted template arguments.
464 return "<$0>";
465 }
466 return *Snippet;
467 }
468
469 std::string summarizeSignature() const {
470 if (auto *Signature = onlyValue<&BundledEntry::Signature>())
471 return *Signature;
472 // All bundles are function calls.
473 return "(…)";
474 }
475
476 // ASTCtx can be nullptr if not run with sema.
477 ASTContext *ASTCtx;
478 CodeCompletion Completion;
479 llvm::SmallVector<BundledEntry, 1> Bundled;
480 bool ExtractDocumentation;
481 bool EnableFunctionArgSnippets;
482 /// When false, no snippets are generated argument lists.
483 bool GenerateSnippets;
484 };
485
486 // Determine the symbol ID for a Sema code completion result, if possible.
487 llvm::Optional<SymbolID> getSymbolID(const CodeCompletionResult &R,
488 const SourceManager &SM) {
489 switch (R.Kind) {
490 case CodeCompletionResult::RK_Declaration:
491 case CodeCompletionResult::RK_Pattern: {
492 return clang::clangd::getSymbolID(R.Declaration);
493 }
494 case CodeCompletionResult::RK_Macro:
495 return clang::clangd::getSymbolID(R.Macro->getName(), R.MacroDefInfo, SM);
496 case CodeCompletionResult::RK_Keyword:
497 return None;
498 }
499 llvm_unreachable("unknown CodeCompletionResult kind");
500 }
501
502 // Scopes of the partial identifier we're trying to complete.
503 // It is used when we query the index for more completion results.
504 struct SpecifiedScope {
505 // The scopes we should look in, determined by Sema.
506 //
507 // If the qualifier was fully resolved, we look for completions in these
508 // scopes; if there is an unresolved part of the qualifier, it should be
509 // resolved within these scopes.
510 //
511 // Examples of qualified completion:
512 //
513 // "::vec" => {""}
514 // "using namespace std; ::vec^" => {"", "std::"}
515 // "namespace ns {using namespace std;} ns::^" => {"ns::", "std::"}
516 // "std::vec^" => {""} // "std" unresolved
517 //
518 // Examples of unqualified completion:
519 //
520 // "vec^" => {""}
521 // "using namespace std; vec^" => {"", "std::"}
522 // "using namespace std; namespace ns { vec^ }" => {"ns::", "std::", ""}
523 //
524 // "" for global namespace, "ns::" for normal namespace.
525 std::vector<std::string> AccessibleScopes;
526 // The full scope qualifier as typed by the user (without the leading "::").
527 // Set if the qualifier is not fully resolved by Sema.
528 llvm::Optional<std::string> UnresolvedQualifier;
529
530 // Construct scopes being queried in indexes. The results are deduplicated.
531 // This method format the scopes to match the index request representation.
532 std::vector<std::string> scopesForIndexQuery() {
533 std::set<std::string> Results;
534 for (llvm::StringRef AS : AccessibleScopes)
535 Results.insert(
536 (AS + (UnresolvedQualifier ? *UnresolvedQualifier : "")).str());
537 return {Results.begin(), Results.end()};
538 }
539 };
540
541 // Get all scopes that will be queried in indexes and whether symbols from
542 // any scope is allowed. The first scope in the list is the preferred scope
543 // (e.g. enclosing namespace).
544 std::pair<std::vector<std::string>, bool>
545 getQueryScopes(CodeCompletionContext &CCContext, const Sema &CCSema,
546 const CompletionPrefix &HeuristicPrefix,
547 const CodeCompleteOptions &Opts) {
548 SpecifiedScope Scopes;
549 for (auto *Context : CCContext.getVisitedContexts()) {
550 if (isa<TranslationUnitDecl>(Context))
551 Scopes.AccessibleScopes.push_back(""); // global namespace
552 else if (isa<NamespaceDecl>(Context))
553 Scopes.AccessibleScopes.push_back(printNamespaceScope(*Context));
554 }
555
556 const CXXScopeSpec *SemaSpecifier =
557 CCContext.getCXXScopeSpecifier().getValueOr(nullptr);
558 // Case 1: unqualified completion.
559 if (!SemaSpecifier) {
560 // Case 2 (exception): sema saw no qualifier, but there appears to be one!
561 // This can happen e.g. in incomplete macro expansions. Use heuristics.
562 if (!HeuristicPrefix.Qualifier.empty()) {
563 vlog("Sema said no scope specifier, but we saw {0} in the source code",
564 HeuristicPrefix.Qualifier);
565 StringRef SpelledSpecifier = HeuristicPrefix.Qualifier;
566 if (SpelledSpecifier.consume_front("::"))
567 Scopes.AccessibleScopes = {""};
568 Scopes.UnresolvedQualifier = SpelledSpecifier;
569 return {Scopes.scopesForIndexQuery(), false};
570 }
571 // The enclosing namespace must be first, it gets a quality boost.
572 std::vector<std::string> EnclosingAtFront;
573 std::string EnclosingScope = printNamespaceScope(*CCSema.CurContext);
574 EnclosingAtFront.push_back(EnclosingScope);
575 for (auto &S : Scopes.scopesForIndexQuery()) {
576 if (EnclosingScope != S)
577 EnclosingAtFront.push_back(std::move(S));
578 }
579 // Allow AllScopes completion as there is no explicit scope qualifier.
580 return {EnclosingAtFront, Opts.AllScopes};
581 }
582 // Case 3: sema saw and resolved a scope qualifier.
583 if (SemaSpecifier && SemaSpecifier->isValid())
584 return {Scopes.scopesForIndexQuery(), false};
585
586 // Case 4: There was a qualifier, and Sema didn't resolve it.
587 Scopes.AccessibleScopes.push_back(""); // Make sure global scope is included.
588 llvm::StringRef SpelledSpecifier = Lexer::getSourceText(
589 CharSourceRange::getCharRange(SemaSpecifier->getRange()),
590 CCSema.SourceMgr, clang::LangOptions());
591 if (SpelledSpecifier.consume_front("::"))
592 Scopes.AccessibleScopes = {""};
593 Scopes.UnresolvedQualifier = SpelledSpecifier;
594 // Sema excludes the trailing "::".
595 if (!Scopes.UnresolvedQualifier->empty())
596 *Scopes.UnresolvedQualifier += "::";
597
598 return {Scopes.scopesForIndexQuery(), false};
599 }
600
601 // Should we perform index-based completion in a context of the specified kind?
602 // FIXME: consider allowing completion, but restricting the result types.
603 bool contextAllowsIndex(enum CodeCompletionContext::Kind K) {
604 switch (K) {
605 case CodeCompletionContext::CCC_TopLevel:
606 case CodeCompletionContext::CCC_ObjCInterface:
607 case CodeCompletionContext::CCC_ObjCImplementation:
608 case CodeCompletionContext::CCC_ObjCIvarList:
609 case CodeCompletionContext::CCC_ClassStructUnion:
610 case CodeCompletionContext::CCC_Statement:
611 case CodeCompletionContext::CCC_Expression:
612 case CodeCompletionContext::CCC_ObjCMessageReceiver:
613 case CodeCompletionContext::CCC_EnumTag:
614 case CodeCompletionContext::CCC_UnionTag:
615 case CodeCompletionContext::CCC_ClassOrStructTag:
616 case CodeCompletionContext::CCC_ObjCProtocolName:
617 case CodeCompletionContext::CCC_Namespace:
618 case CodeCompletionContext::CCC_Type:
619 case CodeCompletionContext::CCC_ParenthesizedExpression:
620 case CodeCompletionContext::CCC_ObjCInterfaceName:
621 case CodeCompletionContext::CCC_ObjCCategoryName:
622 case CodeCompletionContext::CCC_Symbol:
623 case CodeCompletionContext::CCC_SymbolOrNewName:
624 return true;
625 case CodeCompletionContext::CCC_OtherWithMacros:
626 case CodeCompletionContext::CCC_DotMemberAccess:
627 case CodeCompletionContext::CCC_ArrowMemberAccess:
628 case CodeCompletionContext::CCC_ObjCPropertyAccess:
629 case CodeCompletionContext::CCC_MacroName:
630 case CodeCompletionContext::CCC_MacroNameUse:
631 case CodeCompletionContext::CCC_PreprocessorExpression:
632 case CodeCompletionContext::CCC_PreprocessorDirective:
633 case CodeCompletionContext::CCC_SelectorName:
634 case CodeCompletionContext::CCC_TypeQualifiers:
635 case CodeCompletionContext::CCC_ObjCInstanceMessage:
636 case CodeCompletionContext::CCC_ObjCClassMessage:
637 case CodeCompletionContext::CCC_IncludedFile:
638 // FIXME: Provide identifier based completions for the following contexts:
639 case CodeCompletionContext::CCC_Other: // Be conservative.
640 case CodeCompletionContext::CCC_NaturalLanguage:
641 case CodeCompletionContext::CCC_Recovery:
642 case CodeCompletionContext::CCC_NewName:
643 return false;
644 }
645 llvm_unreachable("unknown code completion context");
646 }
647
648 static bool isInjectedClass(const NamedDecl &D) {
649 if (auto *R = dyn_cast_or_null<RecordDecl>(&D))
650 if (R->isInjectedClassName())
651 return true;
652 return false;
653 }
654
655 // Some member calls are blacklisted because they're so rarely useful.
656 static bool isBlacklistedMember(const NamedDecl &D) {
657 // Destructor completion is rarely useful, and works inconsistently.
658 // (s.^ completes ~string, but s.~st^ is an error).
659 if (D.getKind() == Decl::CXXDestructor)
660 return true;
661 // Injected name may be useful for A::foo(), but who writes A::A::foo()?
662 if (isInjectedClass(D))
663 return true;
664 // Explicit calls to operators are also rare.
665 auto NameKind = D.getDeclName().getNameKind();
666 if (NameKind == DeclarationName::CXXOperatorName ||
667 NameKind == DeclarationName::CXXLiteralOperatorName ||
668 NameKind == DeclarationName::CXXConversionFunctionName)
669 return true;
670 return false;
671 }
672
673 // The CompletionRecorder captures Sema code-complete output, including context.
674 // It filters out ignored results (but doesn't apply fuzzy-filtering yet).
675 // It doesn't do scoring or conversion to CompletionItem yet, as we want to
676 // merge with index results first.
677 // Generally the fields and methods of this object should only be used from
678 // within the callback.
679 struct CompletionRecorder : public CodeCompleteConsumer {
680 CompletionRecorder(const CodeCompleteOptions &Opts,
681 llvm::unique_function<void()> ResultsCallback)
682 : CodeCompleteConsumer(Opts.getClangCompleteOpts()),
683 CCContext(CodeCompletionContext::CCC_Other), Opts(Opts),
684 CCAllocator(std::make_shared<GlobalCodeCompletionAllocator>()),
685 CCTUInfo(CCAllocator), ResultsCallback(std::move(ResultsCallback)) {
686 assert(this->ResultsCallback);
687 }
688
689 std::vector<CodeCompletionResult> Results;
690 CodeCompletionContext CCContext;
691 Sema *CCSema = nullptr; // Sema that created the results.
692 // FIXME: Sema is scary. Can we store ASTContext and Preprocessor, instead?
693
694 void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context,
695 CodeCompletionResult *InResults,
696 unsigned NumResults) override final {
697 // Results from recovery mode are generally useless, and the callback after
698 // recovery (if any) is usually more interesting. To make sure we handle the
699 // future callback from sema, we just ignore all callbacks in recovery mode,
700 // as taking only results from recovery mode results in poor completion
701 // results.
702 // FIXME: in case there is no future sema completion callback after the
703 // recovery mode, we might still want to provide some results (e.g. trivial
704 // identifier-based completion).
705 if (Context.getKind() == CodeCompletionContext::CCC_Recovery) {
706 log("Code complete: Ignoring sema code complete callback with Recovery "
707 "context.");
708 return;
709 }
710 // If a callback is called without any sema result and the context does not
711 // support index-based completion, we simply skip it to give way to
712 // potential future callbacks with results.
713 if (NumResults == 0 && !contextAllowsIndex(Context.getKind()))
714 return;
715 if (CCSema) {
716 log("Multiple code complete callbacks (parser backtracked?). "
717 "Dropping results from context {0}, keeping results from {1}.",
718 getCompletionKindString(Context.getKind()),
719 getCompletionKindString(this->CCContext.getKind()));
720 return;
721 }
722 // Record the completion context.
723 CCSema = &S;
724 CCContext = Context;
725
726 // Retain the results we might want.
727 for (unsigned I = 0; I < NumResults; ++I) {
728 auto &Result = InResults[I];
729 // Class members that are shadowed by subclasses are usually noise.
730 if (Result.Hidden && Result.Declaration &&
731 Result.Declaration->isCXXClassMember())
732 continue;
733 if (!Opts.IncludeIneligibleResults &&
734 (Result.Availability == CXAvailability_NotAvailable ||
735 Result.Availability == CXAvailability_NotAccessible))
736 continue;
737 if (Result.Declaration &&
738 !Context.getBaseType().isNull() // is this a member-access context?
739 && isBlacklistedMember(*Result.Declaration))
740 continue;
741 // Skip injected class name when no class scope is not explicitly set.
742 // E.g. show injected A::A in `using A::A^` but not in "A^".
743 if (Result.Declaration && !Context.getCXXScopeSpecifier().hasValue() &&
744 isInjectedClass(*Result.Declaration))
745 continue;
746 // We choose to never append '::' to completion results in clangd.
747 Result.StartsNestedNameSpecifier = false;
748 Results.push_back(Result);
749 }
750 ResultsCallback();
751 }
752
753 CodeCompletionAllocator &getAllocator() override { return *CCAllocator; }
754 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
755
756 // Returns the filtering/sorting name for Result, which must be from Results.
757 // Returned string is owned by this recorder (or the AST).
758 llvm::StringRef getName(const CodeCompletionResult &Result) {
759 switch (Result.Kind) {
760 case CodeCompletionResult::RK_Declaration:
761 if (auto *ID = Result.Declaration->getIdentifier())
762 return ID->getName();
763 break;
764 case CodeCompletionResult::RK_Keyword:
765 return Result.Keyword;
766 case CodeCompletionResult::RK_Macro:
767 return Result.Macro->getName();
768 case CodeCompletionResult::RK_Pattern:
769 return Result.Pattern->getTypedText();
770 }
771 auto *CCS = codeCompletionString(Result);
772 return CCS->getTypedText();
773 }
774
775 // Build a CodeCompletion string for R, which must be from Results.
776 // The CCS will be owned by this recorder.
777 CodeCompletionString *codeCompletionString(const CodeCompletionResult &R) {
778 // CodeCompletionResult doesn't seem to be const-correct. We own it, anyway.
779 return const_cast<CodeCompletionResult &>(R).CreateCodeCompletionString(
780 *CCSema, CCContext, *CCAllocator, CCTUInfo,
781 /*IncludeBriefComments=*/false);
782 }
783
784 private:
785 CodeCompleteOptions Opts;
786 std::shared_ptr<GlobalCodeCompletionAllocator> CCAllocator;
787 CodeCompletionTUInfo CCTUInfo;
788 llvm::unique_function<void()> ResultsCallback;
789 };
790
791 struct ScoredSignature {
792 // When set, requires documentation to be requested from the index with this
793 // ID.
794 llvm::Optional<SymbolID> IDForDoc;
795 SignatureInformation Signature;
796 SignatureQualitySignals Quality;
797 };
798
799 class SignatureHelpCollector final : public CodeCompleteConsumer {
800 public:
801 SignatureHelpCollector(const clang::CodeCompleteOptions &CodeCompleteOpts,
802 const SymbolIndex *Index, SignatureHelp &SigHelp)
803 : CodeCompleteConsumer(CodeCompleteOpts), SigHelp(SigHelp),
804 Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
805 CCTUInfo(Allocator), Index(Index) {}
806
807 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
808 OverloadCandidate *Candidates,
809 unsigned NumCandidates,
810 SourceLocation OpenParLoc) override {
811 assert(!OpenParLoc.isInvalid());
812 SourceManager &SrcMgr = S.getSourceManager();
813 OpenParLoc = SrcMgr.getFileLoc(OpenParLoc);
814 if (SrcMgr.isInMainFile(OpenParLoc))
815 SigHelp.argListStart = sourceLocToPosition(SrcMgr, OpenParLoc);
816 else
817 elog("Location oustide main file in signature help: {0}",
818 OpenParLoc.printToString(SrcMgr));
819
820 std::vector<ScoredSignature> ScoredSignatures;
821 SigHelp.signatures.reserve(NumCandidates);
822 ScoredSignatures.reserve(NumCandidates);
823 // FIXME(rwols): How can we determine the "active overload candidate"?
824 // Right now the overloaded candidates seem to be provided in a "best fit"
825 // order, so I'm not too worried about this.
826 SigHelp.activeSignature = 0;
827 assert(CurrentArg <= (unsigned)std::numeric_limits<int>::max() &&
828 "too many arguments");
829 SigHelp.activeParameter = static_cast<int>(CurrentArg);
830 for (unsigned I = 0; I < NumCandidates; ++I) {
831 OverloadCandidate Candidate = Candidates[I];
832 // We want to avoid showing instantiated signatures, because they may be
833 // long in some cases (e.g. when 'T' is substituted with 'std::string', we
834 // would get 'std::basic_string<char>').
835 if (auto *Func = Candidate.getFunction()) {
836 if (auto *Pattern = Func->getTemplateInstantiationPattern())
837 Candidate = OverloadCandidate(Pattern);
838 }
839
840 const auto *CCS = Candidate.CreateSignatureString(
841 CurrentArg, S, *Allocator, CCTUInfo, true);
842 assert(CCS && "Expected the CodeCompletionString to be non-null");
843 ScoredSignatures.push_back(processOverloadCandidate(
844 Candidate, *CCS,
845 Candidate.getFunction()
846 ? getDeclComment(S.getASTContext(), *Candidate.getFunction())
847 : ""));
848 }
849
850 // Sema does not load the docs from the preamble, so we need to fetch extra
851 // docs from the index instead.
852 llvm::DenseMap<SymbolID, std::string> FetchedDocs;
853 if (Index) {
854 LookupRequest IndexRequest;
855 for (const auto &S : ScoredSignatures) {
856 if (!S.IDForDoc)
857 continue;
858 IndexRequest.IDs.insert(*S.IDForDoc);
859 }
860 Index->lookup(IndexRequest, [&](const Symbol &S) {
861 if (!S.Documentation.empty())
862 FetchedDocs[S.ID] = S.Documentation;
863 });
864 log("SigHelp: requested docs for {0} symbols from the index, got {1} "
865 "symbols with non-empty docs in the response",
866 IndexRequest.IDs.size(), FetchedDocs.size());
867 }
868
869 llvm::sort(ScoredSignatures, [](const ScoredSignature &L,
870 const ScoredSignature &R) {
871 // Ordering follows:
872 // - Less number of parameters is better.
873 // - Function is better than FunctionType which is better than
874 // Function Template.
875 // - High score is better.
876 // - Shorter signature is better.
877 // - Alphabetically smaller is better.
878 if (L.Quality.NumberOfParameters != R.Quality.NumberOfParameters)
879 return L.Quality.NumberOfParameters < R.Quality.NumberOfParameters;
880 if (L.Quality.NumberOfOptionalParameters !=
881 R.Quality.NumberOfOptionalParameters)
882 return L.Quality.NumberOfOptionalParameters <
883 R.Quality.NumberOfOptionalParameters;
884 if (L.Quality.Kind != R.Quality.Kind) {
885 using OC = CodeCompleteConsumer::OverloadCandidate;
886 switch (L.Quality.Kind) {
887 case OC::CK_Function:
888 return true;
889 case OC::CK_FunctionType:
890 return R.Quality.Kind != OC::CK_Function;
891 case OC::CK_FunctionTemplate:
892 return false;
893 }
894 llvm_unreachable("Unknown overload candidate type.");
895 }
896 if (L.Signature.label.size() != R.Signature.label.size())
897 return L.Signature.label.size() < R.Signature.label.size();
898 return L.Signature.label < R.Signature.label;
899 });
900
901 for (auto &SS : ScoredSignatures) {
902 auto IndexDocIt =
903 SS.IDForDoc ? FetchedDocs.find(*SS.IDForDoc) : FetchedDocs.end();
904 if (IndexDocIt != FetchedDocs.end())
905 SS.Signature.documentation = IndexDocIt->second;
906
907 SigHelp.signatures.push_back(std::move(SS.Signature));
908 }
909 }
910
911 GlobalCodeCompletionAllocator &getAllocator() override { return *Allocator; }
912
913 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
914
915 private:
916 void processParameterChunk(llvm::StringRef ChunkText,
917 SignatureInformation &Signature) const {
918 // (!) this is O(n), should still be fast compared to building ASTs.
919 unsigned ParamStartOffset = lspLength(Signature.label);
920 unsigned ParamEndOffset = ParamStartOffset + lspLength(ChunkText);
921 // A piece of text that describes the parameter that corresponds to
922 // the code-completion location within a function call, message send,
923 // macro invocation, etc.
924 Signature.label += ChunkText;
925 ParameterInformation Info;
926 Info.labelOffsets.emplace(ParamStartOffset, ParamEndOffset);
927 // FIXME: only set 'labelOffsets' when all clients migrate out of it.
928 Info.labelString = ChunkText;
929
930 Signature.parameters.push_back(std::move(Info));
931 }
932
933 void processOptionalChunk(const CodeCompletionString &CCS,
934 SignatureInformation &Signature,
935 SignatureQualitySignals &Signal) const {
936 for (const auto &Chunk : CCS) {
937 switch (Chunk.Kind) {
938 case CodeCompletionString::CK_Optional:
939 assert(Chunk.Optional &&
940 "Expected the optional code completion string to be non-null.");
941 processOptionalChunk(*Chunk.Optional, Signature, Signal);
942 break;
943 case CodeCompletionString::CK_VerticalSpace:
944 break;
945 case CodeCompletionString::CK_CurrentParameter:
946 case CodeCompletionString::CK_Placeholder:
947 processParameterChunk(Chunk.Text, Signature);
948 Signal.NumberOfOptionalParameters++;
949 break;
950 default:
951 Signature.label += Chunk.Text;
952 break;
953 }
954 }
955 }
956
957 // FIXME(ioeric): consider moving CodeCompletionString logic here to
958 // CompletionString.h.
959 ScoredSignature processOverloadCandidate(const OverloadCandidate &Candidate,
960 const CodeCompletionString &CCS,
961 llvm::StringRef DocComment) const {
962 SignatureInformation Signature;
963 SignatureQualitySignals Signal;
964 const char *ReturnType = nullptr;
965
966 Signature.documentation = formatDocumentation(CCS, DocComment);
967 Signal.Kind = Candidate.getKind();
968
969 for (const auto &Chunk : CCS) {
970 switch (Chunk.Kind) {
971 case CodeCompletionString::CK_ResultType:
972 // A piece of text that describes the type of an entity or,
973 // for functions and methods, the return type.
974 assert(!ReturnType && "Unexpected CK_ResultType");
975 ReturnType = Chunk.Text;
976 break;
977 case CodeCompletionString::CK_CurrentParameter:
978 case CodeCompletionString::CK_Placeholder:
979 processParameterChunk(Chunk.Text, Signature);
980 Signal.NumberOfParameters++;
981 break;
982 case CodeCompletionString::CK_Optional: {
983 // The rest of the parameters are defaulted/optional.
984 assert(Chunk.Optional &&
985 "Expected the optional code completion string to be non-null.");
986 processOptionalChunk(*Chunk.Optional, Signature, Signal);
987 break;
988 }
989 case CodeCompletionString::CK_VerticalSpace:
990 break;
991 default:
992 Signature.label += Chunk.Text;
993 break;
994 }
995 }
996 if (ReturnType) {
997 Signature.label += " -> ";
998 Signature.label += ReturnType;
999 }
1000 dlog("Signal for {0}: {1}", Signature, Signal);
1001 ScoredSignature Result;
1002 Result.Signature = std::move(Signature);
1003 Result.Quality = Signal;
1004 Result.IDForDoc =
1005 Result.Signature.documentation.empty() && Candidate.getFunction()
1006 ? clangd::getSymbolID(Candidate.getFunction())
1007 : None;
1008 return Result;
1009 }
1010
1011 SignatureHelp &SigHelp;
1012 std::shared_ptr<clang::GlobalCodeCompletionAllocator> Allocator;
1013 CodeCompletionTUInfo CCTUInfo;
1014 const SymbolIndex *Index;
1015 }; // SignatureHelpCollector
1016
1017 struct SemaCompleteInput {
1018 PathRef FileName;
1019 const tooling::CompileCommand &Command;
1020 const PreambleData *Preamble;
1021 llvm::StringRef Contents;
1022 size_t Offset;
1023 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
1024 };
1025
1026 void loadMainFilePreambleMacros(const Preprocessor &PP,
1027 const PreambleData &Preamble) {
1028 // The ExternalPreprocessorSource has our macros, if we know where to look.
1029 // We can read all the macros using PreambleMacros->ReadDefinedMacros(),
1030 // but this includes transitively included files, so may deserialize a lot.
1031 ExternalPreprocessorSource *PreambleMacros = PP.getExternalSource();
1032 // As we have the names of the macros, we can look up their IdentifierInfo
1033 // and then use this to load just the macros we want.
1034 IdentifierInfoLookup *PreambleIdentifiers =
1035 PP.getIdentifierTable().getExternalIdentifierLookup();
1036 if (!PreambleIdentifiers || !PreambleMacros)
1037 return;
1038 for (const auto &MacroName : Preamble.Macros.Names)
1039 if (auto *II = PreambleIdentifiers->get(MacroName.getKey()))
1040 if (II->isOutOfDate())
1041 PreambleMacros->updateOutOfDateIdentifier(*II);
1042 }
1043
1044 // Invokes Sema code completion on a file.
1045 // If \p Includes is set, it will be updated based on the compiler invocation.
1046 bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
1047 const clang::CodeCompleteOptions &Options,
1048 const SemaCompleteInput &Input,
1049 IncludeStructure *Includes = nullptr) {
1050 trace::Span Tracer("Sema completion");
1051 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = Input.VFS;
1052 if (Input.Preamble && Input.Preamble->StatCache)
1053 VFS = Input.Preamble->StatCache->getConsumingFS(std::move(VFS));
1054 ParseInputs ParseInput;
1055 ParseInput.CompileCommand = Input.Command;
1056 ParseInput.FS = VFS;
1057 ParseInput.Contents = Input.Contents;
1058 ParseInput.Opts = ParseOptions();
1059
1060 IgnoreDiagnostics IgnoreDiags;
1061 auto CI = buildCompilerInvocation(ParseInput, IgnoreDiags);
1062 if (!CI) {
1063 elog("Couldn't create CompilerInvocation");
1064 return false;
1065 }
1066 auto &FrontendOpts = CI->getFrontendOpts();
1067 FrontendOpts.SkipFunctionBodies = true;
1068 // Disable typo correction in Sema.
1069 CI->getLangOpts()->SpellChecking = false;
1070 // Setup code completion.
1071 FrontendOpts.CodeCompleteOpts = Options;
1072 FrontendOpts.CodeCompletionAt.FileName = Input.FileName;
1073 std::tie(FrontendOpts.CodeCompletionAt.Line,
1074 FrontendOpts.CodeCompletionAt.Column) =
1075 offsetToClangLineColumn(Input.Contents, Input.Offset);
1076
1077 std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
1078 llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName);
1079 // The diagnostic options must be set before creating a CompilerInstance.
1080 CI->getDiagnosticOpts().IgnoreWarnings = true;
1081 // We reuse the preamble whether it's valid or not. This is a
1082 // correctness/performance tradeoff: building without a preamble is slow, and
1083 // completion is latency-sensitive.
1084 // However, if we're completing *inside* the preamble section of the draft,
1085 // overriding the preamble will break sema completion. Fortunately we can just
1086 // skip all includes in this case; these completions are really simple.
1087 PreambleBounds PreambleRegion =
1088 ComputePreambleBounds(*CI->getLangOpts(), ContentsBuffer.get(), 0);
1089 bool CompletingInPreamble = PreambleRegion.Size > Input.Offset;
1090 // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise
1091 // the remapped buffers do not get freed.
1092 auto Clang = prepareCompilerInstance(
1093 std::move(CI),
1094 (Input.Preamble && !CompletingInPreamble) ? &Input.Preamble->Preamble
1095 : nullptr,
1096 std::move(ContentsBuffer), std::move(VFS), IgnoreDiags);
1097 Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble;
1098 Clang->setCodeCompletionConsumer(Consumer.release());
1099
1100 SyntaxOnlyAction Action;
1101 if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
1102 log("BeginSourceFile() failed when running codeComplete for {0}",
1103 Input.FileName);
1104 return false;
1105 }
1106 // Macros can be defined within the preamble region of the main file.
1107 // They don't fall nicely into our index/Sema dichotomy:
1108 // - they're not indexed for completion (they're not available across files)
1109 // - but Sema code complete won't see them: as part of the preamble, they're
1110 // deserialized only when mentioned.
1111 // Force them to be deserialized so SemaCodeComplete sees them.
1112 if (Input.Preamble)
1113 loadMainFilePreambleMacros(Clang->getPreprocessor(), *Input.Preamble);
1114 if (Includes)
1115 Clang->getPreprocessor().addPPCallbacks(
1116 collectIncludeStructureCallback(Clang->getSourceManager(), Includes));
1117 if (llvm::Error Err = Action.Execute()) {
1118 log("Execute() failed when running codeComplete for {0}: {1}",
1119 Input.FileName, toString(std::move(Err)));
1120 return false;
1121 }
1122 Action.EndSourceFile();
1123
1124 return true;
1125 }
1126
1127 // Should we allow index completions in the specified context?
1128 bool allowIndex(CodeCompletionContext &CC) {
1129 if (!contextAllowsIndex(CC.getKind()))
1130 return false;
1131 // We also avoid ClassName::bar (but allow namespace::bar).
1132 auto Scope = CC.getCXXScopeSpecifier();
1133 if (!Scope)
1134 return true;
1135 NestedNameSpecifier *NameSpec = (*Scope)->getScopeRep();
1136 if (!NameSpec)
1137 return true;
1138 // We only query the index when qualifier is a namespace.
1139 // If it's a class, we rely solely on sema completions.
1140 switch (NameSpec->getKind()) {
1141 case NestedNameSpecifier::Global:
1142 case NestedNameSpecifier::Namespace:
1143 case NestedNameSpecifier::NamespaceAlias:
1144 return true;
1145 case NestedNameSpecifier::Super:
1146 case NestedNameSpecifier::TypeSpec:
1147 case NestedNameSpecifier::TypeSpecWithTemplate:
1148 // Unresolved inside a template.
1149 case NestedNameSpecifier::Identifier:
1150 return false;
1151 }
1152 llvm_unreachable("invalid NestedNameSpecifier kind");
1153 }
1154
1155 std::future<SymbolSlab> startAsyncFuzzyFind(const SymbolIndex &Index,
1156 const FuzzyFindRequest &Req) {
1157 return runAsync<SymbolSlab>([&Index, Req]() {
1158 trace::Span Tracer("Async fuzzyFind");
1159 SymbolSlab::Builder Syms;
1160 Index.fuzzyFind(Req, [&Syms](const Symbol &Sym) { Syms.insert(Sym); });
1161 return std::move(Syms).build();
1162 });
1163 }
1164
1165 // Creates a `FuzzyFindRequest` based on the cached index request from the
1166 // last completion, if any, and the speculated completion filter text in the
1167 // source code.
1168 FuzzyFindRequest speculativeFuzzyFindRequestForCompletion(
1169 FuzzyFindRequest CachedReq, const CompletionPrefix &HeuristicPrefix) {
1170 CachedReq.Query = HeuristicPrefix.Name;
1171 return CachedReq;
1172 }
1173
1174 // Runs Sema-based (AST) and Index-based completion, returns merged results.
1175 //
1176 // There are a few tricky considerations:
1177 // - the AST provides information needed for the index query (e.g. which
1178 // namespaces to search in). So Sema must start first.
1179 // - we only want to return the top results (Opts.Limit).
1180 // Building CompletionItems for everything else is wasteful, so we want to
1181 // preserve the "native" format until we're done with scoring.
1182 // - the data underlying Sema completion items is owned by the AST and various
1183 // other arenas, which must stay alive for us to build CompletionItems.
1184 // - we may get duplicate results from Sema and the Index, we need to merge.
1185 //
1186 // So we start Sema completion first, and do all our work in its callback.
1187 // We use the Sema context information to query the index.
1188 // Then we merge the two result sets, producing items that are Sema/Index/Both.
1189 // These items are scored, and the top N are synthesized into the LSP response.
1190 // Finally, we can clean up the data structures created by Sema completion.
1191 //
1192 // Main collaborators are:
1193 // - semaCodeComplete sets up the compiler machinery to run code completion.
1194 // - CompletionRecorder captures Sema completion results, including context.
1195 // - SymbolIndex (Opts.Index) provides index completion results as Symbols
1196 // - CompletionCandidates are the result of merging Sema and Index results.
1197 // Each candidate points to an underlying CodeCompletionResult (Sema), a
1198 // Symbol (Index), or both. It computes the result quality score.
1199 // CompletionCandidate also does conversion to CompletionItem (at the end).
1200 // - FuzzyMatcher scores how the candidate matches the partial identifier.
1201 // This score is combined with the result quality score for the final score.
1202 // - TopN determines the results with the best score.
1203 class CodeCompleteFlow {
1204 PathRef FileName;
1205 IncludeStructure Includes; // Complete once the compiler runs.
1206 SpeculativeFuzzyFind *SpecFuzzyFind; // Can be nullptr.
1207 const CodeCompleteOptions &Opts;
1208
1209 // Sema takes ownership of Recorder. Recorder is valid until Sema cleanup.
1210 CompletionRecorder *Recorder = nullptr;
1211 CodeCompletionContext::Kind CCContextKind = CodeCompletionContext::CCC_Other;
1212 bool IsUsingDeclaration = false;
1213 // Counters for logging.
1214 int NSema = 0, NIndex = 0, NSemaAndIndex = 0, NIdent = 0;
1215 bool Incomplete = false; // Would more be available with a higher limit?
1216 CompletionPrefix HeuristicPrefix;
1217 llvm::Optional<FuzzyMatcher> Filter; // Initialized once Sema runs.
1218 Range ReplacedRange;
1219 std::vector<std::string> QueryScopes; // Initialized once Sema runs.
1220 // Initialized once QueryScopes is initialized, if there are scopes.
1221 llvm::Optional<ScopeDistance> ScopeProximity;
1222 llvm::Optional<OpaqueType> PreferredType; // Initialized once Sema runs.
1223 // Whether to query symbols from any scope. Initialized once Sema runs.
1224 bool AllScopes = false;
1225 llvm::StringSet<> ContextWords;
1226 // Include-insertion and proximity scoring rely on the include structure.
1227 // This is available after Sema has run.
1228 llvm::Optional<IncludeInserter> Inserter; // Available during runWithSema.
1229 llvm::Optional<URIDistance> FileProximity; // Initialized once Sema runs.
1230 /// Speculative request based on the cached request and the filter text before
1231 /// the cursor.
1232 /// Initialized right before sema run. This is only set if `SpecFuzzyFind` is
1233 /// set and contains a cached request.
1234 llvm::Optional<FuzzyFindRequest> SpecReq;
1235
1236 public:
1237 // A CodeCompleteFlow object is only useful for calling run() exactly once.
1238 CodeCompleteFlow(PathRef FileName, const IncludeStructure &Includes,
1239 SpeculativeFuzzyFind *SpecFuzzyFind,
1240 const CodeCompleteOptions &Opts)
1241 : FileName(FileName), Includes(Includes), SpecFuzzyFind(SpecFuzzyFind),
1242 Opts(Opts) {}
1243
1244 CodeCompleteResult run(const SemaCompleteInput &SemaCCInput) && {
1245 trace::Span Tracer("CodeCompleteFlow");
1246 HeuristicPrefix =
1247 guessCompletionPrefix(SemaCCInput.Contents, SemaCCInput.Offset);
1248 populateContextWords(SemaCCInput.Contents);
1249 if (Opts.Index && SpecFuzzyFind && SpecFuzzyFind->CachedReq.hasValue()) {
1250 assert(!SpecFuzzyFind->Result.valid());
1251 SpecReq = speculativeFuzzyFindRequestForCompletion(
1252 *SpecFuzzyFind->CachedReq, HeuristicPrefix);
1253 SpecFuzzyFind->Result = startAsyncFuzzyFind(*Opts.Index, *SpecReq);
1254 }
1255
1256 // We run Sema code completion first. It builds an AST and calculates:
1257 // - completion results based on the AST.
1258 // - partial identifier and context. We need these for the index query.
1259 CodeCompleteResult Output;
1260 auto RecorderOwner = std::make_unique<CompletionRecorder>(Opts, [&]() {
1261 assert(Recorder && "Recorder is not set");
1262 CCContextKind = Recorder->CCContext.getKind();
1263 IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
1264 auto Style = getFormatStyleForFile(
1265 SemaCCInput.FileName, SemaCCInput.Contents, SemaCCInput.VFS.get());
1266 // If preprocessor was run, inclusions from preprocessor callback should
1267 // already be added to Includes.
1268 Inserter.emplace(
1269 SemaCCInput.FileName, SemaCCInput.Contents, Style,
1270 SemaCCInput.Command.Directory,
1271 &Recorder->CCSema->getPreprocessor().getHeaderSearchInfo());
1272 for (const auto &Inc : Includes.MainFileIncludes)
1273 Inserter->addExisting(Inc);
1274
1275 // Most of the cost of file proximity is in initializing the FileDistance
1276 // structures based on the observed includes, once per query. Conceptually
1277 // that happens here (though the per-URI-scheme initialization is lazy).
1278 // The per-result proximity scoring is (amortized) very cheap.
1279 FileDistanceOptions ProxOpts{}; // Use defaults.
1280 const auto &SM = Recorder->CCSema->getSourceManager();
1281 llvm::StringMap<SourceParams> ProxSources;
1282 for (auto &Entry : Includes.includeDepth(
1283 SM.getFileEntryForID(SM.getMainFileID())->getName())) {
1284 auto &Source = ProxSources[Entry.getKey()];
1285 Source.Cost = Entry.getValue() * ProxOpts.IncludeCost;
1286 // Symbols near our transitive includes are good, but only consider
1287 // things in the same directory or below it. Otherwise there can be
1288 // many false positives.
1289 if (Entry.getValue() > 0)
1290 Source.MaxUpTraversals = 1;
1291 }
1292 FileProximity.emplace(ProxSources, ProxOpts);
1293
1294 Output = runWithSema();
1295 Inserter.reset(); // Make sure this doesn't out-live Clang.
1296 SPAN_ATTACH(Tracer, "sema_completion_kind",
1297 getCompletionKindString(CCContextKind));
1298 log("Code complete: sema context {0}, query scopes [{1}] (AnyScope={2}), "
1299 "expected type {3}{4}",
1300 getCompletionKindString(CCContextKind),
1301 llvm::join(QueryScopes.begin(), QueryScopes.end(), ","), AllScopes,
1302 PreferredType ? Recorder->CCContext.getPreferredType().getAsString()
1303 : "<none>",
1304 IsUsingDeclaration ? ", inside using declaration" : "");
1305 });
1306
1307 Recorder = RecorderOwner.get();
1308
1309 semaCodeComplete(std::move(RecorderOwner), Opts.getClangCompleteOpts(),
1310 SemaCCInput, &Includes);
1311 logResults(Output, Tracer);
1312 return Output;
1313 }
1314
1315 void logResults(const CodeCompleteResult &Output, const trace::Span &Tracer) {
1316 SPAN_ATTACH(Tracer, "sema_results", NSema);
1317 SPAN_ATTACH(Tracer, "index_results", NIndex);
1318 SPAN_ATTACH(Tracer, "merged_results", NSemaAndIndex);
1319 SPAN_ATTACH(Tracer, "identifier_results", NIdent);
1320 SPAN_ATTACH(Tracer, "returned_results", int64_t(Output.Completions.size()));
1321 SPAN_ATTACH(Tracer, "incomplete", Output.HasMore);
1322 log("Code complete: {0} results from Sema, {1} from Index, "
1323 "{2} matched, {3} from identifiers, {4} returned{5}.",
1324 NSema, NIndex, NSemaAndIndex, NIdent, Output.Completions.size(),
1325 Output.HasMore ? " (incomplete)" : "");
1326 assert(!Opts.Limit || Output.Completions.size() <= Opts.Limit);
1327 // We don't assert that isIncomplete means we hit a limit.
1328 // Indexes may choose to impose their own limits even if we don't have one.
1329 }
1330
1331 CodeCompleteResult
1332 runWithoutSema(llvm::StringRef Content, size_t Offset,
1333 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) && {
1334 trace::Span Tracer("CodeCompleteWithoutSema");
1335 // Fill in fields normally set by runWithSema()
1336 HeuristicPrefix = guessCompletionPrefix(Content, Offset);
1337 populateContextWords(Content);
1338 CCContextKind = CodeCompletionContext::CCC_Recovery;
1339 IsUsingDeclaration = false;
1340 Filter = FuzzyMatcher(HeuristicPrefix.Name);
1341 auto Pos = offsetToPosition(Content, Offset);
1342 ReplacedRange.start = ReplacedRange.end = Pos;
1343 ReplacedRange.start.character -= HeuristicPrefix.Name.size();
1344
1345 llvm::StringMap<SourceParams> ProxSources;
1346 ProxSources[FileName].Cost = 0;
1347 FileProximity.emplace(ProxSources);
1348
1349 auto Style = getFormatStyleForFile(FileName, Content, VFS.get());
1350 // This will only insert verbatim headers.
1351 Inserter.emplace(FileName, Content, Style,
1352 /*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr);
1353
1354 auto Identifiers = collectIdentifiers(Content, Style);
1355 std::vector<RawIdentifier> IdentifierResults;
1356 for (const auto &IDAndCount : Identifiers) {
1357 RawIdentifier ID;
1358 ID.Name = IDAndCount.first();
1359 ID.References = IDAndCount.second;
1360 // Avoid treating typed filter as an identifier.
1361 if (ID.Name == HeuristicPrefix.Name)
1362 --ID.References;
1363 if (ID.References > 0)
1364 IdentifierResults.push_back(std::move(ID));
1365 }
1366
1367 // Simplified version of getQueryScopes():
1368 // - accessible scopes are determined heuristically.
1369 // - all-scopes query if no qualifier was typed (and it's allowed).
1370 SpecifiedScope Scopes;
1371 Scopes.AccessibleScopes =
1372 visibleNamespaces(Content.take_front(Offset), Style);
1373 for (std::string &S : Scopes.AccessibleScopes)
1374 if (!S.empty())
1375 S.append("::"); // visibleNamespaces doesn't include trailing ::.
1376 if (HeuristicPrefix.Qualifier.empty())
1377 AllScopes = Opts.AllScopes;
1378 else if (HeuristicPrefix.Qualifier.startswith("::")) {
1379 Scopes.AccessibleScopes = {""};
1380 Scopes.UnresolvedQualifier = HeuristicPrefix.Qualifier.drop_front(2);
1381 } else
1382 Scopes.UnresolvedQualifier = HeuristicPrefix.Qualifier;
1383 // First scope is the (modified) enclosing scope.
1384 QueryScopes = Scopes.scopesForIndexQuery();
1385 ScopeProximity.emplace(QueryScopes);
1386
1387 SymbolSlab IndexResults = Opts.Index ? queryIndex() : SymbolSlab();
1388
1389 CodeCompleteResult Output = toCodeCompleteResult(mergeResults(
1390 /*SemaResults=*/{}, IndexResults, IdentifierResults));
1391 Output.RanParser = false;
1392 logResults(Output, Tracer);
1393 return Output;
1394 }
1395
1396 private:
1397 void populateContextWords(llvm::StringRef Content) {
1398 // Take last 3 lines before the completion point.
1399 unsigned RangeEnd = HeuristicPrefix.Qualifier.begin() - Content.data(),
1400 RangeBegin = RangeEnd;
1401 for (size_t I = 0; I < 3 && RangeBegin > 0; ++I) {
1402 auto PrevNL = Content.rfind('\n', RangeBegin);
1403 if (PrevNL == StringRef::npos) {
1404 RangeBegin = 0;
1405 break;
1406 }
1407 RangeBegin = PrevNL;
1408 }
1409
1410 ContextWords = collectWords(Content.slice(RangeBegin, RangeEnd));
1411 dlog("Completion context words: {0}",
1412 llvm::join(ContextWords.keys(), ", "));
1413 }
1414
1415 // This is called by run() once Sema code completion is done, but before the
1416 // Sema data structures are torn down. It does all the real work.
1417 CodeCompleteResult runWithSema() {
1418 const auto &CodeCompletionRange = CharSourceRange::getCharRange(
1419 Recorder->CCSema->getPreprocessor().getCodeCompletionTokenRange());
1420 // When we are getting completions with an empty identifier, for example
1421 // std::vector<int> asdf;
1422 // asdf.^;
1423 // Then the range will be invalid and we will be doing insertion, use
1424 // current cursor position in such cases as range.
1425 if (CodeCompletionRange.isValid()) {
1426 ReplacedRange = halfOpenToRange(Recorder->CCSema->getSourceManager(),
1427 CodeCompletionRange);
1428 } else {
1429 const auto &Pos = sourceLocToPosition(
1430 Recorder->CCSema->getSourceManager(),
1431 Recorder->CCSema->getPreprocessor().getCodeCompletionLoc());
1432 ReplacedRange.start = ReplacedRange.end = Pos;
1433 }
1434 Filter = FuzzyMatcher(
1435 Recorder->CCSema->getPreprocessor().getCodeCompletionFilter());
1436 std::tie(QueryScopes, AllScopes) = getQueryScopes(
1437 Recorder->CCContext, *Recorder->CCSema, HeuristicPrefix, Opts);
1438 if (!QueryScopes.empty())
1439 ScopeProximity.emplace(QueryScopes);
1440 PreferredType =
1441 OpaqueType::fromType(Recorder->CCSema->getASTContext(),
1442 Recorder->CCContext.getPreferredType());
1443 // Sema provides the needed context to query the index.
1444 // FIXME: in addition to querying for extra/overlapping symbols, we should
1445 // explicitly request symbols corresponding to Sema results.
1446 // We can use their signals even if the index can't suggest them.
1447 // We must copy index results to preserve them, but there are at most Limit.
1448 auto IndexResults = (Opts.Index && allowIndex(Recorder->CCContext))
1449 ? queryIndex()
1450 : SymbolSlab();
1451 trace::Span Tracer("Populate CodeCompleteResult");
1452 // Merge Sema and Index results, score them, and pick the winners.
1453 auto Top =
1454 mergeResults(Recorder->Results, IndexResults, /*Identifiers*/ {});
1455 return toCodeCompleteResult(Top);
1456 }
1457
1458 CodeCompleteResult
1459 toCodeCompleteResult(const std::vector<ScoredBundle> &Scored) {
1460 CodeCompleteResult Output;
1461
1462 // Convert the results to final form, assembling the expensive strings.
1463 for (auto &C : Scored) {
1464 Output.Completions.push_back(toCodeCompletion(C.first));
1465 Output.Completions.back().Score = C.second;
1466 Output.Completions.back().CompletionTokenRange = ReplacedRange;
1467 }
1468 Output.HasMore = Incomplete;
1469 Output.Context = CCContextKind;
1470 return Output;
1471 }
1472
1473 SymbolSlab queryIndex() {
1474 trace::Span Tracer("Query index");
1475 SPAN_ATTACH(Tracer, "limit", int64_t(Opts.Limit));
1476
1477 // Build the query.
1478 FuzzyFindRequest Req;
1479 if (Opts.Limit)
1480 Req.Limit = Opts.Limit;
1481 Req.Query = Filter->pattern();
1482 Req.RestrictForCodeCompletion = true;
1483 Req.Scopes = QueryScopes;
1484 Req.AnyScope = AllScopes;
1485 // FIXME: we should send multiple weighted paths here.
1486 Req.ProximityPaths.push_back(FileName);
1487 if (PreferredType)
1488 Req.PreferredTypes.push_back(PreferredType->raw());
1489 vlog("Code complete: fuzzyFind({0:2})", toJSON(Req));
1490
1491 if (SpecFuzzyFind)
1492 SpecFuzzyFind->NewReq = Req;
1493 if (SpecFuzzyFind && SpecFuzzyFind->Result.valid() && (*SpecReq == Req)) {
1494 vlog("Code complete: speculative fuzzy request matches the actual index "
1495 "request. Waiting for the speculative index results.");
1496 SPAN_ATTACH(Tracer, "Speculative results", true);
1497
1498 trace::Span WaitSpec("Wait speculative results");
1499 return SpecFuzzyFind->Result.get();
1500 }
1501
1502 SPAN_ATTACH(Tracer, "Speculative results", false);
1503
1504 // Run the query against the index.
1505 SymbolSlab::Builder ResultsBuilder;
1506 if (Opts.Index->fuzzyFind(
1507 Req, [&](const Symbol &Sym) { ResultsBuilder.insert(Sym); }))
1508 Incomplete = true;
1509 return std::move(ResultsBuilder).build();
1510 }
1511
1512 // Merges Sema and Index results where possible, to form CompletionCandidates.
1513 // \p Identifiers is raw identifiers that can also be completion candidates.
1514 // Identifiers are not merged with results from index or sema.
1515 // Groups overloads if desired, to form CompletionCandidate::Bundles. The
1516 // bundles are scored and top results are returned, best to worst.
1517 std::vector<ScoredBundle>
1518 mergeResults(const std::vector<CodeCompletionResult> &SemaResults,
1519 const SymbolSlab &IndexResults,
1520 const std::vector<RawIdentifier> &IdentifierResults) {
1521 trace::Span Tracer("Merge and score results");
1522 std::vector<CompletionCandidate::Bundle> Bundles;
1523 llvm::DenseMap<size_t, size_t> BundleLookup;
1524 auto AddToBundles = [&](const CodeCompletionResult *SemaResult,
1525 const Symbol *IndexResult,
1526 const RawIdentifier *IdentifierResult) {
1527 CompletionCandidate C;
1528 C.SemaResult = SemaResult;
1529 C.IndexResult = IndexResult;
1530 C.IdentifierResult = IdentifierResult;
1531 if (C.IndexResult) {
1532 C.Name = IndexResult->Name;
1533 C.RankedIncludeHeaders = getRankedIncludes(*C.IndexResult);
1534 } else if (C.SemaResult) {
1535 C.Name = Recorder->getName(*SemaResult);
1536 } else {
1537 assert(IdentifierResult);
1538 C.Name = IdentifierResult->Name;
1539 }
1540 if (auto OverloadSet = C.overloadSet(Opts)) {
1541 auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
1542 if (Ret.second)
1543 Bundles.emplace_back();
1544 Bundles[Ret.first->second].push_back(std::move(C));
1545 } else {
1546 Bundles.emplace_back();
1547 Bundles.back().push_back(std::move(C));
1548 }
1549 };
1550 llvm::DenseSet<const Symbol *> UsedIndexResults;
1551 auto CorrespondingIndexResult =
1552 [&](const CodeCompletionResult &SemaResult) -> const Symbol * {
1553 if (auto SymID =
1554 getSymbolID(SemaResult, Recorder->CCSema->getSourceManager())) {
1555 auto I = IndexResults.find(*SymID);
1556 if (I != IndexResults.end()) {
1557 UsedIndexResults.insert(&*I);
1558 return &*I;
1559 }
1560 }
1561 return nullptr;
1562 };
1563 // Emit all Sema results, merging them with Index results if possible.
1564 for (auto &SemaResult : SemaResults)
1565 AddToBundles(&SemaResult, CorrespondingIndexResult(SemaResult), nullptr);
1566 // Now emit any Index-only results.
1567 for (const auto &IndexResult : IndexResults) {
1568 if (UsedIndexResults.count(&IndexResult))
1569 continue;
1570 AddToBundles(/*SemaResult=*/nullptr, &IndexResult, nullptr);
1571 }
1572 // Emit identifier results.
1573 for (const auto &Ident : IdentifierResults)
1574 AddToBundles(/*SemaResult=*/nullptr, /*IndexResult=*/nullptr, &Ident);
1575 // We only keep the best N results at any time, in "native" format.
1576 TopN<ScoredBundle, ScoredBundleGreater> Top(
1577 Opts.Limit == 0 ? std::numeric_limits<size_t>::max() : Opts.Limit);
1578 for (auto &Bundle : Bundles)
1579 addCandidate(Top, std::move(Bundle));
1580 return std::move(Top).items();
1581 }
1582
1583 llvm::Optional<float> fuzzyScore(const CompletionCandidate &C) {
1584 // Macros can be very spammy, so we only support prefix completion.
1585 // We won't end up with underfull index results, as macros are sema-only.
1586 if (C.SemaResult && C.SemaResult->Kind == CodeCompletionResult::RK_Macro &&
1587 !C.Name.startswith_lower(Filter->pattern()))
1588 return None;
1589 return Filter->match(C.Name);
1590 }
1591
1592 // Scores a candidate and adds it to the TopN structure.
1593 void addCandidate(TopN<ScoredBundle, ScoredBundleGreater> &Candidates,
1594 CompletionCandidate::Bundle Bundle) {
1595 SymbolQualitySignals Quality;
1596 SymbolRelevanceSignals Relevance;
1597 Relevance.Context = CCContextKind;
1598 Relevance.Name = Bundle.front().Name;
1599 Relevance.Query = SymbolRelevanceSignals::CodeComplete;
1600 Relevance.FileProximityMatch = FileProximity.getPointer();
1601 if (ScopeProximity)
1602 Relevance.ScopeProximityMatch = ScopeProximity.getPointer();
1603 if (PreferredType)
1604 Relevance.HadContextType = true;
1605 Relevance.ContextWords = &ContextWords;
1606
1607 auto &First = Bundle.front();
1608 if (auto FuzzyScore = fuzzyScore(First))
1609 Relevance.NameMatch = *FuzzyScore;
1610 else
1611 return;
1612 SymbolOrigin Origin = SymbolOrigin::Unknown;
1613 bool FromIndex = false;
1614 for (const auto &Candidate : Bundle) {
1615 if (Candidate.IndexResult) {
1616 Quality.merge(*Candidate.IndexResult);
1617 Relevance.merge(*Candidate.IndexResult);
1618 Origin |= Candidate.IndexResult->Origin;
1619 FromIndex = true;
1620 if (!Candidate.IndexResult->Type.empty())
1621 Relevance.HadSymbolType |= true;
1622 if (PreferredType &&
1623 PreferredType->raw() == Candidate.IndexResult->Type) {
1624 Relevance.TypeMatchesPreferred = true;
1625 }
1626 }
1627 if (Candidate.SemaResult) {
1628 Quality.merge(*Candidate.SemaResult);
1629 Relevance.merge(*Candidate.SemaResult);
1630 if (PreferredType) {
1631 if (auto CompletionType = OpaqueType::fromCompletionResult(
1632 Recorder->CCSema->getASTContext(), *Candidate.SemaResult)) {
1633 Relevance.HadSymbolType |= true;
1634 if (PreferredType == CompletionType)
1635 Relevance.TypeMatchesPreferred = true;
1636 }
1637 }
1638 Origin |= SymbolOrigin::AST;
1639 }
1640 if (Candidate.IdentifierResult) {
1641 Quality.References = Candidate.IdentifierResult->References;
1642 Relevance.Scope = SymbolRelevanceSignals::FileScope;
1643 Origin |= SymbolOrigin::Identifier;
1644 }
1645 }
1646
1647 CodeCompletion::Scores Scores;
1648 Scores.Quality = Quality.evaluate();
1649 Scores.Relevance = Relevance.evaluate();
1650 Scores.Total = evaluateSymbolAndRelevance(Scores.Quality, Scores.Relevance);
1651 // NameMatch is in fact a multiplier on total score, so rescoring is sound.
1652 Scores.ExcludingName = Relevance.NameMatch
1653 ? Scores.Total / Relevance.NameMatch
1654 : Scores.Quality;
1655
1656 dlog("CodeComplete: {0} ({1}) = {2}\n{3}{4}\n", First.Name,
1657 llvm::to_string(Origin), Scores.Total, llvm::to_string(Quality),
1658 llvm::to_string(Relevance));
1659
1660 NSema += bool(Origin & SymbolOrigin::AST);
1661 NIndex += FromIndex;
1662 NSemaAndIndex += bool(Origin & SymbolOrigin::AST) && FromIndex;
1663 NIdent += bool(Origin & SymbolOrigin::Identifier);
1664 if (Candidates.push({std::move(Bundle), Scores}))
1665 Incomplete = true;
1666 }
1667
1668 CodeCompletion toCodeCompletion(const CompletionCandidate::Bundle &Bundle) {
1669 llvm::Optional<CodeCompletionBuilder> Builder;
1670 for (const auto &Item : Bundle) {
1671 CodeCompletionString *SemaCCS =
1672 Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
1673 : nullptr;
1674 if (!Builder)
1675 Builder.emplace(Recorder ? &Recorder->CCSema->getASTContext() : nullptr,
1676 Item, SemaCCS, QueryScopes, *Inserter, FileName,
1677 CCContextKind, Opts,
1678 /*GenerateSnippets=*/!IsUsingDeclaration);
1679 else
1680 Builder->add(Item, SemaCCS);
1681 }
1682 return Builder->build();
1683 }
1684 };
1685
1686 } // namespace
1687
1688 clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
1689 clang::CodeCompleteOptions Result;
1690 Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns;
1691 Result.IncludeMacros = IncludeMacros;
1692 Result.IncludeGlobals = true;
1693 // We choose to include full comments and not do doxygen parsing in
1694 // completion.
1695 // FIXME: ideally, we should support doxygen in some form, e.g. do markdown
1696 // formatting of the comments.
1697 Result.IncludeBriefComments = false;
1698
1699 // When an is used, Sema is responsible for completing the main file,
1700 // the index can provide results from the preamble.
1701 // Tell Sema not to deserialize the preamble to look for results.
1702 Result.LoadExternal = !Index;
1703 Result.IncludeFixIts = IncludeFixIts;
1704
1705 return Result;
1706 }
1707
1708 CompletionPrefix guessCompletionPrefix(llvm::StringRef Content,
1709 unsigned Offset) {
1710 assert(Offset <= Content.size());
1711 StringRef Rest = Content.take_front(Offset);
1712 CompletionPrefix Result;
1713
1714 // Consume the unqualified name. We only handle ASCII characters.
1715 // isIdentifierBody will let us match "0invalid", but we don't mind.
1716 while (!Rest.empty() && isIdentifierBody(Rest.back()))
1717 Rest = Rest.drop_back();
1718 Result.Name = Content.slice(Rest.size(), Offset);
1719
1720 // Consume qualifiers.
1721 while (Rest.consume_back("::") && !Rest.endswith(":")) // reject ::::
1722 while (!Rest.empty() && isIdentifierBody(Rest.back()))
1723 Rest = Rest.drop_back();
1724 Result.Qualifier =
1725 Content.slice(Rest.size(), Result.Name.begin() - Content.begin());
1726
1727 return Result;
1728 }
1729
1730 CodeCompleteResult
1731 codeComplete(PathRef FileName, const tooling::CompileCommand &Command,
1732 const PreambleData *Preamble, llvm::StringRef Contents,
1733 Position Pos, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
1734 CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind) {
1735 auto Offset = positionToOffset(Contents, Pos);
1736 if (!Offset) {
1737 elog("Code completion position was invalid {0}", Offset.takeError());
1738 return CodeCompleteResult();
1739 }
1740 auto Flow = CodeCompleteFlow(
1741 FileName, Preamble ? Preamble->Includes : IncludeStructure(),
1742 SpecFuzzyFind, Opts);
1743 return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse)
1744 ? std::move(Flow).runWithoutSema(Contents, *Offset, VFS)
1745 : std::move(Flow).run(
1746 {FileName, Command, Preamble, Contents, *Offset, VFS});
1747 }
1748
1749 SignatureHelp signatureHelp(PathRef FileName,
1750 const tooling::CompileCommand &Command,
1751 const PreambleData *Preamble,
1752 llvm::StringRef Contents, Position Pos,
1753 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
1754 const SymbolIndex *Index) {
1755 auto Offset = positionToOffset(Contents, Pos);
1756 if (!Offset) {
1757 elog("Code completion position was invalid {0}", Offset.takeError());
1758 return SignatureHelp();
1759 }
1760 SignatureHelp Result;
1761 clang::CodeCompleteOptions Options;
1762 Options.IncludeGlobals = false;
1763 Options.IncludeMacros = false;
1764 Options.IncludeCodePatterns = false;
1765 Options.IncludeBriefComments = false;
1766 IncludeStructure PreambleInclusions; // Unused for signatureHelp
1767 semaCodeComplete(
1768 std::make_unique<SignatureHelpCollector>(Options, Index, Result),
1769 Options,
1770 {FileName, Command, Preamble, Contents, *Offset, std::move(VFS)});
1771 return Result;
1772 }
1773
1774 bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx) {
1775 auto InTopLevelScope = [](const NamedDecl &ND) {
1776 switch (ND.getDeclContext()->getDeclKind()) {
1777 case Decl::TranslationUnit:
1778 case Decl::Namespace:
1779 case Decl::LinkageSpec:
1780 return true;
1781 default:
1782 break;
1783 };
1784 return false;
1785 };
1786 // We only complete symbol's name, which is the same as the name of the
1787 // *primary* template in case of template specializations.
1788 if (isExplicitTemplateSpecialization(&ND))
1789 return false;
1790
1791 if (InTopLevelScope(ND))
1792 return true;
1793
1794 if (const auto *EnumDecl = dyn_cast<clang::EnumDecl>(ND.getDeclContext()))
1795 return InTopLevelScope(*EnumDecl) && !EnumDecl->isScoped();
1796
1797 return false;
1798 }
1799
1800 CompletionItem CodeCompletion::render(const CodeCompleteOptions &Opts) const {
1801 CompletionItem LSP;
1802 const auto *InsertInclude = Includes.empty() ? nullptr : &Includes[0];
1803 LSP.label = ((InsertInclude && InsertInclude->Insertion)
1804 ? Opts.IncludeIndicator.Insert
1805 : Opts.IncludeIndicator.NoInsert) +
1806 (Opts.ShowOrigins ? "[" + llvm::to_string(Origin) + "]" : "") +
1807 RequiredQualifier + Name + Signature;
1808
1809 LSP.kind = Kind;
1810 LSP.detail = BundleSize > 1 ? llvm::formatv("[{0} overloads]", BundleSize)
1811 : ReturnType;
1812 LSP.deprecated = Deprecated;
1813 if (InsertInclude)
1814 LSP.detail += "\n" + InsertInclude->Header;
1815 LSP.documentation = Documentation;
1816 LSP.sortText = sortText(Score.Total, Name);
1817 LSP.filterText = Name;
1818 LSP.textEdit = {CompletionTokenRange, RequiredQualifier + Name};
1819 // Merge continuous additionalTextEdits into main edit. The main motivation
1820 // behind this is to help LSP clients, it seems most of them are confused when
1821 // they are provided with additionalTextEdits that are consecutive to main
1822 // edit.
1823 // Note that we store additional text edits from back to front in a line. That
1824 // is mainly to help LSP clients again, so that changes do not effect each
1825 // other.
1826 for (const auto &FixIt : FixIts) {
1827 if (isRangeConsecutive(FixIt.range, LSP.textEdit->range)) {
1828 LSP.textEdit->newText = FixIt.newText + LSP.textEdit->newText;
1829 LSP.textEdit->range.start = FixIt.range.start;
1830 } else {
1831 LSP.additionalTextEdits.push_back(FixIt);
1832 }
1833 }
1834 if (Opts.EnableSnippets)
1835 LSP.textEdit->newText += SnippetSuffix;
1836
1837 // FIXME(kadircet): Do not even fill insertText after making sure textEdit is
1838 // compatible with most of the editors.
1839 LSP.insertText = LSP.textEdit->newText;
1840 LSP.insertTextFormat = Opts.EnableSnippets ? InsertTextFormat::Snippet
1841 : InsertTextFormat::PlainText;
1842 if (InsertInclude && InsertInclude->Insertion)
1843 LSP.additionalTextEdits.push_back(*InsertInclude->Insertion);
1844
1845 LSP.score = Score.ExcludingName;
1846
1847 return LSP;
1848 }
1849
1850 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const CodeCompletion &C) {
1851 // For now just lean on CompletionItem.
1852 return OS << C.render(CodeCompleteOptions());
1853 }
1854
1855 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
1856 const CodeCompleteResult &R) {
1857 OS << "CodeCompleteResult: " << R.Completions.size() << (R.HasMore ? "+" : "")
1858 << " (" << getCompletionKindString(R.Context) << ")"
1859 << " items:\n";
1860 for (const auto &C : R.Completions)
1861 OS << C << "\n";
1862 return OS;
1863 }
1864
1865 } // namespace clangd
1866 } // namespace clang
clang::clangd::CompletionItem::insertText
std::string insertText
A string that should be inserted to a document when selecting this completion.
Definition: Protocol.h:977
AccessibleScopes
std::vector< std::string > AccessibleScopes
Definition: CodeComplete.cpp:525
CCSema
Sema * CCSema
Definition: CodeComplete.cpp:691
clang::clangd::HighlightingKind::StaticMethod
Name
llvm::StringRef Name
Definition: CodeComplete.cpp:156
clang::clangd::CodeCompleteOptions::ShowOrigins
bool ShowOrigins
Expose origins of completion items in the label (for debugging).
Definition: CodeComplete.h:86
Command
const tooling::CompileCommand & Command
Definition: CodeComplete.cpp:1019
clang::clangd::RefKind::Unknown
clang::clangd::collectWords
llvm::StringSet collectWords(llvm::StringRef Content)
Collects words from the source code.
Definition: SourceCode.cpp:949
Allocator
std::shared_ptr< clang::GlobalCodeCompletionAllocator > Allocator
Definition: CodeCompletionStringsTests.cpp:33
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:93
clang::clangd::SymbolRelevanceSignals::FileScope
Definition: Quality.h:118
Quality
SignatureQualitySignals Quality
Definition: CodeComplete.cpp:796
clang::clangd::toJSON
llvm::json::Value toJSON(const FuzzyFindRequest &Request)
Definition: Index.cpp:48
clang::clangd::CodeCompleteResult::Context
CodeCompletionContext::Kind Context
Definition: CodeComplete.h:218
AST.h
clang::clangd::printQualifiedName
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
Definition: AST.cpp:169
clang::clangd::CodeCompleteResult::HasMore
bool HasMore
Definition: CodeComplete.h:217
Trace.h
clang::clangd::CompletionItem::textEdit
llvm::Optional< TextEdit > textEdit
An edit which is applied to a document when selecting this completion.
Definition: Protocol.h:988
Contents
llvm::StringRef Contents
Definition: CodeComplete.cpp:1021
clang::clangd::CodeCompleteOptions::NeverParse
Always use text-based completion.
Definition: CodeComplete.h:130
clang::clangd::HighlightingKind::Macro
clang::clangd::CompletionItemKind::Property
clang::clangd::getSymbolID
llvm::Optional< SymbolID > getSymbolID(const Decl *D)
Gets the symbol ID for a declaration, if possible.
Definition: AST.cpp:286
clang::clangd::MessageType::Error
An error message.
Index.h
clang::clangd::OpaqueType::fromType
static llvm::Optional< OpaqueType > fromType(ASTContext &Ctx, QualType Type)
Construct an instance from a clang::QualType.
Definition: ExpectedTypes.cpp:81
clang::clangd::InsertTextFormat::Snippet
The primary text to be inserted is treated as a snippet.
clang::clangd::CompletionItemKind::Class
VFS
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS
Definition: CodeComplete.cpp:1023
Candidate
ExpectedMatch Candidate
Definition: FuzzyMatchTests.cpp:47
clang::clangd::CodeCompleteResult
Definition: CodeComplete.h:215
clang::clangd::CompletionItem::kind
CompletionItemKind kind
The kind of this completion item.
Definition: Protocol.h:958
Symbol.h
clang::clangd::lspLength
size_t lspLength(llvm::StringRef Code)
Definition: SourceCode.cpp:131
clang::clangd::SymbolOrigin::Identifier
clang::clangd::CodeCompleteOptions::EnableSnippets
bool EnableSnippets
When true, completion items will contain expandable code snippets in completion (e.g.
Definition: CodeComplete.h:46
clang::clangd::CompletionItem
Definition: Protocol.h:951
SymbolKind
clang::find_all_symbols::SymbolInfo::SymbolKind SymbolKind
Definition: SymbolInfo.cpp:21
clang::clangd::InsertTextFormat::PlainText
The primary text to be inserted is treated as a plain string.
clang::clangd::printNamespaceScope
std::string printNamespaceScope(const DeclContext &DC)
Returns the first enclosing namespace scope starting from DC.
Definition: AST.cpp:278
clang::clangd::CodeCompleteResult::Completions
std::vector< CodeCompletion > Completions
Definition: CodeComplete.h:216
clang::clangd::SymbolIndex
Interface for symbol indexes that can be used for searching or matching symbols among a set of symbol...
Definition: Index.h:85
SourceCode.h
clang::clangd::splitQualifiedName
std::pair< StringRef, StringRef > splitQualifiedName(StringRef QName)
Definition: SourceCode.cpp:599
clang::clangd::sortText
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:481
Protocol.h
clang::clangd::Position
Definition: Protocol.h:127
clang::clangd::PathRef
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:23
clang::clangd::CompletionItemKind::Folder
UnresolvedQualifier
llvm::Optional< std::string > UnresolvedQualifier
Definition: CodeComplete.cpp:528
Results
std::vector< CodeCompletionResult > Results
Definition: CodeComplete.cpp:689
clang::clangd::CompletionItem::sortText
std::string sortText
A string that should be used when comparing this item with other items.
Definition: Protocol.h:969
clang::clangd::getDocComment
std::string getDocComment(const ASTContext &Ctx, const CodeCompletionResult &Result, bool CommentsFromHeaders)
Gets a minimally formatted documentation comment of Result, with comment markers stripped.
Definition: CodeCompletionStrings.cpp:61
clang::clangd::SymbolRelevanceSignals::CodeComplete
Definition: Quality.h:123
clang::clangd::prepareCompilerInstance
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:72
clang::clangd::TextDocumentSyncKind::None
Documents should not be synced at all.
clang::clangd::CompletionItem::documentation
std::string documentation
A human-readable string that represents a doc-comment.
Definition: Protocol.h:965
clang::clangd::IncludeStructure
Definition: Headers.h:109
clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator::Insert
std::string Insert
Definition: CodeComplete.h:81
clang::clangd::vlog
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:67
clang::clangd::CompletionItem::additionalTextEdits
std::vector< TextEdit > additionalTextEdits
An optional array of additional text edits that are applied when selecting this completion.
Definition: Protocol.h:993
clang::clangd::elog
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:56
clang::clangd::visibleNamespaces
std::vector< std::string > visibleNamespaces(llvm::StringRef Code, const format::FormatStyle &Style)
Heuristically determine namespaces visible at a point, without parsing Code.
Definition: SourceCode.cpp:901
Headers.h
clang::clangd::isRangeConsecutive
bool isRangeConsecutive(const Range &Left, const Range &Right)
Definition: SourceCode.cpp:670
clang::clangd::CompletionPrefix
Definition: CodeComplete.h:282
clang::clangd::CompletionItemKind
CompletionItemKind
The kind of a completion entry.
Definition: Protocol.h:260
clang::clangd::getReturnType
std::string getReturnType(const CodeCompletionString &CCS)
Gets detail to be used as the detail field in an LSP completion item.
Definition: CodeCompletionStrings.cpp:238
clang::clangd::signatureHelp
SignatureHelp signatureHelp(PathRef FileName, const tooling::CompileCommand &Command, const PreambleData *Preamble, llvm::StringRef Contents, Position Pos, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, const SymbolIndex *Index)
Definition: CodeComplete.cpp:1749
Kind
BindArgumentKind Kind
Definition: AvoidBindCheck.cpp:57
clang::clangd::CompletionItemKind::Missing
clang::clangd::CompletionItemKind::Text
clang::clangd::CompletionItem::detail
std::string detail
A human-readable string with additional information about this item, like type or symbol information...
Definition: Protocol.h:962
Score
llvm::Optional< float > Score
Definition: FuzzyMatchTests.cpp:48
clang::clangd::HighlightingKind::Parameter
clang::clangd::offsetToClangLineColumn
std::pair< size_t, size_t > offsetToClangLineColumn(llvm::StringRef Code, size_t Offset)
Definition: SourceCode.cpp:589
clang::clangd::getSymbolInfo
std::vector< SymbolDetails > getSymbolInfo(ParsedAST &AST, Position Pos)
Get info about symbols at Pos.
Definition: XRefs.cpp:519
clang::clangd::toTextEdit
TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, const LangOptions &L)
Definition: SourceCode.cpp:661
clang::clangd::SymbolOrigin::AST
CodeComplete.h
clang::clangd::offsetToPosition
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
Definition: SourceCode.cpp:188
Preamble.h
clang::clangd::isIndexedForCodeCompletion
bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx)
Definition: CodeComplete.cpp:1774
IgnoreDiags
IgnoringDiagConsumer IgnoreDiags
Definition: HeadersTests.cpp:124
clang::clangd::CompletionItem::filterText
std::string filterText
A string that should be used when filtering a set of completion items.
Definition: Protocol.h:973
clang::clangd::positionToOffset
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:155
FileDistance.h
Compiler.h
clang::clangd::SpeculativeFuzzyFind
A speculative and asynchronous fuzzy find index request (based on cached request) that can be sent be...
Definition: CodeComplete.h:228
clang::clangd::CompletionItem::deprecated
bool deprecated
Indicates if this item is deprecated.
Definition: Protocol.h:996
Action
llvm::unique_function< void()> Action
Definition: TUScheduler.cpp:234
clang::clangd::CompletionItemKind::Field
Diagnostics.h
CodeCompletionStrings.h
clang::clangd::CompletionItemKind::Enum
Signature
std::string Signature
Definition: CodeComplete.cpp:394
clang::clangd::log
void log(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:62
clang::clangd::toString
static const char * toString(OffsetEncoding OE)
Definition: Protocol.cpp:1031
dlog
#define dlog(...)
Definition: Logger.h:72
clang::clangd::toHeaderFile
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:77
clang::clangd::CodeCompleteOptions
Definition: CodeComplete.h:39
clang::clangd::CompletionItemKind::Snippet
clang::clangd::CodeCompleteOptions::RunParser
enum clang::clangd::CodeCompleteOptions::CodeCompletionParse RunParser
Quality.h
clang::clangd::CompletionItemKind::Interface
IndexResult
const Symbol * IndexResult
Definition: CodeComplete.cpp:166
FileName
PathRef FileName
Definition: CodeComplete.cpp:1018
clang::clangd::formatDocumentation
std::string formatDocumentation(const CodeCompletionString &CCS, llvm::StringRef DocComment)
Assembles formatted documentation for a completion result.
Definition: CodeCompletionStrings.cpp:208
SyntaxOnlyAction
clang::clangd::CodeCompleteOptions::NeverInsert
Definition: CodeComplete.h:75
clang::clangd::CompletionItemKind::Method
ReturnType
std::string ReturnType
Definition: CodeComplete.cpp:395
Pos
Position Pos
Definition: SourceCode.cpp:772
clang::clangd::CodeCompleteOptions::getClangCompleteOpts
clang::CodeCompleteOptions getClangCompleteOpts() const
Returns options that can be passed to clang&#39;s completion engine.
Definition: CodeComplete.cpp:1688
SnippetSuffix
std::string SnippetSuffix
Definition: CodeComplete.cpp:393
clang::clangd::CompletionPrefix::Qualifier
llvm::StringRef Qualifier
Definition: CodeComplete.h:288
clang::clangd::sourceLocToPosition
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc)
Turn a SourceLocation into a [line, column] pair.
Definition: SourceCode.cpp:200
ExpectedTypes.h
clang::clangd::MessageType::Info
An information message.
clang::clangd::getFormatStyleForFile
format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, llvm::vfs::FileSystem *FS)
Choose the clang-format style we should apply to a certain file.
Definition: SourceCode.cpp:693
clang::clangd::CompletionPrefix::Name
llvm::StringRef Name
Definition: CodeComplete.h:285
clang::clangd::codeComplete
CodeCompleteResult codeComplete(PathRef FileName, const tooling::CompileCommand &Command, const PreambleData *Preamble, llvm::StringRef Contents, Position Pos, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind)
Definition: CodeComplete.cpp:1731
clang::clangd::evaluateSymbolAndRelevance
float evaluateSymbolAndRelevance(float SymbolQuality, float SymbolRelevance)
Combine symbol quality and relevance into a single score.
Definition: Quality.cpp:463
Builder
CodeCompletionBuilder Builder
Definition: CodeCompletionStringsTests.cpp:35
clang::clangd::CompletionItem::score
float score
This is Clangd extension.
Definition: Protocol.h:1003
Logger.h
Offset
size_t Offset
Definition: CodeComplete.cpp:1022
clang::clangd::getDeclComment
std::string getDeclComment(const ASTContext &Ctx, const NamedDecl &Decl)
Similar to getDocComment, but returns the comment for a NamedDecl.
Definition: CodeCompletionStrings.cpp:73
clang::clangd::CompletionItemKind::Function
clang::clangd::SignatureHelp
Represents the signature of a callable.
Definition: Protocol.h:1061
clang::clangd::isExplicitTemplateSpecialization
bool isExplicitTemplateSpecialization(const NamedDecl *D)
Indicates if D is an explicit template specialization, e.g.
Definition: AST.cpp:153
Preamble
const PreambleData * Preamble
Definition: CodeComplete.cpp:1020
clang::clangd::collectIncludeStructureCallback
std::unique_ptr< PPCallbacks > collectIncludeStructureCallback(const SourceManager &SM, IncludeStructure *Out)
Returns a PPCallback that visits all inclusions in the main file.
Definition: Headers.cpp:113
RankedIncludeHeaders
llvm::SmallVector< llvm::StringRef, 1 > RankedIncludeHeaders
Definition: CodeComplete.cpp:168
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::X
static URISchemeRegistry::Add< TestScheme > X(TestScheme::Scheme, "Test schema")
References
unsigned References
Definition: CodeComplete.cpp:157
clang::clangd::CompletionItemKind::Module
clang::clangd::CompletionItem::label
std::string label
The label of this completion item.
Definition: Protocol.h:954
clang::clangd::CodeCompletion::render
CompletionItem render(const CodeCompleteOptions &) const
Definition: CodeComplete.cpp:1800
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:28
clang::clangd::CodeCompleteOptions::IncludeIndicator
struct clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator IncludeIndicator
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:38
clang::clangd::getRankedIncludes
llvm::SmallVector< llvm::StringRef, 1 > getRankedIncludes(const Symbol &Sym)
Definition: Headers.cpp:97
CCTUInfo
CodeCompletionTUInfo CCTUInfo
Definition: CodeCompletionStringsTests.cpp:34
clang::clangd::SymbolKind::Namespace
clang::clangd::buildCompilerInvocation
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:44
clang::clangd::getSignature
void getSignature(const CodeCompletionString &CCS, std::string *Signature, std::string *Snippet, std::string *RequiredQualifiers, bool CompletingPattern)
Formats the signature for an item, as a display string and snippet.
Definition: CodeCompletionStrings.cpp:92
SymbolOrigin.h
URI.h
clang::clangd::CompletionItemKind::Struct
clang::clangd::SymbolOrigin::Unknown
SemaResult
const CodeCompletionResult * SemaResult
Definition: CodeComplete.cpp:165
Expected
std::vector< const char * > Expected
Definition: PrintASTTests.cpp:27
IdentifierResult
const RawIdentifier * IdentifierResult
Definition: CodeComplete.cpp:167
E
const Expr * E
Definition: AvoidBindCheck.cpp:82
clang::clangd::CompletionItemKind::Variable
clang::clangd::URI::resolve
static llvm::Expected< std::string > resolve(const URI &U, llvm::StringRef HintPath="")
Resolves the absolute path of U.
Definition: URI.cpp:233
clang::clangd::HighlightingKind::EnumConstant
clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator::NoInsert
std::string NoInsert
Definition: CodeComplete.h:82
FixIt
llvm::Optional< FixItHint > FixIt
Definition: UppercaseLiteralSuffixCheck.cpp:62
clang::clangd::Symbol::Deprecated
Indicates if the symbol is deprecated.
Definition: Symbol.h:121
clang::tidy::cppcoreguidelines::join
static std::string join(ArrayRef< SpecialMemberFunctionsCheck::SpecialMemberFunctionKind > SMFS, llvm::StringRef AndOr)
Definition: SpecialMemberFunctionsCheck.cpp:81
clang::clangd::PreambleData::Includes
IncludeStructure Includes
Definition: Preamble.h:56
clang::clangd::guessCompletionPrefix
CompletionPrefix guessCompletionPrefix(llvm::StringRef Content, unsigned Offset)
Definition: CodeComplete.cpp:1708
clang::clangd::CompletionItemKind::Constructor
clang::clangd::operator<<
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
Definition: CodeComplete.cpp:1850
clang::clangd::PreambleData
The parsed preamble and associated data.
Definition: Preamble.h:45
clang::clangd::CodeCompletion
Definition: CodeComplete.h:137
clang::clangd::CompletionItemKind::File
clang::clangd::CompletionItem::insertTextFormat
InsertTextFormat insertTextFormat
The format of the insert text.
Definition: Protocol.h:981
clang::clangd::collectIdentifiers
llvm::StringMap< unsigned > collectIdentifiers(llvm::StringRef Content, const format::FormatStyle &Style)
Collects identifiers with counts in the source code.
Definition: SourceCode.cpp:735
clang::clangd::CompletionItemKind::Value
clang::clangd::SymbolOrigin
SymbolOrigin
Definition: SymbolOrigin.h:21
CCContext
CodeCompletionContext CCContext
Definition: CodeComplete.cpp:690
SPAN_ATTACH
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Definition: Trace.h:97
IDForDoc
llvm::Optional< SymbolID > IDForDoc
Definition: CodeComplete.cpp:794
TUScheduler.h
FuzzyMatch.h
Entry
Definition: Modularize.cpp:429
clang::clangd::OpaqueType::fromCompletionResult
static llvm::Optional< OpaqueType > fromCompletionResult(ASTContext &Ctx, const CodeCompletionResult &R)
Create a type from a code completion result.
Definition: ExpectedTypes.cpp:87
clang::clangd::CompletionItemKind::Keyword
clang::clangd::CompletionItemKind::Reference
clang::clangd::halfOpenToRange
Range halfOpenToRange(const SourceManager &SM, CharSourceRange R)
Definition: SourceCode.cpp:581
Index
const SymbolIndex * Index
Definition: Dexp.cpp:84
Threading.h