clang-tools  15.0.0git
QualityTests.cpp
Go to the documentation of this file.
1 //===-- QualityTests.cpp ----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Evaluating scoring functions isn't a great fit for assert-based tests.
10 // For interesting cases, both exact scores and "X beats Y" are too brittle to
11 // make good hard assertions.
12 //
13 // Here we test the signal extraction and sanity-check that signals point in
14 // the right direction. This should be supplemented by quality metrics which
15 // we can compute from a corpus of queries and preferred rankings.
16 //
17 //===----------------------------------------------------------------------===//
18 
19 #include "FileDistance.h"
20 #include "Quality.h"
21 #include "TestFS.h"
22 #include "TestTU.h"
23 #include "index/FileIndex.h"
24 #include "clang/AST/Decl.h"
25 #include "clang/AST/DeclCXX.h"
26 #include "clang/Sema/CodeCompleteConsumer.h"
27 #include "llvm/Support/Casting.h"
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 #include <vector>
31 
32 namespace clang {
33 namespace clangd {
34 
35 // Force the unittest URI scheme to be linked,
36 static int LLVM_ATTRIBUTE_UNUSED UnittestSchemeAnchorDest =
38 
39 namespace {
40 
41 TEST(QualityTests, SymbolQualitySignalExtraction) {
42  auto Header = TestTU::withHeaderCode(R"cpp(
43  int _X;
44 
45  [[deprecated]]
46  int _f() { return _X; }
47 
48  #define DECL_NAME(x, y) x##_##y##_Decl
49  #define DECL(x, y) class DECL_NAME(x, y) {};
50  DECL(X, Y); // X_Y_Decl
51  )cpp");
52 
53  auto Symbols = Header.headerSymbols();
54  auto AST = Header.build();
55 
57  Quality.merge(findSymbol(Symbols, "X_Y_Decl"));
58  EXPECT_TRUE(Quality.ImplementationDetail);
59 
60  Symbol F = findSymbol(Symbols, "_f");
61  F.References = 24; // TestTU doesn't count references, so fake it.
62  Quality = {};
63  Quality.merge(F);
64  EXPECT_TRUE(Quality.Deprecated);
65  EXPECT_FALSE(Quality.ReservedName);
66  EXPECT_EQ(Quality.References, 24u);
67  EXPECT_EQ(Quality.Category, SymbolQualitySignals::Function);
68 
69  Quality = {};
70  Quality.merge(CodeCompletionResult(&findDecl(AST, "_f"), /*Priority=*/42));
71  EXPECT_TRUE(Quality.Deprecated);
72  EXPECT_FALSE(Quality.ReservedName);
73  EXPECT_EQ(Quality.References, SymbolQualitySignals().References);
74  EXPECT_EQ(Quality.Category, SymbolQualitySignals::Function);
75 
76  Quality = {};
77  Quality.merge(CodeCompletionResult("if"));
78  EXPECT_EQ(Quality.Category, SymbolQualitySignals::Keyword);
79 
80  // Testing ReservedName in main file, we don't index those symbols in headers.
81  auto MainAST = TestTU::withCode("int _X;").build();
82  SymbolSlab MainSymbols = std::get<0>(indexMainDecls(MainAST));
83 
84  Quality = {};
85  Quality.merge(findSymbol(MainSymbols, "_X"));
86  EXPECT_FALSE(Quality.Deprecated);
87  EXPECT_FALSE(Quality.ImplementationDetail);
88  EXPECT_TRUE(Quality.ReservedName);
89 }
90 
91 TEST(QualityTests, SymbolRelevanceSignalExtraction) {
92  TestTU Test;
93  Test.HeaderCode = R"cpp(
94  int header();
95  int header_main();
96 
97  namespace hdr { class Bar {}; } // namespace hdr
98 
99  #define DEFINE_FLAG(X) \
100  namespace flags { \
101  int FLAGS_##X; \
102  } \
103 
104  DEFINE_FLAG(FOO)
105  )cpp";
106  Test.Code = R"cpp(
107  using hdr::Bar;
108 
109  using flags::FLAGS_FOO;
110 
111  int ::header_main() {}
112  int main();
113 
114  [[deprecated]]
115  int deprecated() { return 0; }
116 
117  namespace { struct X { void y() { int z; } }; }
118  struct S{};
119  )cpp";
120  auto AST = Test.build();
121 
122  SymbolRelevanceSignals Relevance;
123  Relevance.merge(CodeCompletionResult(&findDecl(AST, "deprecated"),
124  /*Priority=*/42, nullptr, false,
125  /*Accessible=*/false));
126  EXPECT_EQ(Relevance.NameMatch, SymbolRelevanceSignals().NameMatch);
127  EXPECT_TRUE(Relevance.Forbidden);
128  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::GlobalScope);
129 
130  Relevance = {};
131  Relevance.merge(CodeCompletionResult(&findDecl(AST, "main"), 42));
132  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 1.0f)
133  << "Decl in current file";
134  Relevance = {};
135  Relevance.merge(CodeCompletionResult(&findDecl(AST, "header"), 42));
136  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 0.6f) << "Decl from header";
137  Relevance = {};
138  Relevance.merge(CodeCompletionResult(&findDecl(AST, "header_main"), 42));
139  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 1.0f)
140  << "Current file and header";
141 
142  auto ConstructShadowDeclCompletionResult = [&](const std::string DeclName) {
143  auto *Shadow =
144  *dyn_cast<UsingDecl>(&findDecl(AST, [&](const NamedDecl &ND) {
145  if (const UsingDecl *Using = dyn_cast<UsingDecl>(&ND))
146  if (Using->shadow_size() &&
147  Using->getQualifiedNameAsString() == DeclName)
148  return true;
149  return false;
150  }))->shadow_begin();
151  CodeCompletionResult Result(Shadow->getTargetDecl(), 42);
152  Result.ShadowDecl = Shadow;
153  return Result;
154  };
155 
156  Relevance = {};
157  Relevance.merge(ConstructShadowDeclCompletionResult("Bar"));
158  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 1.0f)
159  << "Using declaration in main file";
160  Relevance.merge(ConstructShadowDeclCompletionResult("FLAGS_FOO"));
161  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 1.0f)
162  << "Using declaration in main file";
163 
164  Relevance = {};
165  Relevance.merge(CodeCompletionResult(&findUnqualifiedDecl(AST, "X"), 42));
166  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FileScope);
167  Relevance = {};
168  Relevance.merge(CodeCompletionResult(&findUnqualifiedDecl(AST, "y"), 42));
169  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::ClassScope);
170  Relevance = {};
171  Relevance.merge(CodeCompletionResult(&findUnqualifiedDecl(AST, "z"), 42));
172  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FunctionScope);
173  // The injected class name is treated as the outer class name.
174  Relevance = {};
175  Relevance.merge(CodeCompletionResult(&findDecl(AST, "S::S"), 42));
176  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::GlobalScope);
177 
178  Relevance = {};
179  EXPECT_FALSE(Relevance.InBaseClass);
180  auto BaseMember = CodeCompletionResult(&findUnqualifiedDecl(AST, "y"), 42);
181  BaseMember.InBaseClass = true;
182  Relevance.merge(BaseMember);
183  EXPECT_TRUE(Relevance.InBaseClass);
184 
185  auto Index = Test.index();
186  FuzzyFindRequest Req;
187  Req.Query = "X";
188  Req.AnyScope = true;
189  bool Matched = false;
190  Index->fuzzyFind(Req, [&](const Symbol &S) {
191  Matched = true;
192  Relevance = {};
193  Relevance.merge(S);
194  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FileScope);
195  });
196  EXPECT_TRUE(Matched);
197 }
198 
199 // Do the signals move the scores in the direction we expect?
200 TEST(QualityTests, SymbolQualitySignalsSanity) {
201  SymbolQualitySignals Default;
202  EXPECT_EQ(Default.evaluateHeuristics(), 1);
203 
205  Deprecated.Deprecated = true;
206  EXPECT_LT(Deprecated.evaluateHeuristics(), Default.evaluateHeuristics());
207 
208  SymbolQualitySignals ReservedName;
209  ReservedName.ReservedName = true;
210  EXPECT_LT(ReservedName.evaluateHeuristics(), Default.evaluateHeuristics());
211 
212  SymbolQualitySignals ImplementationDetail;
213  ImplementationDetail.ImplementationDetail = true;
214  EXPECT_LT(ImplementationDetail.evaluateHeuristics(),
215  Default.evaluateHeuristics());
216 
217  SymbolQualitySignals WithReferences, ManyReferences;
218  WithReferences.References = 20;
219  ManyReferences.References = 1000;
220  EXPECT_GT(WithReferences.evaluateHeuristics(), Default.evaluateHeuristics());
221  EXPECT_GT(ManyReferences.evaluateHeuristics(),
222  WithReferences.evaluateHeuristics());
223 
225  Destructor, Operator;
234  EXPECT_GT(Variable.evaluateHeuristics(), Default.evaluateHeuristics());
235  EXPECT_GT(Keyword.evaluateHeuristics(), Variable.evaluateHeuristics());
236  EXPECT_LT(Macro.evaluateHeuristics(), Default.evaluateHeuristics());
237  EXPECT_LT(Operator.evaluateHeuristics(), Default.evaluateHeuristics());
238  EXPECT_LT(Constructor.evaluateHeuristics(), Function.evaluateHeuristics());
239  EXPECT_LT(Destructor.evaluateHeuristics(), Constructor.evaluateHeuristics());
240 }
241 
242 TEST(QualityTests, SymbolRelevanceSignalsSanity) {
243  SymbolRelevanceSignals Default;
244  EXPECT_EQ(Default.evaluateHeuristics(), 1);
245 
246  SymbolRelevanceSignals Forbidden;
247  Forbidden.Forbidden = true;
248  EXPECT_LT(Forbidden.evaluateHeuristics(), Default.evaluateHeuristics());
249 
250  SymbolRelevanceSignals PoorNameMatch;
251  PoorNameMatch.NameMatch = 0.2f;
252  EXPECT_LT(PoorNameMatch.evaluateHeuristics(), Default.evaluateHeuristics());
253 
254  SymbolRelevanceSignals WithSemaFileProximity;
255  WithSemaFileProximity.SemaFileProximityScore = 0.2f;
256  EXPECT_GT(WithSemaFileProximity.evaluateHeuristics(),
257  Default.evaluateHeuristics());
258 
259  ScopeDistance ScopeProximity({"x::y::"});
260 
261  SymbolRelevanceSignals WithSemaScopeProximity;
262  WithSemaScopeProximity.ScopeProximityMatch = &ScopeProximity;
263  WithSemaScopeProximity.SemaSaysInScope = true;
264  EXPECT_GT(WithSemaScopeProximity.evaluateHeuristics(),
265  Default.evaluateHeuristics());
266 
267  SymbolRelevanceSignals WithIndexScopeProximity;
268  WithIndexScopeProximity.ScopeProximityMatch = &ScopeProximity;
269  WithIndexScopeProximity.SymbolScope = "x::";
270  EXPECT_GT(WithSemaScopeProximity.evaluateHeuristics(),
271  Default.evaluateHeuristics());
272 
273  SymbolRelevanceSignals IndexProximate;
274  IndexProximate.SymbolURI = "unittest:/foo/bar.h";
275  llvm::StringMap<SourceParams> ProxSources;
276  ProxSources.try_emplace(testPath("foo/baz.h"));
277  URIDistance Distance(ProxSources);
278  IndexProximate.FileProximityMatch = &Distance;
279  EXPECT_GT(IndexProximate.evaluateHeuristics(), Default.evaluateHeuristics());
280  SymbolRelevanceSignals IndexDistant = IndexProximate;
281  IndexDistant.SymbolURI = "unittest:/elsewhere/path.h";
282  EXPECT_GT(IndexProximate.evaluateHeuristics(),
283  IndexDistant.evaluateHeuristics())
284  << IndexProximate << IndexDistant;
285  EXPECT_GT(IndexDistant.evaluateHeuristics(), Default.evaluateHeuristics());
286 
287  SymbolRelevanceSignals Scoped;
289  EXPECT_LT(Scoped.evaluateHeuristics(), Default.evaluateHeuristics());
291  EXPECT_GT(Scoped.evaluateHeuristics(), Default.evaluateHeuristics());
292 
293  SymbolRelevanceSignals Instance;
294  Instance.IsInstanceMember = false;
295  EXPECT_EQ(Instance.evaluateHeuristics(), Default.evaluateHeuristics());
296  Instance.Context = CodeCompletionContext::CCC_DotMemberAccess;
297  EXPECT_LT(Instance.evaluateHeuristics(), Default.evaluateHeuristics());
298  Instance.IsInstanceMember = true;
299  EXPECT_EQ(Instance.evaluateHeuristics(), Default.evaluateHeuristics());
300 
301  SymbolRelevanceSignals InBaseClass;
302  InBaseClass.InBaseClass = true;
303  EXPECT_LT(InBaseClass.evaluateHeuristics(), Default.evaluateHeuristics());
304 
305  llvm::StringSet<> Words = {"one", "two", "three"};
306  SymbolRelevanceSignals WithoutMatchingWord;
307  WithoutMatchingWord.ContextWords = &Words;
308  WithoutMatchingWord.Name = "four";
309  EXPECT_EQ(WithoutMatchingWord.evaluateHeuristics(),
310  Default.evaluateHeuristics());
311  SymbolRelevanceSignals WithMatchingWord;
312  WithMatchingWord.ContextWords = &Words;
313  WithMatchingWord.Name = "TheTwoTowers";
314  EXPECT_GT(WithMatchingWord.evaluateHeuristics(),
315  Default.evaluateHeuristics());
316 }
317 
318 TEST(QualityTests, ScopeProximity) {
319  SymbolRelevanceSignals Relevance;
320  ScopeDistance ScopeProximity({"x::y::z::", "x::", "llvm::", ""});
321  Relevance.ScopeProximityMatch = &ScopeProximity;
322 
323  Relevance.SymbolScope = "other::";
324  float NotMatched = Relevance.evaluateHeuristics();
325 
326  Relevance.SymbolScope = "";
327  float Global = Relevance.evaluateHeuristics();
328  EXPECT_GT(Global, NotMatched);
329 
330  Relevance.SymbolScope = "llvm::";
331  float NonParent = Relevance.evaluateHeuristics();
332  EXPECT_GT(NonParent, Global);
333 
334  Relevance.SymbolScope = "x::";
335  float GrandParent = Relevance.evaluateHeuristics();
336  EXPECT_GT(GrandParent, Global);
337 
338  Relevance.SymbolScope = "x::y::";
339  float Parent = Relevance.evaluateHeuristics();
340  EXPECT_GT(Parent, GrandParent);
341 
342  Relevance.SymbolScope = "x::y::z::";
343  float Enclosing = Relevance.evaluateHeuristics();
344  EXPECT_GT(Enclosing, Parent);
345 }
346 
347 TEST(QualityTests, SortText) {
348  EXPECT_LT(sortText(std::numeric_limits<float>::infinity()),
349  sortText(1000.2f));
350  EXPECT_LT(sortText(1000.2f), sortText(1));
351  EXPECT_LT(sortText(1), sortText(0.3f));
352  EXPECT_LT(sortText(0.3f), sortText(0));
353  EXPECT_LT(sortText(0), sortText(-10));
354  EXPECT_LT(sortText(-10), sortText(-std::numeric_limits<float>::infinity()));
355 
356  EXPECT_LT(sortText(1, "z"), sortText(0, "a"));
357  EXPECT_LT(sortText(0, "a"), sortText(0, "z"));
358 }
359 
360 TEST(QualityTests, NoBoostForClassConstructor) {
361  auto Header = TestTU::withHeaderCode(R"cpp(
362  class Foo {
363  public:
364  Foo(int);
365  };
366  )cpp");
367  auto Symbols = Header.headerSymbols();
368  auto AST = Header.build();
369 
370  const NamedDecl *Foo = &findDecl(AST, "Foo");
372  Cls.merge(CodeCompletionResult(Foo, /*Priority=*/0));
373 
374  const NamedDecl *CtorDecl = &findDecl(AST, [](const NamedDecl &ND) {
375  return (ND.getQualifiedNameAsString() == "Foo::Foo") &&
376  isa<CXXConstructorDecl>(&ND);
377  });
379  Ctor.merge(CodeCompletionResult(CtorDecl, /*Priority=*/0));
380 
382  EXPECT_EQ(Ctor.Scope, SymbolRelevanceSignals::GlobalScope);
383 }
384 
385 TEST(QualityTests, IsInstanceMember) {
386  auto Header = TestTU::withHeaderCode(R"cpp(
387  class Foo {
388  public:
389  static void foo() {}
390 
391  template <typename T> void tpl(T *t) {}
392 
393  void bar() {}
394  };
395  )cpp");
396  auto Symbols = Header.headerSymbols();
397 
399  const Symbol &FooSym = findSymbol(Symbols, "Foo::foo");
400  Rel.merge(FooSym);
401  EXPECT_FALSE(Rel.IsInstanceMember);
402  const Symbol &BarSym = findSymbol(Symbols, "Foo::bar");
403  Rel.merge(BarSym);
404  EXPECT_TRUE(Rel.IsInstanceMember);
405 
406  Rel.IsInstanceMember = false;
407  const Symbol &TplSym = findSymbol(Symbols, "Foo::tpl");
408  Rel.merge(TplSym);
409  EXPECT_TRUE(Rel.IsInstanceMember);
410 
411  auto AST = Header.build();
412  const NamedDecl *Foo = &findDecl(AST, "Foo::foo");
413  const NamedDecl *Bar = &findDecl(AST, "Foo::bar");
414  const NamedDecl *Tpl = &findDecl(AST, "Foo::tpl");
415 
416  Rel.IsInstanceMember = false;
417  Rel.merge(CodeCompletionResult(Foo, /*Priority=*/0));
418  EXPECT_FALSE(Rel.IsInstanceMember);
419  Rel.merge(CodeCompletionResult(Bar, /*Priority=*/0));
420  EXPECT_TRUE(Rel.IsInstanceMember);
421  Rel.IsInstanceMember = false;
422  Rel.merge(CodeCompletionResult(Tpl, /*Priority=*/0));
423  EXPECT_TRUE(Rel.IsInstanceMember);
424 }
425 
426 TEST(QualityTests, ConstructorDestructor) {
427  auto Header = TestTU::withHeaderCode(R"cpp(
428  class Foo {
429  public:
430  Foo(int);
431  ~Foo();
432  };
433  )cpp");
434  auto Symbols = Header.headerSymbols();
435  auto AST = Header.build();
436 
437  const NamedDecl *CtorDecl = &findDecl(AST, [](const NamedDecl &ND) {
438  return (ND.getQualifiedNameAsString() == "Foo::Foo") &&
439  isa<CXXConstructorDecl>(&ND);
440  });
441  const NamedDecl *DtorDecl = &findDecl(AST, [](const NamedDecl &ND) {
442  return (ND.getQualifiedNameAsString() == "Foo::~Foo") &&
443  isa<CXXDestructorDecl>(&ND);
444  });
445 
446  SymbolQualitySignals CtorQ;
447  CtorQ.merge(CodeCompletionResult(CtorDecl, /*Priority=*/0));
448  EXPECT_EQ(CtorQ.Category, SymbolQualitySignals::Constructor);
449 
450  CtorQ.Category = SymbolQualitySignals::Unknown;
451  const Symbol &CtorSym = findSymbol(Symbols, "Foo::Foo");
452  CtorQ.merge(CtorSym);
453  EXPECT_EQ(CtorQ.Category, SymbolQualitySignals::Constructor);
454 
455  SymbolQualitySignals DtorQ;
456  DtorQ.merge(CodeCompletionResult(DtorDecl, /*Priority=*/0));
457  EXPECT_EQ(DtorQ.Category, SymbolQualitySignals::Destructor);
458 }
459 
460 TEST(QualityTests, Operator) {
461  auto Header = TestTU::withHeaderCode(R"cpp(
462  class Foo {
463  public:
464  bool operator<(const Foo& f1);
465  };
466  )cpp");
467  auto AST = Header.build();
468 
469  const NamedDecl *Operator = &findDecl(AST, [](const NamedDecl &ND) {
470  if (const auto *OD = dyn_cast<FunctionDecl>(&ND))
471  if (OD->isOverloadedOperator())
472  return true;
473  return false;
474  });
476  Q.merge(CodeCompletionResult(Operator, /*Priority=*/0));
477  EXPECT_EQ(Q.Category, SymbolQualitySignals::Operator);
478 }
479 
480 TEST(QualityTests, ItemWithFixItsRankedDown) {
481  CodeCompleteOptions Opts;
482  Opts.IncludeFixIts = true;
483 
484  auto Header = TestTU::withHeaderCode(R"cpp(
485  int x;
486  )cpp");
487  auto AST = Header.build();
488 
489  SymbolRelevanceSignals RelevanceWithFixIt;
490  RelevanceWithFixIt.merge(CodeCompletionResult(&findDecl(AST, "x"), 0, nullptr,
491  false, true, {FixItHint{}}));
492  EXPECT_TRUE(RelevanceWithFixIt.NeedsFixIts);
493 
494  SymbolRelevanceSignals RelevanceWithoutFixIt;
495  RelevanceWithoutFixIt.merge(
496  CodeCompletionResult(&findDecl(AST, "x"), 0, nullptr, false, true, {}));
497  EXPECT_FALSE(RelevanceWithoutFixIt.NeedsFixIts);
498 
499  EXPECT_LT(RelevanceWithFixIt.evaluateHeuristics(),
500  RelevanceWithoutFixIt.evaluateHeuristics());
501 }
502 
503 } // namespace
504 } // namespace clangd
505 } // namespace clang
clang::clangd::SymbolRelevanceSignals::merge
void merge(const CodeCompletionResult &SemaResult)
Definition: Quality.cpp:323
clang::clangd::findDecl
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition: TestTU.cpp:216
clang::clangd::SymbolQualitySignals::ImplementationDetail
bool ImplementationDetail
Definition: Quality.h:59
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:750
References
unsigned References
Definition: CodeComplete.cpp:178
clang::clangd::SymbolRelevanceSignals::Scope
enum clang::clangd::SymbolRelevanceSignals::AccessibleScope Scope
clang::clangd::testPath
std::string testPath(PathRef File, llvm::sys::path::Style Style)
Definition: TestFS.cpp:94
clang::clangd::SymbolRelevanceSignals::Query
enum clang::clangd::SymbolRelevanceSignals::QueryType Query
clang::clangd::CompletionItemKind::Operator
@ Operator
clang::clangd::TestTU::build
ParsedAST build() const
Definition: TestTU.cpp:109
clang::clangd::SymbolRelevanceSignals::SymbolURI
llvm::StringRef SymbolURI
These are used to calculate proximity between the index symbol and the query.
Definition: Quality.h:100
clang::clangd::SymbolQualitySignals::Variable
@ Variable
Definition: Quality.h:64
clang::clangd::SymbolQualitySignals::Unknown
@ Unknown
Definition: Quality.h:63
clang::clangd::SymbolRelevanceSignals::FunctionScope
@ FunctionScope
Definition: Quality.h:114
TestTU.h
clang::clangd::SymbolRelevanceSignals::evaluateHeuristics
float evaluateHeuristics() const
Definition: Quality.cpp:393
clang::clangd::SymbolQualitySignals::ReservedName
bool ReservedName
Definition: Quality.h:57
clang::clangd::FuzzyFindRequest
Definition: Index.h:26
clang::clangd::ScopeDistance
Support lookups like FileDistance, but the lookup keys are symbol scopes.
Definition: FileDistance.h:112
clang::clangd::TestTU::Code
std::string Code
Definition: TestTU.h:49
clang::clangd::SymbolQualitySignals
Attributes of a symbol that affect how much we like it.
Definition: Quality.h:55
clang::clangd::CompletionItemKind::Keyword
@ Keyword
clang::clangd::UnittestSchemeAnchorSource
volatile int UnittestSchemeAnchorSource
Definition: TestFS.cpp:138
clang::clangd::SymbolRelevanceSignals::Forbidden
bool Forbidden
Definition: Quality.h:92
clang::clangd::findUnqualifiedDecl
const NamedDecl & findUnqualifiedDecl(ParsedAST &AST, llvm::StringRef Name)
Definition: TestTU.cpp:257
clang::clangd::FuzzyFindRequest::Query
std::string Query
A query string for the fuzzy find.
Definition: Index.h:29
clang::clangd::HighlightingKind::Macro
@ Macro
clang::clangd::ParsedAST::build
static llvm::Optional< ParsedAST > build(llvm::StringRef Filename, const ParseInputs &Inputs, std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble)
Attempts to run Clang and store the parsed AST.
Definition: ParsedAST.cpp:342
clang::clangd::UnittestSchemeAnchorDest
static int LLVM_ATTRIBUTE_UNUSED UnittestSchemeAnchorDest
Definition: QualityTests.cpp:36
clang::clangd::TestTU::withHeaderCode
static TestTU withHeaderCode(llvm::StringRef HeaderCode)
Definition: TestTU.h:42
FileDistance.h
clang::clangd::SymbolQualitySignals::Constructor
@ Constructor
Definition: Quality.h:68
clang::clangd::CompletionItemKind::Function
@ Function
clang::clangd::SymbolQualitySignals::References
unsigned References
Definition: Quality.h:60
Quality
SignatureQualitySignals Quality
Definition: CodeComplete.cpp:899
clang::clangd::SymbolQualitySignals::Destructor
@ Destructor
Definition: Quality.h:69
TestFS.h
clang::clangd::Symbol
The class presents a C++ symbol, e.g.
Definition: Symbol.h:36
clang::clangd::SymbolRelevanceSignals::Context
CodeCompletionContext::Kind Context
Definition: Quality.h:125
clang::clangd::CodeCompleteOptions::IncludeFixIts
bool IncludeFixIts
Include completions that require small corrections, e.g.
Definition: CodeComplete.h:92
clang::clangd::SymbolRelevanceSignals::SemaFileProximityScore
float SemaFileProximityScore
FIXME: unify with index proximity score - signals should be source-independent.
Definition: Quality.h:104
clang::clangd::TestTU
Definition: TestTU.h:35
clang::clangd::SymbolQualitySignals::Function
@ Function
Definition: Quality.h:67
clang::clangd::SymbolRelevanceSignals::FileProximityMatch
URIDistance * FileProximityMatch
Definition: Quality.h:97
clang::clangd::TestTU::withCode
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:36
FileIndex.h
Bar
Definition: sample.cpp:5
clang::clangd::CodeCompleteOptions
Definition: CodeComplete.h:41
Parent
const Node * Parent
Definition: ExtractFunction.cpp:157
clang::clangd::SymbolRelevanceSignals::ScopeProximityMatch
ScopeDistance * ScopeProximityMatch
Definition: Quality.h:107
clang::clangd::Deprecated
@ Deprecated
Deprecated or obsolete code.
Definition: Protocol.h:834
Index
const SymbolIndex * Index
Definition: Dexp.cpp:98
clang::clangd::SymbolRelevanceSignals::Name
llvm::StringRef Name
The name of the symbol (for ContextWords). Must be explicitly assigned.
Definition: Quality.h:87
clang::clangd::URIDistance
Definition: FileDistance.h:88
clang::clangd::SymbolRelevanceSignals::IsInstanceMember
bool IsInstanceMember
Definition: Quality.h:128
clang::clangd::SymbolQualitySignals::Keyword
@ Keyword
Definition: Quality.h:71
clang::clangd::SymbolRelevanceSignals::NeedsFixIts
bool NeedsFixIts
Whether fixits needs to be applied for that completion or not.
Definition: Quality.h:94
clang::clangd::sortText
std::string sortText(float Score, llvm::StringRef Name)
Returns a string that sorts in the same order as (-Score, Tiebreak), for LSP.
Definition: Quality.cpp:605
clang::clangd::SymbolQualitySignals::Macro
@ Macro
Definition: Quality.h:65
clang::clangd::SymbolRelevanceSignals::ClassScope
@ ClassScope
Definition: Quality.h:115
clang::clangd::SymbolQualitySignals::Operator
@ Operator
Definition: Quality.h:72
clang::clangd::SymbolRelevanceSignals::SymbolScope
llvm::Optional< llvm::StringRef > SymbolScope
Definition: Quality.h:108
clang::clangd::TestTU::index
std::unique_ptr< SymbolIndex > index() const
Definition: TestTU.cpp:172
clang::clangd::CompletionItemKind::Constructor
@ Constructor
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::SymbolQualitySignals::evaluateHeuristics
float evaluateHeuristics() const
Definition: Quality.cpp:196
clang::clangd::SymbolRelevanceSignals::ContextWords
llvm::StringSet * ContextWords
Lowercase words relevant to the context (e.g. near the completion point).
Definition: Quality.h:91
clang::clangd::FuzzyFindRequest::AnyScope
bool AnyScope
If set to true, allow symbols from any scope.
Definition: Index.h:39
clang::clangd::SymbolQualitySignals::Category
enum clang::clangd::SymbolQualitySignals::SymbolCategory Category
Quality.h
clang::clangd::SymbolSlab
An immutable symbol container that stores a set of symbols.
Definition: Symbol.h:177
clang::clangd::SymbolRelevanceSignals::NameMatch
float NameMatch
0-1+ fuzzy-match score for unqualified name. Must be explicitly assigned.
Definition: Quality.h:89
clang::clangd::SymbolRelevanceSignals::CodeComplete
@ CodeComplete
Definition: Quality.h:121
clang::clangd::SymbolRelevanceSignals::InBaseClass
bool InBaseClass
Definition: Quality.h:95
clang::clangd::SymbolRelevanceSignals::GlobalScope
@ GlobalScope
Definition: Quality.h:117
clang::clangd::SymbolRelevanceSignals
Attributes of a symbol-query pair that affect how much we like it.
Definition: Quality.h:85
clang::clangd::CompletionItemKind::Variable
@ Variable
clang::clangd::findSymbol
const Symbol & findSymbol(const SymbolSlab &Slab, llvm::StringRef QName)
Definition: TestTU.cpp:182
clang::clangd::SymbolIndex::fuzzyFind
virtual bool fuzzyFind(const FuzzyFindRequest &Req, llvm::function_ref< void(const Symbol &)> Callback) const =0
Matches symbols in the index fuzzily and applies Callback on each matched symbol before returning.
clang::clangd::TestTU::HeaderCode
std::string HeaderCode
Definition: TestTU.h:53
clang::clangd::SymbolRelevanceSignals::FileScope
@ FileScope
Definition: Quality.h:116
clang::clangd::SymbolQualitySignals::merge
void merge(const CodeCompletionResult &SemaCCResult)
Definition: Quality.cpp:175
clang::clangd::indexMainDecls
SlabTuple indexMainDecls(ParsedAST &AST)
Retrieves symbols and refs of local top level decls in AST (i.e.
Definition: FileIndex.cpp:222