Skip to content

[refactoring] Avoid producing empty string/comment categorized edit ranges when renaming init. Also disallow renaming inits with no arguments. #14980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion lib/IDE/Refactoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,14 @@ class Renamer {
bool IsSubscript = Old.base() == "subscript" && Config.IsFunctionLike;
bool IsInit = Old.base() == "init" && Config.IsFunctionLike;
bool IsKeywordBase = IsInit || IsSubscript;

// Filter out non-semantic keyword basename locations with no labels.
// We've already filtered out those in active code, so these are
// any appearance of just 'init' or 'subscript' in strings, comments, and
// inactive code.
if (IsKeywordBase && (Config.Usage == NameUsage::Unknown &&
Resolved.LabelType == LabelRangeType::None))
return RegionType::Unmatched;

if (!Config.IsFunctionLike || !IsKeywordBase) {
if (renameBase(Resolved.Range, RefactoringRangeKind::BaseName))
Expand Down Expand Up @@ -352,7 +360,8 @@ class Renamer {
Resolved.LabelType == LabelRangeType::CallArg;

if (renameLabels(Resolved.LabelRanges, Resolved.LabelType, isCallSite))
return RegionType::Mismatch;
return Config.Usage == NameUsage::Unknown ?
RegionType::Unmatched : RegionType::Mismatch;
}

return RegionKind;
Expand Down Expand Up @@ -2892,6 +2901,8 @@ swift::ide::FindRenameRangesAnnotatingConsumer::~FindRenameRangesAnnotatingConsu
void swift::ide::FindRenameRangesAnnotatingConsumer::
accept(SourceManager &SM, RegionType RegionType,
ArrayRef<RenameRangeDetail> Ranges) {
if (RegionType == RegionType::Mismatch || RegionType == RegionType::Unmatched)
return;
for (const auto &Range : Ranges) {
Impl.accept(SM, Range);
}
Expand Down Expand Up @@ -2920,6 +2931,12 @@ swift::ide::collectRenameAvailabilityInfo(const ValueDecl *VD,
// Disallow renaming deinit.
if (isa<DestructorDecl>(VD))
return Scratch;

// Disallow renaming init with no arguments.
if (auto CD = dyn_cast<ConstructorDecl>(VD)) {
if (!CD->getParameters()->size())
return Scratch;
}
}

// Always return local rename for parameters.
Expand Down
4 changes: 4 additions & 0 deletions lib/IDE/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,10 @@ swift::ide::SourceEditOutputConsumer::~SourceEditOutputConsumer() { delete &Impl
void swift::ide::SourceEditOutputConsumer::
accept(SourceManager &SM, RegionType RegionType,
ArrayRef<Replacement> Replacements) {
// ignore mismatched or
if (RegionType == RegionType::Unmatched || RegionType == RegionType::Mismatch)
return;

for (const auto &Replacement : Replacements) {
Impl.accept(SM, Replacement.Range, Replacement.Text);
}
Expand Down
8 changes: 8 additions & 0 deletions test/SourceKit/CursorInfo/cursor_rename.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
class Foo {
func foo() -> Int { return foo() }
init() {}
init(_ a: Int) {}
}
_ = Foo.init()
_ = Foo.init(2)

// RUN: %sourcekitd-test -req=cursor -pos=1:9 -cursor-action %s -- %s | %FileCheck -check-prefix=CHECK1 %s
// RUN: %sourcekitd-test -req=cursor -pos=2:9 %s -- %s | %FileCheck -check-prefix=CHECK2 %s
// RUN: %sourcekitd-test -req=cursor -pos=2:32 -cursor-action %s -- %s | %FileCheck -check-prefix=CHECK1 %s
// RUN: %sourcekitd-test -req=cursor -pos=2:18 %s -- %s | %FileCheck -check-prefix=CHECK2 %s
// RUN: %sourcekitd-test -req=cursor -pos=3:3 -cursor-action %s -- %s | %FileCheck -check-prefix=CHECK2 %s
// RUN: %sourcekitd-test -req=cursor -pos=4:3 -cursor-action %s -- %s | %FileCheck -check-prefix=CHECK1 %s
// RUN: %sourcekitd-test -req=cursor -pos=6:9 -cursor-action %s -- %s | %FileCheck -check-prefix=CHECK2 %s
// RUN: %sourcekitd-test -req=cursor -pos=7:9 -cursor-action %s -- %s | %FileCheck -check-prefix=CHECK1 %s

// CHECK1: Rename
// CHECK2-NOT: Rename
Expand Down
21 changes: 21 additions & 0 deletions test/SourceKit/Refactoring/find-rename-ranges/keywordbase.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
source.edit.kind.active:
95:17-95:18 source.refactoring.range.kind.call-argument-label arg-index=0
95:18-95:20 source.refactoring.range.kind.call-argument-colon arg-index=0
source.edit.kind.active:
96:22-96:23 source.refactoring.range.kind.call-argument-label arg-index=0
96:23-96:25 source.refactoring.range.kind.call-argument-colon arg-index=0
source.edit.kind.unknown:
source.edit.kind.active:
97:37-97:38 source.refactoring.range.kind.call-argument-label arg-index=0
97:38-97:40 source.refactoring.range.kind.call-argument-colon arg-index=0
source.edit.kind.active:
97:59-97:60 source.refactoring.range.kind.call-argument-label arg-index=0
97:60-97:62 source.refactoring.range.kind.call-argument-colon arg-index=0
source.edit.kind.unknown:
source.edit.kind.unknown:
source.edit.kind.unknown:
source.edit.kind.unknown:
source.edit.kind.inactive:
103:22-103:23 source.refactoring.range.kind.call-argument-label arg-index=0
103:23-103:25 source.refactoring.range.kind.call-argument-colon arg-index=0
source.edit.kind.unknown:
16 changes: 16 additions & 0 deletions test/SourceKit/Refactoring/syntactic-rename.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ func genfoo<T: P, U, V where U: P>(x: T, y: U, z: V, a: P) -> P where V: P {
fatalError()
}

_ = Memberwise1(x: 2)
_ = Memberwise1.init(x: 2)
_ = Memberwise2.init(m: Memberwise1(x: 2), n: Memberwise1(x: 34))
_ = " this init is init "
// this init is init too

#if NOTDEFINED
_ = Memberwise1(x: 2)
_ = Memberwise1.init(x: 2)
_ = Memberwise2.init(m: 2, n: Memberwise1(x: 34))
#endif

// RUN: rm -rf %t.result && mkdir -p %t.result
// RUN: %sourcekitd-test -req=syntactic-rename -rename-spec %S/syntactic-rename/x.in.json %s >> %t.result/x.expected
// RUN: diff -u %S/syntactic-rename/x.expected %t.result/x.expected
Expand All @@ -116,6 +128,8 @@ func genfoo<T: P, U, V where U: P>(x: T, y: U, z: V, a: P) -> P where V: P {
// RUN: diff -u %S/syntactic-rename/rename-layer.expected %t.result/rename-layer.expected
// RUN: %sourcekitd-test -req=syntactic-rename -rename-spec %S/syntactic-rename/rename-P.in.json %s -- -swift-version 3 >> %t.result/rename-P.expected
// RUN: diff -u %S/syntactic-rename/rename-P.expected %t.result/rename-P.expected
// RUN: %sourcekitd-test -req=syntactic-rename -rename-spec %S/syntactic-rename/keywordbase.in.json %s -- -swift-version 3 >> %t.result/keywordbase.expected
// RUN: diff -u %S/syntactic-rename/keywordbase.expected %t.result/keywordbase.expected

// RUN: rm -rf %t.ranges && mkdir -p %t.ranges
// RUN: %sourcekitd-test -req=find-rename-ranges -rename-spec %S/syntactic-rename/x.in.json %s >> %t.ranges/x.expected
Expand All @@ -138,3 +152,5 @@ func genfoo<T: P, U, V where U: P>(x: T, y: U, z: V, a: P) -> P where V: P {
// RUN: diff -u %S/find-rename-ranges/rename-layer.expected %t.ranges/rename-layer.expected
// RUN: %sourcekitd-test -req=find-rename-ranges -rename-spec %S/syntactic-rename/rename-P.in.json %s -- -swift-version 3 >> %t.ranges/rename-P.expected
// RUN: diff -u %S/find-rename-ranges/rename-P.expected %t.ranges/rename-P.expected
// RUN: %sourcekitd-test -req=find-rename-ranges -rename-spec %S/syntactic-rename/keywordbase.in.json %s -- -swift-version 3 >> %t.ranges/keywordbase.expected
// RUN: diff -u %S/find-rename-ranges/keywordbase.expected %t.ranges/keywordbase.expected
16 changes: 16 additions & 0 deletions test/SourceKit/Refactoring/syntactic-rename/keywordbase.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
source.edit.kind.active:
95:17-95:18 "y"
source.edit.kind.active:
96:22-96:23 "y"
source.edit.kind.unknown:
source.edit.kind.active:
97:37-97:38 "y"
source.edit.kind.active:
97:59-97:60 "y"
source.edit.kind.unknown:
source.edit.kind.unknown:
source.edit.kind.unknown:
source.edit.kind.unknown:
source.edit.kind.inactive:
103:22-103:23 "y"
source.edit.kind.unknown:
65 changes: 65 additions & 0 deletions test/SourceKit/Refactoring/syntactic-rename/keywordbase.in.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
[
{
"key.name": "init(x:)",
"key.newname": "init(y:)",
"key.is_function_like": 1,
"key.is_non_protocol_type": 0,
"key.locations": [
{
"key.line": 95,
"key.column": 5,
"key.nametype": source.syntacticrename.call
},
{
"key.line": 96,
"key.column": 17,
"key.nametype": source.syntacticrename.call
},
{
"key.line": 97,
"key.column": 17,
"key.nametype": source.syntacticrename.unknown
},
{
"key.line": 97,
"key.column": 25,
"key.nametype": source.syntacticrename.call
},
{
"key.line": 97,
"key.column": 47,
"key.nametype": source.syntacticrename.call
},
{
"key.line": 98,
"key.column": 13,
"key.nametype": source.syntacticrename.unknown
},
{
"key.line": 98,
"key.column": 21,
"key.nametype": source.syntacticrename.unknown
},
{
"key.line": 99,
"key.column": 9,
"key.nametype": source.syntacticrename.unknown
},
{
"key.line": 99,
"key.column": 17,
"key.nametype": source.syntacticrename.unknown
},
{
"key.line": 103,
"key.column": 17,
"key.nametype": source.syntacticrename.unknown
},
{
"key.line": 104,
"key.column": 17,
"key.nametype": source.syntacticrename.unknown
}
]
}
]