Skip to content

Commit 927598f

Browse files
committed
[CodeCompletion] Missing init completions for dotExpr
Fixes non-visible inherited convenience initializers Fixes non-visible initializers from protocol extensions Fixes visible initializers on dynamic metatypes for postfix and parenPostfix expressions
1 parent 38abc74 commit 927598f

File tree

4 files changed

+60
-37
lines changed

4 files changed

+60
-37
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2606,10 +2606,13 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
26062606
assert(isa<ConstructorDecl>(CurrDeclContext) &&
26072607
"can call super.init only inside a constructor");
26082608
needInit = true;
2609-
} else if (addName.empty() && HaveDot &&
2610-
Reason == DeclVisibilityKind::MemberOfCurrentNominal) {
2611-
// This case is querying the init function as member
2612-
needInit = true;
2609+
} else if (addName.empty() && HaveDot) {
2610+
if (Reason == DeclVisibilityKind::MemberOfCurrentNominal ||
2611+
Reason == DeclVisibilityKind::MemberOfSuper ||
2612+
Reason == DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal) {
2613+
// This case is querying the init function as member
2614+
needInit = true;
2615+
}
26132616
}
26142617

26152618
// If we won't be able to provide a result, bail out.
@@ -2943,38 +2946,21 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29432946
return;
29442947
}
29452948

2946-
if (auto MT = ExprType->getRValueType()->getAs<AnyMetatypeType>()) {
2947-
if (HaveDot) {
2948-
Type Ty;
2949-
for (Ty = MT; Ty && Ty->is<AnyMetatypeType>();
2950-
Ty = Ty->getAs<AnyMetatypeType>()->getInstanceType());
2951-
assert(Ty && "Cannot find instance type.");
2952-
2953-
// Add init() as member of the metatype.
2954-
if (Reason == DeclVisibilityKind::MemberOfCurrentNominal) {
2955-
if (IsStaticMetatype || CD->isRequired() ||
2956-
!Ty->is<ClassType>())
2957-
addConstructorCall(CD, Reason, None, None);
2958-
}
2959-
return;
2960-
}
2961-
}
2962-
29632949
if (auto MT = ExprType->getAs<AnyMetatypeType>()) {
2964-
if (HaveDot)
2965-
return;
2950+
Type Ty = MT->getInstanceType();
2951+
assert(Ty && "Cannot find instance type.");
29662952

2967-
// If instance type is type alias, showing users that the constructed
2953+
// If instance type is type alias, show users that the constructed
29682954
// type is the typealias instead of the underlying type of the alias.
29692955
Optional<Type> Result = None;
2970-
if (auto AT = MT->getInstanceType()) {
2971-
if (!CD->getInterfaceType()->is<ErrorType>() &&
2972-
(isa<NameAliasType>(AT.getPointer()) &&
2973-
AT->getDesugaredType() ==
2974-
CD->getResultInterfaceType().getPointer()))
2975-
Result = AT;
2956+
if (!CD->getInterfaceType()->is<ErrorType>() &&
2957+
isa<NameAliasType>(Ty.getPointer()) &&
2958+
Ty->getDesugaredType() ==
2959+
CD->getResultInterfaceType().getPointer()) {
2960+
Result = Ty;
29762961
}
2977-
addConstructorCall(CD, Reason, None, Result);
2962+
if (IsStaticMetatype || CD->isRequired() || !Ty->is<ClassType>())
2963+
addConstructorCall(CD, Reason, None, Result);
29782964
}
29792965
if (IsSuperRefExpr || IsSelfRefExpr) {
29802966
if (!isa<ConstructorDecl>(CurrDeclContext))

test/IDE/complete_after_self.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,6 @@ class ThisDerived1 : ThisBase1 {
214214
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal: .derivedFunc0({#self: ThisDerived1#})[#() -> Void#]
215215
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[StaticVar]/CurrNominal: .derivedStaticVar[#Int#]
216216
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[StaticMethod]/CurrNominal: .derivedStaticFunc0()[#Void#]
217-
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Constructor]/CurrNominal: ()[#ThisDerived1#]
218-
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Constructor]/CurrNominal: ({#a: Int#})[#ThisDerived1#]
219217
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal: .test1({#self: ThisDerived1#})[#() -> Void#]
220218
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal: .test2({#self: ThisDerived1#})[#() -> Void#]
221219
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[StaticMethod]/CurrNominal: .staticTest1()[#Void#]
@@ -226,7 +224,6 @@ class ThisDerived1 : ThisBase1 {
226224
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Class]/CurrNominal: .DerivedExtNestedClass[#ThisDerived1.DerivedExtNestedClass#]
227225
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Enum]/CurrNominal: .DerivedExtNestedEnum[#ThisDerived1.DerivedExtNestedEnum#]
228226
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[TypeAlias]/CurrNominal: .DerivedExtNestedTypealias[#Int#]
229-
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Constructor]/CurrNominal: ({#someExtensionArg: Int#})[#ThisDerived1#]
230227
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[InstanceMethod]/Super: .baseFunc0({#self: ThisBase1#})[#() -> Void#]
231228
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[InstanceMethod]/Super: .baseFunc1({#self: ThisBase1#})[#(Int) -> Void#]
232229
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[StaticVar]/Super: .baseStaticVar[#Int#]

test/IDE/complete_constructor.swift

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,16 @@
1515

1616
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1 | %FileCheck %s -check-prefix=EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1
1717

18+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_INIT_FROM_PROT_NODOT | %FileCheck %s -check-prefix=DEFAULT_INIT_FROM_PROT
19+
20+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_INIT_FROM_PROT_DOT | %FileCheck %s -check-prefix=DEFAULT_INIT_FROM_PROT
21+
22+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_INIT_FROM_PROT_PAREN | %FileCheck %s -check-prefix=DEFAULT_INIT_FROM_PROT
23+
1824
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FROM_METATYPE1 | %FileCheck %s -check-prefix=INIT_FROM_METATYPE1
19-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FROM_METATYPE2 | %FileCheck %s -check-prefix=INIT_FROM_METATYPE2
25+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FROM_METATYPE2_1 | %FileCheck %s -check-prefix=INIT_FROM_METATYPE2
26+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FROM_METATYPE2_2 | %FileCheck %s -check-prefix=INIT_FROM_METATYPE2
27+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FROM_METATYPE2_3 | %FileCheck %s -check-prefix=INIT_FROM_METATYPE2
2028
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FROM_METATYPE3 | %FileCheck %s -check-prefix=INIT_FROM_METATYPE3
2129
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FROM_METATYPE4 | %FileCheck %s -check-prefix=INIT_FROM_METATYPE4
2230
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_FROM_METATYPE5 | %FileCheck %s -check-prefix=INIT_FROM_METATYPE4
@@ -198,10 +206,12 @@ func testGetInitFromMetatype1() {
198206

199207
func testGetInitFromMetatype2() {
200208
var SS = ExplicitConstructorsBase1.self
201-
SS.#^INIT_FROM_METATYPE2^#
209+
SS.#^INIT_FROM_METATYPE2_1^#
210+
SS#^INIT_FROM_METATYPE2_2^#
211+
SS(#^INIT_FROM_METATYPE2_3^#
202212
}
203213

204-
// INIT_FROM_METATYPE2-NOT: Decl[Constructor]/CurrNominal: init()[#ExplicitConstructorsBase1#]{{; name=.+$}}
214+
// INIT_FROM_METATYPE2-NOT: Decl[Constructor]
205215

206216
func testGetInitFromMetatype3() {
207217
var SS = ExplicitConstructorsBase1.self
@@ -245,6 +255,24 @@ func testHaveComma1() {
245255
// HAVE_COMMA_1-NOT: Decl[Constructor]
246256
}
247257

258+
//===--- Test that we show default constuctors inherited from protocols
259+
260+
protocol ProtDefaultInit {}
261+
extension ProtDefaultInit { init(foo: Int) {}}
262+
263+
class ConformsToProtDefaultInit: ProtDefaultInit {
264+
init(bar: Int) {}
265+
}
266+
267+
func testHasDefaultInitFromProtocol() {
268+
ConformsToProtDefaultInit#^DEFAULT_INIT_FROM_PROT_NODOT^#
269+
ConformsToProtDefaultInit.#^DEFAULT_INIT_FROM_PROT_DOT^#
270+
ConformsToProtDefaultInit(#^DEFAULT_INIT_FROM_PROT_PAREN^#
271+
272+
// DEFAULT_INIT_FROM_PROT-DAG: Decl[Constructor]/CurrNominal: {{.+}}{#bar: Int#}
273+
// DEFAULT_INIT_FROM_PROT-DAG: Decl[Constructor]/Super: {{.+}}{#foo: Int#}
274+
}
275+
248276
class WithAlias1 {
249277
init(busted: B) {}
250278
init(working: Int) {}

test/IDE/complete_init_inherited.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TEST_B | %FileCheck %s -check-prefix=TEST_B
33
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TEST_C | %FileCheck %s -check-prefix=TEST_C
44
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TEST_D | %FileCheck %s -check-prefix=TEST_D
5+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TEST_D_DOT | %FileCheck %s -check-prefix=TEST_D_DOT
6+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TEST_D_PAREN | %FileCheck %s -check-prefix=TEST_D_PAREN
57

68
class A {
79
init(int i: Int) {}
@@ -65,6 +67,14 @@ class D : C {
6567
// TEST_D-NEXT: Keyword[self]/CurrNominal: .self[#D.Type#]; name=self
6668
// TEST_D-NEXT: End completions
6769

70+
// TEST_D_DOT: Decl[Constructor]/CurrNominal: init({#d: D#})[#D#]; name=init(d: D)
71+
// TEST_D_DOT-NEXT: Decl[Constructor]/CurrNominal: init({#int: Int#})[#D#]; name=init(int: Int)
72+
// TEST_D_DOT-NEXT: Decl[Constructor]/Super: init({#c: C#})[#C#]; name=init(c: C)
73+
74+
// TEST_D_PAREN: Decl[Constructor]/CurrNominal: ['(']{#d: D#}[')'][#D#]; name=d: D
75+
// TEST_D_PAREN-NEXT: Decl[Constructor]/CurrNominal: ['(']{#int: Int#}[')'][#D#]; name=int: Int
76+
// TEST_D_PAREN-NEXT: Decl[Constructor]/Super: ['(']{#c: C#}[')'][#C#]; name=c: C
77+
6878
func testA() {
6979
A#^TEST_A^#
7080
}
@@ -79,4 +89,6 @@ func testC() {
7989

8090
func testD() {
8191
D#^TEST_D^#
92+
D.#^TEST_D_DOT^#
93+
D(#^TEST_D_PAREN^#
8294
}

0 commit comments

Comments
 (0)