Skip to content

Commit 74cd03b

Browse files
committed
[Index] Consider construction of enums with associated values as a function call
For enum cases with associated values, their construction is modelled by a function. E.g. if you have ```swift enum Foo { case first(associated: Int) } ``` then `Foo.first` is a function of type `(Int) -> Foo`. But if you write `Foo.first(associated: 2)` in source code, we consider this construct as a referenced, not a call. This causes us to miss renaming of associated value labels during local refactoring. rdar://84061868
1 parent d2f7d51 commit 74cd03b

File tree

6 files changed

+53
-3
lines changed

6 files changed

+53
-3
lines changed

lib/Index/Index.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,7 @@ bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc,
15321532
if (!shouldIndex(D, /*IsRef=*/true))
15331533
return true; // keep walking
15341534

1535-
if (isa<AbstractFunctionDecl>(D)) {
1535+
if (isa<AbstractFunctionDecl>(D) || isa<EnumElementDecl>(D)) {
15361536
if (initFuncRefIndexSymbol(D, Loc, Info))
15371537
return true;
15381538
} else if (isa<AbstractStorageDecl>(D)) {

test/Index/local.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func foo(a: Int, b: Int, c: Int) {
3939
let _ = LocalEnum.foo(x: LocalStruct())
4040
// LOCAL: [[@LINE-1]]:13 | enum(local)/Swift | LocalEnum | [[LocalEnum_USR]] | Ref,RelCont | rel: 1
4141
// CHECK-NOT: [[@LINE-2]]:13 | enum(local)/Swift | LocalEnum | {{.*}} | Ref,RelCont | rel: 1
42-
// LOCAL: [[@LINE-3]]:23 | enumerator(local)/Swift | foo(x:) | [[LocalEnum_foo_USR]] | Ref,RelCont | rel: 1
42+
// LOCAL: [[@LINE-3]]:23 | enumerator(local)/Swift | foo(x:) | [[LocalEnum_foo_USR]] | Ref,Call,RelRec,RelCall,RelCont | rel: 2
4343
// CHECK-NOT: [[@LINE-4]]:23 | enumerator(local)/Swift | foo(x:) | {{.*}} | Ref,RelCont | rel: 1
4444
// LOCAL: [[@LINE-5]]:30 | struct(local)/Swift | LocalStruct | [[LocalStruct_USR]] | Ref,RelCont | rel: 1
4545
// CHECK-NOT: [[@LINE-6]]:30 | struct(local)/Swift | LocalStruct | {{.*}} | Ref,RelCont | rel: 1

test/SourceKit/Indexing/index_enum_case.swift.response

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@
139139
key.name: "two(a:)",
140140
key.usr: "s:15index_enum_case1EO3twoyACSS_tcACmF",
141141
key.line: 21,
142-
key.column: 13
142+
key.column: 13,
143+
key.receiver_usr: "s:15index_enum_case1EO"
143144
},
144145
{
145146
key.kind: source.lang.swift.decl.function.free,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
enum Foo {
2+
case primary(with: Int)
3+
case second
4+
}
5+
6+
func test() {
7+
let _ = Foo.primary(with: 1)
8+
let _ = Foo.primary
9+
let _ = Foo.second
10+
}
11+
12+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
enum Foo {
2+
case first(associated: Int)
3+
case secondary
4+
}
5+
6+
func test() {
7+
let _ = Foo.first(associated: 1)
8+
let _ = Foo.first
9+
let _ = Foo.secondary
10+
}
11+
12+

test/refactoring/rename/enum.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
enum Foo {
2+
case first(associated: Int)
3+
case second
4+
}
5+
6+
func test() {
7+
let _ = Foo.first(associated: 1)
8+
let _ = Foo.first
9+
let _ = Foo.second
10+
}
11+
12+
// RUN: %empty-directory(%t.result)
13+
// RUN: %refactor -rename -source-filename %s -pos=2:8 -new-name 'primary(with:)' > %t.result/first_def.swift
14+
// RUN: diff -u %S/Outputs/enum/first.swift.expected %t.result/first_def.swift
15+
// RUN: %refactor -rename -source-filename %s -pos=7:15 -new-name 'primary(with:)' > %t.result/first_ref.swift
16+
// RUN: diff -u %S/Outputs/enum/first.swift.expected %t.result/first_ref.swift
17+
// RUN: %refactor -rename -source-filename %s -pos=7:21 -new-name 'primary(with:)' > %t.result/first_ref_assoc.swift
18+
// RUN: diff -u %S/Outputs/enum/first.swift.expected %t.result/first_ref_assoc.swift
19+
// RUN: %refactor -rename -source-filename %s -pos=8:15 -new-name 'primary(with:)' > %t.result/first_ref_base.swift
20+
// RUN: diff -u %S/Outputs/enum/first.swift.expected %t.result/first_ref_assoc.swift
21+
22+
// RUN: %refactor -rename -source-filename %s -pos=3:8 -new-name 'secondary' > %t.result/second_def.swift
23+
// RUN: diff -u %S/Outputs/enum/second.swift.expected %t.result/second_def.swift
24+
// RUN: %refactor -rename -source-filename %s -pos=9:15 -new-name 'secondary' > %t.result/second_ref.swift
25+
// RUN: diff -u %S/Outputs/enum/second.swift.expected %t.result/second_ref.swift

0 commit comments

Comments
 (0)