@@ -316,21 +316,35 @@ class Renamer {
316
316
// FIXME: handle escaped keyword names `init`
317
317
bool IsSubscript = Old.base () == " subscript" && Config.IsFunctionLike ;
318
318
bool IsInit = Old.base () == " init" && Config.IsFunctionLike ;
319
- bool IsKeywordBase = IsInit || IsSubscript;
319
+
320
+ // FIXME: this should only be treated specially for instance methods.
321
+ bool IsCallAsFunction = Old.base () == " callAsFunction" &&
322
+ Config.IsFunctionLike ;
323
+
324
+ bool IsSpecialBase = IsInit || IsSubscript || IsCallAsFunction;
320
325
321
- // Filter out non-semantic keyword basename locations with no labels.
326
+ // Filter out non-semantic special basename locations with no labels.
322
327
// We've already filtered out those in active code, so these are
323
- // any appearance of just 'init' or 'subscript' in strings, comments, and
324
- // inactive code.
325
- if (IsKeywordBase && (Config.Usage == NameUsage::Unknown &&
326
- Resolved.LabelType == LabelRangeType::None))
328
+ // any appearance of just 'init', 'subscript', or 'callAsFunction' in
329
+ // strings, comments, and inactive code.
330
+ if (IsSpecialBase && (Config.Usage == NameUsage::Unknown &&
331
+ Resolved.LabelType == LabelRangeType::None))
327
332
return RegionType::Unmatched;
328
333
329
- if (!Config.IsFunctionLike || !IsKeywordBase ) {
334
+ if (!Config.IsFunctionLike || !IsSpecialBase ) {
330
335
if (renameBase (Resolved.Range , RefactoringRangeKind::BaseName))
331
336
return RegionType::Mismatch;
332
337
333
- } else if (IsKeywordBase && Config.Usage == NameUsage::Definition) {
338
+ } else if (IsInit || IsCallAsFunction) {
339
+ if (renameBase (Resolved.Range , RefactoringRangeKind::KeywordBaseName)) {
340
+ // The base name doesn't need to match (but may) for calls, but
341
+ // it should for definitions and references.
342
+ if (Config.Usage == NameUsage::Definition ||
343
+ Config.Usage == NameUsage::Reference) {
344
+ return RegionType::Mismatch;
345
+ }
346
+ }
347
+ } else if (IsSubscript && Config.Usage == NameUsage::Definition) {
334
348
if (renameBase (Resolved.Range , RefactoringRangeKind::KeywordBaseName))
335
349
return RegionType::Mismatch;
336
350
}
@@ -528,9 +542,11 @@ static const ValueDecl *getRelatedSystemDecl(const ValueDecl *VD) {
528
542
return nullptr ;
529
543
}
530
544
531
- static Optional<RefactoringKind> getAvailableRenameForDecl (const ValueDecl *VD) {
545
+ static Optional<RefactoringKind>
546
+ getAvailableRenameForDecl (const ValueDecl *VD,
547
+ Optional<RenameRefInfo> RefInfo) {
532
548
std::vector<RenameAvailabiliyInfo> Scratch;
533
- for (auto &Info : collectRenameAvailabilityInfo (VD, Scratch)) {
549
+ for (auto &Info : collectRenameAvailabilityInfo (VD, RefInfo, Scratch)) {
534
550
if (Info.AvailableKind == RenameAvailableKind::Available)
535
551
return Info.Kind ;
536
552
}
@@ -744,15 +760,21 @@ bool RefactoringActionLocalRename::
744
760
isApplicable (ResolvedCursorInfo CursorInfo, DiagnosticEngine &Diag) {
745
761
if (CursorInfo.Kind != CursorInfoKind::ValueRef)
746
762
return false ;
747
- auto RenameOp = getAvailableRenameForDecl (CursorInfo.ValueD );
763
+
764
+ Optional<RenameRefInfo> RefInfo;
765
+ if (CursorInfo.IsRef )
766
+ RefInfo = {CursorInfo.SF , CursorInfo.Loc , CursorInfo.IsKeywordArgument };
767
+
768
+ auto RenameOp = getAvailableRenameForDecl (CursorInfo.ValueD , RefInfo);
748
769
return RenameOp.hasValue () &&
749
770
RenameOp.getValue () == RefactoringKind::LocalRename;
750
771
}
751
772
752
- static void analyzeRenameScope (ValueDecl *VD, DiagnosticEngine &Diags,
773
+ static void analyzeRenameScope (ValueDecl *VD, Optional<RenameRefInfo> RefInfo,
774
+ DiagnosticEngine &Diags,
753
775
llvm::SmallVectorImpl<DeclContext *> &Scopes) {
754
776
Scopes.clear ();
755
- if (!getAvailableRenameForDecl (VD).hasValue ()) {
777
+ if (!getAvailableRenameForDecl (VD, RefInfo ).hasValue ()) {
756
778
Diags.diagnose (SourceLoc (), diag::value_decl_no_loc, VD->getFullName ());
757
779
return ;
758
780
}
@@ -786,7 +808,12 @@ bool RefactoringActionLocalRename::performChange() {
786
808
if (CursorInfo.isValid () && CursorInfo.ValueD ) {
787
809
ValueDecl *VD = CursorInfo.CtorTyRef ? CursorInfo.CtorTyRef : CursorInfo.ValueD ;
788
810
llvm::SmallVector<DeclContext *, 8 > Scopes;
789
- analyzeRenameScope (VD, DiagEngine, Scopes);
811
+
812
+ Optional<RenameRefInfo> RefInfo;
813
+ if (CursorInfo.IsRef )
814
+ RefInfo = {CursorInfo.SF , CursorInfo.Loc , CursorInfo.IsKeywordArgument };
815
+
816
+ analyzeRenameScope (VD, RefInfo, DiagEngine, Scopes);
790
817
if (Scopes.empty ())
791
818
return true ;
792
819
RenameRangeCollector rangeCollector (VD, PreferredName);
@@ -3623,9 +3650,11 @@ accept(SourceManager &SM, RegionType RegionType,
3623
3650
Impl.accept (SM, Range);
3624
3651
}
3625
3652
}
3653
+
3626
3654
ArrayRef<RenameAvailabiliyInfo>
3627
3655
swift::ide::collectRenameAvailabilityInfo (const ValueDecl *VD,
3628
- std::vector<RenameAvailabiliyInfo> &Scratch) {
3656
+ Optional<RenameRefInfo> RefInfo,
3657
+ std::vector<RenameAvailabiliyInfo> &Scratch) {
3629
3658
RenameAvailableKind AvailKind = RenameAvailableKind::Available;
3630
3659
if (getRelatedSystemDecl (VD)){
3631
3660
AvailKind = RenameAvailableKind::Unavailable_system_symbol;
@@ -3650,6 +3679,30 @@ swift::ide::collectRenameAvailabilityInfo(const ValueDecl *VD,
3650
3679
if (auto CD = dyn_cast<ConstructorDecl>(VD)) {
3651
3680
if (!CD->getParameters ()->size ())
3652
3681
return Scratch;
3682
+
3683
+ if (RefInfo && !RefInfo->IsArgLabel ) {
3684
+ NameMatcher Matcher (*(RefInfo->SF ));
3685
+ auto Resolved = Matcher.resolve ({RefInfo->Loc , /* ResolveArgs*/ true });
3686
+ if (Resolved.LabelRanges .empty ())
3687
+ return Scratch;
3688
+ }
3689
+ }
3690
+
3691
+ // Disallow renaming 'callAsFunction' method with no arguments.
3692
+ if (auto FD = dyn_cast<FuncDecl>(VD)) {
3693
+ // FIXME: syntactic rename can only decide by checking the spelling, not
3694
+ // whether it's an instance method, so we do the same here for now.
3695
+ if (FD->getBaseIdentifier () == FD->getASTContext ().Id_callAsFunction ) {
3696
+ if (!FD->getParameters ()->size ())
3697
+ return Scratch;
3698
+
3699
+ if (RefInfo && !RefInfo->IsArgLabel ) {
3700
+ NameMatcher Matcher (*(RefInfo->SF ));
3701
+ auto Resolved = Matcher.resolve ({RefInfo->Loc , /* ResolveArgs*/ true });
3702
+ if (Resolved.LabelRanges .empty ())
3703
+ return Scratch;
3704
+ }
3705
+ }
3653
3706
}
3654
3707
}
3655
3708
@@ -3682,7 +3735,10 @@ collectAvailableRefactorings(SourceFile *SF,
3682
3735
case CursorInfoKind::ExprStart:
3683
3736
break ;
3684
3737
case CursorInfoKind::ValueRef: {
3685
- auto RenameOp = getAvailableRenameForDecl (CursorInfo.ValueD );
3738
+ Optional<RenameRefInfo> RefInfo;
3739
+ if (CursorInfo.IsRef )
3740
+ RefInfo = {CursorInfo.SF , CursorInfo.Loc , CursorInfo.IsKeywordArgument };
3741
+ auto RenameOp = getAvailableRenameForDecl (CursorInfo.ValueD , RefInfo);
3686
3742
if (RenameOp.hasValue () &&
3687
3743
RenameOp.getValue () == RefactoringKind::GlobalRename)
3688
3744
AllKinds.push_back (RenameOp.getValue ());
@@ -3919,8 +3975,12 @@ int swift::ide::findLocalRenameRanges(
3919
3975
return true ;
3920
3976
}
3921
3977
ValueDecl *VD = CursorInfo.CtorTyRef ? CursorInfo.CtorTyRef : CursorInfo.ValueD ;
3978
+ Optional<RenameRefInfo> RefInfo;
3979
+ if (CursorInfo.IsRef )
3980
+ RefInfo = {CursorInfo.SF , CursorInfo.Loc , CursorInfo.IsKeywordArgument };
3981
+
3922
3982
llvm::SmallVector<DeclContext *, 8 > Scopes;
3923
- analyzeRenameScope (VD, Diags, Scopes);
3983
+ analyzeRenameScope (VD, RefInfo, Diags, Scopes);
3924
3984
if (Scopes.empty ())
3925
3985
return true ;
3926
3986
RenameRangeCollector RangeCollector (VD, StringRef ());
0 commit comments