Skip to content

Commit ebfb3a5

Browse files
authored
Merge pull request #38331 from ahoppen/pr/rename-captured-variables-once
[Refactoring] Only rename variables in capture lists once
2 parents b7633a1 + a535203 commit ebfb3a5

13 files changed

+163
-1
lines changed

lib/IDE/Refactoring.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,22 @@ class RenameRangeCollector : public IndexDataConsumer {
654654
Action startSourceEntity(const IndexSymbol &symbol) override {
655655
if (symbol.USR == USR) {
656656
if (auto loc = indexSymbolToRenameLoc(symbol, newName)) {
657-
locations.push_back(std::move(*loc));
657+
// Inside capture lists like `{ [test] in }`, 'test' refers to both the
658+
// newly declared, captured variable and the referenced variable it is
659+
// initialized from. Make sure to only rename it once.
660+
auto existingLoc = llvm::find_if(locations, [&](RenameLoc searchLoc) {
661+
return searchLoc.Line == loc->Line && searchLoc.Column == loc->Column;
662+
});
663+
if (existingLoc == locations.end()) {
664+
locations.push_back(std::move(*loc));
665+
} else {
666+
assert(existingLoc->OldName == loc->OldName &&
667+
existingLoc->NewName == loc->NewName &&
668+
existingLoc->IsFunctionLike == loc->IsFunctionLike &&
669+
existingLoc->IsNonProtocolType ==
670+
existingLoc->IsNonProtocolType &&
671+
"Asked to do a different rename for the same location?");
672+
}
658673
}
659674
}
660675
return IndexDataConsumer::Continue;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
func test1() {
2+
if true {
3+
let x = 1
4+
print(x)
5+
} else {
6+
let x = 2
7+
print(x)
8+
}
9+
}
10+
11+
func test2(arg1: Int?, arg2: (Int, String)?) {
12+
if let x = arg1 {
13+
print(x)
14+
} else if let (x, y) = arg2 {
15+
print(x, y)
16+
}
17+
}
18+
19+
func test3(arg: Int?) {
20+
switch arg {
21+
case let .some(x) where x == 0:
22+
print(x)
23+
case let .some(x) where x == 1,
24+
let .some(x) where x == 2:
25+
print(x)
26+
fallthrough
27+
case let .some(x) where x == 3:
28+
print(x)
29+
default:
30+
break
31+
}
32+
}
33+
34+
struct Err1 : Error { }
35+
func test4(arg: () throws -> Void) {
36+
do {
37+
try arg()
38+
} catch let x as Err1 {
39+
print(x)
40+
} catch let x {
41+
print(x)
42+
}
43+
}
44+
45+
func test5(_ x: Int) {
46+
let x = x
47+
print(x)
48+
}
49+
50+
func testCaputreVariable() {
51+
let capturedVariableRenamed = 0
52+
53+
_ = { [capturedVariableRenamed] in
54+
print(capturedVariableRenamed)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/casebind_1.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/casebind_2.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/catch_1.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/catch_2.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/ifbind_1.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/ifbind_2.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/localvar_1.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/localvar_2.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/param_1.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ xRenamed: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/Outputs/local/param_2.swift.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ func test5(_ x: Int) {
4747
print(xRenamed)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+

test/refactoring/rename/local.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ func test5(_ x: Int) {
4747
print(x)
4848
}
4949

50+
func testCaputreVariable() {
51+
let capturedVariable = 0
52+
53+
_ = { [capturedVariable] in
54+
print(capturedVariable)
55+
}
56+
}
57+
5058
// RUN: %empty-directory(%t.result)
5159
// RUN: %refactor -rename -source-filename %s -pos=3:9 -new-name="xRenamed" >> %t.result/localvar_1.swift
5260
// RUN: %refactor -rename -source-filename %s -pos=7:11 -new-name="xRenamed" >> %t.result/localvar_2.swift
@@ -68,3 +76,5 @@ func test5(_ x: Int) {
6876
// RUN: %refactor -rename -source-filename %s -pos=47:9 -new-name="xRenamed" >> %t.result/param_2.swift
6977
// RUN: diff -u %S/Outputs/local/param_1.swift.expected %t.result/param_1.swift
7078
// RUN: diff -u %S/Outputs/local/param_2.swift.expected %t.result/param_2.swift
79+
// RUN: %refactor -rename -source-filename %s -pos=51:7 -new-name="capturedVariableRenamed" >> %t.result/captured_variable.swift
80+
// RUN: diff -u %S/Outputs/local/captured_variable.swift.expected %t.result/captured_variable.swift

0 commit comments

Comments
 (0)