@@ -625,11 +625,83 @@ static const ValueDecl *getRelatedSystemDecl(const ValueDecl *VD) {
625
625
return nullptr ;
626
626
}
627
627
628
+ // / Stores information about the reference that rename availability is being
629
+ // / queried on.
630
+ struct RenameRefInfo {
631
+ SourceFile *SF; // /< The source file containing the reference.
632
+ SourceLoc Loc; // /< The reference's source location.
633
+ bool IsArgLabel; // /< Whether Loc is on an arg label, rather than base name.
634
+ };
635
+
628
636
struct RenameInfo {
629
637
ValueDecl *VD;
630
- RenameAvailabilityInfo Availability;
638
+ RefactorAvailabilityInfo Availability;
631
639
};
632
640
641
+ static Optional<RefactorAvailabilityInfo>
642
+ renameAvailabilityInfo (const ValueDecl *VD, Optional<RenameRefInfo> RefInfo) {
643
+ RefactorAvailableKind AvailKind = RefactorAvailableKind::Available;
644
+ if (getRelatedSystemDecl (VD)){
645
+ AvailKind = RefactorAvailableKind::Unavailable_system_symbol;
646
+ } else if (VD->getClangDecl ()) {
647
+ AvailKind = RefactorAvailableKind::Unavailable_decl_from_clang;
648
+ } else if (VD->getLoc ().isInvalid ()) {
649
+ AvailKind = RefactorAvailableKind::Unavailable_has_no_location;
650
+ } else if (!VD->hasName ()) {
651
+ AvailKind = RefactorAvailableKind::Unavailable_has_no_name;
652
+ }
653
+
654
+ if (isa<AbstractFunctionDecl>(VD)) {
655
+ // Disallow renaming accessors.
656
+ if (isa<AccessorDecl>(VD))
657
+ return None;
658
+
659
+ // Disallow renaming deinit.
660
+ if (isa<DestructorDecl>(VD))
661
+ return None;
662
+
663
+ // Disallow renaming init with no arguments.
664
+ if (auto CD = dyn_cast<ConstructorDecl>(VD)) {
665
+ if (!CD->getParameters ()->size ())
666
+ return None;
667
+
668
+ if (RefInfo && !RefInfo->IsArgLabel ) {
669
+ NameMatcher Matcher (*(RefInfo->SF ));
670
+ auto Resolved = Matcher.resolve ({RefInfo->Loc , /* ResolveArgs*/ true });
671
+ if (Resolved.LabelRanges .empty ())
672
+ return None;
673
+ }
674
+ }
675
+
676
+ // Disallow renaming 'callAsFunction' method with no arguments.
677
+ if (auto FD = dyn_cast<FuncDecl>(VD)) {
678
+ // FIXME: syntactic rename can only decide by checking the spelling, not
679
+ // whether it's an instance method, so we do the same here for now.
680
+ if (FD->getBaseIdentifier () == FD->getASTContext ().Id_callAsFunction ) {
681
+ if (!FD->getParameters ()->size ())
682
+ return None;
683
+
684
+ if (RefInfo && !RefInfo->IsArgLabel ) {
685
+ NameMatcher Matcher (*(RefInfo->SF ));
686
+ auto Resolved = Matcher.resolve ({RefInfo->Loc , /* ResolveArgs*/ true });
687
+ if (Resolved.LabelRanges .empty ())
688
+ return None;
689
+ }
690
+ }
691
+ }
692
+ }
693
+
694
+ // Always return local rename for parameters.
695
+ // FIXME: if the cursor is on the argument, we should return global rename.
696
+ if (isa<ParamDecl>(VD))
697
+ return RefactorAvailabilityInfo{RefactoringKind::LocalRename, AvailKind};
698
+
699
+ // If the indexer considers VD a global symbol, then we apply global rename.
700
+ if (index::isLocalSymbol (VD))
701
+ return RefactorAvailabilityInfo{RefactoringKind::LocalRename, AvailKind};
702
+ return RefactorAvailabilityInfo{RefactoringKind::GlobalRename, AvailKind};
703
+ }
704
+
633
705
// / Given a cursor, return the decl and its rename availability. \c None if
634
706
// / the cursor did not resolve to a decl or it resolved to a decl that we do
635
707
// / not allow renaming on.
@@ -651,7 +723,7 @@ static Optional<RenameInfo> getRenameInfo(ResolvedCursorInfoPtr cursorInfo) {
651
723
valueCursor->isKeywordArgument ()};
652
724
}
653
725
654
- Optional<RenameAvailabilityInfo > info = renameAvailabilityInfo (VD, refInfo);
726
+ Optional<RefactorAvailabilityInfo > info = renameAvailabilityInfo (VD, refInfo);
655
727
if (!info)
656
728
return None;
657
729
@@ -872,7 +944,7 @@ bool RefactoringActionLocalRename::isApplicable(
872
944
ResolvedCursorInfoPtr CursorInfo, DiagnosticEngine &Diag) {
873
945
Optional<RenameInfo> Info = getRenameInfo (CursorInfo);
874
946
return Info &&
875
- Info->Availability .AvailableKind == RenameAvailableKind ::Available &&
947
+ Info->Availability .AvailableKind == RefactorAvailableKind ::Available &&
876
948
Info->Availability .Kind == RefactoringKind::LocalRename;
877
949
}
878
950
@@ -918,21 +990,21 @@ static Optional<RenameRangeCollector> localRenames(SourceFile *SF,
918
990
}
919
991
920
992
switch (info->Availability .AvailableKind ) {
921
- case RenameAvailableKind ::Available:
993
+ case RefactorAvailableKind ::Available:
922
994
break ;
923
- case RenameAvailableKind ::Unavailable_system_symbol:
995
+ case RefactorAvailableKind ::Unavailable_system_symbol:
924
996
diags.diagnose (startLoc, diag::decl_is_system_symbol, info->VD ->getName ());
925
997
return None;
926
- case RenameAvailableKind ::Unavailable_has_no_location:
998
+ case RefactorAvailableKind ::Unavailable_has_no_location:
927
999
diags.diagnose (startLoc, diag::value_decl_no_loc, info->VD ->getName ());
928
1000
return None;
929
- case RenameAvailableKind ::Unavailable_has_no_name:
1001
+ case RefactorAvailableKind ::Unavailable_has_no_name:
930
1002
diags.diagnose (startLoc, diag::decl_has_no_name);
931
1003
return None;
932
- case RenameAvailableKind ::Unavailable_has_no_accessibility:
1004
+ case RefactorAvailableKind ::Unavailable_has_no_accessibility:
933
1005
diags.diagnose (startLoc, diag::decl_no_accessibility);
934
1006
return None;
935
- case RenameAvailableKind ::Unavailable_decl_from_clang:
1007
+ case RefactorAvailableKind ::Unavailable_decl_from_clang:
936
1008
diags.diagnose (startLoc, diag::decl_from_clang);
937
1009
return None;
938
1010
}
@@ -3028,9 +3100,8 @@ bool RefactoringActionFillProtocolStub::performChange() {
3028
3100
return false ;
3029
3101
}
3030
3102
3031
- static void collectAvailableRefactoringsAtCursor (
3103
+ static SmallVector<RefactorAvailabilityInfo> collectRefactoringsAtCursor (
3032
3104
SourceFile *SF, unsigned Line, unsigned Column,
3033
- SmallVectorImpl<RefactoringKind> &Kinds,
3034
3105
ArrayRef<DiagnosticConsumer *> DiagConsumers) {
3035
3106
// Prepare the tool box.
3036
3107
ASTContext &Ctx = SF->getASTContext ();
@@ -3040,14 +3111,14 @@ static void collectAvailableRefactoringsAtCursor(
3040
3111
[&](DiagnosticConsumer *Con) { DiagEngine.addConsumer (*Con); });
3041
3112
SourceLoc Loc = SM.getLocForLineCol (SF->getBufferID ().value (), Line, Column);
3042
3113
if (Loc.isInvalid ())
3043
- return ;
3114
+ return {} ;
3044
3115
3045
3116
ResolvedCursorInfoPtr Tok =
3046
3117
evaluateOrDefault (SF->getASTContext ().evaluator ,
3047
3118
CursorInfoRequest{CursorInfoOwner (
3048
3119
SF, Lexer::getLocForStartOfToken (SM, Loc))},
3049
3120
new ResolvedCursorInfo ());
3050
- collectAvailableRefactorings (Tok, Kinds, /* Exclude rename */ false );
3121
+ return collectRefactorings (Tok, /* ExcludeRename= */ false );
3051
3122
}
3052
3123
3053
3124
static EnumDecl* getEnumDeclFromSwitchStmt (SwitchStmt *SwitchS) {
@@ -8753,19 +8824,19 @@ getDescriptiveRefactoringKindName(RefactoringKind Kind) {
8753
8824
}
8754
8825
8755
8826
StringRef swift::ide::
8756
- getDescriptiveRenameUnavailableReason (RenameAvailableKind Kind) {
8827
+ getDescriptiveRenameUnavailableReason (RefactorAvailableKind Kind) {
8757
8828
switch (Kind) {
8758
- case RenameAvailableKind ::Available:
8829
+ case RefactorAvailableKind ::Available:
8759
8830
return " " ;
8760
- case RenameAvailableKind ::Unavailable_system_symbol:
8831
+ case RefactorAvailableKind ::Unavailable_system_symbol:
8761
8832
return " symbol from system module cannot be renamed" ;
8762
- case RenameAvailableKind ::Unavailable_has_no_location:
8833
+ case RefactorAvailableKind ::Unavailable_has_no_location:
8763
8834
return " symbol without a declaration location cannot be renamed" ;
8764
- case RenameAvailableKind ::Unavailable_has_no_name:
8835
+ case RefactorAvailableKind ::Unavailable_has_no_name:
8765
8836
return " cannot find the name of the symbol" ;
8766
- case RenameAvailableKind ::Unavailable_has_no_accessibility:
8837
+ case RefactorAvailableKind ::Unavailable_has_no_accessibility:
8767
8838
return " cannot decide the accessibility of the symbol" ;
8768
- case RenameAvailableKind ::Unavailable_decl_from_clang:
8839
+ case RefactorAvailableKind ::Unavailable_decl_from_clang:
8769
8840
return " cannot rename a Clang symbol from its Swift reference" ;
8770
8841
}
8771
8842
llvm_unreachable (" unhandled kind" );
@@ -8838,100 +8909,34 @@ accept(SourceManager &SM, RegionType RegionType,
8838
8909
}
8839
8910
}
8840
8911
8841
- Optional<RenameAvailabilityInfo>
8842
- swift::ide::renameAvailabilityInfo (const ValueDecl *VD,
8843
- Optional<RenameRefInfo> RefInfo) {
8844
- RenameAvailableKind AvailKind = RenameAvailableKind::Available;
8845
- if (getRelatedSystemDecl (VD)){
8846
- AvailKind = RenameAvailableKind::Unavailable_system_symbol;
8847
- } else if (VD->getClangDecl ()) {
8848
- AvailKind = RenameAvailableKind::Unavailable_decl_from_clang;
8849
- } else if (VD->getLoc ().isInvalid ()) {
8850
- AvailKind = RenameAvailableKind::Unavailable_has_no_location;
8851
- } else if (!VD->hasName ()) {
8852
- AvailKind = RenameAvailableKind::Unavailable_has_no_name;
8853
- }
8854
-
8855
- if (isa<AbstractFunctionDecl>(VD)) {
8856
- // Disallow renaming accessors.
8857
- if (isa<AccessorDecl>(VD))
8858
- return None;
8859
-
8860
- // Disallow renaming deinit.
8861
- if (isa<DestructorDecl>(VD))
8862
- return None;
8863
-
8864
- // Disallow renaming init with no arguments.
8865
- if (auto CD = dyn_cast<ConstructorDecl>(VD)) {
8866
- if (!CD->getParameters ()->size ())
8867
- return None;
8868
-
8869
- if (RefInfo && !RefInfo->IsArgLabel ) {
8870
- NameMatcher Matcher (*(RefInfo->SF ));
8871
- auto Resolved = Matcher.resolve ({RefInfo->Loc , /* ResolveArgs*/ true });
8872
- if (Resolved.LabelRanges .empty ())
8873
- return None;
8874
- }
8875
- }
8876
-
8877
- // Disallow renaming 'callAsFunction' method with no arguments.
8878
- if (auto FD = dyn_cast<FuncDecl>(VD)) {
8879
- // FIXME: syntactic rename can only decide by checking the spelling, not
8880
- // whether it's an instance method, so we do the same here for now.
8881
- if (FD->getBaseIdentifier () == FD->getASTContext ().Id_callAsFunction ) {
8882
- if (!FD->getParameters ()->size ())
8883
- return None;
8884
-
8885
- if (RefInfo && !RefInfo->IsArgLabel ) {
8886
- NameMatcher Matcher (*(RefInfo->SF ));
8887
- auto Resolved = Matcher.resolve ({RefInfo->Loc , /* ResolveArgs*/ true });
8888
- if (Resolved.LabelRanges .empty ())
8889
- return None;
8890
- }
8891
- }
8892
- }
8893
- }
8912
+ SmallVector<RefactorAvailabilityInfo> swift::ide::collectRefactorings (
8913
+ ResolvedCursorInfoPtr CursorInfo, bool ExcludeRename) {
8914
+ SmallVector<RefactorAvailabilityInfo, 8 > Infos;
8894
8915
8895
- // Always return local rename for parameters.
8896
- // FIXME: if the cursor is on the argument, we should return global rename.
8897
- if (isa<ParamDecl>(VD))
8898
- return RenameAvailabilityInfo{RefactoringKind::LocalRename, AvailKind};
8899
-
8900
- // If the indexer considers VD a global symbol, then we apply global rename.
8901
- if (index::isLocalSymbol (VD))
8902
- return RenameAvailabilityInfo{RefactoringKind::LocalRename, AvailKind};
8903
- return RenameAvailabilityInfo{RefactoringKind::GlobalRename, AvailKind};
8904
- }
8905
-
8906
- void swift::ide::collectAvailableRefactorings (
8907
- ResolvedCursorInfoPtr CursorInfo, SmallVectorImpl<RefactoringKind> &Kinds,
8908
- bool ExcludeRename) {
8909
8916
DiagnosticEngine DiagEngine (
8910
8917
CursorInfo->getSourceFile ()->getASTContext ().SourceMgr );
8911
8918
8912
8919
if (!ExcludeRename) {
8913
8920
if (auto Info = getRenameInfo (CursorInfo)) {
8914
- if (Info->Availability .AvailableKind == RenameAvailableKind::Available) {
8915
- Kinds.push_back (Info->Availability .Kind );
8916
- }
8921
+ Infos.push_back (std::move (Info->Availability ));
8917
8922
}
8918
8923
}
8919
8924
8920
8925
#define CURSOR_REFACTORING (KIND, NAME, ID ) \
8921
8926
if (RefactoringKind::KIND != RefactoringKind::LocalRename && \
8922
8927
RefactoringAction##KIND::isApplicable (CursorInfo, DiagEngine)) \
8923
- Kinds. push_back (RefactoringKind::KIND);
8928
+ Infos. emplace_back (RefactoringKind::KIND, RefactorAvailableKind::Available );
8924
8929
#include " swift/Refactoring/RefactoringKinds.def"
8930
+
8931
+ return Infos;
8925
8932
}
8926
8933
8927
- void swift::ide::collectAvailableRefactorings (
8934
+ SmallVector<RefactorAvailabilityInfo> swift::ide::collectRefactorings (
8928
8935
SourceFile *SF, RangeConfig Range, bool &CollectRangeStartRefactorings,
8929
- SmallVectorImpl<RefactoringKind> &Kinds,
8930
8936
ArrayRef<DiagnosticConsumer *> DiagConsumers) {
8931
- if (Range.Length == 0 ) {
8932
- return collectAvailableRefactoringsAtCursor (SF, Range.Line , Range.Column ,
8933
- Kinds, DiagConsumers);
8934
- }
8937
+ if (Range.Length == 0 )
8938
+ return collectRefactoringsAtCursor (SF, Range.Line , Range.Column , DiagConsumers);
8939
+
8935
8940
// Prepare the tool box.
8936
8941
ASTContext &Ctx = SF->getASTContext ();
8937
8942
SourceManager &SM = Ctx.SourceMgr ;
@@ -8946,15 +8951,19 @@ void swift::ide::collectAvailableRefactorings(
8946
8951
8947
8952
bool enableInternalRefactoring = getenv (" SWIFT_ENABLE_INTERNAL_REFACTORING_ACTIONS" );
8948
8953
8954
+ SmallVector<RefactorAvailabilityInfo, 8 > Infos;
8955
+
8949
8956
#define RANGE_REFACTORING (KIND, NAME, ID ) \
8950
8957
if (RefactoringAction##KIND::isApplicable (Result, DiagEngine)) \
8951
- Kinds. push_back (RefactoringKind::KIND);
8958
+ Infos. emplace_back (RefactoringKind::KIND, RefactorAvailableKind::Available );
8952
8959
#define INTERNAL_RANGE_REFACTORING (KIND, NAME, ID ) \
8953
8960
if (enableInternalRefactoring) \
8954
8961
RANGE_REFACTORING (KIND, NAME, ID)
8955
8962
#include " swift/Refactoring/RefactoringKinds.def"
8956
8963
8957
8964
CollectRangeStartRefactorings = collectRangeStartRefactorings (Result);
8965
+
8966
+ return Infos;
8958
8967
}
8959
8968
8960
8969
bool swift::ide::
0 commit comments