@@ -2491,126 +2491,139 @@ SwiftLangSupport::findUSRRange(StringRef DocumentName, StringRef USR) {
2491
2491
2492
2492
void SwiftLangSupport::findRelatedIdentifiersInFile (
2493
2493
StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset,
2494
- bool CancelOnSubsequentRequest, ArrayRef<const char *> Args,
2495
- SourceKitCancellationToken CancellationToken,
2496
- std::function<void (const RequestResult<ArrayRef<RelatedIdentInfo>> &)>
2497
- Receiver) {
2494
+ bool IncludeNonEditableBaseNames, bool CancelOnSubsequentRequest,
2495
+ ArrayRef<const char *> Args, SourceKitCancellationToken CancellationToken,
2496
+ std::function<void (const RequestResult<RelatedIdentsResult> &)> Receiver) {
2498
2497
2499
2498
std::string Error;
2500
2499
SwiftInvocationRef Invok =
2501
2500
ASTMgr->getTypecheckInvocation (Args, PrimaryFilePath, Error);
2502
2501
if (!Invok) {
2503
2502
LOG_WARN_FUNC (" failed to create an ASTInvocation: " << Error);
2504
- Receiver (RequestResult<ArrayRef<RelatedIdentInfo> >::fromError (Error));
2503
+ Receiver (RequestResult<RelatedIdentsResult >::fromError (Error));
2505
2504
return ;
2506
2505
}
2507
2506
2508
2507
class RelatedIdConsumer : public SwiftASTConsumer {
2509
2508
std::string InputFile;
2510
2509
unsigned Offset;
2511
- std::function< void ( const RequestResult<ArrayRef<RelatedIdentInfo>> &)>
2512
- Receiver;
2510
+ bool IncludeNonEditableBaseNames;
2511
+ std::function< void ( const RequestResult<RelatedIdentsResult> &)> Receiver;
2513
2512
SwiftInvocationRef Invok;
2514
2513
2514
+ #if SWIFT_BUILD_SWIFT_SYNTAX
2515
+ // FIXME: Don't silently eat errors here.
2516
+ RelatedIdentsResult getRelatedIdents (SourceFile *SrcFile,
2517
+ CompilerInstance &CompInst) {
2518
+ unsigned BufferID = SrcFile->getBufferID ().value ();
2519
+ SourceLoc Loc = Lexer::getLocForStartOfToken (CompInst.getSourceMgr (),
2520
+ BufferID, Offset);
2521
+ if (Loc.isInvalid ())
2522
+ return RelatedIdentsResult::empty ();
2523
+
2524
+ SourceManager &SrcMgr = CompInst.getASTContext ().SourceMgr ;
2525
+
2526
+ ResolvedCursorInfoPtr CursorInfo =
2527
+ evaluateOrDefault (CompInst.getASTContext ().evaluator ,
2528
+ CursorInfoRequest{CursorInfoOwner (SrcFile, Loc)},
2529
+ new ResolvedCursorInfo ());
2530
+ auto ValueRefCursorInfo =
2531
+ dyn_cast<ResolvedValueRefCursorInfo>(CursorInfo);
2532
+ if (!ValueRefCursorInfo)
2533
+ return RelatedIdentsResult::empty ();
2534
+ if (ValueRefCursorInfo->isKeywordArgument ())
2535
+ return RelatedIdentsResult::empty ();
2536
+
2537
+ ValueDecl *VD = ValueRefCursorInfo->typeOrValue ();
2538
+ if (!VD)
2539
+ return RelatedIdentsResult::empty (); // This was a module reference.
2540
+
2541
+ // Only accept pointing to an identifier.
2542
+ if (!IncludeNonEditableBaseNames && !ValueRefCursorInfo->isRef () &&
2543
+ (isa<ConstructorDecl>(VD) || isa<DestructorDecl>(VD) ||
2544
+ isa<SubscriptDecl>(VD)))
2545
+ return RelatedIdentsResult::empty ();
2546
+
2547
+ llvm::Optional<RenameInfo> Info = getRenameInfo (CursorInfo);
2548
+
2549
+ if (!Info) {
2550
+ return RelatedIdentsResult::empty ();
2551
+ }
2552
+
2553
+ RenameLocs Locs = localRenameLocs (SrcFile, Info->VD );
2554
+
2555
+ std::string OldName = Locs.getLocations ().front ().OldName .str ();
2556
+ #ifndef NDEBUG
2557
+ for (auto loc : Locs.getLocations ()) {
2558
+ assert (loc.OldName == OldName &&
2559
+ " Found related identfiers with different names?" );
2560
+ }
2561
+ #endif
2562
+
2563
+ // Ignore any errors produced by `resolveRenameLocations` since, if some
2564
+ // symbol failed to resolve, we still want to return all the other
2565
+ // symbols. This makes related idents more fault-tolerant.
2566
+ DiagnosticEngine Diags (SrcMgr);
2567
+
2568
+ std::vector<ResolvedLoc> ResolvedLocs = resolveRenameLocations (
2569
+ Locs.getLocations (), /* NewName=*/ StringRef (), *SrcFile, Diags);
2570
+
2571
+ SmallVector<RelatedIdentInfo, 8 > Ranges;
2572
+ assert (ResolvedLocs.size () == Locs.getLocations ().size ());
2573
+ for (auto [RenameLoc, ResolvedLoc] :
2574
+ llvm::zip_equal (Locs.getLocations (), ResolvedLocs)) {
2575
+ if (ResolvedLoc.range .isInvalid ()) {
2576
+ continue ;
2577
+ }
2578
+ unsigned Offset =
2579
+ SrcMgr.getLocOffsetInBuffer (ResolvedLoc.range .getStart (), BufferID);
2580
+ Ranges.push_back (
2581
+ {Offset, ResolvedLoc.range .getByteLength (), RenameLoc.Usage });
2582
+ }
2583
+
2584
+ return RelatedIdentsResult (Ranges, OldName);
2585
+ }
2586
+ #endif
2587
+
2515
2588
public:
2516
2589
RelatedIdConsumer (
2517
- StringRef InputFile, unsigned Offset,
2518
- std::function<void (const RequestResult<ArrayRef<RelatedIdentInfo> > &)>
2590
+ StringRef InputFile, unsigned Offset, bool IncludeNonEditableBaseNames,
2591
+ std::function<void (const RequestResult<RelatedIdentsResult > &)>
2519
2592
Receiver,
2520
2593
SwiftInvocationRef Invok)
2521
2594
: InputFile(InputFile.str()), Offset(Offset),
2595
+ IncludeNonEditableBaseNames (IncludeNonEditableBaseNames),
2522
2596
Receiver(std::move(Receiver)), Invok(Invok) {}
2523
2597
2524
- // FIXME: Don't silently eat errors here.
2525
2598
void handlePrimaryAST (ASTUnitRef AstUnit) override {
2526
- using ResultType = RequestResult<ArrayRef<RelatedIdentInfo> >;
2599
+ using ResultType = RequestResult<RelatedIdentsResult >;
2527
2600
#if !SWIFT_BUILD_SWIFT_SYNTAX
2528
- Receiver (
2529
- ResultType::fromError ( " relatedidents is not supported because "
2530
- " sourcekitd was built without swift-syntax" ) );
2601
+ ResultType::fromError (
2602
+ " relatedidents is not supported because sourcekitd was built without "
2603
+ " swift-syntax" );
2531
2604
return ;
2532
2605
#else
2533
2606
auto &CompInst = AstUnit->getCompilerInstance ();
2534
2607
2535
2608
auto *SrcFile = retrieveInputFile (InputFile, CompInst);
2536
2609
if (!SrcFile) {
2537
- Receiver (RequestResult<ArrayRef<RelatedIdentInfo> >::fromError (
2610
+ Receiver (RequestResult<RelatedIdentsResult >::fromError (
2538
2611
" Unable to find input file" ));
2539
2612
return ;
2540
2613
}
2541
2614
2542
- SmallVector<RelatedIdentInfo, 8 > Ranges;
2543
-
2544
- auto Action = [&]() {
2545
- unsigned BufferID = SrcFile->getBufferID ().value ();
2546
- SourceLoc Loc =
2547
- Lexer::getLocForStartOfToken (CompInst.getSourceMgr (), BufferID, Offset);
2548
- if (Loc.isInvalid ())
2549
- return ;
2550
-
2551
- SourceManager &SrcMgr = CompInst.getASTContext ().SourceMgr ;
2552
-
2553
- ResolvedCursorInfoPtr CursorInfo =
2554
- evaluateOrDefault (CompInst.getASTContext ().evaluator ,
2555
- CursorInfoRequest{CursorInfoOwner (SrcFile, Loc)},
2556
- new ResolvedCursorInfo ());
2557
- auto ValueRefCursorInfo =
2558
- dyn_cast<ResolvedValueRefCursorInfo>(CursorInfo);
2559
- if (!ValueRefCursorInfo)
2560
- return ;
2561
- if (ValueRefCursorInfo->isKeywordArgument ())
2562
- return ;
2563
-
2564
- ValueDecl *VD = ValueRefCursorInfo->typeOrValue ();
2565
- if (!VD)
2566
- return ; // This was a module reference.
2567
-
2568
- // Only accept pointing to an identifier.
2569
- if (!ValueRefCursorInfo->isRef () &&
2570
- (isa<ConstructorDecl>(VD) || isa<DestructorDecl>(VD) ||
2571
- isa<SubscriptDecl>(VD)))
2572
- return ;
2573
- if (VD->isOperator ())
2574
- return ;
2575
-
2576
- llvm::Optional<RenameInfo> Info = getRenameInfo (CursorInfo);
2577
-
2578
- if (!Info) {
2579
- return ;
2580
- }
2581
-
2582
- RenameLocs Locs = localRenameLocs (SrcFile, Info->VD );
2583
-
2584
- // Ignore any errors produced by `resolveRenameLocations` since, if some
2585
- // symbol failed to resolve, we still want to return all the other
2586
- // symbols. This makes related idents more fault-tolerant.
2587
- DiagnosticEngine Diags (SrcMgr);
2588
-
2589
- std::vector<ResolvedLoc> ResolvedLocs = resolveRenameLocations (
2590
- Locs.getLocations (), /* NewName=*/ StringRef (), *SrcFile, Diags);
2591
-
2592
- assert (ResolvedLocs.size () == Locs.getLocations ().size ());
2593
- for (auto ResolvedLoc : ResolvedLocs) {
2594
- if (ResolvedLoc.range .isInvalid ()) {
2595
- continue ;
2596
- }
2597
- unsigned Offset = SrcMgr.getLocOffsetInBuffer (
2598
- ResolvedLoc.range .getStart (), BufferID);
2599
- Ranges.push_back ({Offset, ResolvedLoc.range .getByteLength ()});
2600
- }
2601
- };
2602
- Action ();
2603
- Receiver (ResultType::fromResult (Ranges));
2615
+ RelatedIdentsResult Result = getRelatedIdents (SrcFile, CompInst);
2616
+ Receiver (ResultType::fromResult (Result));
2604
2617
#endif
2605
2618
}
2606
2619
2607
2620
void cancelled () override {
2608
- Receiver (RequestResult<ArrayRef<RelatedIdentInfo> >::cancelled ());
2621
+ Receiver (RequestResult<RelatedIdentsResult >::cancelled ());
2609
2622
}
2610
2623
2611
2624
void failed (StringRef Error) override {
2612
2625
LOG_WARN_FUNC (" related idents failed: " << Error);
2613
- Receiver (RequestResult<ArrayRef<RelatedIdentInfo> >::fromError (Error));
2626
+ Receiver (RequestResult<RelatedIdentsResult >::fromError (Error));
2614
2627
}
2615
2628
2616
2629
static CaseStmt *getCaseStmtOfCanonicalVar (Decl *D) {
@@ -2624,8 +2637,8 @@ void SwiftLangSupport::findRelatedIdentifiersInFile(
2624
2637
}
2625
2638
};
2626
2639
2627
- auto Consumer = std::make_shared<RelatedIdConsumer>(InputBufferName, Offset,
2628
- Receiver, Invok);
2640
+ auto Consumer = std::make_shared<RelatedIdConsumer>(
2641
+ InputBufferName, Offset, IncludeNonEditableBaseNames, Receiver, Invok);
2629
2642
// / FIXME: When request cancellation is implemented and Xcode adopts it,
2630
2643
// / don't use 'OncePerASTToken'.
2631
2644
static const char OncePerASTToken = 0 ;
0 commit comments