@@ -616,29 +616,54 @@ static const ValueDecl *getRelatedSystemDecl(const ValueDecl *VD) {
616616 return nullptr ;
617617}
618618
619- static Optional<RefactoringKind>
620- getAvailableRenameForDecl (const ValueDecl *VD,
621- Optional<RenameRefInfo> RefInfo) {
622- SmallVector<RenameAvailabilityInfo, 2 > Infos;
623- collectRenameAvailabilityInfo (VD, RefInfo, Infos);
624- for (auto &Info : Infos) {
625- if (Info.AvailableKind == RenameAvailableKind::Available)
626- return Info.Kind ;
619+ struct RenameInfo {
620+ ValueDecl *VD;
621+ RenameAvailabilityInfo Availability;
622+ };
623+
624+ // / Given a cursor, return the decl and its rename availability. \c None if
625+ // / the cursor did not resolve to a decl or it resolved to a decl that we do
626+ // / not allow renaming on.
627+ static Optional<RenameInfo> getRenameInfo (ResolvedCursorInfoPtr cursorInfo) {
628+ auto valueCursor = dyn_cast<ResolvedValueRefCursorInfo>(cursorInfo);
629+ if (!valueCursor)
630+ return None;
631+
632+ ValueDecl *VD = valueCursor->typeOrValue ();
633+ if (!VD)
634+ return None;
635+
636+ Optional<RenameRefInfo> refInfo;
637+ if (!valueCursor->getShorthandShadowedDecls ().empty ()) {
638+ // Find the outermost decl for a shorthand if let/closure capture
639+ VD = valueCursor->getShorthandShadowedDecls ().back ();
640+ } else if (valueCursor->isRef ()) {
641+ refInfo = {valueCursor->getSourceFile (), valueCursor->getLoc (),
642+ valueCursor->isKeywordArgument ()};
627643 }
628- return None;
644+
645+ Optional<RenameAvailabilityInfo> info = renameAvailabilityInfo (VD, refInfo);
646+ if (!info)
647+ return None;
648+
649+ return RenameInfo{VD, *info};
629650}
630651
631652class RenameRangeCollector : public IndexDataConsumer {
632653public:
633654 RenameRangeCollector (StringRef USR, StringRef newName)
634- : USR(USR.str()) , newName(newName.str() ) {}
655+ : USR(USR) , newName(newName) {}
635656
636657 RenameRangeCollector (const ValueDecl *D, StringRef newName)
637- : newName(newName.str()) {
638- llvm::raw_string_ostream OS (USR);
658+ : newName(newName) {
659+ SmallString<64 > SS;
660+ llvm::raw_svector_ostream OS (SS);
639661 printValueDeclUSR (D, OS);
662+ USR = stringStorage.copyString (SS.str ());
640663 }
641664
665+ RenameRangeCollector (RenameRangeCollector &&collector) = default ;
666+
642667 ArrayRef<RenameLoc> results () const { return locations; }
643668
644669private:
@@ -680,8 +705,8 @@ class RenameRangeCollector : public IndexDataConsumer {
680705 StringRef NewName);
681706
682707private:
683- std::string USR;
684- std::string newName;
708+ StringRef USR;
709+ StringRef newName;
685710 StringScratchSpace stringStorage;
686711 std::vector<RenameLoc> locations;
687712};
@@ -836,29 +861,14 @@ class RefactoringAction##KIND: public RangeBasedRefactoringAction { \
836861
837862bool RefactoringActionLocalRename::isApplicable (
838863 ResolvedCursorInfoPtr CursorInfo, DiagnosticEngine &Diag) {
839- auto ValueRefInfo = dyn_cast<ResolvedValueRefCursorInfo>(CursorInfo);
840- if (!ValueRefInfo)
841- return false ;
842-
843- Optional<RenameRefInfo> RefInfo;
844- if (ValueRefInfo->isRef ())
845- RefInfo = {CursorInfo->getSourceFile (), CursorInfo->getLoc (),
846- ValueRefInfo->isKeywordArgument ()};
847-
848- auto RenameOp = getAvailableRenameForDecl (ValueRefInfo->getValueD (), RefInfo);
849- return RenameOp.has_value () &&
850- RenameOp.value () == RefactoringKind::LocalRename;
864+ Optional<RenameInfo> Info = getRenameInfo (CursorInfo);
865+ return Info &&
866+ Info->Availability .AvailableKind == RenameAvailableKind::Available &&
867+ Info->Availability .Kind == RefactoringKind::LocalRename;
851868}
852869
853- static void analyzeRenameScope (ValueDecl *VD, Optional<RenameRefInfo> RefInfo,
854- DiagnosticEngine &Diags,
870+ static void analyzeRenameScope (ValueDecl *VD,
855871 SmallVectorImpl<DeclContext *> &Scopes) {
856- Scopes.clear ();
857- if (!getAvailableRenameForDecl (VD, RefInfo).has_value ()) {
858- Diags.diagnose (SourceLoc (), diag::value_decl_no_loc, VD->getName ());
859- return ;
860- }
861-
862872 auto *Scope = VD->getDeclContext ();
863873 // There may be sibling decls that the renamed symbol is visible from.
864874 switch (Scope->getContextKind ()) {
@@ -883,6 +893,53 @@ static void analyzeRenameScope(ValueDecl *VD, Optional<RenameRefInfo> RefInfo,
883893 Scopes.push_back (Scope);
884894}
885895
896+ static Optional<RenameRangeCollector> localRenames (SourceFile *SF,
897+ SourceLoc startLoc,
898+ StringRef preferredName,
899+ DiagnosticEngine &diags) {
900+ auto cursorInfo =
901+ evaluateOrDefault (SF->getASTContext ().evaluator ,
902+ CursorInfoRequest{CursorInfoOwner (SF, startLoc)},
903+ new ResolvedCursorInfo ());
904+
905+ Optional<RenameInfo> info = getRenameInfo (cursorInfo);
906+ if (!info) {
907+ diags.diagnose (startLoc, diag::unresolved_location);
908+ return None;
909+ }
910+
911+ switch (info->Availability .AvailableKind ) {
912+ case RenameAvailableKind::Available:
913+ break ;
914+ case RenameAvailableKind::Unavailable_system_symbol:
915+ diags.diagnose (startLoc, diag::decl_is_system_symbol, info->VD ->getName ());
916+ return None;
917+ case RenameAvailableKind::Unavailable_has_no_location:
918+ diags.diagnose (startLoc, diag::value_decl_no_loc, info->VD ->getName ());
919+ return None;
920+ case RenameAvailableKind::Unavailable_has_no_name:
921+ diags.diagnose (startLoc, diag::decl_has_no_name);
922+ return None;
923+ case RenameAvailableKind::Unavailable_has_no_accessibility:
924+ diags.diagnose (startLoc, diag::decl_no_accessibility);
925+ return None;
926+ case RenameAvailableKind::Unavailable_decl_from_clang:
927+ diags.diagnose (startLoc, diag::decl_from_clang);
928+ return None;
929+ }
930+
931+ SmallVector<DeclContext *, 8 > scopes;
932+ analyzeRenameScope (info->VD , scopes);
933+ if (scopes.empty ())
934+ return None;
935+
936+ RenameRangeCollector rangeCollector (info->VD , preferredName);
937+ for (DeclContext *DC : scopes)
938+ indexDeclContext (DC, rangeCollector);
939+
940+ return rangeCollector;
941+ }
942+
886943bool RefactoringActionLocalRename::performChange () {
887944 if (StartLoc.isInvalid ()) {
888945 DiagEngine.diagnose (SourceLoc (), diag::invalid_location);
@@ -897,40 +954,16 @@ bool RefactoringActionLocalRename::performChange() {
897954 MD->getNameStr ());
898955 return true ;
899956 }
900- CursorInfo =
901- evaluateOrDefault (TheFile->getASTContext ().evaluator ,
902- CursorInfoRequest{CursorInfoOwner (TheFile, StartLoc)},
903- new ResolvedCursorInfo ());
904- auto ValueRefCursorInfo = dyn_cast<ResolvedValueRefCursorInfo>(CursorInfo);
905- if (ValueRefCursorInfo && ValueRefCursorInfo->getValueD ()) {
906- ValueDecl *VD = ValueRefCursorInfo->typeOrValue ();
907- // The index always uses the outermost shadow for references
908- if (!ValueRefCursorInfo->getShorthandShadowedDecls ().empty ()) {
909- VD = ValueRefCursorInfo->getShorthandShadowedDecls ().back ();
910- }
911-
912- SmallVector<DeclContext *, 8 > Scopes;
913-
914- Optional<RenameRefInfo> RefInfo;
915- if (ValueRefCursorInfo->isRef ())
916- RefInfo = {CursorInfo->getSourceFile (), CursorInfo->getLoc (),
917- ValueRefCursorInfo->isKeywordArgument ()};
918957
919- analyzeRenameScope (VD, RefInfo, DiagEngine, Scopes);
920- if (Scopes.empty ())
921- return true ;
922- RenameRangeCollector rangeCollector (VD, PreferredName);
923- for (DeclContext *DC : Scopes)
924- indexDeclContext (DC, rangeCollector);
925-
926- auto consumers = DiagEngine.takeConsumers ();
927- assert (consumers.size () == 1 );
928- return syntacticRename (TheFile, rangeCollector.results (), EditConsumer,
929- *consumers[0 ]);
930- } else {
931- DiagEngine.diagnose (StartLoc, diag::unresolved_location);
958+ Optional<RenameRangeCollector> rangeCollector =
959+ localRenames (TheFile, StartLoc, PreferredName, DiagEngine);
960+ if (!rangeCollector)
932961 return true ;
933- }
962+
963+ auto consumers = DiagEngine.takeConsumers ();
964+ assert (consumers.size () == 1 );
965+ return syntacticRename (TheFile, rangeCollector->results (), EditConsumer,
966+ *consumers[0 ]);
934967}
935968
936969StringRef getDefaultPreferredName (RefactoringKind Kind) {
@@ -8783,9 +8816,9 @@ accept(SourceManager &SM, RegionType RegionType,
87838816 }
87848817}
87858818
8786- void swift::ide::collectRenameAvailabilityInfo (
8787- const ValueDecl *VD, Optional<RenameRefInfo> RefInfo ,
8788- SmallVectorImpl<RenameAvailabilityInfo> &Infos ) {
8819+ Optional<RenameAvailabilityInfo>
8820+ swift::ide::renameAvailabilityInfo ( const ValueDecl *VD,
8821+ Optional<RenameRefInfo> RefInfo ) {
87898822 RenameAvailableKind AvailKind = RenameAvailableKind::Available;
87908823 if (getRelatedSystemDecl (VD)){
87918824 AvailKind = RenameAvailableKind::Unavailable_system_symbol;
@@ -8800,22 +8833,22 @@ void swift::ide::collectRenameAvailabilityInfo(
88008833 if (isa<AbstractFunctionDecl>(VD)) {
88018834 // Disallow renaming accessors.
88028835 if (isa<AccessorDecl>(VD))
8803- return ;
8836+ return None ;
88048837
88058838 // Disallow renaming deinit.
88068839 if (isa<DestructorDecl>(VD))
8807- return ;
8840+ return None ;
88088841
88098842 // Disallow renaming init with no arguments.
88108843 if (auto CD = dyn_cast<ConstructorDecl>(VD)) {
88118844 if (!CD->getParameters ()->size ())
8812- return ;
8845+ return None ;
88138846
88148847 if (RefInfo && !RefInfo->IsArgLabel ) {
88158848 NameMatcher Matcher (*(RefInfo->SF ));
88168849 auto Resolved = Matcher.resolve ({RefInfo->Loc , /* ResolveArgs*/ true });
88178850 if (Resolved.LabelRanges .empty ())
8818- return ;
8851+ return None ;
88198852 }
88208853 }
88218854
@@ -8825,30 +8858,27 @@ void swift::ide::collectRenameAvailabilityInfo(
88258858 // whether it's an instance method, so we do the same here for now.
88268859 if (FD->getBaseIdentifier () == FD->getASTContext ().Id_callAsFunction ) {
88278860 if (!FD->getParameters ()->size ())
8828- return ;
8861+ return None ;
88298862
88308863 if (RefInfo && !RefInfo->IsArgLabel ) {
88318864 NameMatcher Matcher (*(RefInfo->SF ));
88328865 auto Resolved = Matcher.resolve ({RefInfo->Loc , /* ResolveArgs*/ true });
88338866 if (Resolved.LabelRanges .empty ())
8834- return ;
8867+ return None ;
88358868 }
88368869 }
88378870 }
88388871 }
88398872
88408873 // Always return local rename for parameters.
88418874 // FIXME: if the cursor is on the argument, we should return global rename.
8842- if (isa<ParamDecl>(VD)) {
8843- Infos.emplace_back (RefactoringKind::LocalRename, AvailKind);
8844- return ;
8845- }
8875+ if (isa<ParamDecl>(VD))
8876+ return RenameAvailabilityInfo{RefactoringKind::LocalRename, AvailKind};
88468877
88478878 // If the indexer considers VD a global symbol, then we apply global rename.
88488879 if (index::isLocalSymbol (VD))
8849- Infos.emplace_back (RefactoringKind::LocalRename, AvailKind);
8850- else
8851- Infos.emplace_back (RefactoringKind::GlobalRename, AvailKind);
8880+ return RenameAvailabilityInfo{RefactoringKind::LocalRename, AvailKind};
8881+ return RenameAvailabilityInfo{RefactoringKind::GlobalRename, AvailKind};
88528882}
88538883
88548884void swift::ide::collectAvailableRefactorings (
@@ -8858,27 +8888,10 @@ void swift::ide::collectAvailableRefactorings(
88588888 CursorInfo->getSourceFile ()->getASTContext ().SourceMgr );
88598889
88608890 if (!ExcludeRename) {
8861- if (RefactoringActionLocalRename::isApplicable (CursorInfo, DiagEngine))
8862- Kinds.push_back (RefactoringKind::LocalRename);
8863-
8864- switch (CursorInfo->getKind ()) {
8865- case CursorInfoKind::ModuleRef:
8866- case CursorInfoKind::Invalid:
8867- case CursorInfoKind::StmtStart:
8868- case CursorInfoKind::ExprStart:
8869- break ;
8870- case CursorInfoKind::ValueRef: {
8871- auto ValueRefInfo = cast<ResolvedValueRefCursorInfo>(CursorInfo);
8872- Optional<RenameRefInfo> RefInfo;
8873- if (ValueRefInfo->isRef ())
8874- RefInfo = {CursorInfo->getSourceFile (), CursorInfo->getLoc (),
8875- ValueRefInfo->isKeywordArgument ()};
8876- auto RenameOp =
8877- getAvailableRenameForDecl (ValueRefInfo->getValueD (), RefInfo);
8878- if (RenameOp.has_value () &&
8879- RenameOp.value () == RefactoringKind::GlobalRename)
8880- Kinds.push_back (RenameOp.value ());
8881- }
8891+ if (auto Info = getRenameInfo (CursorInfo)) {
8892+ if (Info->Availability .AvailableKind == RenameAvailableKind::Available) {
8893+ Kinds.push_back (Info->Availability .Kind );
8894+ }
88828895 }
88838896 }
88848897
@@ -9084,29 +9097,11 @@ int swift::ide::findLocalRenameRanges(
90849097 Diags.addConsumer (DiagConsumer);
90859098
90869099 auto StartLoc = Lexer::getLocForStartOfToken (SM, Range.getStart (SM));
9087- ResolvedCursorInfoPtr CursorInfo =
9088- evaluateOrDefault (SF->getASTContext ().evaluator ,
9089- CursorInfoRequest{CursorInfoOwner (SF, StartLoc)},
9090- new ResolvedCursorInfo ());
9091- auto ValueRefCursorInfo = dyn_cast<ResolvedValueRefCursorInfo>(CursorInfo);
9092- if (!ValueRefCursorInfo || !ValueRefCursorInfo->getValueD ()) {
9093- Diags.diagnose (StartLoc, diag::unresolved_location);
9094- return true ;
9095- }
9096- ValueDecl *VD = ValueRefCursorInfo->typeOrValue ();
9097- Optional<RenameRefInfo> RefInfo;
9098- if (ValueRefCursorInfo->isRef ())
9099- RefInfo = {CursorInfo->getSourceFile (), CursorInfo->getLoc (),
9100- ValueRefCursorInfo->isKeywordArgument ()};
9101-
9102- llvm::SmallVector<DeclContext *, 8 > Scopes;
9103- analyzeRenameScope (VD, RefInfo, Diags, Scopes);
9104- if (Scopes.empty ())
9100+ Optional<RenameRangeCollector> RangeCollector =
9101+ localRenames (SF, StartLoc, StringRef (), Diags);
9102+ if (!RangeCollector)
91059103 return true ;
9106- RenameRangeCollector RangeCollector (VD, StringRef ());
9107- for (DeclContext *DC : Scopes)
9108- indexDeclContext (DC, RangeCollector);
91099104
9110- return findSyntacticRenameRanges (SF, RangeCollector. results (), RenameConsumer ,
9111- DiagConsumer);
9105+ return findSyntacticRenameRanges (SF, RangeCollector-> results (),
9106+ RenameConsumer, DiagConsumer);
91129107}
0 commit comments