clang-tools  14.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 "clang/AST/Decl.h"
24 #include "clang/AST/DeclCXX.h"
25 #include "clang/AST/Type.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"));
58  EXPECT_FALSE(Quality.Deprecated);
59  EXPECT_FALSE(Quality.ImplementationDetail);
60  EXPECT_TRUE(Quality.ReservedName);
61  EXPECT_EQ(Quality.References, SymbolQualitySignals().References);
62  EXPECT_EQ(Quality.Category, SymbolQualitySignals::Variable);
63 
64  Quality.merge(findSymbol(Symbols, "X_Y_Decl"));
65  EXPECT_TRUE(Quality.ImplementationDetail);
66 
67  Symbol F = findSymbol(Symbols, "_f");
68  F.References = 24; // TestTU doesn't count references, so fake it.
69  Quality = {};
70  Quality.merge(F);
71  EXPECT_TRUE(Quality.Deprecated);
72  EXPECT_FALSE(Quality.ReservedName);
73  EXPECT_EQ(Quality.References, 24u);
74  EXPECT_EQ(Quality.Category, SymbolQualitySignals::Function);
75 
76  Quality = {};
77  Quality.merge(CodeCompletionResult(&findDecl(AST, "_f"), /*Priority=*/42));
78  EXPECT_TRUE(Quality.Deprecated);
79  EXPECT_FALSE(Quality.ReservedName);
80  EXPECT_EQ(Quality.References, SymbolQualitySignals().References);
81  EXPECT_EQ(Quality.Category, SymbolQualitySignals::Function);
82 
83  Quality = {};
84  Quality.merge(CodeCompletionResult("if"));
85  EXPECT_EQ(Quality.Category, SymbolQualitySignals::Keyword);
86 }
87 
88 TEST(QualityTests, SymbolRelevanceSignalExtraction) {
89  TestTU Test;
90  Test.HeaderCode = R"cpp(
91  int header();
92  int header_main();
93 
94  namespace hdr { class Bar {}; } // namespace hdr
95 
96  #define DEFINE_FLAG(X) \
97  namespace flags { \
98  int FLAGS_##X; \
99  } \
100 
101  DEFINE_FLAG(FOO)
102  )cpp";
103  Test.Code = R"cpp(
104  using hdr::Bar;
105 
106  using flags::FLAGS_FOO;
107 
108  int ::header_main() {}
109  int main();
110 
111  [[deprecated]]
112  int deprecated() { return 0; }
113 
114  namespace { struct X { void y() { int z; } }; }
115  struct S{};
116  )cpp";
117  auto AST = Test.build();
118 
119  SymbolRelevanceSignals Relevance;
120  Relevance.merge(CodeCompletionResult(&findDecl(AST, "deprecated"),
121  /*Priority=*/42, nullptr, false,
122  /*Accessible=*/false));
123  EXPECT_EQ(Relevance.NameMatch, SymbolRelevanceSignals().NameMatch);
124  EXPECT_TRUE(Relevance.Forbidden);
125  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::GlobalScope);
126 
127  Relevance = {};
128  Relevance.merge(CodeCompletionResult(&findDecl(AST, "main"), 42));
129  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 1.0f)
130  << "Decl in current file";
131  Relevance = {};
132  Relevance.merge(CodeCompletionResult(&findDecl(AST, "header"), 42));
133  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 0.6f) << "Decl from header";
134  Relevance = {};
135  Relevance.merge(CodeCompletionResult(&findDecl(AST, "header_main"), 42));
136  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 1.0f)
137  << "Current file and header";
138 
139  auto constructShadowDeclCompletionResult = [&](const std::string DeclName) {
140  auto *Shadow =
141  *dyn_cast<UsingDecl>(&findDecl(AST, [&](const NamedDecl &ND) {
142  if (const UsingDecl *Using = dyn_cast<UsingDecl>(&ND))
143  if (Using->shadow_size() &&
144  Using->getQualifiedNameAsString() == DeclName)
145  return true;
146  return false;
147  }))->shadow_begin();
148  CodeCompletionResult Result(Shadow->getTargetDecl(), 42);
149  Result.ShadowDecl = Shadow;
150  return Result;
151  };
152 
153  Relevance = {};
154  Relevance.merge(constructShadowDeclCompletionResult("Bar"));
155  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 1.0f)
156  << "Using declaration in main file";
157  Relevance.merge(constructShadowDeclCompletionResult("FLAGS_FOO"));
158  EXPECT_FLOAT_EQ(Relevance.SemaFileProximityScore, 1.0f)
159  << "Using declaration in main file";
160 
161  Relevance = {};
162  Relevance.merge(CodeCompletionResult(&findUnqualifiedDecl(AST, "X"), 42));
163  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FileScope);
164  Relevance = {};
165  Relevance.merge(CodeCompletionResult(&findUnqualifiedDecl(AST, "y"), 42));
166  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::ClassScope);
167  Relevance = {};
168  Relevance.merge(CodeCompletionResult(&findUnqualifiedDecl(AST, "z"), 42));
169  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FunctionScope);
170  // The injected class name is treated as the outer class name.
171  Relevance = {};
172  Relevance.merge(CodeCompletionResult(&findDecl(AST, "S::S"), 42));
173  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::GlobalScope);
174 
175  Relevance = {};
176  EXPECT_FALSE(Relevance.InBaseClass);
177  auto BaseMember = CodeCompletionResult(&findUnqualifiedDecl(AST, "y"), 42);
178  BaseMember.InBaseClass = true;
179  Relevance.merge(BaseMember);
180  EXPECT_TRUE(Relevance.InBaseClass);
181 
182  auto Index = Test.index();
183  FuzzyFindRequest Req;
184  Req.Query = "X";
185  Req.AnyScope = true;
186  bool Matched = false;
187  Index->fuzzyFind(Req, [&](const Symbol &S) {
188  Matched = true;
189  Relevance = {};
190  Relevance.merge(S);
191  EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FileScope);
192  });
193  EXPECT_TRUE(Matched);
194 }
195 
196 // Do the signals move the scores in the direction we expect?
197 TEST(QualityTests, SymbolQualitySignalsSanity) {
198  SymbolQualitySignals Default;
199  EXPECT_EQ(Default.evaluateHeuristics(), 1);
200 
202  Deprecated.Deprecated = true;
203  EXPECT_LT(Deprecated.evaluateHeuristics(), Default.evaluateHeuristics());
204 
205  SymbolQualitySignals ReservedName;
206  ReservedName.ReservedName = true;
207  EXPECT_LT(ReservedName.evaluateHeuristics(), Default.evaluateHeuristics());
208 
209  SymbolQualitySignals ImplementationDetail;
210  ImplementationDetail.ImplementationDetail = true;
211  EXPECT_LT(ImplementationDetail.evaluateHeuristics(),
212  Default.evaluateHeuristics());
213 
214  SymbolQualitySignals WithReferences, ManyReferences;
215  WithReferences.References = 20;
216  ManyReferences.References = 1000;
217  EXPECT_GT(WithReferences.evaluateHeuristics(), Default.evaluateHeuristics());
218  EXPECT_GT(ManyReferences.evaluateHeuristics(),
219  WithReferences.evaluateHeuristics());
220 
222  Destructor, Operator;
231  EXPECT_GT(Variable.evaluateHeuristics(), Default.evaluateHeuristics());
232  EXPECT_GT(Keyword.evaluateHeuristics(), Variable.evaluateHeuristics());
233  EXPECT_LT(Macro.evaluateHeuristics(), Default.evaluateHeuristics());
234  EXPECT_LT(Operator.evaluateHeuristics(), Default.evaluateHeuristics());
235  EXPECT_LT(Constructor.evaluateHeuristics(), Function.evaluateHeuristics());
236  EXPECT_LT(Destructor.evaluateHeuristics(), Constructor.evaluateHeuristics());
237 }
238 
239 TEST(QualityTests, SymbolRelevanceSignalsSanity) {
240  SymbolRelevanceSignals Default;
241  EXPECT_EQ(Default.evaluateHeuristics(), 1);
242 
243  SymbolRelevanceSignals Forbidden;
244  Forbidden.Forbidden = true;
245  EXPECT_LT(Forbidden.evaluateHeuristics(), Default.evaluateHeuristics());
246 
247  SymbolRelevanceSignals PoorNameMatch;
248  PoorNameMatch.NameMatch = 0.2f;
249  EXPECT_LT(PoorNameMatch.evaluateHeuristics(), Default.evaluateHeuristics());
250 
251  SymbolRelevanceSignals WithSemaFileProximity;
252  WithSemaFileProximity.SemaFileProximityScore = 0.2f;
253  EXPECT_GT(WithSemaFileProximity.evaluateHeuristics(),
254  Default.evaluateHeuristics());
255 
256  ScopeDistance ScopeProximity({"x::y::"});
257 
258  SymbolRelevanceSignals WithSemaScopeProximity;
259  WithSemaScopeProximity.ScopeProximityMatch = &ScopeProximity;
260  WithSemaScopeProximity.SemaSaysInScope = true;
261  EXPECT_GT(WithSemaScopeProximity.evaluateHeuristics(),
262  Default.evaluateHeuristics());
263 
264  SymbolRelevanceSignals WithIndexScopeProximity;
265  WithIndexScopeProximity.ScopeProximityMatch = &ScopeProximity;
266  WithIndexScopeProximity.SymbolScope = "x::";
267  EXPECT_GT(WithSemaScopeProximity.evaluateHeuristics(),
268  Default.evaluateHeuristics());
269 
270  SymbolRelevanceSignals IndexProximate;
271  IndexProximate.SymbolURI = "unittest:/foo/bar.h";
272  llvm::StringMap<SourceParams> ProxSources;
273  ProxSources.try_emplace(testPath("foo/baz.h"));
274  URIDistance Distance(ProxSources);
275  IndexProximate.FileProximityMatch = &Distance;
276  EXPECT_GT(IndexProximate.evaluateHeuristics(), Default.evaluateHeuristics());
277  SymbolRelevanceSignals IndexDistant = IndexProximate;
278  IndexDistant.SymbolURI = "unittest:/elsewhere/path.h";
279  EXPECT_GT(IndexProximate.evaluateHeuristics(),
280  IndexDistant.evaluateHeuristics())
281  << IndexProximate << IndexDistant;
282  EXPECT_GT(IndexDistant.evaluateHeuristics(), Default.evaluateHeuristics());
283 
284  SymbolRelevanceSignals Scoped;
286  EXPECT_LT(Scoped.evaluateHeuristics(), Default.evaluateHeuristics());
288  EXPECT_GT(Scoped.evaluateHeuristics(), Default.evaluateHeuristics());
289 
290  SymbolRelevanceSignals Instance;
291  Instance.IsInstanceMember = false;
292  EXPECT_EQ(Instance.evaluateHeuristics(), Default.evaluateHeuristics());
293  Instance.Context = CodeCompletionContext::CCC_DotMemberAccess;
294  EXPECT_LT(Instance.evaluateHeuristics(), Default.evaluateHeuristics());
295  Instance.IsInstanceMember = true;
296  EXPECT_EQ(Instance.evaluateHeuristics(), Default.evaluateHeuristics());
297 
298  SymbolRelevanceSignals InBaseClass;
299  InBaseClass.InBaseClass = true;
300  EXPECT_LT(InBaseClass.evaluateHeuristics(), Default.evaluateHeuristics());
301 
302  llvm::StringSet<> Words = {"one", "two", "three"};
303  SymbolRelevanceSignals WithoutMatchingWord;
304  WithoutMatchingWord.ContextWords = &Words;
305  WithoutMatchingWord.Name = "four";
306  EXPECT_EQ(WithoutMatchingWord.evaluateHeuristics(),
307  Default.evaluateHeuristics());
308  SymbolRelevanceSignals WithMatchingWord;
309  WithMatchingWord.ContextWords = &Words;
310  WithMatchingWord.Name = "TheTwoTowers";
311  EXPECT_GT(WithMatchingWord.evaluateHeuristics(),
312  Default.evaluateHeuristics());
313 }
314 
315 TEST(QualityTests, ScopeProximity) {
316  SymbolRelevanceSignals Relevance;
317  ScopeDistance ScopeProximity({"x::y::z::", "x::", "llvm::", ""});
318  Relevance.ScopeProximityMatch = &ScopeProximity;
319 
320  Relevance.SymbolScope = "other::";
321  float NotMatched = Relevance.evaluateHeuristics();
322 
323  Relevance.SymbolScope = "";
324  float Global = Relevance.evaluateHeuristics();
325  EXPECT_GT(Global, NotMatched);
326 
327  Relevance.SymbolScope = "llvm::";
328  float NonParent = Relevance.evaluateHeuristics();
329  EXPECT_GT(NonParent, Global);
330 
331  Relevance.SymbolScope = "x::";
332  float GrandParent = Relevance.evaluateHeuristics();
333  EXPECT_GT(GrandParent, Global);
334 
335  Relevance.SymbolScope = "x::y::";
336  float Parent = Relevance.evaluateHeuristics();
337  EXPECT_GT(Parent, GrandParent);
338 
339  Relevance.SymbolScope = "x::y::z::";
340  float Enclosing = Relevance.evaluateHeuristics();
341  EXPECT_GT(Enclosing, Parent);
342 }
343 
344 TEST(QualityTests, SortText) {
345  EXPECT_LT(sortText(std::numeric_limits<float>::infinity()),
346  sortText(1000.2f));
347  EXPECT_LT(sortText(1000.2f), sortText(1));
348  EXPECT_LT(sortText(1), sortText(0.3f));
349  EXPECT_LT(sortText(0.3f), sortText(0));
350  EXPECT_LT(sortText(0), sortText(-10));
351  EXPECT_LT(sortText(-10), sortText(-std::numeric_limits<float>::infinity()));
352 
353  EXPECT_LT(sortText(1, "z"), sortText(0, "a"));
354  EXPECT_LT(sortText(0, "a"), sortText(0, "z"));
355 }
356 
357 TEST(QualityTests, NoBoostForClassConstructor) {
358  auto Header = TestTU::withHeaderCode(R"cpp(
359  class Foo {
360  public:
361  Foo(int);
362  };
363  )cpp");
364  auto Symbols = Header.headerSymbols();
365  auto AST = Header.build();
366 
367  const NamedDecl *Foo = &findDecl(AST, "Foo");
369  Cls.merge(CodeCompletionResult(Foo, /*Priority=*/0));
370 
371  const NamedDecl *CtorDecl = &findDecl(AST, [](const NamedDecl &ND) {
372  return (ND.getQualifiedNameAsString() == "Foo::Foo") &&
373  isa<CXXConstructorDecl>(&ND);
374  });
376  Ctor.merge(CodeCompletionResult(CtorDecl, /*Priority=*/0));
377 
379  EXPECT_EQ(Ctor.Scope, SymbolRelevanceSignals::GlobalScope);
380 }
381 
382 TEST(QualityTests, IsInstanceMember) {
383  auto Header = TestTU::withHeaderCode(R"cpp(
384  class Foo {
385  public:
386  static void foo() {}
387 
388  template <typename T> void tpl(T *t) {}
389 
390  void bar() {}
391  };
392  )cpp");
393  auto Symbols = Header.headerSymbols();
394 
396  const Symbol &FooSym = findSymbol(Symbols, "Foo::foo");
397  Rel.merge(FooSym);
398  EXPECT_FALSE(Rel.IsInstanceMember);
399  const Symbol &BarSym = findSymbol(Symbols, "Foo::bar");
400  Rel.merge(BarSym);
401  EXPECT_TRUE(Rel.IsInstanceMember);
402 
403  Rel.IsInstanceMember = false;
404  const Symbol &TplSym = findSymbol(Symbols, "Foo::tpl");
405  Rel.merge(TplSym);
406  EXPECT_TRUE(Rel.IsInstanceMember);
407 
408  auto AST = Header.build();
409  const NamedDecl *Foo = &findDecl(AST, "Foo::foo");
410  const NamedDecl *Bar = &findDecl(AST, "Foo::bar");
411  const NamedDecl *Tpl = &findDecl(AST, "Foo::tpl");
412 
413  Rel.IsInstanceMember = false;
414  Rel.merge(CodeCompletionResult(Foo, /*Priority=*/0));
415  EXPECT_FALSE(Rel.IsInstanceMember);
416  Rel.merge(CodeCompletionResult(Bar, /*Priority=*/0));
417  EXPECT_TRUE(Rel.IsInstanceMember);
418  Rel.IsInstanceMember = false;
419  Rel.merge(CodeCompletionResult(Tpl, /*Priority=*/0));
420  EXPECT_TRUE(Rel.IsInstanceMember);
421 }
422 
423 TEST(QualityTests, ConstructorDestructor) {
424  auto Header = TestTU::withHeaderCode(R"cpp(
425  class Foo {
426  public:
427  Foo(int);
428  ~Foo();
429  };
430  )cpp");
431  auto Symbols = Header.headerSymbols();
432  auto AST = Header.build();
433 
434  const NamedDecl *CtorDecl = &findDecl(AST, [](const NamedDecl &ND) {
435  return (ND.getQualifiedNameAsString() == "Foo::Foo") &&
436  isa<CXXConstructorDecl>(&ND);
437  });
438  const NamedDecl *DtorDecl = &findDecl(AST, [](const NamedDecl &ND) {
439  return (ND.getQualifiedNameAsString() == "Foo::~Foo") &&
440  isa<CXXDestructorDecl>(&ND);
441  });
442 
443  SymbolQualitySignals CtorQ;
444  CtorQ.merge(CodeCompletionResult(CtorDecl, /*Priority=*/0));
445  EXPECT_EQ(CtorQ.Category, SymbolQualitySignals::Constructor);
446 
447  CtorQ.Category = SymbolQualitySignals::Unknown;
448  const Symbol &CtorSym = findSymbol(Symbols, "Foo::Foo");
449  CtorQ.merge(CtorSym);
450  EXPECT_EQ(CtorQ.Category, SymbolQualitySignals::Constructor);
451 
452  SymbolQualitySignals DtorQ;
453  DtorQ.merge(CodeCompletionResult(DtorDecl, /*Priority=*/0));
454  EXPECT_EQ(DtorQ.Category, SymbolQualitySignals::Destructor);
455 }
456 
457 TEST(QualityTests, Operator) {
458  auto Header = TestTU::withHeaderCode(R"cpp(
459  class Foo {
460  public:
461  bool operator<(const Foo& f1);
462  };
463  )cpp");
464  auto AST = Header.build();
465 
466  const NamedDecl *Operator = &findDecl(AST, [](const NamedDecl &ND) {
467  if (const auto *OD = dyn_cast<FunctionDecl>(&ND))
468  if (OD->isOverloadedOperator())
469  return true;
470  return false;
471  });
473  Q.merge(CodeCompletionResult(Operator, /*Priority=*/0));
474  EXPECT_EQ(Q.Category, SymbolQualitySignals::Operator);
475 }
476 
477 TEST(QualityTests, ItemWithFixItsRankedDown) {
478  CodeCompleteOptions Opts;
479  Opts.IncludeFixIts = true;
480 
481  auto Header = TestTU::withHeaderCode(R"cpp(
482  int x;
483  )cpp");
484  auto AST = Header.build();
485 
486  SymbolRelevanceSignals RelevanceWithFixIt;
487  RelevanceWithFixIt.merge(CodeCompletionResult(&findDecl(AST, "x"), 0, nullptr,
488  false, true, {FixItHint{}}));
489  EXPECT_TRUE(RelevanceWithFixIt.NeedsFixIts);
490 
491  SymbolRelevanceSignals RelevanceWithoutFixIt;
492  RelevanceWithoutFixIt.merge(
493  CodeCompletionResult(&findDecl(AST, "x"), 0, nullptr, false, true, {}));
494  EXPECT_FALSE(RelevanceWithoutFixIt.NeedsFixIts);
495 
496  EXPECT_LT(RelevanceWithFixIt.evaluateHeuristics(),
497  RelevanceWithoutFixIt.evaluateHeuristics());
498 }
499 
500 } // namespace
501 } // namespace clangd
502 } // namespace clang
clang::clangd::SymbolRelevanceSignals::merge
void merge(const CodeCompletionResult &SemaResult)
Definition: Quality.cpp:331
clang::clangd::findDecl
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition: TestTU.cpp:215
clang::clangd::SymbolQualitySignals::ImplementationDetail
bool ImplementationDetail
Definition: Quality.h:62
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:751
References
unsigned References
Definition: CodeComplete.cpp:163
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:82
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:103
clang::clangd::SymbolQualitySignals::Variable
@ Variable
Definition: Quality.h:67
clang::clangd::SymbolQualitySignals::Unknown
@ Unknown
Definition: Quality.h:66
clang::clangd::SymbolRelevanceSignals::FunctionScope
@ FunctionScope
Definition: Quality.h:117
TestTU.h
clang::clangd::SymbolRelevanceSignals::evaluateHeuristics
float evaluateHeuristics() const
Definition: Quality.cpp:401
clang::clangd::SymbolQualitySignals::ReservedName
bool ReservedName
Definition: Quality.h:60
clang::clangd::FuzzyFindRequest
Definition: Index.h:27
clang::clangd::ScopeDistance
Support lookups like FileDistance, but the lookup keys are symbol scopes.
Definition: FileDistance.h:117
clang::clangd::TestTU::Code
std::string Code
Definition: TestTU.h:50
clang::clangd::SymbolQualitySignals
Attributes of a symbol that affect how much we like it.
Definition: Quality.h:58
clang::clangd::CompletionItemKind::Keyword
@ Keyword
clang::clangd::UnittestSchemeAnchorSource
volatile int UnittestSchemeAnchorSource
Definition: TestFS.cpp:127
clang::clangd::SymbolRelevanceSignals::Forbidden
bool Forbidden
Definition: Quality.h:95
clang::clangd::findUnqualifiedDecl
const NamedDecl & findUnqualifiedDecl(ParsedAST &AST, llvm::StringRef Name)
Definition: TestTU.cpp:256
clang::clangd::FuzzyFindRequest::Query
std::string Query
A query string for the fuzzy find.
Definition: Index.h:30
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:252
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:43
FileDistance.h
clang::clangd::SymbolQualitySignals::Constructor
@ Constructor
Definition: Quality.h:71
clang::clangd::CompletionItemKind::Function
@ Function
clang::clangd::SymbolQualitySignals::References
unsigned References
Definition: Quality.h:63
Quality
SignatureQualitySignals Quality
Definition: CodeComplete.cpp:872
clang::clangd::SymbolQualitySignals::Destructor
@ Destructor
Definition: Quality.h:72
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:128
clang::clangd::CodeCompleteOptions::IncludeFixIts
bool IncludeFixIts
Include completions that require small corrections, e.g.
Definition: CodeComplete.h:96
clang::clangd::SymbolRelevanceSignals::SemaFileProximityScore
float SemaFileProximityScore
FIXME: unify with index proximity score - signals should be source-independent.
Definition: Quality.h:107
clang::clangd::TestTU
Definition: TestTU.h:36
clang::clangd::SymbolQualitySignals::Function
@ Function
Definition: Quality.h:70
clang::clangd::SymbolRelevanceSignals::FileProximityMatch
URIDistance * FileProximityMatch
Definition: Quality.h:100
Bar
Definition: sample.cpp:5
clang::clangd::CodeCompleteOptions
Definition: CodeComplete.h:45
Parent
const Node * Parent
Definition: ExtractFunction.cpp:152
clang::clangd::SymbolRelevanceSignals::ScopeProximityMatch
ScopeDistance * ScopeProximityMatch
Definition: Quality.h:110
clang::clangd::Deprecated
@ Deprecated
Deprecated or obsolete code.
Definition: Protocol.h:829
Index
const SymbolIndex * Index
Definition: Dexp.cpp:99
clang::clangd::SymbolRelevanceSignals::Name
llvm::StringRef Name
The name of the symbol (for ContextWords). Must be explicitly assigned.
Definition: Quality.h:90
clang::clangd::URIDistance
Definition: FileDistance.h:93
clang::clangd::SymbolRelevanceSignals::IsInstanceMember
bool IsInstanceMember
Definition: Quality.h:131
clang::clangd::SymbolQualitySignals::Keyword
@ Keyword
Definition: Quality.h:74
clang::clangd::SymbolRelevanceSignals::NeedsFixIts
bool NeedsFixIts
Whether fixits needs to be applied for that completion or not.
Definition: Quality.h:97
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:613
clang::clangd::SymbolQualitySignals::Macro
@ Macro
Definition: Quality.h:68
clang::clangd::SymbolRelevanceSignals::ClassScope
@ ClassScope
Definition: Quality.h:118
clang::clangd::SymbolQualitySignals::Operator
@ Operator
Definition: Quality.h:75
clang::clangd::SymbolRelevanceSignals::SymbolScope
llvm::Optional< llvm::StringRef > SymbolScope
Definition: Quality.h:111
clang::clangd::TestTU::index
std::unique_ptr< SymbolIndex > index() const
Definition: TestTU.cpp:171
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:204
clang::clangd::SymbolRelevanceSignals::ContextWords
llvm::StringSet * ContextWords
Lowercase words relevant to the context (e.g. near the completion point).
Definition: Quality.h:94
clang::clangd::FuzzyFindRequest::AnyScope
bool AnyScope
If set to true, allow symbols from any scope.
Definition: Index.h:40
clang::clangd::SymbolQualitySignals::Category
enum clang::clangd::SymbolQualitySignals::SymbolCategory Category
Quality.h
clang::clangd::SymbolRelevanceSignals::NameMatch
float NameMatch
0-1+ fuzzy-match score for unqualified name. Must be explicitly assigned.
Definition: Quality.h:92
clang::clangd::SymbolRelevanceSignals::CodeComplete
@ CodeComplete
Definition: Quality.h:124
clang::clangd::SymbolRelevanceSignals::InBaseClass
bool InBaseClass
Definition: Quality.h:98
clang::clangd::SymbolRelevanceSignals::GlobalScope
@ GlobalScope
Definition: Quality.h:120
clang::clangd::SymbolRelevanceSignals
Attributes of a symbol-query pair that affect how much we like it.
Definition: Quality.h:88
clang::clangd::CompletionItemKind::Variable
@ Variable
clang::clangd::findSymbol
const Symbol & findSymbol(const SymbolSlab &Slab, llvm::StringRef QName)
Definition: TestTU.cpp:181
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:54
clang::clangd::SymbolRelevanceSignals::FileScope
@ FileScope
Definition: Quality.h:119
clang::clangd::SymbolQualitySignals::merge
void merge(const CodeCompletionResult &SemaCCResult)
Definition: Quality.cpp:184