Skip to content

Commit 31d1b3a

Browse files
committed
Index expressible-by-literal expressions.
When a value is initialized or coerced for a type that conforms to one of the `ExpressibleBy*Literal` protocols (or `ExpressibleByStringInterpolation`), this change records an implicit call to the corresponding `init(...Literal:)` in the indexstore, located at the beginning of the literal.
1 parent a159636 commit 31d1b3a

File tree

5 files changed

+182
-19
lines changed

5 files changed

+182
-19
lines changed

lib/AST/Expr.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -320,12 +320,12 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
320320
->GetSubExpr()->getReferencedDecl(stopAtParenExpr)
321321

322322
NO_REFERENCE(Error);
323-
NO_REFERENCE(NilLiteral);
324-
NO_REFERENCE(IntegerLiteral);
325-
NO_REFERENCE(FloatLiteral);
326-
NO_REFERENCE(BooleanLiteral);
327-
NO_REFERENCE(StringLiteral);
328-
NO_REFERENCE(InterpolatedStringLiteral);
323+
SIMPLE_REFERENCE(NilLiteral, getInitializer);
324+
SIMPLE_REFERENCE(IntegerLiteral, getInitializer);
325+
SIMPLE_REFERENCE(FloatLiteral, getInitializer);
326+
SIMPLE_REFERENCE(BooleanLiteral, getInitializer);
327+
SIMPLE_REFERENCE(StringLiteral, getInitializer);
328+
SIMPLE_REFERENCE(InterpolatedStringLiteral, getInitializer);
329329
NO_REFERENCE(RegexLiteral);
330330
NO_REFERENCE(ObjectLiteral);
331331
NO_REFERENCE(MagicIdentifierLiteral);
@@ -371,8 +371,8 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
371371
PASS_THROUGH_REFERENCE(OptionalTry, getSubExpr);
372372

373373
NO_REFERENCE(Tuple);
374-
NO_REFERENCE(Array);
375-
NO_REFERENCE(Dictionary);
374+
SIMPLE_REFERENCE(Array, getInitializer);
375+
SIMPLE_REFERENCE(Dictionary, getInitializer);
376376

377377
case ExprKind::Subscript: {
378378
auto subscript = cast<SubscriptExpr>(this);

lib/IDE/SourceEntityWalker.cpp

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -386,18 +386,32 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
386386
}
387387
}
388388

389-
if (!isa<InOutExpr>(E) &&
390-
!isa<LoadExpr>(E) &&
391-
!isa<OpenExistentialExpr>(E) &&
389+
if (!isa<InOutExpr>(E) && !isa<LoadExpr>(E) && !isa<OpenExistentialExpr>(E) &&
392390
!isa<MakeTemporarilyEscapableExpr>(E) &&
393-
!isa<CollectionUpcastConversionExpr>(E) &&
394-
!isa<OpaqueValueExpr>(E) &&
395-
!isa<SubscriptExpr>(E) &&
396-
!isa<KeyPathExpr>(E) &&
397-
E->isImplicit())
398-
return { true, E };
399-
400-
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
391+
!isa<CollectionUpcastConversionExpr>(E) && !isa<OpaqueValueExpr>(E) &&
392+
!isa<SubscriptExpr>(E) && !isa<KeyPathExpr>(E) && !isa<LiteralExpr>(E) &&
393+
!isa<CollectionExpr>(E) && E->isImplicit())
394+
return {true, E};
395+
396+
if (auto LE = dyn_cast<LiteralExpr>(E)) {
397+
if (LE->getInitializer() &&
398+
!passReference(LE->getInitializer().getDecl(), LE->getType(), {},
399+
LE->getSourceRange(),
400+
ReferenceMetaData(SemaReferenceKind::DeclRef, OpAccess,
401+
/*isImplicit=*/true))) {
402+
return doStopTraversal();
403+
}
404+
return {true, E};
405+
} else if (auto CE = dyn_cast<CollectionExpr>(E)) {
406+
if (CE->getInitializer() &&
407+
!passReference(CE->getInitializer().getDecl(), CE->getType(), {},
408+
CE->getSourceRange(),
409+
ReferenceMetaData(SemaReferenceKind::DeclRef, OpAccess,
410+
/*isImplicit=*/true))) {
411+
return doStopTraversal();
412+
}
413+
return {true, E};
414+
} else if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
401415
if (auto *module = dyn_cast<ModuleDecl>(DRE->getDecl())) {
402416
if (!passReference(ModuleEntity(module),
403417
{module->getName(), E->getLoc()}))

lib/IDE/Utils.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,13 @@ bool swift::ide::isBeingCalled(ArrayRef<Expr *> ExprStack) {
12031203
Expr *Target = ExprStack.back();
12041204
auto UnderlyingDecl = getReferencedDecl(Target).second;
12051205
for (Expr *E: reverse(ExprStack)) {
1206+
auto *LE = dyn_cast<LiteralExpr>(E);
1207+
if (LE && getReferencedDecl(LE).second == UnderlyingDecl)
1208+
return true;
1209+
auto *CE = dyn_cast<CollectionExpr>(E);
1210+
if (CE && getReferencedDecl(CE).second == UnderlyingDecl)
1211+
return true;
1212+
12061213
auto *AE = dyn_cast<ApplyExpr>(E);
12071214
if (!AE || AE->isImplicit())
12081215
continue;
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s
2+
3+
struct CustomInteger: ExpressibleByIntegerLiteral {
4+
init(integerLiteral: Int) {}
5+
}
6+
struct CustomFloat: ExpressibleByFloatLiteral {
7+
init(floatLiteral: Double) {}
8+
}
9+
struct CustomBool: ExpressibleByBooleanLiteral {
10+
init(booleanLiteral: Bool) {}
11+
}
12+
struct CustomNil: ExpressibleByNilLiteral {
13+
init(nilLiteral: ()) {}
14+
}
15+
struct CustomString: ExpressibleByStringLiteral {
16+
init(stringLiteral: StaticString) {}
17+
}
18+
struct CustomScalar: ExpressibleByUnicodeScalarLiteral {
19+
init(unicodeScalarLiteral: Unicode.Scalar) {}
20+
}
21+
struct CustomCharacter: ExpressibleByExtendedGraphemeClusterLiteral {
22+
init(extendedGraphemeClusterLiteral: Character) {}
23+
}
24+
struct CustomArray: ExpressibleByArrayLiteral {
25+
init(arrayLiteral: Int...) {}
26+
}
27+
struct CustomDictionary: ExpressibleByDictionaryLiteral {
28+
init(dictionaryLiteral: (Int, Int)...) {}
29+
}
30+
struct CustomInterpolation: ExpressibleByStringInterpolation {
31+
init(stringInterpolation: StringInterpolation) {}
32+
init(stringLiteral: String) {}
33+
}
34+
35+
func customInteger() {
36+
// CHECK: [[@LINE+2]]:26 | constructor/Swift | init(integerLiteral:) | s:14swift_ide_test13CustomIntegerV14integerLiteralACSi_tcfc | Ref,Call,Impl,RelCall,RelCont |
37+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInteger() | s:14swift_ide_test13customIntegeryyF
38+
let _: CustomInteger = 100
39+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(integerLiteral:) | s:14swift_ide_test13CustomIntegerV14integerLiteralACSi_tcfc | Ref,Call,Impl,RelCall,RelCont |
40+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInteger() | s:14swift_ide_test13customIntegeryyF
41+
_ = 100 as CustomInteger
42+
// CHECK: [[@LINE+2]]:21 | constructor/Swift | init(integerLiteral:) | s:14swift_ide_test13CustomIntegerV14integerLiteralACSi_tcfc | Ref,Call,Impl,RelCall,RelCont |
43+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInteger() | s:14swift_ide_test13customIntegeryyF
44+
_ = CustomInteger(100)
45+
}
46+
func customFloat() {
47+
// CHECK: [[@LINE+2]]:24 | constructor/Swift | init(floatLiteral:) | s:14swift_ide_test11CustomFloatV12floatLiteralACSd_tcfc | Ref,Call,Impl,RelCall,RelCont |
48+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customFloat() | s:14swift_ide_test11customFloatyyF
49+
let _: CustomFloat = -1.23
50+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(floatLiteral:) | s:14swift_ide_test11CustomFloatV12floatLiteralACSd_tcfc | Ref,Call,Impl,RelCall,RelCont |
51+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customFloat() | s:14swift_ide_test11customFloatyyF
52+
_ = -1.23 as CustomFloat
53+
// CHECK: [[@LINE+2]]:19 | constructor/Swift | init(floatLiteral:) | s:14swift_ide_test11CustomFloatV12floatLiteralACSd_tcfc | Ref,Call,Impl,RelCall,RelCont |
54+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customFloat() | s:14swift_ide_test11customFloatyyF
55+
_ = CustomFloat(-1.23)
56+
}
57+
func customBool() {
58+
// CHECK: [[@LINE+2]]:23 | constructor/Swift | init(booleanLiteral:) | s:14swift_ide_test10CustomBoolV14booleanLiteralACSb_tcfc | Ref,Call,Impl,RelCall,RelCont |
59+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customBool() | s:14swift_ide_test10customBoolyyF
60+
let _: CustomBool = true
61+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(booleanLiteral:) | s:14swift_ide_test10CustomBoolV14booleanLiteralACSb_tcfc | Ref,Call,Impl,RelCall,RelCont |
62+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customBool() | s:14swift_ide_test10customBoolyyF
63+
_ = false as CustomBool
64+
// CHECK: [[@LINE+2]]:18 | constructor/Swift | init(booleanLiteral:) | s:14swift_ide_test10CustomBoolV14booleanLiteralACSb_tcfc | Ref,Call,Impl,RelCall,RelCont |
65+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customBool() | s:14swift_ide_test10customBoolyyF
66+
_ = CustomBool(true)
67+
}
68+
func customNil() {
69+
// CHECK: [[@LINE+2]]:22 | constructor/Swift | init(nilLiteral:) | s:14swift_ide_test9CustomNilV10nilLiteralACyt_tcfc | Ref,Call,Impl,RelCall,RelCont |
70+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customNil() | s:14swift_ide_test9customNilyyF
71+
let _: CustomNil = nil
72+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(nilLiteral:) | s:14swift_ide_test9CustomNilV10nilLiteralACyt_tcfc | Ref,Call,Impl,RelCall,RelCont |
73+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customNil() | s:14swift_ide_test9customNilyyF
74+
_ = nil as CustomNil
75+
}
76+
func customString() {
77+
// CHECK: [[@LINE+2]]:25 | constructor/Swift | init(stringLiteral:) | s:14swift_ide_test12CustomStringV13stringLiteralACs06StaticE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
78+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customString() | s:14swift_ide_test12customStringyyF
79+
let _: CustomString = "abc"
80+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(stringLiteral:) | s:14swift_ide_test12CustomStringV13stringLiteralACs06StaticE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
81+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customString() | s:14swift_ide_test12customStringyyF
82+
_ = "abc" as CustomString
83+
// CHECK: [[@LINE+2]]:20 | constructor/Swift | init(stringLiteral:) | s:14swift_ide_test12CustomStringV13stringLiteralACs06StaticE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
84+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customString() | s:14swift_ide_test12customStringyyF
85+
_ = CustomString("abc")
86+
}
87+
func customScalar() {
88+
// CHECK: [[@LINE+2]]:25 | constructor/Swift | init(unicodeScalarLiteral:) | s:14swift_ide_test12CustomScalarV07unicodeE7LiteralACs7UnicodeO0E0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
89+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customScalar() | s:14swift_ide_test12customScalaryyF
90+
let _: CustomScalar = "a"
91+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(unicodeScalarLiteral:) | s:14swift_ide_test12CustomScalarV07unicodeE7LiteralACs7UnicodeO0E0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
92+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customScalar() | s:14swift_ide_test12customScalaryyF
93+
_ = "a" as CustomScalar
94+
// CHECK: [[@LINE+2]]:20 | constructor/Swift | init(unicodeScalarLiteral:) | s:14swift_ide_test12CustomScalarV07unicodeE7LiteralACs7UnicodeO0E0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
95+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customScalar() | s:14swift_ide_test12customScalaryyF
96+
_ = CustomScalar("a")
97+
}
98+
func customCharacter() {
99+
// CHECK: [[@LINE+2]]:28 | constructor/Swift | init(extendedGraphemeClusterLiteral:) | s:14swift_ide_test15CustomCharacterV30extendedGraphemeClusterLiteralACSJ_tcfc | Ref,Call,Impl,RelCall,RelCont |
100+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customCharacter() | s:14swift_ide_test15customCharacteryyF
101+
let _: CustomCharacter = "a"
102+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(extendedGraphemeClusterLiteral:) | s:14swift_ide_test15CustomCharacterV30extendedGraphemeClusterLiteralACSJ_tcfc | Ref,Call,Impl,RelCall,RelCont |
103+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customCharacter() | s:14swift_ide_test15customCharacteryyF
104+
_ = "a" as CustomCharacter
105+
// CHECK: [[@LINE+2]]:23 | constructor/Swift | init(extendedGraphemeClusterLiteral:) | s:14swift_ide_test15CustomCharacterV30extendedGraphemeClusterLiteralACSJ_tcfc | Ref,Call,Impl,RelCall,RelCont |
106+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customCharacter() | s:14swift_ide_test15customCharacteryyF
107+
_ = CustomCharacter("a")
108+
}
109+
func customArray() {
110+
// CHECK: [[@LINE+2]]:24 | constructor/Swift | init(arrayLiteral:) | s:14swift_ide_test11CustomArrayV12arrayLiteralACSid_tcfc | Ref,Call,Impl,RelCall,RelCont |
111+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customArray() | s:14swift_ide_test11customArrayyyF
112+
let _: CustomArray = [1, 2, 3]
113+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(arrayLiteral:) | s:14swift_ide_test11CustomArrayV12arrayLiteralACSid_tcfc | Ref,Call,Impl,RelCall,RelCont |
114+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customArray() | s:14swift_ide_test11customArrayyyF
115+
_ = [1, 2, 3] as CustomArray
116+
}
117+
func customDictionary() {
118+
// CHECK: [[@LINE+2]]:29 | constructor/Swift | init(dictionaryLiteral:) | s:14swift_ide_test16CustomDictionaryV17dictionaryLiteralACSi_Sitd_tcfc | Ref,Call,Impl,RelCall,RelCont |
119+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customDictionary() | s:14swift_ide_test16customDictionaryyyF
120+
let _: CustomDictionary = [1: 1, 2: 2, 3: 3]
121+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(dictionaryLiteral:) | s:14swift_ide_test16CustomDictionaryV17dictionaryLiteralACSi_Sitd_tcfc | Ref,Call,Impl,RelCall,RelCont |
122+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customDictionary() | s:14swift_ide_test16customDictionaryyyF
123+
_ = [1: 1, 2: 2, 3: 3] as CustomDictionary
124+
}
125+
func customInterpolation() {
126+
// CHECK: [[@LINE+2]]:32 | constructor/Swift | init(stringInterpolation:) | s:14swift_ide_test19CustomInterpolationV06stringE0ACs013DefaultStringE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
127+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInterpolation() | s:14swift_ide_test19customInterpolationyyF
128+
let _: CustomInterpolation = "a\(0)b"
129+
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(stringInterpolation:) | s:14swift_ide_test19CustomInterpolationV06stringE0ACs013DefaultStringE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
130+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInterpolation() | s:14swift_ide_test19customInterpolationyyF
131+
_ = "a\(0)b" as CustomInterpolation
132+
// CHECK: [[@LINE+2]]:27 | constructor/Swift | init(stringInterpolation:) | s:14swift_ide_test19CustomInterpolationV06stringE0ACs013DefaultStringE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
133+
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInterpolation() | s:14swift_ide_test19customInterpolationyyF
134+
_ = CustomInterpolation("a\(0)b")
135+
}

test/SourceKit/Indexing/index_big_array.swift.response

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
key.usr: "s:Sf",
3939
key.line: 1,
4040
key.column: 23
41+
},
42+
{
43+
key.kind: source.lang.swift.ref.function.constructor,
44+
key.usr: "s:Sa12arrayLiteralSayxGxd_tcfc",
45+
key.line: 1,
46+
key.column: 32,
47+
key.is_implicit: 1
4148
}
4249
]
4350
}

0 commit comments

Comments
 (0)