Skip to content

Commit 395f565

Browse files
committed
chore: allow for caller to filter lookup results
1 parent 11febb6 commit 395f565

File tree

3 files changed

+115
-37
lines changed

3 files changed

+115
-37
lines changed

src/lib/Lib/Lookup.cpp

+38-31
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ SymbolLookup::
125125
lookupInContext(
126126
const Info* context,
127127
std::string_view name,
128-
bool for_nns)
128+
bool for_nns,
129+
LookupCallback& callback)
129130
{
130131
// if the lookup context is a typedef, we want to
131132
// lookup the name in the type it denotes
@@ -136,17 +137,27 @@ lookupInContext(
136137
// KRYSTIAN FIXME: disambiguation based on signature
137138
for(auto& result : table.lookup(name))
138139
{
139-
// per [basic.lookup.qual.general] p1, when looking up a
140-
// component name of a nested-name-specifier, we only consider:
141-
// - namespaces,
142-
// - types, and
143-
// - templates whose specializations are types
144-
if(! for_nns ||
145-
result->isNamespace() ||
146-
result->isRecord() ||
147-
result->isEnum() ||
148-
result->isTypedef())
149-
return result;
140+
if(for_nns)
141+
{
142+
// per [basic.lookup.qual.general] p1, when looking up a
143+
// component name of a nested-name-specifier, we only consider:
144+
// - namespaces,
145+
// - types, and
146+
// - templates whose specializations are types
147+
// KRYSTIAN FIXME: should we if the result is acceptable?
148+
if(result->isNamespace() ||
149+
result->isRecord() ||
150+
result->isEnum() ||
151+
result->isTypedef())
152+
return result;
153+
}
154+
else
155+
{
156+
// if we are looking up a terminal name, call the handler
157+
// to determine whether the result is acceptable
158+
if(callback(*result))
159+
return result;
160+
}
150161
}
151162

152163
// if this is a record and nothing was found,
@@ -159,7 +170,8 @@ lookupInContext(
159170
for(const auto& B : RI->Bases)
160171
{
161172
if(const Info* result = lookupInContext(
162-
corpus_.find(B.Type->namedSymbol()), name, for_nns))
173+
corpus_.find(B.Type->namedSymbol()),
174+
name, for_nns, callback))
163175
return result;
164176
}
165177
}
@@ -172,14 +184,16 @@ SymbolLookup::
172184
lookupUnqualifiedImpl(
173185
const Info* context,
174186
std::string_view name,
175-
bool for_nns)
187+
bool for_nns,
188+
LookupCallback& callback)
176189
{
177190
if(! context)
178191
return nullptr;
179192
context = adjustLookupContext(context);
180193
while(context)
181194
{
182-
if(auto result = lookupInContext(context, name, for_nns))
195+
if(auto result = lookupInContext(
196+
context, name, for_nns, callback))
183197
return result;
184198
if(context->Namespace.empty())
185199
return nullptr;
@@ -191,38 +205,31 @@ lookupUnqualifiedImpl(
191205

192206
const Info*
193207
SymbolLookup::
194-
lookupUnqualified(
195-
const Info* context,
196-
std::string_view name)
197-
{
198-
return lookupUnqualifiedImpl(
199-
context, name, false);
200-
}
201-
202-
const Info*
203-
SymbolLookup::
204-
lookupQualified(
208+
lookupQualifiedImpl(
205209
const Info* context,
206210
std::span<const std::string_view> qualifier,
207-
std::string_view terminal)
211+
std::string_view terminal,
212+
LookupCallback& callback)
208213
{
209214
if(! context)
210215
return nullptr;
211216
if(qualifier.empty())
212-
return lookupInContext(context, terminal);
217+
return lookupInContext(
218+
context, terminal, false, callback);
213219
context = lookupUnqualifiedImpl(
214-
context, qualifier.front(), true);
220+
context, qualifier.front(), true, callback);
215221
qualifier = qualifier.subspan(1);
216222
if(! context)
217223
return nullptr;
218224
while(! qualifier.empty())
219225
{
220226
if(! (context = lookupInContext(
221-
context, qualifier.front(), true)))
227+
context, qualifier.front(), true, callback)))
222228
return nullptr;
223229
qualifier = qualifier.subspan(1);
224230
}
225-
return lookupInContext(context, terminal);
231+
return lookupInContext(
232+
context, terminal, false, callback);
226233
}
227234

228235
} // mrdocs

src/lib/Lib/Lookup.hpp

+60-4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ class SymbolLookup
6060
const Info*,
6161
LookupTable> lookup_tables_;
6262

63+
struct LookupCallback
64+
{
65+
virtual bool operator()(const Info&) = 0;
66+
};
67+
68+
template<typename Fn>
69+
auto makeHandler(Fn& fn);
70+
6371
const Info*
6472
adjustLookupContext(const Info* context);
6573

@@ -74,28 +82,76 @@ class SymbolLookup
7482
lookupInContext(
7583
const Info* context,
7684
std::string_view name,
77-
bool for_nns = false);
85+
bool for_nns,
86+
LookupCallback& callback);
7887

7988
const Info*
8089
lookupUnqualifiedImpl(
8190
const Info* context,
8291
std::string_view name,
83-
bool for_nns);
92+
bool for_nns,
93+
LookupCallback& callback);
94+
95+
const Info*
96+
lookupQualifiedImpl(
97+
const Info* context,
98+
std::span<const std::string_view> qualifier,
99+
std::string_view terminal,
100+
LookupCallback& callback);
101+
84102
public:
85103
SymbolLookup(const Corpus& corpus);
86104

105+
template<typename Fn>
87106
const Info*
88107
lookupUnqualified(
89108
const Info* context,
90-
std::string_view name);
109+
std::string_view name,
110+
Fn&& callback)
111+
{
112+
auto handler = makeHandler(callback);
113+
return lookupUnqualifiedImpl(
114+
context, name, false, handler);
115+
}
91116

117+
template<typename Fn>
92118
const Info*
93119
lookupQualified(
94120
const Info* context,
95121
std::span<const std::string_view> qualifier,
96-
std::string_view terminal);
122+
std::string_view terminal,
123+
Fn&& callback)
124+
{
125+
auto handler = makeHandler(callback);
126+
return lookupQualifiedImpl(
127+
context, qualifier, terminal, handler);
128+
}
97129
};
98130

131+
template<typename Fn>
132+
auto
133+
SymbolLookup::
134+
makeHandler(Fn& fn)
135+
{
136+
class LookupCallbackImpl
137+
: public LookupCallback
138+
{
139+
Fn& fn_;
140+
141+
public:
142+
LookupCallbackImpl(Fn& fn)
143+
: fn_(fn)
144+
{
145+
}
146+
147+
bool operator()(const Info& I) override
148+
{
149+
return fn_(I);
150+
}
151+
};
152+
return LookupCallbackImpl(fn);
153+
}
154+
99155
} // mrdocs
100156
} // clang
101157

src/lib/Metadata/Finalize.cpp

+17-2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ class Finalizer
4040
if(parse_result->name.empty())
4141
return false;
4242

43+
auto is_acceptable = [&](const Info& I) -> bool
44+
{
45+
// if we are copying the documentation of the
46+
// referenced symbol, ignore the current declaration
47+
if(ref.kind == doc::Kind::copied)
48+
return &I != current_;
49+
// otherwise, consider the result to be acceptable
50+
return true;
51+
};
52+
4353
const Info* found = nullptr;
4454
if(parse_result->qualified)
4555
{
@@ -55,12 +65,17 @@ class Finalizer
5565
context = info_.find(SymbolID::global)->get();
5666
}
5767
found = lookup_.lookupQualified(
58-
context, qualifier, parse_result->name);
68+
context,
69+
qualifier,
70+
parse_result->name,
71+
is_acceptable);
5972
}
6073
else
6174
{
6275
found = lookup_.lookupUnqualified(
63-
current_, parse_result->name);
76+
current_,
77+
parse_result->name,
78+
is_acceptable);
6479
}
6580

6681
// prevent recursive documentation copies

0 commit comments

Comments
 (0)