@@ -204,10 +204,19 @@ void ResolvedRangeInfo::print(llvm::raw_ostream &OS) {
204
204
Ty->print (OS);
205
205
OS << " </Type>\n " ;
206
206
}
207
+ for (auto *VD : DeclaredDecls) {
208
+ OS << " <Declared>" << VD->getNameStr () << " </Declared>\n " ;
209
+ }
210
+ for (auto *VD : ReferencedDecls) {
211
+ OS << " <Referenced>" << VD->getNameStr () << " </Referenced>\n " ;
212
+ }
213
+ OS << " <end>\n " ;
207
214
}
208
215
209
216
struct RangeResolver ::Implementation {
210
217
SourceFile &File;
218
+ ASTContext &Ctx;
219
+ SourceManager &SM;
211
220
private:
212
221
enum class RangeMatchKind : int8_t {
213
222
NoneMatch,
@@ -233,19 +242,40 @@ struct RangeResolver::Implementation {
233
242
return ContextStack.back ();
234
243
}
235
244
245
+ std::vector<ValueDecl*> DeclaredDecls;
246
+ std::vector<ValueDecl*> ReferencedDecls;
247
+
248
+ void pushBackDeclUniquely (std::vector<ValueDecl*> &Bag, ValueDecl* VD) {
249
+ if (std::find (Bag.begin (), Bag.end (), VD) == Bag.end ()) {
250
+ Bag.push_back (VD);
251
+ }
252
+ }
253
+
236
254
ResolvedRangeInfo getSingleNodeKind (ASTNode Node) {
237
255
assert (!Node.isNull ());
238
256
if (Node.is <Expr*>())
239
257
return ResolvedRangeInfo (RangeKind::SingleExpression,
240
- Node.get <Expr*>()->getType (), Content);
258
+ Node.get <Expr*>()->getType (), Content,
259
+ llvm::makeArrayRef (DeclaredDecls),
260
+ llvm::makeArrayRef (ReferencedDecls));
241
261
else if (Node.is <Stmt*>())
242
- return ResolvedRangeInfo (RangeKind::SingleStatement, Type (), Content);
262
+ return ResolvedRangeInfo (RangeKind::SingleStatement, Type (), Content,
263
+ DeclaredDecls, ReferencedDecls);
243
264
else {
244
265
assert (Node.is <Decl*>());
245
- return ResolvedRangeInfo (RangeKind::SingleDecl, Type (), Content);
266
+ return ResolvedRangeInfo (RangeKind::SingleDecl, Type (), Content,
267
+ DeclaredDecls, ReferencedDecls);
246
268
}
247
269
}
248
270
271
+ bool isContainedInSelection (CharSourceRange Range) {
272
+ if (SM.isBeforeInBuffer (Range.getStart (), Start))
273
+ return false ;
274
+ if (SM.isBeforeInBuffer (End, Range.getEnd ()))
275
+ return false ;
276
+ return true ;
277
+ }
278
+
249
279
static SourceLoc getNonwhitespaceLocBefore (SourceManager &SM,
250
280
unsigned BufferID,
251
281
unsigned Offset) {
@@ -284,7 +314,8 @@ struct RangeResolver::Implementation {
284
314
}
285
315
286
316
Implementation (SourceFile &File, SourceLoc Start, SourceLoc End) :
287
- File (File), Start(Start), End(End), Content(getContent()) {}
317
+ File (File), Ctx(File.getASTContext()), SM(Ctx.SourceMgr), Start(Start),
318
+ End (End), Content(getContent()) {}
288
319
289
320
public:
290
321
bool hasResult () { return Result.hasValue (); }
@@ -318,6 +349,13 @@ struct RangeResolver::Implementation {
318
349
}
319
350
320
351
void analyze (ASTNode Node) {
352
+ // Collect declared decls in the range.
353
+ if (Node.is <Decl*>()) {
354
+ if (auto *VD = dyn_cast<ValueDecl>(Node.get <Decl*>())) {
355
+ pushBackDeclUniquely (DeclaredDecls, VD);
356
+ }
357
+ }
358
+
321
359
auto &DCInfo = getCurrentDC ();
322
360
switch (getRangeMatchKind (Node.getSourceRange ())) {
323
361
case RangeMatchKind::NoneMatch:
@@ -332,14 +370,16 @@ struct RangeResolver::Implementation {
332
370
DCInfo.EndMatches .emplace_back (Node);
333
371
break ;
334
372
}
373
+
335
374
if (!DCInfo.StartMatches .empty () && !DCInfo.EndMatches .empty ()) {
336
- Result = {RangeKind::MultiStatement, Type (), Content};
375
+ Result = {RangeKind::MultiStatement, Type (), Content,
376
+ llvm::makeArrayRef (DeclaredDecls),
377
+ llvm::makeArrayRef (ReferencedDecls)};
337
378
return ;
338
379
}
339
380
}
340
381
341
382
bool shouldEnter (ASTNode Node) {
342
- SourceManager &SM = File.getASTContext ().SourceMgr ;
343
383
if (hasResult ())
344
384
return false ;
345
385
if (SM.isBeforeInBuffer (End, Node.getSourceRange ().Start ))
@@ -352,7 +392,14 @@ struct RangeResolver::Implementation {
352
392
ResolvedRangeInfo getResult () {
353
393
if (Result.hasValue ())
354
394
return Result.getValue ();
355
- return ResolvedRangeInfo (RangeKind::Invalid, Type (), getContent ());
395
+ return ResolvedRangeInfo ();
396
+ }
397
+
398
+ void analyzeDeclRef (ValueDecl *VD, CharSourceRange Range) {
399
+ if (!isContainedInSelection (Range))
400
+ return ;
401
+ // Collect referenced decls in the range.
402
+ pushBackDeclUniquely (ReferencedDecls, VD);
356
403
}
357
404
358
405
private:
@@ -422,6 +469,14 @@ bool RangeResolver::walkToDeclPost(Decl *D) {
422
469
return !Impl->hasResult ();
423
470
}
424
471
472
+
473
+ bool RangeResolver::
474
+ visitDeclReference (ValueDecl *D, CharSourceRange Range, TypeDecl *CtorTyRef,
475
+ Type T) {
476
+ Impl->analyzeDeclRef (D, Range);
477
+ return true ;
478
+ }
479
+
425
480
ResolvedRangeInfo RangeResolver::resolve () {
426
481
if (!Impl)
427
482
return ResolvedRangeInfo ();
0 commit comments