43 #include "clang/AST/Decl.h"
44 #include "clang/AST/DeclBase.h"
45 #include "clang/Basic/CharInfo.h"
46 #include "clang/Basic/LangOptions.h"
47 #include "clang/Basic/SourceLocation.h"
48 #include "clang/Basic/TokenKinds.h"
49 #include "clang/Format/Format.h"
50 #include "clang/Frontend/CompilerInstance.h"
51 #include "clang/Frontend/FrontendActions.h"
52 #include "clang/Lex/ExternalPreprocessorSource.h"
53 #include "clang/Lex/Lexer.h"
54 #include "clang/Lex/Preprocessor.h"
55 #include "clang/Lex/PreprocessorOptions.h"
56 #include "clang/Sema/CodeCompleteConsumer.h"
57 #include "clang/Sema/DeclSpec.h"
58 #include "clang/Sema/Sema.h"
59 #include "llvm/ADT/ArrayRef.h"
60 #include "llvm/ADT/None.h"
61 #include "llvm/ADT/Optional.h"
62 #include "llvm/ADT/SmallVector.h"
63 #include "llvm/ADT/StringExtras.h"
64 #include "llvm/ADT/StringRef.h"
65 #include "llvm/Support/Compiler.h"
66 #include "llvm/Support/Debug.h"
67 #include "llvm/Support/Error.h"
68 #include "llvm/Support/Format.h"
69 #include "llvm/Support/FormatVariadic.h"
70 #include "llvm/Support/ScopedPrinter.h"
75 #define DEBUG_TYPE "CodeComplete"
88 case SK::NamespaceAlias:
108 case SK::ConversionFunction:
112 case SK::NonTypeTemplateParm:
118 case SK::InstanceMethod:
119 case SK::ClassMethod:
123 case SK::InstanceProperty:
124 case SK::ClassProperty:
125 case SK::StaticProperty:
129 case SK::TemplateTypeParm:
130 case SK::TemplateTemplateParm:
133 llvm_unreachable(
"Unhandled clang::index::SymbolKind.");
137 toCompletionItemKind(CodeCompletionResult::ResultKind ResKind,
138 const NamedDecl *
Decl,
142 if (CtxKind == CodeCompletionContext::CCC_IncludedFile)
145 case CodeCompletionResult::RK_Declaration:
146 llvm_unreachable(
"RK_Declaration without Decl");
147 case CodeCompletionResult::RK_Keyword:
149 case CodeCompletionResult::RK_Macro:
152 case CodeCompletionResult::RK_Pattern:
155 llvm_unreachable(
"Unhandled CodeCompletionResult::ResultKind.");
159 struct RawIdentifier {
166 struct CompletionCandidate {
167 llvm::StringRef
Name;
176 size_t overloadSet(
const CodeCompleteOptions &Opts)
const {
177 if (!Opts.BundleOverloads.getValueOr(
false))
179 llvm::SmallString<256> Scratch;
182 case index::SymbolKind::ClassMethod:
183 case index::SymbolKind::InstanceMethod:
184 case index::SymbolKind::StaticMethod:
186 llvm_unreachable(
"Don't expect members from index in code completion");
190 case index::SymbolKind::Function:
193 return llvm::hash_combine(
195 headerToInsertIfAllowed(Opts).getValueOr(
""));
203 if (!D || !D->isFunctionOrFunctionTemplate())
206 llvm::raw_svector_ostream
OS(Scratch);
207 D->printQualifiedName(
OS);
209 return llvm::hash_combine(Scratch,
210 headerToInsertIfAllowed(Opts).getValueOr(
""));
217 llvm::Optional<llvm::StringRef>
218 headerToInsertIfAllowed(
const CodeCompleteOptions &Opts)
const {
225 auto &SM =
SemaResult->Declaration->getASTContext().getSourceManager();
227 if (SM.isInMainFile(SM.getExpansionLoc(RD->getBeginLoc())))
233 using Bundle = llvm::SmallVector<CompletionCandidate, 4>;
236 std::pair<CompletionCandidate::Bundle, CodeCompletion::Scores>;
237 struct ScoredBundleGreater {
238 bool operator()(
const ScoredBundle &L,
const ScoredBundle &R) {
239 if (L.second.Total != R.second.Total)
240 return L.second.Total > R.second.Total;
241 return L.first.front().Name <
242 R.first.front().Name;
253 struct CodeCompletionBuilder {
254 CodeCompletionBuilder(ASTContext *ASTCtx,
const CompletionCandidate &C,
255 CodeCompletionString *SemaCCS,
256 llvm::ArrayRef<std::string> QueryScopes,
257 const IncludeInserter &Includes,
260 const CodeCompleteOptions &Opts,
261 bool IsUsingDeclaration, tok::TokenKind NextTokenKind)
262 : ASTCtx(ASTCtx), ExtractDocumentation(Opts.IncludeComments),
263 EnableFunctionArgSnippets(Opts.EnableFunctionArgSnippets),
264 IsUsingDeclaration(IsUsingDeclaration), NextTokenKind(NextTokenKind) {
269 Completion.Name = std::string(llvm::StringRef(SemaCCS->getTypedText()));
270 if (Completion.Scope.empty()) {
271 if ((C.SemaResult->Kind == CodeCompletionResult::RK_Declaration) ||
272 (C.SemaResult->Kind == CodeCompletionResult::RK_Pattern))
273 if (
const auto *D = C.SemaResult->getDeclaration())
274 if (
const auto *ND = dyn_cast<NamedDecl>(D))
275 Completion.Scope = std::string(
278 Completion.Kind = toCompletionItemKind(
279 C.SemaResult->Kind, C.SemaResult->Declaration, ContextKind);
283 Completion.Name.back() ==
'/')
285 for (
const auto &
FixIt : C.SemaResult->FixIts) {
287 FixIt, ASTCtx->getSourceManager(), ASTCtx->getLangOpts()));
289 llvm::sort(Completion.FixIts, [](
const TextEdit &
X,
const TextEdit &Y) {
290 return std::tie(X.range.start.line, X.range.start.character) <
291 std::tie(Y.range.start.line, Y.range.start.character);
293 Completion.Deprecated |=
294 (C.SemaResult->Availability == CXAvailability_Deprecated);
297 Completion.Origin |= C.IndexResult->Origin;
298 if (Completion.Scope.empty())
299 Completion.Scope = std::string(C.IndexResult->Scope);
301 Completion.Kind = toCompletionItemKind(C.IndexResult->SymInfo.Kind);
302 if (Completion.Name.empty())
303 Completion.Name = std::string(C.IndexResult->Name);
306 if (Completion.RequiredQualifier.empty() && !C.SemaResult) {
307 llvm::StringRef ShortestQualifier = C.IndexResult->Scope;
308 for (llvm::StringRef Scope : QueryScopes) {
309 llvm::StringRef
Qualifier = C.IndexResult->Scope;
311 Qualifier.size() < ShortestQualifier.size())
312 ShortestQualifier = Qualifier;
314 Completion.RequiredQualifier = std::string(ShortestQualifier);
318 if (C.IdentifierResult) {
321 Completion.Name = std::string(C.IdentifierResult->Name);
325 auto Inserted = [&](llvm::StringRef Header)
327 auto ResolvedDeclaring =
329 if (!ResolvedDeclaring)
330 return ResolvedDeclaring.takeError();
332 if (!ResolvedInserted)
333 return ResolvedInserted.takeError();
334 auto Spelled = Includes.calculateIncludePath(*ResolvedInserted,
FileName);
336 return llvm::createStringError(llvm::inconvertibleErrorCode(),
337 "Header not on include path");
338 return std::make_pair(
340 Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
342 bool ShouldInsert = C.headerToInsertIfAllowed(Opts).hasValue();
344 for (
const auto &Inc : C.RankedIncludeHeaders) {
345 if (
auto ToInclude = Inserted(Inc)) {
346 CodeCompletion::IncludeCandidate Include;
347 Include.Header = ToInclude->first;
348 if (ToInclude->second && ShouldInsert)
349 Include.Insertion = Includes.insert(ToInclude->first);
350 Completion.Includes.push_back(std::move(Include));
352 log(
"Failed to generate include insertion edits for adding header "
353 "(FileURI='{0}', IncludeHeader='{1}') into {2}: {3}",
354 C.IndexResult->CanonicalDeclaration.FileURI, Inc,
FileName,
355 ToInclude.takeError());
358 std::stable_partition(Completion.Includes.begin(),
359 Completion.Includes.end(),
360 [](
const CodeCompletion::IncludeCandidate &I) {
361 return !I.Insertion.hasValue();
365 void add(
const CompletionCandidate &C, CodeCompletionString *SemaCCS) {
366 assert(
bool(C.SemaResult) ==
bool(SemaCCS));
367 Bundled.emplace_back();
368 BundledEntry &S = Bundled.back();
370 bool IsPattern = C.SemaResult->Kind == CodeCompletionResult::RK_Pattern;
372 &Completion.RequiredQualifier, IsPattern);
374 }
else if (C.IndexResult) {
375 S.Signature = std::string(C.IndexResult->Signature);
376 S.SnippetSuffix = std::string(C.IndexResult->CompletionSnippetSuffix);
377 S.ReturnType = std::string(C.IndexResult->ReturnType);
379 if (ExtractDocumentation && !Completion.Documentation) {
380 auto SetDoc = [&](llvm::StringRef Doc) {
382 Completion.Documentation.emplace();
387 SetDoc(C.IndexResult->Documentation);
388 }
else if (C.SemaResult) {
395 CodeCompletion build() {
396 Completion.ReturnType = summarizeReturnType();
397 Completion.Signature = summarizeSignature();
398 Completion.SnippetSuffix = summarizeSnippet();
399 Completion.BundleSize = Bundled.size();
400 return std::move(Completion);
404 struct BundledEntry {
411 template <std::
string BundledEntry::*Member>
412 const std::string *onlyValue()
const {
413 auto B = Bundled.begin(),
E = Bundled.end();
414 for (
auto I = B + 1; I !=
E; ++I)
415 if (I->*Member != B->*Member)
417 return &(B->*Member);
420 template <
bool BundledEntry::*Member>
const bool *onlyValue()
const {
421 auto B = Bundled.begin(),
E = Bundled.end();
422 for (
auto I = B + 1; I !=
E; ++I)
423 if (I->*Member != B->*Member)
425 return &(B->*Member);
428 std::string summarizeReturnType()
const {
429 if (
auto *RT = onlyValue<&BundledEntry::ReturnType>())
434 std::string summarizeSnippet()
const {
435 if (IsUsingDeclaration)
441 NextTokenKind == tok::l_paren)
443 auto *
Snippet = onlyValue<&BundledEntry::SnippetSuffix>();
449 if (EnableFunctionArgSnippets)
465 bool EmptyArgs = llvm::StringRef(*Snippet).endswith(
"()");
467 return EmptyArgs ?
"<$1>()$0" :
"<$1>($0)";
469 return EmptyArgs ?
"()" :
"($0)";
480 if (llvm::StringRef(*Snippet).endswith(
"<>"))
487 std::string summarizeSignature()
const {
488 if (
auto *
Signature = onlyValue<&BundledEntry::Signature>())
496 CodeCompletion Completion;
497 llvm::SmallVector<BundledEntry, 1> Bundled;
498 bool ExtractDocumentation;
499 bool EnableFunctionArgSnippets;
502 bool IsUsingDeclaration;
503 tok::TokenKind NextTokenKind;
507 llvm::Optional<SymbolID>
getSymbolID(
const CodeCompletionResult &R,
508 const SourceManager &SM) {
510 case CodeCompletionResult::RK_Declaration:
511 case CodeCompletionResult::RK_Pattern: {
517 case CodeCompletionResult::RK_Macro:
519 case CodeCompletionResult::RK_Keyword:
522 llvm_unreachable(
"unknown CodeCompletionResult kind");
527 struct SpecifiedScope {
555 std::vector<std::string> scopesForIndexQuery() {
567 std::pair<std::vector<std::string>,
bool>
569 const CompletionPrefix &HeuristicPrefix,
570 const CodeCompleteOptions &Opts) {
571 SpecifiedScope Scopes;
572 for (
auto *Context :
CCContext.getVisitedContexts()) {
573 if (isa<TranslationUnitDecl>(Context))
574 Scopes.AccessibleScopes.push_back(
"");
575 else if (isa<NamespaceDecl>(Context))
579 const CXXScopeSpec *SemaSpecifier =
580 CCContext.getCXXScopeSpecifier().getValueOr(
nullptr);
582 if (!SemaSpecifier) {
585 if (!HeuristicPrefix.
Qualifier.empty()) {
586 vlog(
"Sema said no scope specifier, but we saw {0} in the source code",
588 StringRef SpelledSpecifier = HeuristicPrefix.
Qualifier;
589 if (SpelledSpecifier.consume_front(
"::"))
590 Scopes.AccessibleScopes = {
""};
591 Scopes.UnresolvedQualifier = std::string(SpelledSpecifier);
592 return {Scopes.scopesForIndexQuery(),
false};
595 std::vector<std::string> EnclosingAtFront;
597 EnclosingAtFront.push_back(EnclosingScope);
598 for (
auto &S : Scopes.scopesForIndexQuery()) {
599 if (EnclosingScope != S)
600 EnclosingAtFront.push_back(std::move(S));
603 return {EnclosingAtFront, Opts.
AllScopes};
606 if (SemaSpecifier && SemaSpecifier->isValid())
607 return {Scopes.scopesForIndexQuery(),
false};
610 Scopes.AccessibleScopes.push_back(
"");
611 llvm::StringRef SpelledSpecifier = Lexer::getSourceText(
612 CharSourceRange::getCharRange(SemaSpecifier->getRange()),
613 CCSema.SourceMgr, clang::LangOptions());
614 if (SpelledSpecifier.consume_front(
"::"))
615 Scopes.AccessibleScopes = {
""};
616 Scopes.UnresolvedQualifier = std::string(SpelledSpecifier);
618 if (!Scopes.UnresolvedQualifier->empty())
619 *Scopes.UnresolvedQualifier +=
"::";
621 return {Scopes.scopesForIndexQuery(),
false};
628 case CodeCompletionContext::CCC_TopLevel:
629 case CodeCompletionContext::CCC_ObjCInterface:
630 case CodeCompletionContext::CCC_ObjCImplementation:
631 case CodeCompletionContext::CCC_ObjCIvarList:
632 case CodeCompletionContext::CCC_ClassStructUnion:
633 case CodeCompletionContext::CCC_Statement:
634 case CodeCompletionContext::CCC_Expression:
635 case CodeCompletionContext::CCC_ObjCMessageReceiver:
636 case CodeCompletionContext::CCC_EnumTag:
637 case CodeCompletionContext::CCC_UnionTag:
638 case CodeCompletionContext::CCC_ClassOrStructTag:
639 case CodeCompletionContext::CCC_ObjCProtocolName:
640 case CodeCompletionContext::CCC_Namespace:
641 case CodeCompletionContext::CCC_Type:
642 case CodeCompletionContext::CCC_ParenthesizedExpression:
643 case CodeCompletionContext::CCC_ObjCInterfaceName:
644 case CodeCompletionContext::CCC_ObjCCategoryName:
645 case CodeCompletionContext::CCC_Symbol:
646 case CodeCompletionContext::CCC_SymbolOrNewName:
648 case CodeCompletionContext::CCC_OtherWithMacros:
649 case CodeCompletionContext::CCC_DotMemberAccess:
650 case CodeCompletionContext::CCC_ArrowMemberAccess:
651 case CodeCompletionContext::CCC_ObjCPropertyAccess:
652 case CodeCompletionContext::CCC_MacroName:
653 case CodeCompletionContext::CCC_MacroNameUse:
654 case CodeCompletionContext::CCC_PreprocessorExpression:
655 case CodeCompletionContext::CCC_PreprocessorDirective:
656 case CodeCompletionContext::CCC_SelectorName:
657 case CodeCompletionContext::CCC_TypeQualifiers:
658 case CodeCompletionContext::CCC_ObjCInstanceMessage:
659 case CodeCompletionContext::CCC_ObjCClassMessage:
660 case CodeCompletionContext::CCC_IncludedFile:
662 case CodeCompletionContext::CCC_Other:
663 case CodeCompletionContext::CCC_NaturalLanguage:
664 case CodeCompletionContext::CCC_Recovery:
665 case CodeCompletionContext::CCC_NewName:
668 llvm_unreachable(
"unknown code completion context");
671 static bool isInjectedClass(
const NamedDecl &D) {
672 if (
auto *R = dyn_cast_or_null<RecordDecl>(&D))
673 if (R->isInjectedClassName())
679 static bool isExcludedMember(
const NamedDecl &D) {
682 if (D.getKind() == Decl::CXXDestructor)
685 if (isInjectedClass(D))
688 auto NameKind = D.getDeclName().getNameKind();
689 if (NameKind == DeclarationName::CXXOperatorName ||
690 NameKind == DeclarationName::CXXLiteralOperatorName ||
691 NameKind == DeclarationName::CXXConversionFunctionName)
702 struct CompletionRecorder :
public CodeCompleteConsumer {
703 CompletionRecorder(
const CodeCompleteOptions &Opts,
704 llvm::unique_function<
void()> ResultsCallback)
705 : CodeCompleteConsumer(Opts.getClangCompleteOpts()),
706 CCContext(CodeCompletionContext::CCC_Other), Opts(Opts),
707 CCAllocator(std::make_shared<GlobalCodeCompletionAllocator>()),
708 CCTUInfo(CCAllocator), ResultsCallback(std::move(ResultsCallback)) {
709 assert(this->ResultsCallback);
717 void ProcessCodeCompleteResults(
class Sema &S, CodeCompletionContext Context,
718 CodeCompletionResult *InResults,
719 unsigned NumResults)
override final {
728 if (Context.getKind() == CodeCompletionContext::CCC_Recovery) {
729 log(
"Code complete: Ignoring sema code complete callback with Recovery "
736 if (NumResults == 0 && !contextAllowsIndex(Context.getKind()))
739 log(
"Multiple code complete callbacks (parser backtracked?). "
740 "Dropping results from context {0}, keeping results from {1}.",
741 getCompletionKindString(Context.getKind()),
742 getCompletionKindString(this->CCContext.getKind()));
750 for (
unsigned I = 0; I < NumResults; ++I) {
751 auto &Result = InResults[I];
753 if (Result.Hidden && Result.Declaration &&
754 Result.Declaration->isCXXClassMember())
756 if (!Opts.IncludeIneligibleResults &&
757 (Result.Availability == CXAvailability_NotAvailable ||
758 Result.Availability == CXAvailability_NotAccessible))
760 if (Result.Declaration &&
761 !Context.getBaseType().isNull()
762 && isExcludedMember(*Result.Declaration))
766 if (Result.Declaration && !Context.getCXXScopeSpecifier().hasValue() &&
767 isInjectedClass(*Result.Declaration))
770 Result.StartsNestedNameSpecifier =
false;
776 CodeCompletionAllocator &getAllocator()
override {
return *CCAllocator; }
777 CodeCompletionTUInfo &getCodeCompletionTUInfo()
override {
return CCTUInfo; }
781 llvm::StringRef getName(
const CodeCompletionResult &Result) {
782 switch (Result.Kind) {
783 case CodeCompletionResult::RK_Declaration:
784 if (
auto *ID = Result.Declaration->getIdentifier())
785 return ID->getName();
787 case CodeCompletionResult::RK_Keyword:
788 return Result.Keyword;
789 case CodeCompletionResult::RK_Macro:
790 return Result.Macro->getName();
791 case CodeCompletionResult::RK_Pattern:
792 return Result.Pattern->getTypedText();
794 auto *CCS = codeCompletionString(Result);
795 return CCS->getTypedText();
800 CodeCompletionString *codeCompletionString(
const CodeCompletionResult &R) {
802 return const_cast<CodeCompletionResult &>(R).CreateCodeCompletionString(
808 CodeCompleteOptions Opts;
809 std::shared_ptr<GlobalCodeCompletionAllocator> CCAllocator;
811 llvm::unique_function<void()> ResultsCallback;
814 struct ScoredSignature {
822 class SignatureHelpCollector final :
public CodeCompleteConsumer {
824 SignatureHelpCollector(
const clang::CodeCompleteOptions &CodeCompleteOpts,
825 const SymbolIndex *
Index, SignatureHelp &SigHelp)
826 : CodeCompleteConsumer(CodeCompleteOpts), SigHelp(SigHelp),
827 Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
830 void ProcessOverloadCandidates(Sema &S,
unsigned CurrentArg,
831 OverloadCandidate *Candidates,
832 unsigned NumCandidates,
833 SourceLocation OpenParLoc)
override {
834 assert(!OpenParLoc.isInvalid());
835 SourceManager &SrcMgr = S.getSourceManager();
836 OpenParLoc = SrcMgr.getFileLoc(OpenParLoc);
837 if (SrcMgr.isInMainFile(OpenParLoc))
840 elog(
"Location oustide main file in signature help: {0}",
841 OpenParLoc.printToString(SrcMgr));
843 std::vector<ScoredSignature> ScoredSignatures;
844 SigHelp.signatures.reserve(NumCandidates);
845 ScoredSignatures.reserve(NumCandidates);
849 SigHelp.activeSignature = 0;
850 assert(CurrentArg <= (
unsigned)std::numeric_limits<int>::max() &&
851 "too many arguments");
852 SigHelp.activeParameter = static_cast<int>(CurrentArg);
853 for (
unsigned I = 0; I < NumCandidates; ++I) {
854 OverloadCandidate
Candidate = Candidates[I];
858 if (
auto *Func =
Candidate.getFunction()) {
859 if (
auto *Pattern = Func->getTemplateInstantiationPattern())
863 const auto *CCS =
Candidate.CreateSignatureString(
865 assert(CCS &&
"Expected the CodeCompletionString to be non-null");
866 ScoredSignatures.push_back(processOverloadCandidate(
875 llvm::DenseMap<SymbolID, std::string> FetchedDocs;
877 LookupRequest IndexRequest;
878 for (
const auto &S : ScoredSignatures) {
881 IndexRequest.IDs.insert(*S.IDForDoc);
883 Index->lookup(IndexRequest, [&](
const Symbol &S) {
884 if (!S.Documentation.empty())
885 FetchedDocs[S.ID] = std::string(S.Documentation);
887 log(
"SigHelp: requested docs for {0} symbols from the index, got {1} "
888 "symbols with non-empty docs in the response",
889 IndexRequest.IDs.size(), FetchedDocs.size());
892 llvm::sort(ScoredSignatures, [](
const ScoredSignature &L,
893 const ScoredSignature &R) {
901 if (L.Quality.NumberOfParameters != R.Quality.NumberOfParameters)
902 return L.Quality.NumberOfParameters < R.Quality.NumberOfParameters;
903 if (L.Quality.NumberOfOptionalParameters !=
904 R.Quality.NumberOfOptionalParameters)
905 return L.Quality.NumberOfOptionalParameters <
906 R.Quality.NumberOfOptionalParameters;
907 if (L.Quality.Kind != R.Quality.Kind) {
908 using OC = CodeCompleteConsumer::OverloadCandidate;
909 switch (L.Quality.Kind) {
910 case OC::CK_Function:
912 case OC::CK_FunctionType:
913 return R.Quality.Kind != OC::CK_Function;
914 case OC::CK_FunctionTemplate:
917 llvm_unreachable(
"Unknown overload candidate type.");
919 if (L.Signature.label.size() != R.Signature.label.size())
920 return L.Signature.label.size() < R.Signature.label.size();
921 return L.Signature.label < R.Signature.label;
924 for (
auto &SS : ScoredSignatures) {
926 SS.IDForDoc ? FetchedDocs.find(*SS.IDForDoc) : FetchedDocs.end();
927 if (IndexDocIt != FetchedDocs.end())
928 SS.Signature.documentation = IndexDocIt->second;
930 SigHelp.signatures.push_back(std::move(SS.Signature));
934 GlobalCodeCompletionAllocator &getAllocator()
override {
return *
Allocator; }
936 CodeCompletionTUInfo &getCodeCompletionTUInfo()
override {
return CCTUInfo; }
939 void processParameterChunk(llvm::StringRef ChunkText,
943 unsigned ParamEndOffset = ParamStartOffset +
lspLength(ChunkText);
948 ParameterInformation
Info;
949 Info.labelOffsets.emplace(ParamStartOffset, ParamEndOffset);
951 Info.labelString = std::string(ChunkText);
956 void processOptionalChunk(
const CodeCompletionString &CCS,
958 SignatureQualitySignals &Signal)
const {
959 for (
const auto &Chunk : CCS) {
960 switch (Chunk.Kind) {
961 case CodeCompletionString::CK_Optional:
962 assert(Chunk.Optional &&
963 "Expected the optional code completion string to be non-null.");
964 processOptionalChunk(*Chunk.Optional,
Signature, Signal);
966 case CodeCompletionString::CK_VerticalSpace:
968 case CodeCompletionString::CK_CurrentParameter:
969 case CodeCompletionString::CK_Placeholder:
970 processParameterChunk(Chunk.Text,
Signature);
971 Signal.NumberOfOptionalParameters++;
982 ScoredSignature processOverloadCandidate(
const OverloadCandidate &
Candidate,
983 const CodeCompletionString &CCS,
984 llvm::StringRef DocComment)
const {
986 SignatureQualitySignals Signal;
992 for (
const auto &Chunk : CCS) {
993 switch (Chunk.Kind) {
994 case CodeCompletionString::CK_ResultType:
997 assert(!
ReturnType &&
"Unexpected CK_ResultType");
1000 case CodeCompletionString::CK_CurrentParameter:
1001 case CodeCompletionString::CK_Placeholder:
1002 processParameterChunk(Chunk.Text,
Signature);
1003 Signal.NumberOfParameters++;
1005 case CodeCompletionString::CK_Optional: {
1007 assert(Chunk.Optional &&
1008 "Expected the optional code completion string to be non-null.");
1009 processOptionalChunk(*Chunk.Optional,
Signature, Signal);
1012 case CodeCompletionString::CK_VerticalSpace:
1024 ScoredSignature Result;
1025 Result.Signature = std::move(
Signature);
1026 Result.Quality = Signal;
1027 const FunctionDecl *Func =
Candidate.getFunction();
1028 if (Func && Result.Signature.documentation.empty()) {
1036 SignatureHelp &SigHelp;
1037 std::shared_ptr<clang::GlobalCodeCompletionAllocator>
Allocator;
1039 const SymbolIndex *
Index;
1042 struct SemaCompleteInput {
1046 const llvm::Optional<PreamblePatch>
Patch;
1050 void loadMainFilePreambleMacros(
const Preprocessor &
PP,
1055 ExternalPreprocessorSource *PreambleMacros =
PP.getExternalSource();
1058 IdentifierInfoLookup *PreambleIdentifiers =
1059 PP.getIdentifierTable().getExternalIdentifierLookup();
1060 if (!PreambleIdentifiers || !PreambleMacros)
1062 for (
const auto &MacroName :
Preamble.Macros.Names)
1063 if (
auto *II = PreambleIdentifiers->get(MacroName.getKey()))
1064 if (II->isOutOfDate())
1065 PreambleMacros->updateOutOfDateIdentifier(*II);
1070 bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
1071 const clang::CodeCompleteOptions &Options,
1072 const SemaCompleteInput &Input,
1073 IncludeStructure *Includes =
nullptr) {
1074 trace::Span
Tracer(
"Sema completion");
1079 elog(
"Couldn't create CompilerInvocation");
1082 auto &FrontendOpts =
CI->getFrontendOpts();
1083 FrontendOpts.SkipFunctionBodies =
true;
1085 CI->getLangOpts()->SpellChecking =
false;
1089 CI->getLangOpts()->DelayedTemplateParsing =
false;
1091 FrontendOpts.CodeCompleteOpts = Options;
1092 FrontendOpts.CodeCompletionAt.FileName = std::string(Input.FileName);
1093 std::tie(FrontendOpts.CodeCompletionAt.Line,
1094 FrontendOpts.CodeCompletionAt.Column) =
1097 std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
1098 llvm::MemoryBuffer::getMemBufferCopy(Input.ParseInput.Contents,
1101 CI->getDiagnosticOpts().IgnoreWarnings =
true;
1108 PreambleBounds PreambleRegion =
1109 ComputePreambleBounds(*
CI->getLangOpts(), ContentsBuffer.get(), 0);
1110 bool CompletingInPreamble = PreambleRegion.Size > Input.Offset;
1112 Input.Patch->apply(*
CI);
1115 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1116 Input.ParseInput.TFS->view(Input.ParseInput.CompileCommand.Directory);
1117 if (Input.Preamble.StatCache)
1118 VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS));
1120 std::move(
CI), !CompletingInPreamble ? &Input.Preamble.Preamble :
nullptr,
1121 std::move(ContentsBuffer), std::move(VFS),
IgnoreDiags);
1122 Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble;
1123 Clang->setCodeCompletionConsumer(Consumer.release());
1126 if (!
Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
1127 log(
"BeginSourceFile() failed when running codeComplete for {0}",
1137 loadMainFilePreambleMacros(Clang->getPreprocessor(), Input.Preamble);
1139 Clang->getPreprocessor().addPPCallbacks(
1141 if (llvm::Error Err =
Action.Execute()) {
1142 log(
"Execute() failed when running codeComplete for {0}: {1}",
1143 Input.FileName,
toString(std::move(Err)));
1152 bool allowIndex(CodeCompletionContext &CC) {
1153 if (!contextAllowsIndex(CC.getKind()))
1156 auto Scope = CC.getCXXScopeSpecifier();
1159 NestedNameSpecifier *NameSpec = (*Scope)->getScopeRep();
1164 switch (NameSpec->getKind()) {
1165 case NestedNameSpecifier::Global:
1166 case NestedNameSpecifier::Namespace:
1167 case NestedNameSpecifier::NamespaceAlias:
1169 case NestedNameSpecifier::Super:
1170 case NestedNameSpecifier::TypeSpec:
1171 case NestedNameSpecifier::TypeSpecWithTemplate:
1173 case NestedNameSpecifier::Identifier:
1176 llvm_unreachable(
"invalid NestedNameSpecifier kind");
1179 std::future<SymbolSlab> startAsyncFuzzyFind(
const SymbolIndex &
Index,
1180 const FuzzyFindRequest &Req) {
1181 return runAsync<SymbolSlab>([&
Index, Req]() {
1182 trace::Span
Tracer(
"Async fuzzyFind");
1184 Index.fuzzyFind(Req, [&Syms](
const Symbol &Sym) { Syms.insert(Sym); });
1185 return std::move(Syms).build();
1192 FuzzyFindRequest speculativeFuzzyFindRequestForCompletion(
1193 FuzzyFindRequest CachedReq,
const CompletionPrefix &HeuristicPrefix) {
1194 CachedReq.Query = std::string(HeuristicPrefix.Name);
1227 class CodeCompleteFlow {
1229 IncludeStructure Includes;
1230 SpeculativeFuzzyFind *SpecFuzzyFind;
1231 const CodeCompleteOptions &Opts;
1234 CompletionRecorder *Recorder =
nullptr;
1236 bool IsUsingDeclaration =
false;
1240 tok::TokenKind NextTokenKind = tok::eof;
1242 int NSema = 0, NIndex = 0, NSemaAndIndex = 0, NIdent = 0;
1243 bool Incomplete =
false;
1244 CompletionPrefix HeuristicPrefix;
1245 llvm::Optional<FuzzyMatcher> Filter;
1246 Range ReplacedRange;
1247 std::vector<std::string> QueryScopes;
1249 llvm::Optional<ScopeDistance> ScopeProximity;
1250 llvm::Optional<OpaqueType> PreferredType;
1252 bool AllScopes =
false;
1253 llvm::StringSet<> ContextWords;
1256 llvm::Optional<IncludeInserter> Inserter;
1257 llvm::Optional<URIDistance> FileProximity;
1262 llvm::Optional<FuzzyFindRequest> SpecReq;
1267 SpeculativeFuzzyFind *SpecFuzzyFind,
1268 const CodeCompleteOptions &Opts)
1272 CodeCompleteResult run(
const SemaCompleteInput &SemaCCInput) && {
1273 trace::Span
Tracer(
"CodeCompleteFlow");
1275 SemaCCInput.Offset);
1276 populateContextWords(SemaCCInput.ParseInput.Contents);
1277 if (Opts.Index && SpecFuzzyFind && SpecFuzzyFind->CachedReq.hasValue()) {
1278 assert(!SpecFuzzyFind->Result.valid());
1279 SpecReq = speculativeFuzzyFindRequestForCompletion(
1280 *SpecFuzzyFind->CachedReq, HeuristicPrefix);
1281 SpecFuzzyFind->Result = startAsyncFuzzyFind(*Opts.Index, *SpecReq);
1287 CodeCompleteResult
Output;
1288 auto RecorderOwner = std::make_unique<CompletionRecorder>(Opts, [&]() {
1289 assert(Recorder &&
"Recorder is not set");
1290 CCContextKind = Recorder->CCContext.getKind();
1291 IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
1293 SemaCCInput.ParseInput.Contents,
1294 *SemaCCInput.ParseInput.TFS);
1295 const auto NextToken = Lexer::findNextToken(
1296 Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(),
1297 Recorder->CCSema->getSourceManager(), Recorder->CCSema->LangOpts);
1299 NextTokenKind = NextToken->getKind();
1303 SemaCCInput.FileName, SemaCCInput.ParseInput.Contents, Style,
1304 SemaCCInput.ParseInput.CompileCommand.Directory,
1305 &Recorder->CCSema->getPreprocessor().getHeaderSearchInfo());
1306 for (
const auto &Inc : Includes.MainFileIncludes)
1307 Inserter->addExisting(Inc);
1313 FileDistanceOptions ProxOpts{};
1314 const auto &SM = Recorder->CCSema->getSourceManager();
1315 llvm::StringMap<SourceParams> ProxSources;
1316 for (
auto &
Entry : Includes.includeDepth(
1317 SM.getFileEntryForID(SM.getMainFileID())->getName())) {
1318 auto &Source = ProxSources[
Entry.getKey()];
1319 Source.Cost =
Entry.getValue() * ProxOpts.IncludeCost;
1323 if (
Entry.getValue() > 0)
1324 Source.MaxUpTraversals = 1;
1326 FileProximity.emplace(ProxSources, ProxOpts);
1331 getCompletionKindString(CCContextKind));
1332 log(
"Code complete: sema context {0}, query scopes [{1}] (AnyScope={2}), "
1333 "expected type {3}{4}",
1334 getCompletionKindString(CCContextKind),
1335 llvm::join(QueryScopes.begin(), QueryScopes.end(),
","), AllScopes,
1336 PreferredType ? Recorder->CCContext.getPreferredType().getAsString()
1338 IsUsingDeclaration ?
", inside using declaration" :
"");
1341 Recorder = RecorderOwner.get();
1343 semaCodeComplete(std::move(RecorderOwner), Opts.getClangCompleteOpts(),
1344 SemaCCInput, &Includes);
1349 void logResults(
const CodeCompleteResult &
Output,
const trace::Span &
Tracer) {
1356 log(
"Code complete: {0} results from Sema, {1} from Index, "
1357 "{2} matched, {3} from identifiers, {4} returned{5}.",
1358 NSema, NIndex, NSemaAndIndex, NIdent,
Output.Completions.size(),
1359 Output.HasMore ?
" (incomplete)" :
"");
1360 assert(!Opts.Limit ||
Output.Completions.size() <= Opts.Limit);
1365 CodeCompleteResult runWithoutSema(llvm::StringRef Content,
size_t Offset,
1366 const ThreadsafeFS &TFS) && {
1367 trace::Span
Tracer(
"CodeCompleteWithoutSema");
1370 populateContextWords(Content);
1371 CCContextKind = CodeCompletionContext::CCC_Recovery;
1372 IsUsingDeclaration =
false;
1373 Filter = FuzzyMatcher(HeuristicPrefix.Name);
1375 ReplacedRange.start = ReplacedRange.end =
Pos;
1376 ReplacedRange.start.character -= HeuristicPrefix.Name.size();
1378 llvm::StringMap<SourceParams> ProxSources;
1380 FileProximity.emplace(ProxSources);
1384 Inserter.emplace(
FileName, Content, Style,
1388 std::vector<RawIdentifier> IdentifierResults;
1389 for (
const auto &IDAndCount : Identifiers) {
1391 ID.Name = IDAndCount.first();
1392 ID.References = IDAndCount.second;
1394 if (ID.Name == HeuristicPrefix.Name)
1396 if (ID.References > 0)
1397 IdentifierResults.push_back(std::move(ID));
1403 SpecifiedScope Scopes;
1405 Content.take_front(
Offset), format::getFormattingLangOpts(Style));
1406 for (std::string &S : Scopes.AccessibleScopes)
1409 if (HeuristicPrefix.Qualifier.empty())
1410 AllScopes = Opts.AllScopes;
1411 else if (HeuristicPrefix.Qualifier.startswith(
"::")) {
1412 Scopes.AccessibleScopes = {
""};
1413 Scopes.UnresolvedQualifier =
1414 std::string(HeuristicPrefix.Qualifier.drop_front(2));
1416 Scopes.UnresolvedQualifier = std::string(HeuristicPrefix.Qualifier);
1418 QueryScopes = Scopes.scopesForIndexQuery();
1419 ScopeProximity.emplace(QueryScopes);
1421 SymbolSlab IndexResults = Opts.Index ? queryIndex() : SymbolSlab();
1423 CodeCompleteResult
Output = toCodeCompleteResult(mergeResults(
1424 {}, IndexResults, IdentifierResults));
1425 Output.RanParser =
false;
1431 void populateContextWords(llvm::StringRef Content) {
1433 unsigned RangeEnd = HeuristicPrefix.Qualifier.begin() - Content.data(),
1434 RangeBegin = RangeEnd;
1435 for (
size_t I = 0; I < 3 && RangeBegin > 0; ++I) {
1436 auto PrevNL = Content.rfind(
'\n', RangeBegin);
1437 if (PrevNL == StringRef::npos) {
1441 RangeBegin = PrevNL;
1444 ContextWords =
collectWords(Content.slice(RangeBegin, RangeEnd));
1445 dlog(
"Completion context words: {0}",
1451 CodeCompleteResult runWithSema() {
1452 const auto &CodeCompletionRange = CharSourceRange::getCharRange(
1453 Recorder->CCSema->getPreprocessor().getCodeCompletionTokenRange());
1459 if (CodeCompletionRange.isValid()) {
1461 CodeCompletionRange);
1464 Recorder->CCSema->getSourceManager(),
1465 Recorder->CCSema->getPreprocessor().getCodeCompletionLoc());
1466 ReplacedRange.start = ReplacedRange.end =
Pos;
1468 Filter = FuzzyMatcher(
1469 Recorder->CCSema->getPreprocessor().getCodeCompletionFilter());
1470 std::tie(QueryScopes, AllScopes) = getQueryScopes(
1471 Recorder->CCContext, *Recorder->CCSema, HeuristicPrefix, Opts);
1472 if (!QueryScopes.empty())
1473 ScopeProximity.emplace(QueryScopes);
1475 OpaqueType::fromType(Recorder->CCSema->getASTContext(),
1476 Recorder->CCContext.getPreferredType());
1482 auto IndexResults = (Opts.Index && allowIndex(Recorder->CCContext))
1485 trace::Span
Tracer(
"Populate CodeCompleteResult");
1488 mergeResults(Recorder->Results, IndexResults, {});
1489 return toCodeCompleteResult(Top);
1493 toCodeCompleteResult(
const std::vector<ScoredBundle> &Scored) {
1494 CodeCompleteResult
Output;
1497 for (
auto &C : Scored) {
1498 Output.Completions.push_back(toCodeCompletion(C.first));
1499 Output.Completions.back().Score = C.second;
1500 Output.Completions.back().CompletionTokenRange = ReplacedRange;
1502 Output.HasMore = Incomplete;
1503 Output.Context = CCContextKind;
1504 Output.CompletionRange = ReplacedRange;
1508 SymbolSlab queryIndex() {
1509 trace::Span
Tracer(
"Query index");
1513 FuzzyFindRequest Req;
1515 Req.Limit = Opts.Limit;
1516 Req.Query = std::string(Filter->pattern());
1517 Req.RestrictForCodeCompletion =
true;
1518 Req.Scopes = QueryScopes;
1519 Req.AnyScope = AllScopes;
1521 Req.ProximityPaths.push_back(std::string(
FileName));
1523 Req.PreferredTypes.push_back(std::string(PreferredType->raw()));
1524 vlog(
"Code complete: fuzzyFind({0:2})",
toJSON(Req));
1527 SpecFuzzyFind->NewReq = Req;
1528 if (SpecFuzzyFind && SpecFuzzyFind->Result.valid() && (*SpecReq == Req)) {
1529 vlog(
"Code complete: speculative fuzzy request matches the actual index "
1530 "request. Waiting for the speculative index results.");
1533 trace::Span WaitSpec(
"Wait speculative results");
1534 return SpecFuzzyFind->Result.get();
1541 if (Opts.Index->fuzzyFind(
1542 Req, [&](
const Symbol &Sym) { ResultsBuilder.insert(Sym); }))
1544 return std::move(ResultsBuilder).build();
1552 std::vector<ScoredBundle>
1553 mergeResults(
const std::vector<CodeCompletionResult> &SemaResults,
1554 const SymbolSlab &IndexResults,
1555 const std::vector<RawIdentifier> &IdentifierResults) {
1556 trace::Span
Tracer(
"Merge and score results");
1557 std::vector<CompletionCandidate::Bundle> Bundles;
1558 llvm::DenseMap<size_t, size_t> BundleLookup;
1559 auto AddToBundles = [&](
const CodeCompletionResult *
SemaResult,
1562 CompletionCandidate C;
1566 if (C.IndexResult) {
1569 }
else if (C.SemaResult) {
1575 if (
auto OverloadSet = C.overloadSet(Opts)) {
1576 auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
1578 Bundles.emplace_back();
1579 Bundles[Ret.first->second].push_back(std::move(C));
1581 Bundles.emplace_back();
1582 Bundles.back().push_back(std::move(C));
1585 llvm::DenseSet<const Symbol *> UsedIndexResults;
1586 auto CorrespondingIndexResult =
1587 [&](
const CodeCompletionResult &
SemaResult) ->
const Symbol * {
1590 auto I = IndexResults.find(*SymID);
1591 if (I != IndexResults.end()) {
1592 UsedIndexResults.insert(&*I);
1608 for (
const auto &Ident : IdentifierResults)
1609 AddToBundles(
nullptr,
nullptr, &Ident);
1611 TopN<ScoredBundle, ScoredBundleGreater> Top(
1612 Opts.Limit == 0 ? std::numeric_limits<size_t>::max() : Opts.Limit);
1613 for (
auto &Bundle : Bundles)
1614 addCandidate(Top, std::move(Bundle));
1615 return std::move(Top).items();
1618 llvm::Optional<float> fuzzyScore(
const CompletionCandidate &C) {
1621 if (C.SemaResult && C.SemaResult->Kind == CodeCompletionResult::RK_Macro &&
1622 !C.Name.startswith_lower(Filter->pattern()))
1624 return Filter->match(C.Name);
1628 void addCandidate(TopN<ScoredBundle, ScoredBundleGreater> &Candidates,
1629 CompletionCandidate::Bundle Bundle) {
1631 SymbolRelevanceSignals Relevance;
1632 Relevance.Context = CCContextKind;
1633 Relevance.Name = Bundle.front().Name;
1634 Relevance.Query = SymbolRelevanceSignals::CodeComplete;
1635 Relevance.FileProximityMatch = FileProximity.getPointer();
1637 Relevance.ScopeProximityMatch = ScopeProximity.getPointer();
1639 Relevance.HadContextType =
true;
1640 Relevance.ContextWords = &ContextWords;
1642 auto &First = Bundle.front();
1643 if (
auto FuzzyScore = fuzzyScore(First))
1644 Relevance.NameMatch = *FuzzyScore;
1648 bool FromIndex =
false;
1652 Relevance.merge(*
Candidate.IndexResult);
1653 Origin |=
Candidate.IndexResult->Origin;
1655 if (!
Candidate.IndexResult->Type.empty())
1656 Relevance.HadSymbolType |=
true;
1657 if (PreferredType &&
1658 PreferredType->raw() ==
Candidate.IndexResult->Type) {
1659 Relevance.TypeMatchesPreferred =
true;
1665 if (PreferredType) {
1666 if (
auto CompletionType = OpaqueType::fromCompletionResult(
1667 Recorder->CCSema->getASTContext(), *
Candidate.SemaResult)) {
1668 Relevance.HadSymbolType |=
true;
1669 if (PreferredType == CompletionType)
1670 Relevance.TypeMatchesPreferred =
true;
1677 Relevance.Scope = SymbolRelevanceSignals::FileScope;
1678 Origin |= SymbolOrigin::Identifier;
1682 CodeCompletion::Scores Scores;
1683 Scores.Quality =
Quality.evaluate();
1684 Scores.Relevance = Relevance.evaluate();
1687 Scores.ExcludingName = Relevance.NameMatch
1688 ? Scores.Total / Relevance.NameMatch
1691 if (Opts.RecordCCResult)
1692 Opts.RecordCCResult(toCodeCompletion(Bundle),
Quality, Relevance,
1695 dlog(
"CodeComplete: {0} ({1}) = {2}\n{3}{4}\n", First.Name,
1696 llvm::to_string(Origin), Scores.Total, llvm::to_string(
Quality),
1697 llvm::to_string(Relevance));
1700 NIndex += FromIndex;
1702 NIdent += bool(Origin & SymbolOrigin::Identifier);
1703 if (Candidates.push({std::move(Bundle), Scores}))
1707 CodeCompletion toCodeCompletion(
const CompletionCandidate::Bundle &Bundle) {
1708 llvm::Optional<CodeCompletionBuilder>
Builder;
1709 for (
const auto &Item : Bundle) {
1710 CodeCompletionString *SemaCCS =
1711 Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
1714 Builder.emplace(Recorder ? &Recorder->CCSema->getASTContext() :
nullptr,
1715 Item, SemaCCS, QueryScopes, *Inserter,
FileName,
1716 CCContextKind, Opts, IsUsingDeclaration, NextTokenKind);
1726 clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts()
const {
1727 clang::CodeCompleteOptions Result;
1728 Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns;
1729 Result.IncludeMacros = IncludeMacros;
1730 Result.IncludeGlobals =
true;
1735 Result.IncludeBriefComments =
false;
1740 Result.LoadExternal = !
Index;
1741 Result.IncludeFixIts = IncludeFixIts;
1748 assert(
Offset <= Content.size());
1749 StringRef Rest = Content.take_front(
Offset);
1754 while (!Rest.empty() && isIdentifierBody(Rest.back()))
1755 Rest = Rest.drop_back();
1756 Result.Name = Content.slice(Rest.size(),
Offset);
1759 while (Rest.consume_back(
"::") && !Rest.endswith(
":"))
1760 while (!Rest.empty() && isIdentifierBody(Rest.back()))
1761 Rest = Rest.drop_back();
1763 Content.slice(Rest.size(), Result.Name.begin() - Content.begin());
1775 elog(
"Code completion position was invalid {0}",
Offset.takeError());
1778 auto Flow = CodeCompleteFlow(
1780 SpecFuzzyFind, Opts);
1781 return (!
Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse)
1795 elog(
"Signature help position was invalid {0}",
Offset.takeError());
1799 clang::CodeCompleteOptions Options;
1800 Options.IncludeGlobals =
false;
1801 Options.IncludeMacros =
false;
1802 Options.IncludeCodePatterns =
false;
1803 Options.IncludeBriefComments =
false;
1805 std::make_unique<SignatureHelpCollector>(Options,
ParseInput.Index,
1808 {FileName, *Offset, Preamble,
1809 PreamblePatch::create(FileName, ParseInput, Preamble), ParseInput});
1814 auto InTopLevelScope = [](
const NamedDecl &ND) {
1815 switch (ND.getDeclContext()->getDeclKind()) {
1816 case Decl::TranslationUnit:
1817 case Decl::Namespace:
1818 case Decl::LinkageSpec:
1830 if (InTopLevelScope(ND))
1833 if (
const auto *EnumDecl = dyn_cast<clang::EnumDecl>(ND.getDeclContext()))
1834 return InTopLevelScope(*EnumDecl) && !EnumDecl->isScoped();
1844 case MarkupKind::PlainText:
1847 case MarkupKind::Markdown:
1856 const auto *InsertInclude = Includes.empty() ? nullptr : &Includes[0];
1857 LSP.
label = ((InsertInclude && InsertInclude->Insertion)
1858 ? Opts.IncludeIndicator.Insert
1859 : Opts.IncludeIndicator.NoInsert) +
1860 (Opts.ShowOrigins ?
"[" + llvm::to_string(Origin) +
"]" :
"") +
1864 LSP.
detail = BundleSize > 1
1865 ? std::string(llvm::formatv(
"[{0} overloads]", BundleSize))
1870 if (InsertInclude || Documentation) {
1875 Doc.
append(*Documentation);
1880 LSP.
textEdit = {CompletionTokenRange, RequiredQualifier +
Name};
1888 for (
const auto &
FixIt : FixIts) {
1896 if (Opts.EnableSnippets)
1903 : InsertTextFormat::PlainText;
1904 if (InsertInclude && InsertInclude->Insertion)
1920 <<
" (" << getCompletionKindString(R.
Context) <<
")"
1930 if (!
Line.consume_front(
"#"))
1933 if (!(
Line.consume_front(
"include_next") ||
Line.consume_front(
"include") ||
1934 Line.consume_front(
"import")))
1937 if (
Line.consume_front(
"<"))
1938 return Line.count(
'>') == 0;
1939 if (
Line.consume_front(
"\""))
1940 return Line.count(
'"') == 0;
1946 Content = Content.take_front(
Offset);
1947 auto Pos = Content.rfind(
'\n');
1948 if (
Pos != llvm::StringRef::npos)
1949 Content = Content.substr(
Pos + 1);
1952 if (Content.endswith(
".") || Content.endswith(
"->") || Content.endswith(
"::"))
1955 if ((Content.endswith(
"<") || Content.endswith(
"\"") ||
1956 Content.endswith(
"/")) &&
1961 return !Content.empty() &&
1962 (isIdentifierBody(Content.back()) || !llvm::isASCII(Content.back()));