clang-tools 8.0.0

Quality.h
Go to the documentation of this file.
1 //===--- Quality.h - Ranking alternatives for ambiguous queries --*- 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 ///
10 /// Some operations such as code completion produce a set of candidates.
11 /// Usually the user can choose between them, but we should put the best options
12 /// at the top (they're easier to select, and more likely to be seen).
13 ///
14 /// This file defines building blocks for ranking candidates.
15 /// It's used by the features directly and also in the implementation of
16 /// indexes, as indexes also need to heuristically limit their results.
17 ///
18 /// The facilities here are:
19 /// - retrieving scoring signals from e.g. indexes, AST, CodeCompletionString
20 /// These are structured in a way that they can be debugged, and are fairly
21 /// consistent regardless of the source.
22 /// - compute scores from scoring signals. These are suitable for sorting.
23 /// - sorting utilities like the TopN container.
24 /// These could be split up further to isolate dependencies if we care.
25 ///
26 //===----------------------------------------------------------------------===//
27
28 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_QUALITY_H
29 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_QUALITY_H
30
31 #include "ExpectedTypes.h"
32 #include "FileDistance.h"
33 #include "clang/Sema/CodeCompleteConsumer.h"
34 #include "llvm/ADT/ArrayRef.h"
35 #include "llvm/ADT/StringRef.h"
36 #include <algorithm>
37 #include <functional>
38 #include <vector>
39
40 namespace llvm {
41 class raw_ostream;
42 }
43
44 namespace clang {
45 class CodeCompletionResult;
46
47 namespace clangd {
48
49 struct Symbol;
50 class URIDistance;
51
52 // Signals structs are designed to be aggregated from 0 or more sources.
53 // A default instance has neutral signals, and sources are merged into it.
54 // They can be dumped for debugging, and evaluate()d into a score.
55
56 /// Attributes of a symbol that affect how much we like it.
57 struct SymbolQualitySignals {
58 bool Deprecated = false;
59 bool ReservedName = false; // __foo, _Foo are usually implementation details.
60 // FIXME: make these findable once user types _.
61 bool ImplementationDetail = false;
62 unsigned References = 0;
63
64 enum SymbolCategory {
65 Unknown = 0,
66 Variable,
67 Macro,
68 Type,
69 Function,
70 Constructor,
71 Destructor,
72 Namespace,
73 Keyword,
74 Operator,
75 } Category = Unknown;
76
77 void merge(const CodeCompletionResult &SemaCCResult);
78 void merge(const Symbol &IndexResult);
79
80 // Condense these signals down to a single number, higher is better.
81 float evaluate() const;
82 };
83 llvm::raw_ostream &operator<<(llvm::raw_ostream &,
84 const SymbolQualitySignals &);
85
86 /// Attributes of a symbol-query pair that affect how much we like it.
87 struct SymbolRelevanceSignals {
88 /// 0-1+ fuzzy-match score for unqualified name. Must be explicitly assigned.
89 float NameMatch = 1;
90 bool Forbidden = false; // Unavailable (e.g const) or inaccessible (private).
91 /// Whether fixits needs to be applied for that completion or not.
92 bool NeedsFixIts = false;
93 bool InBaseClass = false; // A member from base class of the accessed class.
94
95 URIDistance *FileProximityMatch = nullptr;
96 /// These are used to calculate proximity between the index symbol and the
97 /// query.
98 llvm::StringRef SymbolURI;
99 /// FIXME: unify with index proximity score - signals should be
100 /// source-independent.
101 /// Proximity between best declaration and the query. [0-1], 1 is closest.
102 float SemaFileProximityScore = 0;
103
104 // Scope proximity is only considered (both index and sema) when this is set.
105 ScopeDistance *ScopeProximityMatch = nullptr;
106 llvm::Optional<llvm::StringRef> SymbolScope;
107 // A symbol from sema should be accessible from the current scope.
108 bool SemaSaysInScope = false;
109
110 // An approximate measure of where we expect the symbol to be used.
111 enum AccessibleScope {
112 FunctionScope,
113 ClassScope,
114 FileScope,
115 GlobalScope,
116 } Scope = GlobalScope;
117
118 enum QueryType {
119 CodeComplete,
120 Generic,
121 } Query = Generic;
122
123 CodeCompletionContext::Kind Context = CodeCompletionContext::CCC_Other;
124
125 // Whether symbol is an instance member of a class.
126 bool IsInstanceMember = false;
127
128 // Whether clang provided a preferred type in the completion context.
129 bool HadContextType = false;
130 // Whether a source completion item or a symbol had a type information.
131 bool HadSymbolType = false;
132 // Whether the item matches the type expected in the completion context.
133 bool TypeMatchesPreferred = false;
134
135 void merge(const CodeCompletionResult &SemaResult);
136 void merge(const Symbol &IndexResult);
137
138 // Condense these signals down to a single number, higher is better.
139 float evaluate() const;
140 };
141 llvm::raw_ostream &operator<<(llvm::raw_ostream &,
142 const SymbolRelevanceSignals &);
143
144 /// Combine symbol quality and relevance into a single score.
145 float evaluateSymbolAndRelevance(float SymbolQuality, float SymbolRelevance);
146
147 /// TopN<T> is a lossy container that preserves only the "best" N elements.
148 template <typename T, typename Compare = std::greater<T>> class TopN {
149 public:
150 using value_type = T;
151 TopN(size_t N, Compare Greater = Compare())
152 : N(N), Greater(std::move(Greater)) {}
153
154 // Adds a candidate to the set.
155 // Returns true if a candidate was dropped to get back under N.
156 bool push(value_type &&V) {
157 bool Dropped = false;
158 if (Heap.size() >= N) {
159 Dropped = true;
160 if (N > 0 && Greater(V, Heap.front())) {
161 std::pop_heap(Heap.begin(), Heap.end(), Greater);
162 Heap.back() = std::move(V);
163 std::push_heap(Heap.begin(), Heap.end(), Greater);
164 }
165 } else {
166 Heap.push_back(std::move(V));
167 std::push_heap(Heap.begin(), Heap.end(), Greater);
168 }
169 assert(Heap.size() <= N);
170 assert(std::is_heap(Heap.begin(), Heap.end(), Greater));
171 return Dropped;
172 }
173
174 // Returns candidates from best to worst.
175 std::vector<value_type> items() && {
176 std::sort_heap(Heap.begin(), Heap.end(), Greater);
177 assert(Heap.size() <= N);
178 return std::move(Heap);
179 }
180
181 private:
182 const size_t N;
183 std::vector<value_type> Heap; // Min-heap, comparator is Greater.
184 Compare Greater;
185 };
186
187 /// Returns a string that sorts in the same order as (-Score, Tiebreak), for
188 /// LSP. (The highest score compares smallest so it sorts at the top).
189 std::string sortText(float Score, llvm::StringRef Tiebreak = "");
190
191 struct SignatureQualitySignals {
192 uint32_t NumberOfParameters = 0;
193 uint32_t NumberOfOptionalParameters = 0;
194 bool ContainsActiveParameter = false;
195 CodeCompleteConsumer::OverloadCandidate::CandidateKind Kind =
196 CodeCompleteConsumer::OverloadCandidate::CandidateKind::CK_Function;
197 };
198 llvm::raw_ostream &operator<<(llvm::raw_ostream &,
199 const SignatureQualitySignals &);
200
201 } // namespace clangd
202 } // namespace clang
203
204 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_QUALITY_H
clang::clangd::SymbolRelevanceSignals::GlobalScope
Definition: Quality.h:115
clang::clangd::SymbolRelevanceSignals::FileScope
Definition: Quality.h:114
llvm
Some operations such as code completion produce a set of candidates.
Definition: YAMLGenerator.cpp:28
clang::clangd::SymbolQualitySignals::Destructor
Definition: Quality.h:71
clang::clangd::SymbolRelevanceSignals::SymbolScope
llvm::Optional< llvm::StringRef > SymbolScope
Definition: Quality.h:106
clang::clangd::TopN::TopN
TopN(size_t N, Compare Greater=Compare())
Definition: Quality.h:151
clang::clangd::SymbolRelevanceSignals::ClassScope
Definition: Quality.h:113
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:452
clang::clangd::SymbolQualitySignals::Variable
Definition: Quality.h:66
clang::clangd::SymbolRelevanceSignals::CodeComplete
Definition: Quality.h:119
clang::clangd::SymbolQualitySignals
Attributes of a symbol that affect how much we like it.
Definition: Quality.h:57
clang::clangd::SymbolQualitySignals::Constructor
Definition: Quality.h:70
clang::clangd::TopN::value_type
T value_type
Definition: Quality.h:150
Kind
BindArgumentKind Kind
Definition: AvoidBindCheck.cpp:41
clang::clangd::SymbolRelevanceSignals::QueryType
QueryType
Definition: Quality.h:118
clang::clangd::Unknown
Definition: FuzzyMatch.h:57
clang::clangd::SymbolRelevanceSignals::Generic
Definition: Quality.h:120
FileDistance.h
clang::clangd::SymbolRelevanceSignals::AccessibleScope
AccessibleScope
Definition: Quality.h:111
clang::clangd::SymbolQualitySignals::Function
Definition: Quality.h:69
clang::clangd::TopN::push
bool push(value_type &&V)
Definition: Quality.h:156
IndexResult
const Symbol * IndexResult
Definition: CodeComplete.cpp:209
clang::clangd::Context
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:70
ExpectedTypes.h
clang::clangd::SymbolRelevanceSignals::SymbolURI
llvm::StringRef SymbolURI
These are used to calculate proximity between the index symbol and the query.
Definition: Quality.h:98
clang::clangd::SymbolQualitySignals::Keyword
Definition: Quality.h:73
clang::clangd::SymbolQualitySignals::Namespace
Definition: Quality.h:72
clang::clangd::evaluateSymbolAndRelevance
float evaluateSymbolAndRelevance(float SymbolQuality, float SymbolRelevance)
Combine symbol quality and relevance into a single score.
Definition: Quality.cpp:434
clang::clangd::URIDistance
Definition: FileDistance.h:93
clang::clangd::Symbol
Definition: Index.h:160
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ChangeNamespace.cpp:18
clang::clangd::ScopeDistance
Support lookups like FileDistance, but the lookup keys are symbol scopes.
Definition: FileDistance.h:117
clang::clangd::SymbolQualitySignals::SymbolCategory
SymbolCategory
Definition: Quality.h:64
clang::clangd::SignatureQualitySignals
Definition: Quality.h:191
clang::clangd::SymbolQualitySignals::Macro
Definition: Quality.h:67
SemaResult
const CodeCompletionResult * SemaResult
Definition: CodeComplete.cpp:208
clang::clangd::SymbolQualitySignals::Operator
Definition: Quality.h:74
clang::clangd::TopN::items
std::vector< value_type > items() &&
Definition: Quality.h:175
clang::clangd::operator<<
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
Definition: CodeComplete.cpp:1719
clang::clangd::SymbolRelevanceSignals::FunctionScope
Definition: Quality.h:112
clang::clangd::SymbolQualitySignals::Type
Definition: Quality.h:68
clang::clangd::SymbolRelevanceSignals
Attributes of a symbol-query pair that affect how much we like it.
Definition: Quality.h:87
clang::clangd::TopN
TopN<T> is a lossy container that preserves only the "best" N elements.
Definition: Quality.h:148