15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/DeclVisitor.h"
20 #include "clang/Basic/SourceManager.h"
21 #include "clang/Sema/CodeCompleteConsumer.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/Casting.h"
24 #include "llvm/Support/FormatVariadic.h"
25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/Support/raw_ostream.h"
35 auto &
SourceMgr =
D.getASTContext().getSourceManager();
36 for (
auto *Redecl :
D.redecls()) {
44 const auto &
Context = R.Declaration->getASTContext();
54 if (
const auto *FD = dyn_cast<FunctionDecl>(&ND)) {
55 if (FD->isOverloadedOperator())
59 :
public ConstDeclVisitor<Switch, SymbolQualitySignals::SymbolCategory> {
61 #define MAP(DeclType, Category) \
62 SymbolQualitySignals::SymbolCategory Visit##DeclType(const DeclType *) { \
63 return SymbolQualitySignals::Category; \
68 MAP(TypeAliasTemplateDecl,
Type);
71 MAP(CXXDestructorDecl, Destructor);
79 return Switch().Visit(&ND);
86 if (R.Kind == CodeCompletionResult::RK_Macro)
90 switch (R.CursorKind) {
91 case CXCursor_CXXMethod:
93 case CXCursor_ModuleImportDecl:
95 case CXCursor_MacroDefinition:
97 case CXCursor_TypeRef:
99 case CXCursor_MemberRef:
101 case CXCursor_Constructor:
111 case index::SymbolKind::Namespace:
112 case index::SymbolKind::NamespaceAlias:
114 case index::SymbolKind::Macro:
116 case index::SymbolKind::Enum:
117 case index::SymbolKind::Struct:
118 case index::SymbolKind::Class:
119 case index::SymbolKind::Protocol:
120 case index::SymbolKind::Extension:
121 case index::SymbolKind::Union:
122 case index::SymbolKind::TypeAlias:
123 case index::SymbolKind::TemplateTypeParm:
124 case index::SymbolKind::TemplateTemplateParm:
125 case index::SymbolKind::Concept:
127 case index::SymbolKind::Function:
128 case index::SymbolKind::ClassMethod:
129 case index::SymbolKind::InstanceMethod:
130 case index::SymbolKind::StaticMethod:
131 case index::SymbolKind::InstanceProperty:
132 case index::SymbolKind::ClassProperty:
133 case index::SymbolKind::StaticProperty:
134 case index::SymbolKind::ConversionFunction:
136 case index::SymbolKind::Destructor:
138 case index::SymbolKind::Constructor:
140 case index::SymbolKind::Variable:
142 case index::SymbolKind::EnumConstant:
143 case index::SymbolKind::Parameter:
144 case index::SymbolKind::NonTypeTemplateParm:
146 case index::SymbolKind::Using:
147 case index::SymbolKind::Module:
151 llvm_unreachable(
"Unknown index::SymbolKind");
157 if (
const auto *TP = dyn_cast<FunctionTemplateDecl>(ND))
158 ND = TP->TemplateDecl::getTemplatedDecl();
159 if (
const auto *
CM = dyn_cast<CXXMethodDecl>(ND))
160 return !
CM->isStatic();
161 return isa<FieldDecl>(ND);
166 case index::SymbolKind::InstanceMethod:
167 case index::SymbolKind::InstanceProperty:
176 Deprecated |= (SemaCCResult.Availability == CXAvailability_Deprecated);
179 if (SemaCCResult.Declaration) {
181 if (
auto *
ID = SemaCCResult.Declaration->getIdentifier())
183 }
else if (SemaCCResult.Kind == CodeCompletionResult::RK_Macro)
211 Score *= 6.0 * (1 - S) / (1 + S) + 0.59;
249 OS << llvm::formatv(
"\tReferences: {0}\n", S.
References);
250 OS << llvm::formatv(
"\tDeprecated: {0}\n", S.
Deprecated);
253 OS << llvm::formatv(
"\tCategory: {0}\n",
static_cast<int>(S.
Category));
260 const DeclContext *DC =
D->getDeclContext();
261 if (
auto *R = dyn_cast_or_null<RecordDecl>(
D))
262 if (R->isInjectedClassName())
263 DC = DC->getParent();
265 if (isa<CXXConstructorDecl>(
D))
266 DC = DC->getParent();
267 bool InClass =
false;
268 for (; !DC->isFileContext(); DC = DC->getParent()) {
269 if (DC->isFunctionOrMethod())
271 InClass = InClass || DC->isRecord();
287 Scope = AccessibleScope::FileScope;
303 if ((
SemaResult.Kind != CodeCompletionResult::RK_Declaration) &&
304 (
SemaResult.Kind != CodeCompletionResult::RK_Pattern))
306 if (
const NamedDecl *ND =
SemaResult.getDeclaration()) {
314 if (
const auto *NSD = dyn_cast<NamespaceDecl>(ND->getDeclContext())) {
315 if (NSD->isAnonymousNamespace())
326 if (SemaCCResult.Availability == CXAvailability_NotAvailable ||
327 SemaCCResult.Availability == CXAvailability_NotAccessible)
330 if (SemaCCResult.Declaration) {
346 if (SemaCCResult.Declaration)
368 return std::max(0.65, 2.0 * std::pow(0.6,
ScopeDistance / 2.0));
371 static std::optional<llvm::StringRef>
374 for (
const auto &
Word : ContextWords->keys())
375 if (
Name.contains_insensitive(
Word))
380 SymbolRelevanceSignals::DerivedSignals
459 (
Context == CodeCompletionContext::CCC_DotMemberAccess ||
460 Context == CodeCompletionContext::CCC_ArrowMemberAccess)) {
478 Score *= 11.0 * (1 - S) / (1 + S) + 0.7;
483 Score *= 10.0 * (1 - S) / (1 + S) + 0.7;
492 OS << llvm::formatv(
"\tName: {0}\n", S.
Name);
493 OS << llvm::formatv(
"\tName match: {0}\n", S.
NameMatch);
496 "\tMatching context word: {0}\n",
498 OS << llvm::formatv(
"\tForbidden: {0}\n", S.
Forbidden);
502 OS << llvm::formatv(
"\tContext: {0}\n", getCompletionKindString(S.
Context));
503 OS << llvm::formatv(
"\tQuery type: {0}\n",
static_cast<int>(S.
Query));
504 OS << llvm::formatv(
"\tScope: {0}\n",
static_cast<int>(S.
Scope));
506 OS << llvm::formatv(
"\tSymbol URI: {0}\n", S.
SymbolURI);
507 OS << llvm::formatv(
"\tSymbol scope: {0}\n",
513 OS << llvm::formatv(
"\tIndex URI proximity: {0} (distance={1})\n",
Score,
520 OS << llvm::formatv(
"\tIndex scope boost: {0}\n",
524 "\tType matched preferred: {0} (Context type: {1}, Symbol type: {2}\n",
531 return SymbolQuality * SymbolRelevance;
537 static_assert(std::numeric_limits<float>::is_iec559);
538 constexpr uint32_t TopBit = ~(~uint32_t{0} >> 1);
541 uint32_t U = llvm::FloatToBits(F);
552 llvm::raw_string_ostream
OS(S);
562 OS << llvm::formatv(
"=== Signature Quality:\n");
564 OS << llvm::formatv(
"\tNumber of optional parameters: {0}\n",
566 OS << llvm::formatv(
"\tKind: {0}\n", S.
Kind);