@@ -282,11 +282,17 @@ class CursorInfoTypeCheckSolutionCallback : public TypeCheckCompletionCallback {
282
282
bool IsDynamicRef;
283
283
// / The declaration that is being referenced. Will never be \c nullptr.
284
284
ValueDecl *ReferencedDecl;
285
+ // / The interface type of the referenced declaration. This might not be
286
+ // / stored in `ReferencedDecl->getInterfaceType()` if the declaration's
287
+ // / type hasn't been applied to the AST.
288
+ Type SolutionSpecificInterfaceType;
285
289
286
290
bool operator ==(const CursorInfoDeclReference &Other) const {
287
291
return nullableTypesEqual (BaseType, Other.BaseType ) &&
288
292
IsDynamicRef == Other.IsDynamicRef &&
289
- ReferencedDecl == Other.ReferencedDecl ;
293
+ ReferencedDecl == Other.ReferencedDecl &&
294
+ nullableTypesEqual (SolutionSpecificInterfaceType,
295
+ Other.SolutionSpecificInterfaceType );
290
296
}
291
297
};
292
298
@@ -313,13 +319,42 @@ class CursorInfoTypeCheckSolutionCallback : public TypeCheckCompletionCallback {
313
319
}
314
320
315
321
void sawSolutionImpl (const Solution &S) override {
316
- auto &CS = S.getConstraintSystem ();
317
- auto ResolveExpr = getExprToResolve ();
318
- if (!ResolveExpr) {
322
+ NodeFinder Finder (DC, ResolveLoc);
323
+ Finder.resolve ();
324
+ auto Result = Finder.takeResult ();
325
+ if (!Result) {
319
326
return ;
320
327
}
328
+ switch (Result->getKind ()) {
329
+ case NodeFinderResultKind::Decl: {
330
+ ValueDecl *DeclToResolve =
331
+ cast<NodeFinderDeclResult>(Result.get ())->getDecl ();
332
+ addCursorInfoResultForDecl (DeclToResolve, S);
333
+ break ;
334
+ }
335
+ case NodeFinderResultKind::Expr: {
336
+ Expr *ExprToResolve = cast<NodeFinderExprResult>(Result.get ())->getExpr ();
337
+ addCursorInfoResultForExpr (ExprToResolve, S);
338
+ break ;
339
+ }
340
+ }
341
+ }
342
+
343
+ void addCursorInfoResultForDecl (ValueDecl *DeclToResolve, const Solution &S) {
344
+ if (!S.hasType (DeclToResolve)) {
345
+ return ;
346
+ }
347
+ Type SolutionInterfaceTy =
348
+ S.simplifyType (S.getType (DeclToResolve))->mapTypeOutOfContext ();
349
+
350
+ addResult ({/* BaseType=*/ nullptr , /* IsDynamicRef=*/ false , DeclToResolve,
351
+ SolutionInterfaceTy});
352
+ }
321
353
322
- auto Locator = CS.getConstraintLocator (ResolveExpr);
354
+ void addCursorInfoResultForExpr (Expr *ExprToResolve, const Solution &S) {
355
+ auto &CS = S.getConstraintSystem ();
356
+
357
+ auto Locator = CS.getConstraintLocator (ExprToResolve);
323
358
auto CalleeLocator = S.getCalleeLocator (Locator);
324
359
auto OverloadInfo = getSelectedOverloadInfo (S, CalleeLocator);
325
360
if (!OverloadInfo.ValueRef ) {
@@ -337,9 +372,11 @@ class CursorInfoTypeCheckSolutionCallback : public TypeCheckCompletionCallback {
337
372
[&S](Expr *E) { return S.getResolvedType (E); });
338
373
}
339
374
340
- CursorInfoDeclReference NewResult = {OverloadInfo.BaseTy , IsDynamicRef,
341
- OverloadInfo.getValue ()};
375
+ addResult ({OverloadInfo.BaseTy , IsDynamicRef, OverloadInfo.getValue (),
376
+ /* SolutionSpecificInterfaceType=*/ Type ()});
377
+ }
342
378
379
+ void addResult (const CursorInfoDeclReference &NewResult) {
343
380
if (llvm::any_of (Results, [&](const CursorInfoDeclReference &R) {
344
381
return R == NewResult;
345
382
})) {
@@ -367,36 +404,22 @@ class CursorInfoDoneParsingCallback : public DoneParsingCallback {
367
404
SourceLoc RequestedLoc)
368
405
: DoneParsingCallback(), Consumer(Consumer), RequestedLoc(RequestedLoc) {}
369
406
370
- std::vector<ResolvedCursorInfoPtr>
371
- getDeclResult (NodeFinderDeclResult *DeclResult, SourceFile *SrcFile,
372
- NodeFinder &Finder) const {
373
- typeCheckDeclAndParentClosures (DeclResult->getDecl ());
374
- auto CursorInfo = new ResolvedValueRefCursorInfo (
375
- SrcFile, RequestedLoc, DeclResult->getDecl (),
376
- /* CtorTyRef=*/ nullptr ,
377
- /* ExtTyRef=*/ nullptr , /* IsRef=*/ false , /* Ty=*/ Type (),
378
- /* ContainerType=*/ Type (),
379
- /* CustomAttrRef=*/ std::nullopt,
380
- /* IsKeywordArgument=*/ false ,
381
- /* IsDynamic=*/ false ,
382
- /* ReceiverTypes=*/ {},
383
- Finder.getShorthandShadowedDecls (DeclResult->getDecl ()));
384
- return {CursorInfo};
385
- }
386
-
387
- std::vector<ResolvedCursorInfoPtr>
388
- getExprResult (NodeFinderExprResult *ExprResult, SourceFile *SrcFile,
389
- NodeFinder &Finder) const {
390
- Expr *E = ExprResult->getExpr ();
391
- DeclContext *DC = ExprResult->getDeclContext ();
392
-
407
+ private:
408
+ // / Shared core of `getExprResult` and `getDeclResult`.
409
+ std::vector<ResolvedCursorInfoPtr> getResult (ASTNode Node, DeclContext *DC,
410
+ SourceFile *SrcFile,
411
+ NodeFinder &Finder) const {
393
412
// Type check the statemnt containing E and listen for solutions.
394
413
CursorInfoTypeCheckSolutionCallback Callback (*DC, RequestedLoc);
395
414
{
396
415
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector (
397
416
DC->getASTContext ().SolutionCallback , &Callback);
398
- typeCheckASTNodeAtLoc (TypeCheckASTNodeAtLocContext::declContext (DC),
399
- E->getLoc ());
417
+ if (ValueDecl *VD = getAsDecl<ValueDecl>(Node)) {
418
+ typeCheckDeclAndParentClosures (VD);
419
+ } else {
420
+ typeCheckASTNodeAtLoc (TypeCheckASTNodeAtLocContext::declContext (DC),
421
+ Node.getStartLoc ());
422
+ }
400
423
}
401
424
402
425
if (Callback.getResults ().empty ()) {
@@ -434,7 +457,8 @@ class CursorInfoDoneParsingCallback : public DoneParsingCallback {
434
457
auto CursorInfo = new ResolvedValueRefCursorInfo (
435
458
SrcFile, RequestedLoc, Res.ReferencedDecl ,
436
459
/* CtorTyRef=*/ nullptr ,
437
- /* ExtTyRef=*/ nullptr , /* IsRef=*/ true , /* Ty=*/ Type (),
460
+ /* ExtTyRef=*/ nullptr , /* IsRef=*/ true ,
461
+ Res.SolutionSpecificInterfaceType ,
438
462
/* ContainerType=*/ Res.BaseType ,
439
463
/* CustomAttrRef=*/ std::nullopt,
440
464
/* IsKeywordArgument=*/ false , Res.IsDynamicRef , ReceiverTypes,
@@ -444,6 +468,43 @@ class CursorInfoDoneParsingCallback : public DoneParsingCallback {
444
468
return Results;
445
469
}
446
470
471
+ public:
472
+ std::vector<ResolvedCursorInfoPtr>
473
+ getDeclResult (NodeFinderDeclResult *DeclResult, SourceFile *SrcFile,
474
+ NodeFinder &Finder) const {
475
+ std::vector<ResolvedCursorInfoPtr> Results =
476
+ getResult (DeclResult->getDecl (),
477
+ DeclResult->getDecl ()->getDeclContext (), SrcFile, Finder);
478
+
479
+ if (!Results.empty ()) {
480
+ return Results;
481
+ }
482
+
483
+ // If we didn't get any solution from the constraint system, try getting the
484
+ // type from the decl itself. This may happen if the decl is in an inactive
485
+ // branch of a `#if` clause.
486
+ auto CursorInfo = new ResolvedValueRefCursorInfo (
487
+ SrcFile, RequestedLoc, DeclResult->getDecl (),
488
+ /* CtorTyRef=*/ nullptr ,
489
+ /* ExtTyRef=*/ nullptr ,
490
+ /* IsRef=*/ false ,
491
+ /* SolutionSpecificInterfaceType=*/ Type (),
492
+ /* ContainerType=*/ Type (),
493
+ /* CustomAttrRef=*/ std::nullopt,
494
+ /* IsKeywordArgument=*/ false ,
495
+ /* IsDynamic=*/ false ,
496
+ /* ReceiverTypes=*/ {},
497
+ Finder.getShorthandShadowedDecls (DeclResult->getDecl ()));
498
+ return {CursorInfo};
499
+ }
500
+
501
+ std::vector<ResolvedCursorInfoPtr>
502
+ getExprResult (NodeFinderExprResult *ExprResult, SourceFile *SrcFile,
503
+ NodeFinder &Finder) const {
504
+ return getResult (ExprResult->getExpr (), ExprResult->getDeclContext (),
505
+ SrcFile, Finder);
506
+ }
507
+
447
508
void doneParsing (SourceFile *SrcFile) override {
448
509
if (!SrcFile) {
449
510
return ;
0 commit comments