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/CharInfo.h"
21 #include "clang/Basic/SourceManager.h"
22 #include "clang/Sema/CodeCompleteConsumer.h"
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/ADT/StringExtras.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/Support/Casting.h"
29 #include "llvm/Support/FormatVariadic.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/raw_ostream.h"
39 return Name.size() >= 2 &&
Name[0] ==
'_' &&
40 (isUppercase(
Name[1]) ||
Name[1] ==
'_');
44 auto &
SourceMgr = D.getASTContext().getSourceManager();
45 for (
auto *Redecl : D.redecls()) {
53 const auto &
Context = R.Declaration->getASTContext();
63 if (
const auto *FD = dyn_cast<FunctionDecl>(&ND)) {
64 if (FD->isOverloadedOperator())
68 :
public ConstDeclVisitor<Switch, SymbolQualitySignals::SymbolCategory> {
70 #define MAP(DeclType, Category) \
71 SymbolQualitySignals::SymbolCategory Visit##DeclType(const DeclType *) { \
72 return SymbolQualitySignals::Category; \
77 MAP(TypeAliasTemplateDecl,
Type);
80 MAP(CXXDestructorDecl, Destructor);
88 return Switch().Visit(&ND);
95 if (R.Kind == CodeCompletionResult::RK_Macro)
99 switch (R.CursorKind) {
100 case CXCursor_CXXMethod:
102 case CXCursor_ModuleImportDecl:
104 case CXCursor_MacroDefinition:
106 case CXCursor_TypeRef:
108 case CXCursor_MemberRef:
110 case CXCursor_Constructor:
120 case index::SymbolKind::Namespace:
121 case index::SymbolKind::NamespaceAlias:
123 case index::SymbolKind::Macro:
125 case index::SymbolKind::Enum:
126 case index::SymbolKind::Struct:
127 case index::SymbolKind::Class:
128 case index::SymbolKind::Protocol:
129 case index::SymbolKind::Extension:
130 case index::SymbolKind::Union:
131 case index::SymbolKind::TypeAlias:
132 case index::SymbolKind::TemplateTypeParm:
133 case index::SymbolKind::TemplateTemplateParm:
135 case index::SymbolKind::Function:
136 case index::SymbolKind::ClassMethod:
137 case index::SymbolKind::InstanceMethod:
138 case index::SymbolKind::StaticMethod:
139 case index::SymbolKind::InstanceProperty:
140 case index::SymbolKind::ClassProperty:
141 case index::SymbolKind::StaticProperty:
142 case index::SymbolKind::ConversionFunction:
144 case index::SymbolKind::Destructor:
146 case index::SymbolKind::Constructor:
148 case index::SymbolKind::Variable:
149 case index::SymbolKind::Field:
150 case index::SymbolKind::EnumConstant:
151 case index::SymbolKind::Parameter:
152 case index::SymbolKind::NonTypeTemplateParm:
154 case index::SymbolKind::Using:
155 case index::SymbolKind::Module:
156 case index::SymbolKind::Unknown:
159 llvm_unreachable(
"Unknown index::SymbolKind");
165 if (
const auto *TP = dyn_cast<FunctionTemplateDecl>(ND))
166 ND = TP->TemplateDecl::getTemplatedDecl();
167 if (
const auto *
CM = dyn_cast<CXXMethodDecl>(ND))
168 return !
CM->isStatic();
169 return isa<FieldDecl>(ND);
174 case index::SymbolKind::InstanceMethod:
175 case index::SymbolKind::InstanceProperty:
176 case index::SymbolKind::Field:
184 Deprecated |= (SemaCCResult.Availability == CXAvailability_Deprecated);
187 if (SemaCCResult.Declaration) {
189 if (
auto *ID = SemaCCResult.Declaration->getIdentifier())
191 }
else if (SemaCCResult.Kind == CodeCompletionResult::RK_Macro)
218 Score *= 6.0 * (1 - S) / (1 + S) + 0.59;
255 OS << llvm::formatv(
"=== Symbol quality: {0}\n", S.
evaluate());
256 OS << llvm::formatv(
"\tReferences: {0}\n", S.
References);
257 OS << llvm::formatv(
"\tDeprecated: {0}\n", S.
Deprecated);
259 OS << llvm::formatv(
"\tCategory: {0}\n", static_cast<int>(S.
Category));
266 const DeclContext *DC = D->getDeclContext();
267 if (
auto *R = dyn_cast_or_null<RecordDecl>(D))
268 if (R->isInjectedClassName())
269 DC = DC->getParent();
271 if (isa<CXXConstructorDecl>(D))
272 DC = DC->getParent();
273 bool InClass =
false;
274 for (; !DC->isFileContext(); DC = DC->getParent()) {
275 if (DC->isFunctionOrMethod())
277 InClass = InClass || DC->isRecord();
293 Scope = AccessibleScope::FileScope;
298 if (SemaCCResult.Availability == CXAvailability_NotAvailable ||
299 SemaCCResult.Availability == CXAvailability_NotAccessible)
302 if (SemaCCResult.Declaration) {
317 if (SemaCCResult.Declaration)
323 static std::pair<float, unsigned>
uriProximity(llvm::StringRef SymbolURI,
325 if (!D || SymbolURI.empty())
327 unsigned Distance = D->
distance(SymbolURI);
333 llvm::Optional<llvm::StringRef> SymbolScope) {
336 auto D = Distance.
distance(*SymbolScope);
339 return std::max(0.65, 2.0 * std::pow(0.6, D / 2.0));
342 static llvm::Optional<llvm::StringRef>
345 for (
const auto&
Word : ContextWords->keys())
413 (
Context == CodeCompletionContext::CCC_DotMemberAccess ||
414 Context == CodeCompletionContext::CCC_ArrowMemberAccess)) {
430 OS << llvm::formatv(
"=== Symbol relevance: {0}\n", S.
evaluate());
431 OS << llvm::formatv(
"\tName: {0}\n", S.
Name);
432 OS << llvm::formatv(
"\tName match: {0}\n", S.
NameMatch);
435 "\tMatching context word: {0}\n",
437 OS << llvm::formatv(
"\tForbidden: {0}\n", S.
Forbidden);
440 OS << llvm::formatv(
"\tContext: {0}\n", getCompletionKindString(S.
Context));
441 OS << llvm::formatv(
"\tQuery type: {0}\n", static_cast<int>(S.
Query));
442 OS << llvm::formatv(
"\tScope: {0}\n", static_cast<int>(S.
Scope));
444 OS << llvm::formatv(
"\tSymbol URI: {0}\n", S.
SymbolURI);
445 OS << llvm::formatv(
"\tSymbol scope: {0}\n",
450 OS << llvm::formatv(
"\tIndex URI proximity: {0} (distance={1})\n",
457 OS << llvm::formatv(
"\tIndex scope boost: {0}\n",
461 "\tType matched preferred: {0} (Context type: {1}, Symbol type: {2}\n",
468 return SymbolQuality * SymbolRelevance;
474 static_assert(std::numeric_limits<float>::is_iec559,
"");
475 constexpr uint32_t TopBit = ~(~uint32_t{0} >> 1);
478 uint32_t U = llvm::FloatToBits(F);
489 llvm::raw_string_ostream
OS(S);
499 OS << llvm::formatv(
"=== Signature Quality:\n");
501 OS << llvm::formatv(
"\tNumber of optional parameters: {0}\n",
503 OS << llvm::formatv(
"\tKind: {0}\n", S.
Kind);