blob: e8a77e6248bf129c90e0bb9fa7673bf26416b692 [file] [log] [blame]
Sam McCall98775c52017-12-04 13:49:59 +00001//===--- CodeComplete.cpp ---------------------------------------*- C++-*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9//
Sam McCallc18c2802018-06-15 11:06:29 +000010// Code completion has several moving parts:
11// - AST-based completions are provided using the completion hooks in Sema.
12// - external completions are retrieved from the index (using hints from Sema)
13// - the two sources overlap, and must be merged and overloads bundled
14// - results must be scored and ranked (see Quality.h) before rendering
Sam McCall98775c52017-12-04 13:49:59 +000015//
Sam McCallc18c2802018-06-15 11:06:29 +000016// Signature help works in a similar way as code completion, but it is simpler:
17// it's purely AST-based, and there are few candidates.
Sam McCall98775c52017-12-04 13:49:59 +000018//
19//===---------------------------------------------------------------------===//
20
21#include "CodeComplete.h"
Eric Liu7ad16962018-06-22 10:46:59 +000022#include "AST.h"
Eric Liu63696e12017-12-20 17:24:31 +000023#include "CodeCompletionStrings.h"
Sam McCall98775c52017-12-04 13:49:59 +000024#include "Compiler.h"
Sam McCall3f0243f2018-07-03 08:09:29 +000025#include "FileDistance.h"
Sam McCall84652cc2018-01-12 16:16:09 +000026#include "FuzzyMatch.h"
Eric Liu63f419a2018-05-15 15:29:32 +000027#include "Headers.h"
Eric Liu6f648df2017-12-19 16:50:37 +000028#include "Logger.h"
Sam McCallc5707b62018-05-15 17:43:27 +000029#include "Quality.h"
Eric Liuc5105f92018-02-16 14:15:55 +000030#include "SourceCode.h"
Sam McCall2b780162018-01-30 17:20:54 +000031#include "Trace.h"
Eric Liu63f419a2018-05-15 15:29:32 +000032#include "URI.h"
Eric Liu6f648df2017-12-19 16:50:37 +000033#include "index/Index.h"
Marc-Andre Laperle945b5a32018-06-05 14:01:40 +000034#include "clang/ASTMatchers/ASTMatchFinder.h"
Ilya Biryukovc22d3442018-05-16 12:32:49 +000035#include "clang/Basic/LangOptions.h"
Eric Liuc5105f92018-02-16 14:15:55 +000036#include "clang/Format/Format.h"
Sam McCall98775c52017-12-04 13:49:59 +000037#include "clang/Frontend/CompilerInstance.h"
38#include "clang/Frontend/FrontendActions.h"
Sam McCall545a20d2018-01-19 14:34:02 +000039#include "clang/Index/USRGeneration.h"
Sam McCall98775c52017-12-04 13:49:59 +000040#include "clang/Sema/CodeCompleteConsumer.h"
41#include "clang/Sema/Sema.h"
Eric Liuc5105f92018-02-16 14:15:55 +000042#include "clang/Tooling/Core/Replacement.h"
Haojian Wuba28e9a2018-01-10 14:44:34 +000043#include "llvm/Support/Format.h"
Eric Liubc25ef72018-07-05 08:29:33 +000044#include "llvm/Support/FormatVariadic.h"
Sam McCall2161ec72018-07-05 06:20:41 +000045#include "llvm/Support/ScopedPrinter.h"
Sam McCall98775c52017-12-04 13:49:59 +000046#include <queue>
47
Sam McCallc5707b62018-05-15 17:43:27 +000048// We log detailed candidate here if you run with -debug-only=codecomplete.
Sam McCall27c979a2018-06-29 14:47:57 +000049#define DEBUG_TYPE "CodeComplete"
Sam McCallc5707b62018-05-15 17:43:27 +000050
Sam McCall98775c52017-12-04 13:49:59 +000051namespace clang {
52namespace clangd {
53namespace {
54
Eric Liu6f648df2017-12-19 16:50:37 +000055CompletionItemKind toCompletionItemKind(index::SymbolKind Kind) {
56 using SK = index::SymbolKind;
57 switch (Kind) {
58 case SK::Unknown:
59 return CompletionItemKind::Missing;
60 case SK::Module:
61 case SK::Namespace:
62 case SK::NamespaceAlias:
63 return CompletionItemKind::Module;
64 case SK::Macro:
65 return CompletionItemKind::Text;
66 case SK::Enum:
67 return CompletionItemKind::Enum;
68 // FIXME(ioeric): use LSP struct instead of class when it is suppoted in the
69 // protocol.
70 case SK::Struct:
71 case SK::Class:
72 case SK::Protocol:
73 case SK::Extension:
74 case SK::Union:
75 return CompletionItemKind::Class;
76 // FIXME(ioeric): figure out whether reference is the right type for aliases.
77 case SK::TypeAlias:
78 case SK::Using:
79 return CompletionItemKind::Reference;
80 case SK::Function:
81 // FIXME(ioeric): this should probably be an operator. This should be fixed
82 // when `Operator` is support type in the protocol.
83 case SK::ConversionFunction:
84 return CompletionItemKind::Function;
85 case SK::Variable:
86 case SK::Parameter:
87 return CompletionItemKind::Variable;
88 case SK::Field:
89 return CompletionItemKind::Field;
90 // FIXME(ioeric): use LSP enum constant when it is supported in the protocol.
91 case SK::EnumConstant:
92 return CompletionItemKind::Value;
93 case SK::InstanceMethod:
94 case SK::ClassMethod:
95 case SK::StaticMethod:
96 case SK::Destructor:
97 return CompletionItemKind::Method;
98 case SK::InstanceProperty:
99 case SK::ClassProperty:
100 case SK::StaticProperty:
101 return CompletionItemKind::Property;
102 case SK::Constructor:
103 return CompletionItemKind::Constructor;
104 }
105 llvm_unreachable("Unhandled clang::index::SymbolKind.");
106}
107
Sam McCall83305892018-06-08 21:17:19 +0000108CompletionItemKind
109toCompletionItemKind(CodeCompletionResult::ResultKind ResKind,
110 const NamedDecl *Decl) {
111 if (Decl)
112 return toCompletionItemKind(index::getSymbolInfo(Decl).Kind);
113 switch (ResKind) {
114 case CodeCompletionResult::RK_Declaration:
115 llvm_unreachable("RK_Declaration without Decl");
116 case CodeCompletionResult::RK_Keyword:
117 return CompletionItemKind::Keyword;
118 case CodeCompletionResult::RK_Macro:
119 return CompletionItemKind::Text; // unfortunately, there's no 'Macro'
120 // completion items in LSP.
121 case CodeCompletionResult::RK_Pattern:
122 return CompletionItemKind::Snippet;
123 }
124 llvm_unreachable("Unhandled CodeCompletionResult::ResultKind.");
125}
126
Sam McCall98775c52017-12-04 13:49:59 +0000127/// Get the optional chunk as a string. This function is possibly recursive.
128///
129/// The parameter info for each parameter is appended to the Parameters.
130std::string
131getOptionalParameters(const CodeCompletionString &CCS,
132 std::vector<ParameterInformation> &Parameters) {
133 std::string Result;
134 for (const auto &Chunk : CCS) {
135 switch (Chunk.Kind) {
136 case CodeCompletionString::CK_Optional:
137 assert(Chunk.Optional &&
138 "Expected the optional code completion string to be non-null.");
139 Result += getOptionalParameters(*Chunk.Optional, Parameters);
140 break;
141 case CodeCompletionString::CK_VerticalSpace:
142 break;
143 case CodeCompletionString::CK_Placeholder:
144 // A string that acts as a placeholder for, e.g., a function call
145 // argument.
146 // Intentional fallthrough here.
147 case CodeCompletionString::CK_CurrentParameter: {
148 // A piece of text that describes the parameter that corresponds to
149 // the code-completion location within a function call, message send,
150 // macro invocation, etc.
151 Result += Chunk.Text;
152 ParameterInformation Info;
153 Info.label = Chunk.Text;
154 Parameters.push_back(std::move(Info));
155 break;
156 }
157 default:
158 Result += Chunk.Text;
159 break;
160 }
161 }
162 return Result;
163}
164
Eric Liu63f419a2018-05-15 15:29:32 +0000165/// Creates a `HeaderFile` from \p Header which can be either a URI or a literal
166/// include.
167static llvm::Expected<HeaderFile> toHeaderFile(StringRef Header,
168 llvm::StringRef HintPath) {
169 if (isLiteralInclude(Header))
170 return HeaderFile{Header.str(), /*Verbatim=*/true};
171 auto U = URI::parse(Header);
172 if (!U)
173 return U.takeError();
174
175 auto IncludePath = URI::includeSpelling(*U);
176 if (!IncludePath)
177 return IncludePath.takeError();
178 if (!IncludePath->empty())
179 return HeaderFile{std::move(*IncludePath), /*Verbatim=*/true};
180
181 auto Resolved = URI::resolve(*U, HintPath);
182 if (!Resolved)
183 return Resolved.takeError();
184 return HeaderFile{std::move(*Resolved), /*Verbatim=*/false};
185}
186
Sam McCall545a20d2018-01-19 14:34:02 +0000187/// A code completion result, in clang-native form.
Sam McCall98775c52017-12-04 13:49:59 +0000188/// It may be promoted to a CompletionItem if it's among the top-ranked results.
189struct CompletionCandidate {
Sam McCall545a20d2018-01-19 14:34:02 +0000190 llvm::StringRef Name; // Used for filtering and sorting.
191 // We may have a result from Sema, from the index, or both.
192 const CodeCompletionResult *SemaResult = nullptr;
193 const Symbol *IndexResult = nullptr;
Sam McCall98775c52017-12-04 13:49:59 +0000194
Sam McCallc18c2802018-06-15 11:06:29 +0000195 // Returns a token identifying the overload set this is part of.
196 // 0 indicates it's not part of any overload set.
197 size_t overloadSet() const {
198 SmallString<256> Scratch;
199 if (IndexResult) {
200 switch (IndexResult->SymInfo.Kind) {
201 case index::SymbolKind::ClassMethod:
202 case index::SymbolKind::InstanceMethod:
203 case index::SymbolKind::StaticMethod:
204 assert(false && "Don't expect members from index in code completion");
205 // fall through
206 case index::SymbolKind::Function:
207 // We can't group overloads together that need different #includes.
208 // This could break #include insertion.
209 return hash_combine(
210 (IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
211 headerToInsertIfNotPresent().getValueOr(""));
212 default:
213 return 0;
214 }
215 }
216 assert(SemaResult);
217 // We need to make sure we're consistent with the IndexResult case!
218 const NamedDecl *D = SemaResult->Declaration;
219 if (!D || !D->isFunctionOrFunctionTemplate())
220 return 0;
221 {
222 llvm::raw_svector_ostream OS(Scratch);
223 D->printQualifiedName(OS);
224 }
225 return hash_combine(Scratch, headerToInsertIfNotPresent().getValueOr(""));
226 }
227
228 llvm::Optional<llvm::StringRef> headerToInsertIfNotPresent() const {
229 if (!IndexResult || !IndexResult->Detail ||
230 IndexResult->Detail->IncludeHeader.empty())
231 return llvm::None;
232 if (SemaResult && SemaResult->Declaration) {
233 // Avoid inserting new #include if the declaration is found in the current
234 // file e.g. the symbol is forward declared.
235 auto &SM = SemaResult->Declaration->getASTContext().getSourceManager();
236 for (const Decl *RD : SemaResult->Declaration->redecls())
237 if (SM.isInMainFile(SM.getExpansionLoc(RD->getLocStart())))
238 return llvm::None;
239 }
240 return IndexResult->Detail->IncludeHeader;
241 }
242
Sam McCallc18c2802018-06-15 11:06:29 +0000243 using Bundle = llvm::SmallVector<CompletionCandidate, 4>;
Sam McCall98775c52017-12-04 13:49:59 +0000244};
Sam McCallc18c2802018-06-15 11:06:29 +0000245using ScoredBundle =
Sam McCall27c979a2018-06-29 14:47:57 +0000246 std::pair<CompletionCandidate::Bundle, CodeCompletion::Scores>;
Sam McCallc18c2802018-06-15 11:06:29 +0000247struct ScoredBundleGreater {
248 bool operator()(const ScoredBundle &L, const ScoredBundle &R) {
Sam McCall27c979a2018-06-29 14:47:57 +0000249 if (L.second.Total != R.second.Total)
250 return L.second.Total > R.second.Total;
Sam McCallc18c2802018-06-15 11:06:29 +0000251 return L.first.front().Name <
252 R.first.front().Name; // Earlier name is better.
253 }
254};
Sam McCall98775c52017-12-04 13:49:59 +0000255
Sam McCall27c979a2018-06-29 14:47:57 +0000256// Assembles a code completion out of a bundle of >=1 completion candidates.
257// Many of the expensive strings are only computed at this point, once we know
258// the candidate bundle is going to be returned.
259//
260// Many fields are the same for all candidates in a bundle (e.g. name), and are
261// computed from the first candidate, in the constructor.
262// Others vary per candidate, so add() must be called for remaining candidates.
263struct CodeCompletionBuilder {
264 CodeCompletionBuilder(ASTContext &ASTCtx, const CompletionCandidate &C,
265 CodeCompletionString *SemaCCS,
266 const IncludeInserter &Includes, StringRef FileName,
267 const CodeCompleteOptions &Opts)
268 : ASTCtx(ASTCtx), ExtractDocumentation(Opts.IncludeComments) {
269 add(C, SemaCCS);
270 if (C.SemaResult) {
Sam McCall2161ec72018-07-05 06:20:41 +0000271 Completion.Origin =
272 static_cast<SymbolOrigin>(Completion.Origin | SymbolOrigin::AST);
Sam McCall27c979a2018-06-29 14:47:57 +0000273 Completion.Name = llvm::StringRef(SemaCCS->getTypedText());
274 if (Completion.Scope.empty())
275 if (C.SemaResult->Kind == CodeCompletionResult::RK_Declaration)
276 if (const auto *D = C.SemaResult->getDeclaration())
277 if (const auto *ND = llvm::dyn_cast<NamedDecl>(D))
278 Completion.Scope =
279 splitQualifiedName(printQualifiedName(*ND)).first;
280 Completion.Kind =
281 toCompletionItemKind(C.SemaResult->Kind, C.SemaResult->Declaration);
282 }
283 if (C.IndexResult) {
Sam McCall2161ec72018-07-05 06:20:41 +0000284 Completion.Origin =
285 static_cast<SymbolOrigin>(Completion.Origin | C.IndexResult->Origin);
Sam McCall27c979a2018-06-29 14:47:57 +0000286 if (Completion.Scope.empty())
287 Completion.Scope = C.IndexResult->Scope;
288 if (Completion.Kind == CompletionItemKind::Missing)
289 Completion.Kind = toCompletionItemKind(C.IndexResult->SymInfo.Kind);
290 if (Completion.Name.empty())
291 Completion.Name = C.IndexResult->Name;
292 }
293 if (auto Inserted = C.headerToInsertIfNotPresent()) {
294 // Turn absolute path into a literal string that can be #included.
295 auto Include = [&]() -> Expected<std::pair<std::string, bool>> {
296 auto ResolvedDeclaring =
297 toHeaderFile(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
298 if (!ResolvedDeclaring)
299 return ResolvedDeclaring.takeError();
300 auto ResolvedInserted = toHeaderFile(*Inserted, FileName);
301 if (!ResolvedInserted)
302 return ResolvedInserted.takeError();
303 return std::make_pair(Includes.calculateIncludePath(*ResolvedDeclaring,
304 *ResolvedInserted),
305 Includes.shouldInsertInclude(*ResolvedDeclaring,
306 *ResolvedInserted));
307 }();
308 if (Include) {
309 Completion.Header = Include->first;
310 if (Include->second)
311 Completion.HeaderInsertion = Includes.insert(Include->first);
312 } else
313 log(llvm::formatv(
314 "Failed to generate include insertion edits for adding header "
315 "(FileURI='{0}', IncludeHeader='{1}') into {2}",
316 C.IndexResult->CanonicalDeclaration.FileURI,
317 C.IndexResult->Detail->IncludeHeader, FileName));
318 }
319 }
320
321 void add(const CompletionCandidate &C, CodeCompletionString *SemaCCS) {
322 assert(bool(C.SemaResult) == bool(SemaCCS));
323 Bundled.emplace_back();
324 BundledEntry &S = Bundled.back();
325 if (C.SemaResult) {
326 getSignature(*SemaCCS, &S.Signature, &S.SnippetSuffix,
327 &Completion.RequiredQualifier);
328 S.ReturnType = getReturnType(*SemaCCS);
329 } else if (C.IndexResult) {
330 S.Signature = C.IndexResult->Signature;
331 S.SnippetSuffix = C.IndexResult->CompletionSnippetSuffix;
332 if (auto *D = C.IndexResult->Detail)
333 S.ReturnType = D->ReturnType;
334 }
335 if (ExtractDocumentation && Completion.Documentation.empty()) {
336 if (C.IndexResult && C.IndexResult->Detail)
337 Completion.Documentation = C.IndexResult->Detail->Documentation;
338 else if (C.SemaResult)
339 Completion.Documentation = getDocComment(ASTCtx, *C.SemaResult,
340 /*CommentsFromHeader=*/false);
341 }
342 }
343
344 CodeCompletion build() {
345 Completion.ReturnType = summarizeReturnType();
346 Completion.Signature = summarizeSignature();
347 Completion.SnippetSuffix = summarizeSnippet();
348 Completion.BundleSize = Bundled.size();
349 return std::move(Completion);
350 }
351
352private:
353 struct BundledEntry {
354 std::string SnippetSuffix;
355 std::string Signature;
356 std::string ReturnType;
357 };
358
359 // If all BundledEntrys have the same value for a property, return it.
360 template <std::string BundledEntry::*Member>
361 const std::string *onlyValue() const {
362 auto B = Bundled.begin(), E = Bundled.end();
363 for (auto I = B + 1; I != E; ++I)
364 if (I->*Member != B->*Member)
365 return nullptr;
366 return &(B->*Member);
367 }
368
369 std::string summarizeReturnType() const {
370 if (auto *RT = onlyValue<&BundledEntry::ReturnType>())
371 return *RT;
372 return "";
373 }
374
375 std::string summarizeSnippet() const {
376 if (auto *Snippet = onlyValue<&BundledEntry::SnippetSuffix>())
377 return *Snippet;
378 // All bundles are function calls.
379 return "(${0})";
380 }
381
382 std::string summarizeSignature() const {
383 if (auto *Signature = onlyValue<&BundledEntry::Signature>())
384 return *Signature;
385 // All bundles are function calls.
386 return "(…)";
387 }
388
389 ASTContext &ASTCtx;
390 CodeCompletion Completion;
391 SmallVector<BundledEntry, 1> Bundled;
392 bool ExtractDocumentation;
393};
394
Sam McCall545a20d2018-01-19 14:34:02 +0000395// Determine the symbol ID for a Sema code completion result, if possible.
396llvm::Optional<SymbolID> getSymbolID(const CodeCompletionResult &R) {
397 switch (R.Kind) {
398 case CodeCompletionResult::RK_Declaration:
399 case CodeCompletionResult::RK_Pattern: {
400 llvm::SmallString<128> USR;
401 if (/*Ignore=*/clang::index::generateUSRForDecl(R.Declaration, USR))
402 return None;
403 return SymbolID(USR);
404 }
405 case CodeCompletionResult::RK_Macro:
406 // FIXME: Macros do have USRs, but the CCR doesn't contain enough info.
407 case CodeCompletionResult::RK_Keyword:
408 return None;
409 }
410 llvm_unreachable("unknown CodeCompletionResult kind");
411}
412
Haojian Wu061c73e2018-01-23 11:37:26 +0000413// Scopes of the paritial identifier we're trying to complete.
414// It is used when we query the index for more completion results.
Eric Liu6f648df2017-12-19 16:50:37 +0000415struct SpecifiedScope {
Haojian Wu061c73e2018-01-23 11:37:26 +0000416 // The scopes we should look in, determined by Sema.
417 //
418 // If the qualifier was fully resolved, we look for completions in these
419 // scopes; if there is an unresolved part of the qualifier, it should be
420 // resolved within these scopes.
421 //
422 // Examples of qualified completion:
423 //
424 // "::vec" => {""}
425 // "using namespace std; ::vec^" => {"", "std::"}
426 // "namespace ns {using namespace std;} ns::^" => {"ns::", "std::"}
427 // "std::vec^" => {""} // "std" unresolved
428 //
429 // Examples of unqualified completion:
430 //
431 // "vec^" => {""}
432 // "using namespace std; vec^" => {"", "std::"}
433 // "using namespace std; namespace ns { vec^ }" => {"ns::", "std::", ""}
434 //
435 // "" for global namespace, "ns::" for normal namespace.
436 std::vector<std::string> AccessibleScopes;
437 // The full scope qualifier as typed by the user (without the leading "::").
438 // Set if the qualifier is not fully resolved by Sema.
439 llvm::Optional<std::string> UnresolvedQualifier;
Sam McCall545a20d2018-01-19 14:34:02 +0000440
Haojian Wu061c73e2018-01-23 11:37:26 +0000441 // Construct scopes being queried in indexes.
442 // This method format the scopes to match the index request representation.
443 std::vector<std::string> scopesForIndexQuery() {
444 std::vector<std::string> Results;
445 for (llvm::StringRef AS : AccessibleScopes) {
446 Results.push_back(AS);
447 if (UnresolvedQualifier)
448 Results.back() += *UnresolvedQualifier;
449 }
450 return Results;
Sam McCall545a20d2018-01-19 14:34:02 +0000451 }
Eric Liu6f648df2017-12-19 16:50:37 +0000452};
453
Haojian Wu061c73e2018-01-23 11:37:26 +0000454// Get all scopes that will be queried in indexes.
455std::vector<std::string> getQueryScopes(CodeCompletionContext &CCContext,
Kirill Bobyrev5a267ed2018-05-29 11:50:51 +0000456 const SourceManager &SM) {
457 auto GetAllAccessibleScopes = [](CodeCompletionContext &CCContext) {
Haojian Wu061c73e2018-01-23 11:37:26 +0000458 SpecifiedScope Info;
Kirill Bobyrev5a267ed2018-05-29 11:50:51 +0000459 for (auto *Context : CCContext.getVisitedContexts()) {
Haojian Wu061c73e2018-01-23 11:37:26 +0000460 if (isa<TranslationUnitDecl>(Context))
461 Info.AccessibleScopes.push_back(""); // global namespace
Kirill Bobyrev5a267ed2018-05-29 11:50:51 +0000462 else if (const auto *NS = dyn_cast<NamespaceDecl>(Context))
Haojian Wu061c73e2018-01-23 11:37:26 +0000463 Info.AccessibleScopes.push_back(NS->getQualifiedNameAsString() + "::");
464 }
465 return Info;
466 };
467
468 auto SS = CCContext.getCXXScopeSpecifier();
469
470 // Unqualified completion (e.g. "vec^").
471 if (!SS) {
472 // FIXME: Once we can insert namespace qualifiers and use the in-scope
473 // namespaces for scoring, search in all namespaces.
474 // FIXME: Capture scopes and use for scoring, for example,
475 // "using namespace std; namespace foo {v^}" =>
476 // foo::value > std::vector > boost::variant
477 return GetAllAccessibleScopes(CCContext).scopesForIndexQuery();
478 }
479
480 // Qualified completion ("std::vec^"), we have two cases depending on whether
481 // the qualifier can be resolved by Sema.
482 if ((*SS)->isValid()) { // Resolved qualifier.
Haojian Wu061c73e2018-01-23 11:37:26 +0000483 return GetAllAccessibleScopes(CCContext).scopesForIndexQuery();
484 }
485
486 // Unresolved qualifier.
487 // FIXME: When Sema can resolve part of a scope chain (e.g.
488 // "known::unknown::id"), we should expand the known part ("known::") rather
489 // than treating the whole thing as unknown.
490 SpecifiedScope Info;
491 Info.AccessibleScopes.push_back(""); // global namespace
492
493 Info.UnresolvedQualifier =
Kirill Bobyrev5a267ed2018-05-29 11:50:51 +0000494 Lexer::getSourceText(CharSourceRange::getCharRange((*SS)->getRange()), SM,
495 clang::LangOptions())
496 .ltrim("::");
Haojian Wu061c73e2018-01-23 11:37:26 +0000497 // Sema excludes the trailing "::".
498 if (!Info.UnresolvedQualifier->empty())
499 *Info.UnresolvedQualifier += "::";
500
501 return Info.scopesForIndexQuery();
502}
503
Eric Liu42abe412018-05-24 11:20:19 +0000504// Should we perform index-based completion in a context of the specified kind?
505// FIXME: consider allowing completion, but restricting the result types.
506bool contextAllowsIndex(enum CodeCompletionContext::Kind K) {
507 switch (K) {
508 case CodeCompletionContext::CCC_TopLevel:
509 case CodeCompletionContext::CCC_ObjCInterface:
510 case CodeCompletionContext::CCC_ObjCImplementation:
511 case CodeCompletionContext::CCC_ObjCIvarList:
512 case CodeCompletionContext::CCC_ClassStructUnion:
513 case CodeCompletionContext::CCC_Statement:
514 case CodeCompletionContext::CCC_Expression:
515 case CodeCompletionContext::CCC_ObjCMessageReceiver:
516 case CodeCompletionContext::CCC_EnumTag:
517 case CodeCompletionContext::CCC_UnionTag:
518 case CodeCompletionContext::CCC_ClassOrStructTag:
519 case CodeCompletionContext::CCC_ObjCProtocolName:
520 case CodeCompletionContext::CCC_Namespace:
521 case CodeCompletionContext::CCC_Type:
522 case CodeCompletionContext::CCC_Name: // FIXME: why does ns::^ give this?
523 case CodeCompletionContext::CCC_PotentiallyQualifiedName:
524 case CodeCompletionContext::CCC_ParenthesizedExpression:
525 case CodeCompletionContext::CCC_ObjCInterfaceName:
526 case CodeCompletionContext::CCC_ObjCCategoryName:
527 return true;
528 case CodeCompletionContext::CCC_Other: // Be conservative.
529 case CodeCompletionContext::CCC_OtherWithMacros:
530 case CodeCompletionContext::CCC_DotMemberAccess:
531 case CodeCompletionContext::CCC_ArrowMemberAccess:
532 case CodeCompletionContext::CCC_ObjCPropertyAccess:
533 case CodeCompletionContext::CCC_MacroName:
534 case CodeCompletionContext::CCC_MacroNameUse:
535 case CodeCompletionContext::CCC_PreprocessorExpression:
536 case CodeCompletionContext::CCC_PreprocessorDirective:
537 case CodeCompletionContext::CCC_NaturalLanguage:
538 case CodeCompletionContext::CCC_SelectorName:
539 case CodeCompletionContext::CCC_TypeQualifiers:
540 case CodeCompletionContext::CCC_ObjCInstanceMessage:
541 case CodeCompletionContext::CCC_ObjCClassMessage:
542 case CodeCompletionContext::CCC_Recovery:
543 return false;
544 }
545 llvm_unreachable("unknown code completion context");
546}
547
Sam McCall4caa8512018-06-07 12:49:17 +0000548// Some member calls are blacklisted because they're so rarely useful.
549static bool isBlacklistedMember(const NamedDecl &D) {
550 // Destructor completion is rarely useful, and works inconsistently.
551 // (s.^ completes ~string, but s.~st^ is an error).
552 if (D.getKind() == Decl::CXXDestructor)
553 return true;
554 // Injected name may be useful for A::foo(), but who writes A::A::foo()?
555 if (auto *R = dyn_cast_or_null<RecordDecl>(&D))
556 if (R->isInjectedClassName())
557 return true;
558 // Explicit calls to operators are also rare.
559 auto NameKind = D.getDeclName().getNameKind();
560 if (NameKind == DeclarationName::CXXOperatorName ||
561 NameKind == DeclarationName::CXXLiteralOperatorName ||
562 NameKind == DeclarationName::CXXConversionFunctionName)
563 return true;
564 return false;
565}
566
Sam McCall545a20d2018-01-19 14:34:02 +0000567// The CompletionRecorder captures Sema code-complete output, including context.
568// It filters out ignored results (but doesn't apply fuzzy-filtering yet).
569// It doesn't do scoring or conversion to CompletionItem yet, as we want to
570// merge with index results first.
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000571// Generally the fields and methods of this object should only be used from
572// within the callback.
Sam McCall545a20d2018-01-19 14:34:02 +0000573struct CompletionRecorder : public CodeCompleteConsumer {
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000574 CompletionRecorder(const CodeCompleteOptions &Opts,
Benjamin Kramerc36c09f2018-07-03 20:59:33 +0000575 llvm::unique_function<void()> ResultsCallback)
Sam McCall545a20d2018-01-19 14:34:02 +0000576 : CodeCompleteConsumer(Opts.getClangCompleteOpts(),
Sam McCall98775c52017-12-04 13:49:59 +0000577 /*OutputIsBinary=*/false),
Sam McCall545a20d2018-01-19 14:34:02 +0000578 CCContext(CodeCompletionContext::CCC_Other), Opts(Opts),
579 CCAllocator(std::make_shared<GlobalCodeCompletionAllocator>()),
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000580 CCTUInfo(CCAllocator), ResultsCallback(std::move(ResultsCallback)) {
581 assert(this->ResultsCallback);
582 }
583
Sam McCall545a20d2018-01-19 14:34:02 +0000584 std::vector<CodeCompletionResult> Results;
585 CodeCompletionContext CCContext;
586 Sema *CCSema = nullptr; // Sema that created the results.
587 // FIXME: Sema is scary. Can we store ASTContext and Preprocessor, instead?
Sam McCall98775c52017-12-04 13:49:59 +0000588
Sam McCall545a20d2018-01-19 14:34:02 +0000589 void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context,
590 CodeCompletionResult *InResults,
Sam McCall98775c52017-12-04 13:49:59 +0000591 unsigned NumResults) override final {
Eric Liu42abe412018-05-24 11:20:19 +0000592 // If a callback is called without any sema result and the context does not
593 // support index-based completion, we simply skip it to give way to
594 // potential future callbacks with results.
595 if (NumResults == 0 && !contextAllowsIndex(Context.getKind()))
596 return;
Ilya Biryukov94da7bd2018-03-16 15:23:44 +0000597 if (CCSema) {
598 log(llvm::formatv(
599 "Multiple code complete callbacks (parser backtracked?). "
600 "Dropping results from context {0}, keeping results from {1}.",
Eric Liu42abe412018-05-24 11:20:19 +0000601 getCompletionKindString(Context.getKind()),
602 getCompletionKindString(this->CCContext.getKind())));
Ilya Biryukov94da7bd2018-03-16 15:23:44 +0000603 return;
604 }
Sam McCall545a20d2018-01-19 14:34:02 +0000605 // Record the completion context.
Sam McCall545a20d2018-01-19 14:34:02 +0000606 CCSema = &S;
607 CCContext = Context;
Eric Liu6f648df2017-12-19 16:50:37 +0000608
Sam McCall545a20d2018-01-19 14:34:02 +0000609 // Retain the results we might want.
Sam McCall98775c52017-12-04 13:49:59 +0000610 for (unsigned I = 0; I < NumResults; ++I) {
Sam McCall545a20d2018-01-19 14:34:02 +0000611 auto &Result = InResults[I];
612 // Drop hidden items which cannot be found by lookup after completion.
613 // Exception: some items can be named by using a qualifier.
Ilya Biryukovf60bf342018-01-10 13:51:09 +0000614 if (Result.Hidden && (!Result.Qualifier || Result.QualifierIsInformative))
615 continue;
Sam McCall545a20d2018-01-19 14:34:02 +0000616 if (!Opts.IncludeIneligibleResults &&
Sam McCall98775c52017-12-04 13:49:59 +0000617 (Result.Availability == CXAvailability_NotAvailable ||
618 Result.Availability == CXAvailability_NotAccessible))
619 continue;
Sam McCall4caa8512018-06-07 12:49:17 +0000620 if (Result.Declaration &&
621 !Context.getBaseType().isNull() // is this a member-access context?
622 && isBlacklistedMember(*Result.Declaration))
Sam McCalld2a95922018-01-22 21:05:00 +0000623 continue;
Ilya Biryukov53d6d932018-03-06 16:45:21 +0000624 // We choose to never append '::' to completion results in clangd.
625 Result.StartsNestedNameSpecifier = false;
Sam McCall545a20d2018-01-19 14:34:02 +0000626 Results.push_back(Result);
Sam McCall98775c52017-12-04 13:49:59 +0000627 }
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000628 ResultsCallback();
Sam McCall98775c52017-12-04 13:49:59 +0000629 }
630
Sam McCall545a20d2018-01-19 14:34:02 +0000631 CodeCompletionAllocator &getAllocator() override { return *CCAllocator; }
Sam McCall98775c52017-12-04 13:49:59 +0000632 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
633
Sam McCall545a20d2018-01-19 14:34:02 +0000634 // Returns the filtering/sorting name for Result, which must be from Results.
635 // Returned string is owned by this recorder (or the AST).
636 llvm::StringRef getName(const CodeCompletionResult &Result) {
Sam McCall98775c52017-12-04 13:49:59 +0000637 switch (Result.Kind) {
638 case CodeCompletionResult::RK_Declaration:
639 if (auto *ID = Result.Declaration->getIdentifier())
Sam McCall545a20d2018-01-19 14:34:02 +0000640 return ID->getName();
Sam McCall98775c52017-12-04 13:49:59 +0000641 break;
642 case CodeCompletionResult::RK_Keyword:
Sam McCall545a20d2018-01-19 14:34:02 +0000643 return Result.Keyword;
Sam McCall98775c52017-12-04 13:49:59 +0000644 case CodeCompletionResult::RK_Macro:
Sam McCall545a20d2018-01-19 14:34:02 +0000645 return Result.Macro->getName();
Sam McCall98775c52017-12-04 13:49:59 +0000646 case CodeCompletionResult::RK_Pattern:
Sam McCall545a20d2018-01-19 14:34:02 +0000647 return Result.Pattern->getTypedText();
Sam McCall98775c52017-12-04 13:49:59 +0000648 }
Ilya Biryukov43714502018-05-16 12:32:44 +0000649 auto *CCS = codeCompletionString(Result);
Sam McCall545a20d2018-01-19 14:34:02 +0000650 return CCS->getTypedText();
Sam McCall98775c52017-12-04 13:49:59 +0000651 }
652
Sam McCall545a20d2018-01-19 14:34:02 +0000653 // Build a CodeCompletion string for R, which must be from Results.
654 // The CCS will be owned by this recorder.
Ilya Biryukov43714502018-05-16 12:32:44 +0000655 CodeCompletionString *codeCompletionString(const CodeCompletionResult &R) {
Sam McCall545a20d2018-01-19 14:34:02 +0000656 // CodeCompletionResult doesn't seem to be const-correct. We own it, anyway.
657 return const_cast<CodeCompletionResult &>(R).CreateCodeCompletionString(
Ilya Biryukov43714502018-05-16 12:32:44 +0000658 *CCSema, CCContext, *CCAllocator, CCTUInfo,
659 /*IncludeBriefComments=*/false);
Sam McCall98775c52017-12-04 13:49:59 +0000660 }
661
Sam McCall545a20d2018-01-19 14:34:02 +0000662private:
663 CodeCompleteOptions Opts;
664 std::shared_ptr<GlobalCodeCompletionAllocator> CCAllocator;
Sam McCall98775c52017-12-04 13:49:59 +0000665 CodeCompletionTUInfo CCTUInfo;
Benjamin Kramerc36c09f2018-07-03 20:59:33 +0000666 llvm::unique_function<void()> ResultsCallback;
Sam McCall545a20d2018-01-19 14:34:02 +0000667};
668
Sam McCall98775c52017-12-04 13:49:59 +0000669class SignatureHelpCollector final : public CodeCompleteConsumer {
670
671public:
672 SignatureHelpCollector(const clang::CodeCompleteOptions &CodeCompleteOpts,
673 SignatureHelp &SigHelp)
674 : CodeCompleteConsumer(CodeCompleteOpts, /*OutputIsBinary=*/false),
675 SigHelp(SigHelp),
676 Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
677 CCTUInfo(Allocator) {}
678
679 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
680 OverloadCandidate *Candidates,
681 unsigned NumCandidates) override {
682 SigHelp.signatures.reserve(NumCandidates);
683 // FIXME(rwols): How can we determine the "active overload candidate"?
684 // Right now the overloaded candidates seem to be provided in a "best fit"
685 // order, so I'm not too worried about this.
686 SigHelp.activeSignature = 0;
687 assert(CurrentArg <= (unsigned)std::numeric_limits<int>::max() &&
688 "too many arguments");
689 SigHelp.activeParameter = static_cast<int>(CurrentArg);
690 for (unsigned I = 0; I < NumCandidates; ++I) {
691 const auto &Candidate = Candidates[I];
692 const auto *CCS = Candidate.CreateSignatureString(
693 CurrentArg, S, *Allocator, CCTUInfo, true);
694 assert(CCS && "Expected the CodeCompletionString to be non-null");
Ilya Biryukovbe0eb8f2018-05-24 14:49:23 +0000695 // FIXME: for headers, we need to get a comment from the index.
Ilya Biryukov43714502018-05-16 12:32:44 +0000696 SigHelp.signatures.push_back(ProcessOverloadCandidate(
697 Candidate, *CCS,
Ilya Biryukovbe0eb8f2018-05-24 14:49:23 +0000698 getParameterDocComment(S.getASTContext(), Candidate, CurrentArg,
Kirill Bobyrev5a267ed2018-05-29 11:50:51 +0000699 /*CommentsFromHeaders=*/false)));
Sam McCall98775c52017-12-04 13:49:59 +0000700 }
701 }
702
703 GlobalCodeCompletionAllocator &getAllocator() override { return *Allocator; }
704
705 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
706
707private:
Eric Liu63696e12017-12-20 17:24:31 +0000708 // FIXME(ioeric): consider moving CodeCompletionString logic here to
709 // CompletionString.h.
Sam McCall98775c52017-12-04 13:49:59 +0000710 SignatureInformation
711 ProcessOverloadCandidate(const OverloadCandidate &Candidate,
Ilya Biryukov43714502018-05-16 12:32:44 +0000712 const CodeCompletionString &CCS,
713 llvm::StringRef DocComment) const {
Sam McCall98775c52017-12-04 13:49:59 +0000714 SignatureInformation Result;
715 const char *ReturnType = nullptr;
716
Ilya Biryukov43714502018-05-16 12:32:44 +0000717 Result.documentation = formatDocumentation(CCS, DocComment);
Sam McCall98775c52017-12-04 13:49:59 +0000718
719 for (const auto &Chunk : CCS) {
720 switch (Chunk.Kind) {
721 case CodeCompletionString::CK_ResultType:
722 // A piece of text that describes the type of an entity or,
723 // for functions and methods, the return type.
724 assert(!ReturnType && "Unexpected CK_ResultType");
725 ReturnType = Chunk.Text;
726 break;
727 case CodeCompletionString::CK_Placeholder:
728 // A string that acts as a placeholder for, e.g., a function call
729 // argument.
730 // Intentional fallthrough here.
731 case CodeCompletionString::CK_CurrentParameter: {
732 // A piece of text that describes the parameter that corresponds to
733 // the code-completion location within a function call, message send,
734 // macro invocation, etc.
735 Result.label += Chunk.Text;
736 ParameterInformation Info;
737 Info.label = Chunk.Text;
738 Result.parameters.push_back(std::move(Info));
739 break;
740 }
741 case CodeCompletionString::CK_Optional: {
742 // The rest of the parameters are defaulted/optional.
743 assert(Chunk.Optional &&
744 "Expected the optional code completion string to be non-null.");
745 Result.label +=
746 getOptionalParameters(*Chunk.Optional, Result.parameters);
747 break;
748 }
749 case CodeCompletionString::CK_VerticalSpace:
750 break;
751 default:
752 Result.label += Chunk.Text;
753 break;
754 }
755 }
756 if (ReturnType) {
757 Result.label += " -> ";
758 Result.label += ReturnType;
759 }
760 return Result;
761 }
762
763 SignatureHelp &SigHelp;
764 std::shared_ptr<clang::GlobalCodeCompletionAllocator> Allocator;
765 CodeCompletionTUInfo CCTUInfo;
766
767}; // SignatureHelpCollector
768
Sam McCall545a20d2018-01-19 14:34:02 +0000769struct SemaCompleteInput {
770 PathRef FileName;
771 const tooling::CompileCommand &Command;
772 PrecompiledPreamble const *Preamble;
773 StringRef Contents;
774 Position Pos;
775 IntrusiveRefCntPtr<vfs::FileSystem> VFS;
776 std::shared_ptr<PCHContainerOperations> PCHs;
777};
778
779// Invokes Sema code completion on a file.
Sam McCall3f0243f2018-07-03 08:09:29 +0000780// If \p Includes is set, it will be updated based on the compiler invocation.
Sam McCalld1a7a372018-01-31 13:40:48 +0000781bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
Sam McCall545a20d2018-01-19 14:34:02 +0000782 const clang::CodeCompleteOptions &Options,
Eric Liu63f419a2018-05-15 15:29:32 +0000783 const SemaCompleteInput &Input,
Sam McCall3f0243f2018-07-03 08:09:29 +0000784 IncludeStructure *Includes = nullptr) {
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000785 trace::Span Tracer("Sema completion");
Sam McCall98775c52017-12-04 13:49:59 +0000786 std::vector<const char *> ArgStrs;
Sam McCall545a20d2018-01-19 14:34:02 +0000787 for (const auto &S : Input.Command.CommandLine)
Sam McCall98775c52017-12-04 13:49:59 +0000788 ArgStrs.push_back(S.c_str());
789
Ilya Biryukova9cf3112018-02-13 17:15:06 +0000790 if (Input.VFS->setCurrentWorkingDirectory(Input.Command.Directory)) {
791 log("Couldn't set working directory");
792 // We run parsing anyway, our lit-tests rely on results for non-existing
793 // working dirs.
794 }
Sam McCall98775c52017-12-04 13:49:59 +0000795
796 IgnoreDiagnostics DummyDiagsConsumer;
797 auto CI = createInvocationFromCommandLine(
798 ArgStrs,
799 CompilerInstance::createDiagnostics(new DiagnosticOptions,
800 &DummyDiagsConsumer, false),
Sam McCall545a20d2018-01-19 14:34:02 +0000801 Input.VFS);
Ilya Biryukovb6ad25c2018-02-09 13:51:57 +0000802 if (!CI) {
Kirill Bobyrev5a267ed2018-05-29 11:50:51 +0000803 log("Couldn't create CompilerInvocation");
Ilya Biryukovb6ad25c2018-02-09 13:51:57 +0000804 return false;
805 }
Ilya Biryukov981a35d2018-05-28 12:11:37 +0000806 auto &FrontendOpts = CI->getFrontendOpts();
807 FrontendOpts.DisableFree = false;
Sam McCall98775c52017-12-04 13:49:59 +0000808 FrontendOpts.SkipFunctionBodies = true;
Ilya Biryukov981a35d2018-05-28 12:11:37 +0000809 CI->getLangOpts()->CommentOpts.ParseAllComments = true;
810 // Disable typo correction in Sema.
811 CI->getLangOpts()->SpellChecking = false;
812 // Setup code completion.
Sam McCall98775c52017-12-04 13:49:59 +0000813 FrontendOpts.CodeCompleteOpts = Options;
Sam McCall545a20d2018-01-19 14:34:02 +0000814 FrontendOpts.CodeCompletionAt.FileName = Input.FileName;
Sam McCalla4962cc2018-04-27 11:59:28 +0000815 auto Offset = positionToOffset(Input.Contents, Input.Pos);
816 if (!Offset) {
817 log("Code completion position was invalid " +
818 llvm::toString(Offset.takeError()));
819 return false;
820 }
821 std::tie(FrontendOpts.CodeCompletionAt.Line,
822 FrontendOpts.CodeCompletionAt.Column) =
823 offsetToClangLineColumn(Input.Contents, *Offset);
Sam McCall98775c52017-12-04 13:49:59 +0000824
Ilya Biryukov981a35d2018-05-28 12:11:37 +0000825 std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
826 llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName);
827 // The diagnostic options must be set before creating a CompilerInstance.
828 CI->getDiagnosticOpts().IgnoreWarnings = true;
829 // We reuse the preamble whether it's valid or not. This is a
830 // correctness/performance tradeoff: building without a preamble is slow, and
831 // completion is latency-sensitive.
832 // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise
833 // the remapped buffers do not get freed.
834 auto Clang = prepareCompilerInstance(
835 std::move(CI), Input.Preamble, std::move(ContentsBuffer),
836 std::move(Input.PCHs), std::move(Input.VFS), DummyDiagsConsumer);
Sam McCall98775c52017-12-04 13:49:59 +0000837 Clang->setCodeCompletionConsumer(Consumer.release());
838
839 SyntaxOnlyAction Action;
840 if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
Sam McCalld1a7a372018-01-31 13:40:48 +0000841 log("BeginSourceFile() failed when running codeComplete for " +
842 Input.FileName);
Sam McCall98775c52017-12-04 13:49:59 +0000843 return false;
844 }
Sam McCall3f0243f2018-07-03 08:09:29 +0000845 if (Includes)
846 Clang->getPreprocessor().addPPCallbacks(
847 collectIncludeStructureCallback(Clang->getSourceManager(), Includes));
Sam McCall98775c52017-12-04 13:49:59 +0000848 if (!Action.Execute()) {
Sam McCalld1a7a372018-01-31 13:40:48 +0000849 log("Execute() failed when running codeComplete for " + Input.FileName);
Sam McCall98775c52017-12-04 13:49:59 +0000850 return false;
851 }
Sam McCall98775c52017-12-04 13:49:59 +0000852 Action.EndSourceFile();
853
854 return true;
855}
856
Ilya Biryukova907ba42018-05-14 10:50:04 +0000857// Should we allow index completions in the specified context?
858bool allowIndex(CodeCompletionContext &CC) {
859 if (!contextAllowsIndex(CC.getKind()))
860 return false;
861 // We also avoid ClassName::bar (but allow namespace::bar).
862 auto Scope = CC.getCXXScopeSpecifier();
863 if (!Scope)
864 return true;
865 NestedNameSpecifier *NameSpec = (*Scope)->getScopeRep();
866 if (!NameSpec)
867 return true;
868 // We only query the index when qualifier is a namespace.
869 // If it's a class, we rely solely on sema completions.
870 switch (NameSpec->getKind()) {
871 case NestedNameSpecifier::Global:
872 case NestedNameSpecifier::Namespace:
873 case NestedNameSpecifier::NamespaceAlias:
874 return true;
875 case NestedNameSpecifier::Super:
876 case NestedNameSpecifier::TypeSpec:
877 case NestedNameSpecifier::TypeSpecWithTemplate:
878 // Unresolved inside a template.
879 case NestedNameSpecifier::Identifier:
880 return false;
881 }
Ilya Biryukova6556e22018-05-14 11:47:30 +0000882 llvm_unreachable("invalid NestedNameSpecifier kind");
Ilya Biryukova907ba42018-05-14 10:50:04 +0000883}
884
Sam McCall98775c52017-12-04 13:49:59 +0000885} // namespace
886
887clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
888 clang::CodeCompleteOptions Result;
889 Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns;
890 Result.IncludeMacros = IncludeMacros;
Sam McCalld8169a82018-01-18 15:31:30 +0000891 Result.IncludeGlobals = true;
Ilya Biryukov43714502018-05-16 12:32:44 +0000892 // We choose to include full comments and not do doxygen parsing in
893 // completion.
894 // FIXME: ideally, we should support doxygen in some form, e.g. do markdown
895 // formatting of the comments.
896 Result.IncludeBriefComments = false;
Sam McCall98775c52017-12-04 13:49:59 +0000897
Sam McCall3d139c52018-01-12 18:30:08 +0000898 // When an is used, Sema is responsible for completing the main file,
899 // the index can provide results from the preamble.
900 // Tell Sema not to deserialize the preamble to look for results.
901 Result.LoadExternal = !Index;
Eric Liu6f648df2017-12-19 16:50:37 +0000902
Sam McCall98775c52017-12-04 13:49:59 +0000903 return Result;
904}
905
Sam McCall545a20d2018-01-19 14:34:02 +0000906// Runs Sema-based (AST) and Index-based completion, returns merged results.
907//
908// There are a few tricky considerations:
909// - the AST provides information needed for the index query (e.g. which
910// namespaces to search in). So Sema must start first.
911// - we only want to return the top results (Opts.Limit).
912// Building CompletionItems for everything else is wasteful, so we want to
913// preserve the "native" format until we're done with scoring.
914// - the data underlying Sema completion items is owned by the AST and various
915// other arenas, which must stay alive for us to build CompletionItems.
916// - we may get duplicate results from Sema and the Index, we need to merge.
917//
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000918// So we start Sema completion first, and do all our work in its callback.
Sam McCall545a20d2018-01-19 14:34:02 +0000919// We use the Sema context information to query the index.
920// Then we merge the two result sets, producing items that are Sema/Index/Both.
921// These items are scored, and the top N are synthesized into the LSP response.
922// Finally, we can clean up the data structures created by Sema completion.
923//
924// Main collaborators are:
925// - semaCodeComplete sets up the compiler machinery to run code completion.
926// - CompletionRecorder captures Sema completion results, including context.
927// - SymbolIndex (Opts.Index) provides index completion results as Symbols
928// - CompletionCandidates are the result of merging Sema and Index results.
929// Each candidate points to an underlying CodeCompletionResult (Sema), a
930// Symbol (Index), or both. It computes the result quality score.
931// CompletionCandidate also does conversion to CompletionItem (at the end).
932// - FuzzyMatcher scores how the candidate matches the partial identifier.
933// This score is combined with the result quality score for the final score.
934// - TopN determines the results with the best score.
935class CodeCompleteFlow {
Eric Liuc5105f92018-02-16 14:15:55 +0000936 PathRef FileName;
Sam McCall3f0243f2018-07-03 08:09:29 +0000937 IncludeStructure Includes; // Complete once the compiler runs.
Sam McCall545a20d2018-01-19 14:34:02 +0000938 const CodeCompleteOptions &Opts;
939 // Sema takes ownership of Recorder. Recorder is valid until Sema cleanup.
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000940 CompletionRecorder *Recorder = nullptr;
Sam McCall545a20d2018-01-19 14:34:02 +0000941 int NSema = 0, NIndex = 0, NBoth = 0; // Counters for logging.
942 bool Incomplete = false; // Would more be available with a higher limit?
Eric Liu63f419a2018-05-15 15:29:32 +0000943 llvm::Optional<FuzzyMatcher> Filter; // Initialized once Sema runs.
Eric Liubc25ef72018-07-05 08:29:33 +0000944 std::vector<std::string> QueryScopes; // Initialized once Sema runs.
Sam McCall3f0243f2018-07-03 08:09:29 +0000945 // Include-insertion and proximity scoring rely on the include structure.
946 // This is available after Sema has run.
947 llvm::Optional<IncludeInserter> Inserter; // Available during runWithSema.
948 llvm::Optional<URIDistance> FileProximity; // Initialized once Sema runs.
Sam McCall545a20d2018-01-19 14:34:02 +0000949
950public:
951 // A CodeCompleteFlow object is only useful for calling run() exactly once.
Sam McCall3f0243f2018-07-03 08:09:29 +0000952 CodeCompleteFlow(PathRef FileName, const IncludeStructure &Includes,
953 const CodeCompleteOptions &Opts)
954 : FileName(FileName), Includes(Includes), Opts(Opts) {}
Sam McCall545a20d2018-01-19 14:34:02 +0000955
Sam McCall27c979a2018-06-29 14:47:57 +0000956 CodeCompleteResult run(const SemaCompleteInput &SemaCCInput) && {
Sam McCalld1a7a372018-01-31 13:40:48 +0000957 trace::Span Tracer("CodeCompleteFlow");
Eric Liu63f419a2018-05-15 15:29:32 +0000958
Sam McCall545a20d2018-01-19 14:34:02 +0000959 // We run Sema code completion first. It builds an AST and calculates:
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000960 // - completion results based on the AST.
Sam McCall545a20d2018-01-19 14:34:02 +0000961 // - partial identifier and context. We need these for the index query.
Sam McCall27c979a2018-06-29 14:47:57 +0000962 CodeCompleteResult Output;
Ilya Biryukovddf6a332018-03-02 12:28:27 +0000963 auto RecorderOwner = llvm::make_unique<CompletionRecorder>(Opts, [&]() {
964 assert(Recorder && "Recorder is not set");
Sam McCall3f0243f2018-07-03 08:09:29 +0000965 auto Style =
Eric Liu9338a882018-07-03 14:51:23 +0000966 format::getStyle(format::DefaultFormatStyle, SemaCCInput.FileName,
967 format::DefaultFallbackStyle, SemaCCInput.Contents,
968 SemaCCInput.VFS.get());
Sam McCall3f0243f2018-07-03 08:09:29 +0000969 if (!Style) {
970 log("Failed to get FormatStyle for file" + SemaCCInput.FileName + ": " +
971 llvm::toString(Style.takeError()) + ". Fallback is LLVM style.");
972 Style = format::getLLVMStyle();
973 }
Eric Liu63f419a2018-05-15 15:29:32 +0000974 // If preprocessor was run, inclusions from preprocessor callback should
Sam McCall3f0243f2018-07-03 08:09:29 +0000975 // already be added to Includes.
976 Inserter.emplace(
977 SemaCCInput.FileName, SemaCCInput.Contents, *Style,
978 SemaCCInput.Command.Directory,
979 Recorder->CCSema->getPreprocessor().getHeaderSearchInfo());
980 for (const auto &Inc : Includes.MainFileIncludes)
981 Inserter->addExisting(Inc);
982
983 // Most of the cost of file proximity is in initializing the FileDistance
984 // structures based on the observed includes, once per query. Conceptually
985 // that happens here (though the per-URI-scheme initialization is lazy).
986 // The per-result proximity scoring is (amortized) very cheap.
987 FileDistanceOptions ProxOpts{}; // Use defaults.
988 const auto &SM = Recorder->CCSema->getSourceManager();
989 llvm::StringMap<SourceParams> ProxSources;
990 for (auto &Entry : Includes.includeDepth(
991 SM.getFileEntryForID(SM.getMainFileID())->getName())) {
992 auto &Source = ProxSources[Entry.getKey()];
993 Source.Cost = Entry.getValue() * ProxOpts.IncludeCost;
994 // Symbols near our transitive includes are good, but only consider
995 // things in the same directory or below it. Otherwise there can be
996 // many false positives.
997 if (Entry.getValue() > 0)
998 Source.MaxUpTraversals = 1;
999 }
1000 FileProximity.emplace(ProxSources, ProxOpts);
1001
Ilya Biryukovddf6a332018-03-02 12:28:27 +00001002 Output = runWithSema();
Sam McCall3f0243f2018-07-03 08:09:29 +00001003 Inserter.reset(); // Make sure this doesn't out-live Clang.
Ilya Biryukovddf6a332018-03-02 12:28:27 +00001004 SPAN_ATTACH(Tracer, "sema_completion_kind",
1005 getCompletionKindString(Recorder->CCContext.getKind()));
Eric Liubc25ef72018-07-05 08:29:33 +00001006 log(llvm::formatv(
1007 "Code complete: sema context {0}, query scopes [{1}]",
1008 getCompletionKindString(Recorder->CCContext.getKind()),
1009 llvm::join(QueryScopes.begin(), QueryScopes.end(), ",")));
Ilya Biryukovddf6a332018-03-02 12:28:27 +00001010 });
1011
1012 Recorder = RecorderOwner.get();
Sam McCalld1a7a372018-01-31 13:40:48 +00001013 semaCodeComplete(std::move(RecorderOwner), Opts.getClangCompleteOpts(),
Eric Liu63f419a2018-05-15 15:29:32 +00001014 SemaCCInput, &Includes);
Sam McCall545a20d2018-01-19 14:34:02 +00001015
Sam McCall2b780162018-01-30 17:20:54 +00001016 SPAN_ATTACH(Tracer, "sema_results", NSema);
1017 SPAN_ATTACH(Tracer, "index_results", NIndex);
1018 SPAN_ATTACH(Tracer, "merged_results", NBoth);
Sam McCall27c979a2018-06-29 14:47:57 +00001019 SPAN_ATTACH(Tracer, "returned_results", Output.Completions.size());
1020 SPAN_ATTACH(Tracer, "incomplete", Output.HasMore);
Sam McCall0f8df3e2018-06-13 11:31:20 +00001021 log(llvm::formatv("Code complete: {0} results from Sema, {1} from Index, "
1022 "{2} matched, {3} returned{4}.",
Sam McCall27c979a2018-06-29 14:47:57 +00001023 NSema, NIndex, NBoth, Output.Completions.size(),
1024 Output.HasMore ? " (incomplete)" : ""));
1025 assert(!Opts.Limit || Output.Completions.size() <= Opts.Limit);
Sam McCall545a20d2018-01-19 14:34:02 +00001026 // We don't assert that isIncomplete means we hit a limit.
1027 // Indexes may choose to impose their own limits even if we don't have one.
1028 return Output;
1029 }
1030
1031private:
1032 // This is called by run() once Sema code completion is done, but before the
1033 // Sema data structures are torn down. It does all the real work.
Sam McCall27c979a2018-06-29 14:47:57 +00001034 CodeCompleteResult runWithSema() {
Sam McCall545a20d2018-01-19 14:34:02 +00001035 Filter = FuzzyMatcher(
Ilya Biryukovddf6a332018-03-02 12:28:27 +00001036 Recorder->CCSema->getPreprocessor().getCodeCompletionFilter());
Eric Liubc25ef72018-07-05 08:29:33 +00001037 QueryScopes = getQueryScopes(Recorder->CCContext,
1038 Recorder->CCSema->getSourceManager());
Sam McCall545a20d2018-01-19 14:34:02 +00001039 // Sema provides the needed context to query the index.
1040 // FIXME: in addition to querying for extra/overlapping symbols, we should
1041 // explicitly request symbols corresponding to Sema results.
1042 // We can use their signals even if the index can't suggest them.
1043 // We must copy index results to preserve them, but there are at most Limit.
Eric Liu8f3678d2018-06-15 13:34:18 +00001044 auto IndexResults = (Opts.Index && allowIndex(Recorder->CCContext))
1045 ? queryIndex()
1046 : SymbolSlab();
Sam McCall545a20d2018-01-19 14:34:02 +00001047 // Merge Sema and Index results, score them, and pick the winners.
Ilya Biryukovddf6a332018-03-02 12:28:27 +00001048 auto Top = mergeResults(Recorder->Results, IndexResults);
Sam McCall27c979a2018-06-29 14:47:57 +00001049 // Convert the results to final form, assembling the expensive strings.
1050 CodeCompleteResult Output;
1051 for (auto &C : Top) {
1052 Output.Completions.push_back(toCodeCompletion(C.first));
1053 Output.Completions.back().Score = C.second;
1054 }
1055 Output.HasMore = Incomplete;
Sam McCall545a20d2018-01-19 14:34:02 +00001056 return Output;
1057 }
1058
1059 SymbolSlab queryIndex() {
Sam McCalld1a7a372018-01-31 13:40:48 +00001060 trace::Span Tracer("Query index");
Sam McCall2b780162018-01-30 17:20:54 +00001061 SPAN_ATTACH(Tracer, "limit", Opts.Limit);
1062
Sam McCall545a20d2018-01-19 14:34:02 +00001063 SymbolSlab::Builder ResultsBuilder;
1064 // Build the query.
1065 FuzzyFindRequest Req;
Haojian Wu48b48652018-01-25 09:20:09 +00001066 if (Opts.Limit)
1067 Req.MaxCandidateCount = Opts.Limit;
Sam McCall545a20d2018-01-19 14:34:02 +00001068 Req.Query = Filter->pattern();
Marc-Andre Laperle945b5a32018-06-05 14:01:40 +00001069 Req.RestrictForCodeCompletion = true;
Eric Liubc25ef72018-07-05 08:29:33 +00001070 Req.Scopes = QueryScopes;
Sam McCall3f0243f2018-07-03 08:09:29 +00001071 // FIXME: we should send multiple weighted paths here.
Eric Liu6de95ec2018-06-12 08:48:20 +00001072 Req.ProximityPaths.push_back(FileName);
Sam McCalld1a7a372018-01-31 13:40:48 +00001073 log(llvm::formatv("Code complete: fuzzyFind(\"{0}\", scopes=[{1}])",
Sam McCall2b780162018-01-30 17:20:54 +00001074 Req.Query,
1075 llvm::join(Req.Scopes.begin(), Req.Scopes.end(), ",")));
Sam McCall545a20d2018-01-19 14:34:02 +00001076 // Run the query against the index.
Sam McCallab8e3932018-02-19 13:04:41 +00001077 if (Opts.Index->fuzzyFind(
1078 Req, [&](const Symbol &Sym) { ResultsBuilder.insert(Sym); }))
1079 Incomplete = true;
Sam McCall545a20d2018-01-19 14:34:02 +00001080 return std::move(ResultsBuilder).build();
1081 }
1082
Sam McCallc18c2802018-06-15 11:06:29 +00001083 // Merges Sema and Index results where possible, to form CompletionCandidates.
1084 // Groups overloads if desired, to form CompletionCandidate::Bundles.
1085 // The bundles are scored and top results are returned, best to worst.
1086 std::vector<ScoredBundle>
Sam McCall545a20d2018-01-19 14:34:02 +00001087 mergeResults(const std::vector<CodeCompletionResult> &SemaResults,
1088 const SymbolSlab &IndexResults) {
Sam McCalld1a7a372018-01-31 13:40:48 +00001089 trace::Span Tracer("Merge and score results");
Sam McCallc18c2802018-06-15 11:06:29 +00001090 std::vector<CompletionCandidate::Bundle> Bundles;
1091 llvm::DenseMap<size_t, size_t> BundleLookup;
1092 auto AddToBundles = [&](const CodeCompletionResult *SemaResult,
1093 const Symbol *IndexResult) {
1094 CompletionCandidate C;
1095 C.SemaResult = SemaResult;
1096 C.IndexResult = IndexResult;
1097 C.Name = IndexResult ? IndexResult->Name : Recorder->getName(*SemaResult);
1098 if (auto OverloadSet = Opts.BundleOverloads ? C.overloadSet() : 0) {
1099 auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
1100 if (Ret.second)
1101 Bundles.emplace_back();
1102 Bundles[Ret.first->second].push_back(std::move(C));
1103 } else {
1104 Bundles.emplace_back();
1105 Bundles.back().push_back(std::move(C));
1106 }
1107 };
Sam McCall545a20d2018-01-19 14:34:02 +00001108 llvm::DenseSet<const Symbol *> UsedIndexResults;
1109 auto CorrespondingIndexResult =
1110 [&](const CodeCompletionResult &SemaResult) -> const Symbol * {
1111 if (auto SymID = getSymbolID(SemaResult)) {
1112 auto I = IndexResults.find(*SymID);
1113 if (I != IndexResults.end()) {
1114 UsedIndexResults.insert(&*I);
1115 return &*I;
1116 }
1117 }
1118 return nullptr;
1119 };
1120 // Emit all Sema results, merging them with Index results if possible.
Ilya Biryukovddf6a332018-03-02 12:28:27 +00001121 for (auto &SemaResult : Recorder->Results)
Sam McCallc18c2802018-06-15 11:06:29 +00001122 AddToBundles(&SemaResult, CorrespondingIndexResult(SemaResult));
Sam McCall545a20d2018-01-19 14:34:02 +00001123 // Now emit any Index-only results.
1124 for (const auto &IndexResult : IndexResults) {
1125 if (UsedIndexResults.count(&IndexResult))
1126 continue;
Sam McCallc18c2802018-06-15 11:06:29 +00001127 AddToBundles(/*SemaResult=*/nullptr, &IndexResult);
Sam McCall545a20d2018-01-19 14:34:02 +00001128 }
Sam McCallc18c2802018-06-15 11:06:29 +00001129 // We only keep the best N results at any time, in "native" format.
1130 TopN<ScoredBundle, ScoredBundleGreater> Top(
1131 Opts.Limit == 0 ? std::numeric_limits<size_t>::max() : Opts.Limit);
1132 for (auto &Bundle : Bundles)
1133 addCandidate(Top, std::move(Bundle));
Sam McCall545a20d2018-01-19 14:34:02 +00001134 return std::move(Top).items();
1135 }
1136
Sam McCall80ad7072018-06-08 13:32:25 +00001137 Optional<float> fuzzyScore(const CompletionCandidate &C) {
1138 // Macros can be very spammy, so we only support prefix completion.
1139 // We won't end up with underfull index results, as macros are sema-only.
1140 if (C.SemaResult && C.SemaResult->Kind == CodeCompletionResult::RK_Macro &&
1141 !C.Name.startswith_lower(Filter->pattern()))
1142 return None;
1143 return Filter->match(C.Name);
1144 }
1145
Sam McCall545a20d2018-01-19 14:34:02 +00001146 // Scores a candidate and adds it to the TopN structure.
Sam McCallc18c2802018-06-15 11:06:29 +00001147 void addCandidate(TopN<ScoredBundle, ScoredBundleGreater> &Candidates,
1148 CompletionCandidate::Bundle Bundle) {
Sam McCallc5707b62018-05-15 17:43:27 +00001149 SymbolQualitySignals Quality;
1150 SymbolRelevanceSignals Relevance;
Sam McCalld9b54f02018-06-05 16:30:25 +00001151 Relevance.Query = SymbolRelevanceSignals::CodeComplete;
Sam McCallf84dd022018-07-05 08:26:53 +00001152 Relevance.FileProximityMatch = FileProximity.getPointer();
Sam McCallc18c2802018-06-15 11:06:29 +00001153 auto &First = Bundle.front();
1154 if (auto FuzzyScore = fuzzyScore(First))
Sam McCallc5707b62018-05-15 17:43:27 +00001155 Relevance.NameMatch = *FuzzyScore;
Sam McCall545a20d2018-01-19 14:34:02 +00001156 else
1157 return;
Sam McCall2161ec72018-07-05 06:20:41 +00001158 SymbolOrigin Origin = SymbolOrigin::Unknown;
Sam McCallc18c2802018-06-15 11:06:29 +00001159 for (const auto &Candidate : Bundle) {
1160 if (Candidate.IndexResult) {
1161 Quality.merge(*Candidate.IndexResult);
1162 Relevance.merge(*Candidate.IndexResult);
Sam McCall2161ec72018-07-05 06:20:41 +00001163 Origin =
1164 static_cast<SymbolOrigin>(Origin | Candidate.IndexResult->Origin);
Sam McCallc18c2802018-06-15 11:06:29 +00001165 }
1166 if (Candidate.SemaResult) {
1167 Quality.merge(*Candidate.SemaResult);
1168 Relevance.merge(*Candidate.SemaResult);
Sam McCall2161ec72018-07-05 06:20:41 +00001169 Origin = static_cast<SymbolOrigin>(Origin | SymbolOrigin::AST);
Sam McCallc18c2802018-06-15 11:06:29 +00001170 }
Sam McCallc5707b62018-05-15 17:43:27 +00001171 }
1172
Sam McCall27c979a2018-06-29 14:47:57 +00001173 CodeCompletion::Scores Scores;
1174 Scores.Quality = Quality.evaluate();
1175 Scores.Relevance = Relevance.evaluate();
1176 Scores.Total = evaluateSymbolAndRelevance(Scores.Quality, Scores.Relevance);
1177 // NameMatch is in fact a multiplier on total score, so rescoring is sound.
1178 Scores.ExcludingName = Relevance.NameMatch
1179 ? Scores.Total / Relevance.NameMatch
1180 : Scores.Quality;
Sam McCallc5707b62018-05-15 17:43:27 +00001181
Sam McCall2161ec72018-07-05 06:20:41 +00001182 LLVM_DEBUG(llvm::dbgs() << "CodeComplete: " << First.Name << " (" << Origin
1183 << ") = " << Scores.Total << "\n"
Sam McCallc18c2802018-06-15 11:06:29 +00001184 << Quality << Relevance << "\n");
Sam McCall545a20d2018-01-19 14:34:02 +00001185
Sam McCall2161ec72018-07-05 06:20:41 +00001186 NSema += bool(Origin & SymbolOrigin::AST);
1187 NIndex += bool(Origin & ~SymbolOrigin::AST);
1188 NBoth += (Origin & SymbolOrigin::AST) && (Origin & ~SymbolOrigin::AST);
Sam McCallc18c2802018-06-15 11:06:29 +00001189 if (Candidates.push({std::move(Bundle), Scores}))
Sam McCallab8e3932018-02-19 13:04:41 +00001190 Incomplete = true;
Sam McCall545a20d2018-01-19 14:34:02 +00001191 }
1192
Sam McCall27c979a2018-06-29 14:47:57 +00001193 CodeCompletion toCodeCompletion(const CompletionCandidate::Bundle &Bundle) {
1194 llvm::Optional<CodeCompletionBuilder> Builder;
1195 for (const auto &Item : Bundle) {
1196 CodeCompletionString *SemaCCS =
1197 Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
1198 : nullptr;
1199 if (!Builder)
1200 Builder.emplace(Recorder->CCSema->getASTContext(), Item, SemaCCS,
Sam McCall3f0243f2018-07-03 08:09:29 +00001201 *Inserter, FileName, Opts);
Sam McCall27c979a2018-06-29 14:47:57 +00001202 else
1203 Builder->add(Item, SemaCCS);
Ilya Biryukov43714502018-05-16 12:32:44 +00001204 }
Sam McCall27c979a2018-06-29 14:47:57 +00001205 return Builder->build();
Sam McCall545a20d2018-01-19 14:34:02 +00001206 }
1207};
1208
Sam McCall3f0243f2018-07-03 08:09:29 +00001209CodeCompleteResult codeComplete(PathRef FileName,
1210 const tooling::CompileCommand &Command,
1211 PrecompiledPreamble const *Preamble,
1212 const IncludeStructure &PreambleInclusions,
1213 StringRef Contents, Position Pos,
1214 IntrusiveRefCntPtr<vfs::FileSystem> VFS,
1215 std::shared_ptr<PCHContainerOperations> PCHs,
1216 CodeCompleteOptions Opts) {
1217 return CodeCompleteFlow(FileName, PreambleInclusions, Opts)
1218 .run({FileName, Command, Preamble, Contents, Pos, VFS, PCHs});
Sam McCall98775c52017-12-04 13:49:59 +00001219}
1220
Sam McCalld1a7a372018-01-31 13:40:48 +00001221SignatureHelp signatureHelp(PathRef FileName,
Ilya Biryukov940901e2017-12-13 12:51:22 +00001222 const tooling::CompileCommand &Command,
1223 PrecompiledPreamble const *Preamble,
1224 StringRef Contents, Position Pos,
1225 IntrusiveRefCntPtr<vfs::FileSystem> VFS,
1226 std::shared_ptr<PCHContainerOperations> PCHs) {
Sam McCall98775c52017-12-04 13:49:59 +00001227 SignatureHelp Result;
1228 clang::CodeCompleteOptions Options;
1229 Options.IncludeGlobals = false;
1230 Options.IncludeMacros = false;
1231 Options.IncludeCodePatterns = false;
Ilya Biryukov43714502018-05-16 12:32:44 +00001232 Options.IncludeBriefComments = false;
Sam McCall3f0243f2018-07-03 08:09:29 +00001233 IncludeStructure PreambleInclusions; // Unused for signatureHelp
Sam McCalld1a7a372018-01-31 13:40:48 +00001234 semaCodeComplete(llvm::make_unique<SignatureHelpCollector>(Options, Result),
1235 Options,
Sam McCall3f0243f2018-07-03 08:09:29 +00001236 {FileName, Command, Preamble, Contents, Pos, std::move(VFS),
1237 std::move(PCHs)});
Sam McCall98775c52017-12-04 13:49:59 +00001238 return Result;
1239}
1240
Marc-Andre Laperle945b5a32018-06-05 14:01:40 +00001241bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx) {
1242 using namespace clang::ast_matchers;
1243 auto InTopLevelScope = hasDeclContext(
1244 anyOf(namespaceDecl(), translationUnitDecl(), linkageSpecDecl()));
1245 return !match(decl(anyOf(InTopLevelScope,
1246 hasDeclContext(
1247 enumDecl(InTopLevelScope, unless(isScoped()))))),
1248 ND, ASTCtx)
1249 .empty();
1250}
1251
Sam McCall27c979a2018-06-29 14:47:57 +00001252CompletionItem CodeCompletion::render(const CodeCompleteOptions &Opts) const {
1253 CompletionItem LSP;
1254 LSP.label = (HeaderInsertion ? Opts.IncludeIndicator.Insert
1255 : Opts.IncludeIndicator.NoInsert) +
Sam McCall2161ec72018-07-05 06:20:41 +00001256 (Opts.ShowOrigins ? "[" + llvm::to_string(Origin) + "]" : "") +
Sam McCall27c979a2018-06-29 14:47:57 +00001257 RequiredQualifier + Name + Signature;
Sam McCall2161ec72018-07-05 06:20:41 +00001258
Sam McCall27c979a2018-06-29 14:47:57 +00001259 LSP.kind = Kind;
1260 LSP.detail = BundleSize > 1 ? llvm::formatv("[{0} overloads]", BundleSize)
1261 : ReturnType;
1262 if (!Header.empty())
1263 LSP.detail += "\n" + Header;
1264 LSP.documentation = Documentation;
1265 LSP.sortText = sortText(Score.Total, Name);
1266 LSP.filterText = Name;
1267 LSP.insertText = RequiredQualifier + Name;
1268 if (Opts.EnableSnippets)
1269 LSP.insertText += SnippetSuffix;
1270 LSP.insertTextFormat = Opts.EnableSnippets ? InsertTextFormat::Snippet
1271 : InsertTextFormat::PlainText;
1272 if (HeaderInsertion)
1273 LSP.additionalTextEdits = {*HeaderInsertion};
Sam McCall27c979a2018-06-29 14:47:57 +00001274 return LSP;
1275}
1276
Sam McCalle746a2b2018-07-02 11:13:16 +00001277raw_ostream &operator<<(raw_ostream &OS, const CodeCompletion &C) {
1278 // For now just lean on CompletionItem.
1279 return OS << C.render(CodeCompleteOptions());
1280}
1281
1282raw_ostream &operator<<(raw_ostream &OS, const CodeCompleteResult &R) {
1283 OS << "CodeCompleteResult: " << R.Completions.size() << (R.HasMore ? "+" : "")
1284 << " items:\n";
1285 for (const auto &C : R.Completions)
1286 OS << C << "\n";
1287 return OS;
1288}
1289
Sam McCall98775c52017-12-04 13:49:59 +00001290} // namespace clangd
1291} // namespace clang