Skip to content

Commit b59eb14

Browse files
committed
Emit refs to collections initialized with a type shorthand expression.
Normally references to initializers of collections like Array and Dict are emitted into the index data. It was missing any initializer called using the collection's literal type resentation instead of the type name. For example: ``` _ = Array<Int>(repeating: 0, count: 1) // Reference is emitted. _ = [Int](repeating: 0, count: 1) // Reference is missing. ``` This PR fixes the inconsistency by emitting references for those collection intializers. fixes swiftlang#68974
1 parent 0d16cbf commit b59eb14

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

lib/Index/Index.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,35 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
678678
return true;
679679
}
680680

681+
/// Indexes refs to initializers of collections when initialized from a short
682+
/// hand version of the collection's type.
683+
///
684+
/// For example, emits refs for `[Int](repeating:count:)`.
685+
void handleCollectionShortHandTypeInitRefs(Expr *E) {
686+
auto *ctorRef = dyn_cast<ConstructorRefCallExpr>(E);
687+
if (!ctorRef)
688+
return;
689+
auto TE = dyn_cast<TypeExpr>(ctorRef->getBase());
690+
if (!TE || TE->isImplicit())
691+
return;
692+
auto TR = TE->getTypeRepr();
693+
if (TR && !isa<ArrayTypeRepr>(TR) && !isa<DictionaryTypeRepr>(TR))
694+
return;
695+
auto DRE = dyn_cast<DeclRefExpr>(ctorRef->getFn());
696+
if (!DRE)
697+
return;
698+
699+
auto decl = DRE->getDecl();
700+
if (!shouldIndex(decl, /*IsRef=*/true))
701+
return;
702+
IndexSymbol Info;
703+
if (initIndexSymbol(decl, ctorRef->getSourceRange().Start, /*IsRef=*/true,
704+
Info))
705+
return;
706+
if (startEntity(decl, Info, /*IsRef=*/true))
707+
finishCurrentEntity();
708+
}
709+
681710
void handleMemberwiseInitRefs(Expr *E) {
682711
if (!isa<ApplyExpr>(E))
683712
return;
@@ -744,6 +773,7 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
744773
ExprStack.push_back(E);
745774
Containers.activateContainersFor(E);
746775
handleMemberwiseInitRefs(E);
776+
handleCollectionShortHandTypeInitRefs(E);
747777
return true;
748778
}
749779

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s
2+
3+
struct Foo: Hashable {}
4+
5+
_ = Array<Int>(repeating: 0, count: 1)
6+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(repeating:count:) | s:Sa9repeating5countSayxGx_Sitcfc | {{.*}}Ref
7+
_ = [Int](repeating: 0, count: 1)
8+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(repeating:count:) | s:Sa9repeating5countSayxGx_Sitcfc | {{.*}}Ref
9+
_ = Array<Foo>(repeating: Foo(), count: 1)
10+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(repeating:count:) | s:Sa9repeating5countSayxGx_Sitcfc | {{.*}}Ref
11+
// CHECK: [[@LINE-2]]:27 | constructor/Swift | init() | s:14swift_ide_test3FooVACycfc | Ref,Call
12+
_ = [Foo](repeating: Foo(), count: 1)
13+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(repeating:count:) | s:Sa9repeating5countSayxGx_Sitcfc | {{.*}}Ref
14+
// CHECK: [[@LINE-2]]:22 | constructor/Swift | init() | s:14swift_ide_test3FooVACycfc | Ref,Call
15+
16+
_ = Dictionary<Foo, String>(minimumCapacity: 1)
17+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(minimumCapacity:) | s:SD15minimumCapacitySDyxq_GSi_tcfc | {{.*}}Ref
18+
_ = [Foo: String](minimumCapacity: 1)
19+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(minimumCapacity:) | s:SD15minimumCapacitySDyxq_GSi_tcfc | {{.*}}Ref
20+
_ = [String: Int](uniqueKeysWithValues: zip(["one", "two", "three"], 1...3))
21+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(uniqueKeysWithValues:) | s:SD20uniqueKeysWithValuesSDyxq_Gqd__n_tcSTRd__x_q_t7ElementRtd__lufc | {{.*}}Ref
22+
23+
extension Array where Element == Int {
24+
// CHECK: [[@LINE+1]]:3 | constructor/Swift | init(_:) | s:Sa14swift_ide_testSiRszlEySaySiGSicfc | {{.*}}Def
25+
init(_ input: Int) {
26+
self = [input]
27+
}
28+
}
29+
30+
_ = [Int](0)
31+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(_:) | s:Sa14swift_ide_testSiRszlEySaySiGSicfc | {{.*}}Ref
32+
33+
extension Dictionary {
34+
// CHECK: [[@LINE+1]]:3 | constructor/Swift | init(_:_:) | s:SD14swift_ide_testEySDyxq_Gx_q_tcfc | {{.*}}Def
35+
init(_ k: Key, _ v: Value) {
36+
self = [k: v]
37+
}
38+
}
39+
40+
_ = [Int: Int](0, 1)
41+
// CHECK: [[@LINE-1]]:5 | constructor/Swift | init(_:_:) | s:SD14swift_ide_testEySDyxq_Gx_q_tcfc | {{.*}}Ref

0 commit comments

Comments
 (0)