Skip to content

Commit 968112e

Browse files
committed
[Sema] Support code completion for heterogeneous unresolved member chains
1 parent 5de23f5 commit 968112e

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@ static Expr *getMemberChainSubExpr(Expr *expr) {
491491
return FVE->getSubExpr();
492492
} else if (auto *SE = dyn_cast<SubscriptExpr>(expr)) {
493493
return SE->getBase();
494+
} else if (auto *CCE = dyn_cast<CodeCompletionExpr>(expr)) {
495+
return CCE->getBase();
494496
} else {
495497
return nullptr;
496498
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_CHAIN_1 | %FileCheck %s -check-prefix=UNRESOLVED_CHAIN_1
2+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_CHAIN_2 | %FileCheck %s -check-prefix=UNRESOLVED_CHAIN_1
3+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_CHAIN_3 | %FileCheck %s -check-prefix=UNRESOLVED_CHAIN_1
4+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_CHAIN_4 | %FileCheck %s -check-prefix=UNRESOLVED_CHAIN_1
5+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_CHAIN_5 | %FileCheck %s -check-prefix=UNRESOLVED_CHAIN_2
6+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_CHAIN_6 | %FileCheck %s -check-prefix=UNRESOLVED_CHAIN_3
7+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_CHAIN_7 | %FileCheck %s -check-prefix=UNRESOLVED_CHAIN_3
8+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DOUBLY_NESTED| %FileCheck %s -check-prefix=DOUBLY_NESTED
9+
10+
struct ChainStruct1 {
11+
static var chain2 = ChainStruct2()
12+
static func chain2Func() -> ChainStruct2 { ChainStruct2() }
13+
}
14+
15+
struct ChainStruct2 {
16+
var chainStruct1 = ChainStruct1()
17+
var chainEnum = ChainEnum.case1
18+
var chainStruct2: ChainStruct2 { ChainStruct2() }
19+
func chainStruct1Func() -> ChainStruct1 { ChainStruct1() }
20+
}
21+
22+
enum ChainEnum {
23+
case case1
24+
var chainStruct2: ChainStruct2 { ChainStruct2() }
25+
func chainStruct2Func() -> ChainStruct2 { ChainStruct2() }
26+
}
27+
28+
func testChains() {
29+
let _: ChainStruct1 = .chain2.#^UNRESOLVED_CHAIN_1^#
30+
let _: ChainStruct1 = .chain2.chainStruct2.#^UNRESOLVED_CHAIN_2^#
31+
let _: ChainStruct1 = .chain2Func().#^UNRESOLVED_CHAIN_3^#
32+
let _: ChainStruct1 = .chain2Func().#^UNRESOLVED_CHAIN_4^#
33+
let _: ChainEnum = .case1.#^UNRESOLVED_CHAIN_5^#
34+
let _: ChainEnum = .case1.chainStruct2.#^UNRESOLVED_CHAIN_6^#
35+
let _: ChainEnum = .case1.chainStruct2.#^UNRESOLVED_CHAIN_7^#
36+
}
37+
38+
// UNRESOLVED_CHAIN_1: Begin completions, 5 items
39+
// UNRESOLVED_CHAIN_1-DAG: Decl[InstanceVar]/CurrNominal/TypeRelation[Identical]: chainStruct1[#ChainStruct1#];
40+
// UNRESOLVED_CHAIN_1-DAG: Decl[InstanceVar]/CurrNominal: chainEnum[#ChainEnum#];
41+
// UNRESOLVED_CHAIN_1-DAG: Decl[InstanceVar]/CurrNominal: chainStruct2[#ChainStruct2#];
42+
// UNRESOLVED_CHAIN_1-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Identical]: chainStruct1Func()[#ChainStruct1#];
43+
// UNRESOLVED_CHAIN_1: End completions
44+
45+
// UNRESOLVED_CHAIN_2: Begin completions, 5 items
46+
// UNRESOLVED_CHAIN_2-DAG: Decl[InstanceVar]/CurrNominal: chainStruct2[#ChainStruct2#];
47+
// UNRESOLVED_CHAIN_2: End completions
48+
49+
// UNRESOLVED_CHAIN_3: Begin completions, 5 items
50+
// UNRESOLVED_CHAIN_3-DAG: Decl[InstanceVar]/CurrNominal: chainStruct1[#ChainStruct1#]; name=chainStruct1
51+
// UNRESOLVED_CHAIN_3-DAG: Decl[InstanceVar]/CurrNominal/TypeRelation[Identical]: chainEnum[#ChainEnum#]; name=chainEnum
52+
// UNRESOLVED_CHAIN_3-DAG: Decl[InstanceVar]/CurrNominal: chainStruct2[#ChainStruct2#]; name=chainStruct2
53+
// UNRESOLVED_CHAIN_3-DAG: Decl[InstanceMethod]/CurrNominal: chainStruct1Func()[#ChainStruct1#]; name=chainStruct1Func()
54+
// UNRESOLVED_CHAIN_3: End completions
55+
56+
class Outer {
57+
class Inner: Outer {
58+
class InnerInner: Inner {}
59+
static var outer = Outer()
60+
static var inner = Inner()
61+
static func makeOuter() -> Outer { Outer() }
62+
static func makeInner() -> Inner { Inner() }
63+
}
64+
}
65+
66+
func testDoublyNestedType() {
67+
let _: Outer = .Inner.#^DOUBLY_NESTED^#
68+
}
69+
70+
// DOUBLY_NESTED: Begin completions, 8 items
71+
// DOUBLY_NESTED-DAG: Decl[Class]/CurrNominal/TypeRelation[Convertible]: InnerInner[#Outer.Inner.InnerInner#];
72+
// DOUBLY_NESTED-DAG: Decl[StaticVar]/CurrNominal/TypeRelation[Identical]: outer[#Outer#];
73+
// DOUBLY_NESTED-DAG: Decl[StaticVar]/CurrNominal/TypeRelation[Convertible]: inner[#Outer.Inner#];
74+
// DOUBLY_NESTED-DAG: Decl[StaticMethod]/CurrNominal/TypeRelation[Identical]: makeOuter()[#Outer#];
75+
// DOUBLY_NESTED-DAG: Decl[StaticMethod]/CurrNominal/TypeRelation[Convertible]: makeInner()[#Outer.Inner#];
76+
// DOUBLY_NESTED-DAG: Decl[Constructor]/CurrNominal/TypeRelation[Convertible]: init()[#Outer.Inner#];
77+
// DOUBLY_NESTED-DAG: Decl[Class]/Super/TypeRelation[Convertible]: Inner[#Outer.Inner#];
78+
// DOUBLY_NESTED: End completions
79+

0 commit comments

Comments
 (0)