@@ -121,7 +121,7 @@ class NodeFinderExprResult : public NodeFinderResult {
121
121
// / Walks the AST, looking for a node at \c LocToResolve. While walking the
122
122
// / AST, also gathers information about shorthand shadows.
123
123
class NodeFinder : ASTWalker {
124
- SourceFile &SrcFile ;
124
+ DeclContext &DC ;
125
125
SourceLoc LocToResolve;
126
126
127
127
// / As we are walking the tree, this variable is updated to the last seen
@@ -139,11 +139,10 @@ class NodeFinder : ASTWalker {
139
139
llvm::DenseMap<ValueDecl *, ValueDecl *> ShorthandShadowedDecls;
140
140
141
141
public:
142
- NodeFinder (SourceFile &SrcFile, SourceLoc LocToResolve)
143
- : SrcFile(SrcFile), LocToResolve(LocToResolve),
144
- DeclContextStack ({&SrcFile}) {}
142
+ NodeFinder (DeclContext &DC, SourceLoc LocToResolve)
143
+ : DC(DC), LocToResolve(LocToResolve), DeclContextStack({&DC}) {}
145
144
146
- void resolve () { SrcFile. walk (*this ); }
145
+ void resolve () { DC. walkContext (*this ); }
147
146
148
147
std::unique_ptr<NodeFinderResult> takeResult () { return std::move (Result); }
149
148
@@ -161,9 +160,7 @@ class NodeFinder : ASTWalker {
161
160
}
162
161
163
162
private:
164
- SourceManager &getSourceMgr () const {
165
- return SrcFile.getASTContext ().SourceMgr ;
166
- }
163
+ SourceManager &getSourceMgr () const { return DC.getASTContext ().SourceMgr ; }
167
164
168
165
// / The decl context that is currently being walked.
169
166
DeclContext *getCurrentDeclContext () { return DeclContextStack.back (); }
@@ -219,7 +216,9 @@ class NodeFinder : ASTWalker {
219
216
if (auto CaptureList = dyn_cast<CaptureListExpr>(E)) {
220
217
for (auto ShorthandShadows :
221
218
getShorthandShadows (CaptureList, getCurrentDeclContext ())) {
222
- assert (ShorthandShadowedDecls.count (ShorthandShadows.first ) == 0 );
219
+ assert (ShorthandShadowedDecls.count (ShorthandShadows.first ) == 0 ||
220
+ ShorthandShadowedDecls[ShorthandShadows.first ] ==
221
+ ShorthandShadows.second );
223
222
ShorthandShadowedDecls[ShorthandShadows.first ] =
224
223
ShorthandShadows.second ;
225
224
}
@@ -232,7 +231,8 @@ class NodeFinder : ASTWalker {
232
231
switch (E->getKind ()) {
233
232
case ExprKind::DeclRef:
234
233
case ExprKind::UnresolvedDot:
235
- case ExprKind::UnresolvedDeclRef: {
234
+ case ExprKind::UnresolvedDeclRef:
235
+ case ExprKind::OverloadedDeclRef: {
236
236
assert (Result == nullptr );
237
237
Result =
238
238
std::make_unique<NodeFinderExprResult>(E, getCurrentDeclContext ());
@@ -280,13 +280,33 @@ class CursorInfoTypeCheckSolutionCallback : public TypeCheckCompletionCallback {
280
280
};
281
281
282
282
private:
283
- // / The expression for which we want to provide cursor info results.
284
- Expr *ResolveExpr;
283
+ // / The location to resolve and the \c DeclContext to resolve it in.
284
+ // / Note that we cannot store the expression to resolve directly because an
285
+ // / \c UnresolvedDeclRefExpr might be replaced by an \c OverloadedDeclRefExpr
286
+ // / and thus the constraint system solution doesn't know about the
287
+ // / \c UnresolvedDeclRefExpr. Instead, we find the expression to resolve in
288
+ // / the source file again after expression pre-check has run.
289
+ DeclContext &DC;
290
+ SourceLoc ResolveLoc;
285
291
286
292
SmallVector<CursorInfoDeclReference, 1 > Results;
287
293
294
+ Expr *getExprToResolve () {
295
+ NodeFinder Finder (DC, ResolveLoc);
296
+ Finder.resolve ();
297
+ auto Result = Finder.takeResult ();
298
+ if (!Result || Result->getKind () != NodeFinderResultKind::Expr) {
299
+ return nullptr ;
300
+ }
301
+ return cast<NodeFinderExprResult>(Result.get ())->getExpr ();
302
+ }
303
+
288
304
void sawSolutionImpl (const Solution &S) override {
289
305
auto &CS = S.getConstraintSystem ();
306
+ auto ResolveExpr = getExprToResolve ();
307
+ if (!ResolveExpr) {
308
+ return ;
309
+ }
290
310
291
311
auto Locator = CS.getConstraintLocator (ResolveExpr);
292
312
auto CalleeLocator = S.getCalleeLocator (Locator);
@@ -310,8 +330,8 @@ class CursorInfoTypeCheckSolutionCallback : public TypeCheckCompletionCallback {
310
330
}
311
331
312
332
public:
313
- CursorInfoTypeCheckSolutionCallback (Expr *ResolveExpr )
314
- : ResolveExpr(ResolveExpr ) {}
333
+ CursorInfoTypeCheckSolutionCallback (DeclContext &DC, SourceLoc ResolveLoc )
334
+ : DC(DC), ResolveLoc(ResolveLoc ) {}
315
335
316
336
ArrayRef<CursorInfoDeclReference> getResults () const { return Results; }
317
337
};
@@ -327,11 +347,11 @@ class CursorInfoDoneParsingCallback : public DoneParsingCallback {
327
347
SourceLoc RequestedLoc)
328
348
: DoneParsingCallback(), Consumer(Consumer), RequestedLoc(RequestedLoc) {}
329
349
330
- ResolvedCursorInfoPtr getDeclResult (NodeFinderDeclResult *DeclResult,
331
- SourceFile *SrcFile,
332
- NodeFinder &Finder) const {
350
+ std::vector< ResolvedCursorInfoPtr>
351
+ getDeclResult (NodeFinderDeclResult *DeclResult, SourceFile *SrcFile,
352
+ NodeFinder &Finder) const {
333
353
typeCheckDeclAndParentClosures (DeclResult->getDecl ());
334
- return new ResolvedValueRefCursorInfo (
354
+ auto CursorInfo = new ResolvedValueRefCursorInfo (
335
355
SrcFile, RequestedLoc, DeclResult->getDecl (),
336
356
/* CtorTyRef=*/ nullptr ,
337
357
/* ExtTyRef=*/ nullptr , /* IsRef=*/ false , /* Ty=*/ Type (),
@@ -341,24 +361,27 @@ class CursorInfoDoneParsingCallback : public DoneParsingCallback {
341
361
/* IsDynamic=*/ false ,
342
362
/* ReceiverTypes=*/ {},
343
363
Finder.getShorthandShadowedDecls (DeclResult->getDecl ()));
364
+ return {CursorInfo};
344
365
}
345
366
346
- ResolvedCursorInfoPtr getExprResult (NodeFinderExprResult *ExprResult,
347
- SourceFile *SrcFile,
348
- NodeFinder &Finder) const {
367
+ std::vector< ResolvedCursorInfoPtr>
368
+ getExprResult (NodeFinderExprResult *ExprResult, SourceFile *SrcFile,
369
+ NodeFinder &Finder) const {
349
370
Expr *E = ExprResult->getExpr ();
350
371
DeclContext *DC = ExprResult->getDeclContext ();
351
372
352
373
// Type check the statemnt containing E and listen for solutions.
353
- CursorInfoTypeCheckSolutionCallback Callback (E);
354
- llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector (
355
- DC->getASTContext ().SolutionCallback , &Callback);
356
- typeCheckASTNodeAtLoc (TypeCheckASTNodeAtLocContext::declContext (DC),
357
- E->getLoc ());
374
+ CursorInfoTypeCheckSolutionCallback Callback (*DC, RequestedLoc);
375
+ {
376
+ llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector (
377
+ DC->getASTContext ().SolutionCallback , &Callback);
378
+ typeCheckASTNodeAtLoc (TypeCheckASTNodeAtLocContext::declContext (DC),
379
+ E->getLoc ());
380
+ }
358
381
359
382
if (Callback.getResults ().empty ()) {
360
383
// No results.
361
- return nullptr ;
384
+ return {} ;
362
385
}
363
386
364
387
for (auto Info : Callback.getResults ()) {
@@ -367,34 +390,38 @@ class CursorInfoDoneParsingCallback : public DoneParsingCallback {
367
390
typeCheckDeclAndParentClosures (Info.ReferencedDecl );
368
391
}
369
392
370
- if (Callback.getResults ().size () != 1 ) {
371
- // FIXME: We need to be able to report multiple results.
372
- return nullptr ;
373
- }
374
-
375
393
// Deliver results
376
394
377
- auto Res = Callback.getResults ()[0 ];
378
- SmallVector<NominalTypeDecl *> ReceiverTypes;
379
- if (Res.IsDynamicRef && Res.BaseType ) {
380
- if (auto ReceiverType = Res.BaseType ->getAnyNominal ()) {
381
- ReceiverTypes = {ReceiverType};
382
- } else if (auto MT = Res.BaseType ->getAs <AnyMetatypeType>()) {
383
- // Look through metatypes to get the nominal type decl.
384
- if (auto ReceiverType = MT->getInstanceType ()->getAnyNominal ()) {
395
+ std::vector<ResolvedCursorInfoPtr> Results;
396
+ for (auto Res : Callback.getResults ()) {
397
+ SmallVector<NominalTypeDecl *> ReceiverTypes;
398
+ if (isa<ModuleDecl>(Res.ReferencedDecl )) {
399
+ // ResolvedModuleRefCursorInfo is not supported by solver-based cursor
400
+ // info yet.
401
+ continue ;
402
+ }
403
+ if (Res.IsDynamicRef && Res.BaseType ) {
404
+ if (auto ReceiverType = Res.BaseType ->getAnyNominal ()) {
385
405
ReceiverTypes = {ReceiverType};
406
+ } else if (auto MT = Res.BaseType ->getAs <AnyMetatypeType>()) {
407
+ // Look through metatypes to get the nominal type decl.
408
+ if (auto ReceiverType = MT->getInstanceType ()->getAnyNominal ()) {
409
+ ReceiverTypes = {ReceiverType};
410
+ }
386
411
}
387
412
}
388
- }
389
413
390
- return new ResolvedValueRefCursorInfo (
391
- SrcFile, RequestedLoc, Res.ReferencedDecl ,
392
- /* CtorTyRef=*/ nullptr ,
393
- /* ExtTyRef=*/ nullptr , /* IsRef=*/ true , /* Ty=*/ Type (),
394
- /* ContainerType=*/ Res.BaseType ,
395
- /* CustomAttrRef=*/ None,
396
- /* IsKeywordArgument=*/ false , Res.IsDynamicRef , ReceiverTypes,
397
- Finder.getShorthandShadowedDecls (Res.ReferencedDecl ));
414
+ auto CursorInfo = new ResolvedValueRefCursorInfo (
415
+ SrcFile, RequestedLoc, Res.ReferencedDecl ,
416
+ /* CtorTyRef=*/ nullptr ,
417
+ /* ExtTyRef=*/ nullptr , /* IsRef=*/ true , /* Ty=*/ Type (),
418
+ /* ContainerType=*/ Res.BaseType ,
419
+ /* CustomAttrRef=*/ None,
420
+ /* IsKeywordArgument=*/ false , Res.IsDynamicRef , ReceiverTypes,
421
+ Finder.getShorthandShadowedDecls (Res.ReferencedDecl ));
422
+ Results.push_back (CursorInfo);
423
+ }
424
+ return Results;
398
425
}
399
426
400
427
void doneParsing (SourceFile *SrcFile) override {
@@ -407,7 +434,7 @@ class CursorInfoDoneParsingCallback : public DoneParsingCallback {
407
434
if (!Result) {
408
435
return ;
409
436
}
410
- ResolvedCursorInfoPtr CursorInfo;
437
+ std::vector< ResolvedCursorInfoPtr> CursorInfo;
411
438
switch (Result->getKind ()) {
412
439
case NodeFinderResultKind::Decl:
413
440
CursorInfo = getDeclResult (cast<NodeFinderDeclResult>(Result.get ()),
0 commit comments