Skip to content

Commit ee2f39c

Browse files
committed
[CodeCompletion] Expr context type analysis for failed array literal expr
let _: [Foo] = [ .create(str: Int) .create(#^COMPLETE^#) ] Previously, this completion used to fail because the array expression isn't typechecked. We need to analyze the context type of the array literal first, that defines the type of the unresolved member expression. rdar://problem/50696432
1 parent da61cc8 commit ee2f39c

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,15 @@ class ExprContextAnalyzer {
583583
case ExprKind::Array: {
584584
if (auto type = ParsedExpr->getType()) {
585585
recordPossibleType(type);
586+
break;
587+
}
588+
589+
// Check context types of the array literal expression.
590+
ExprContextInfo arrayCtxtInfo(DC, Parent);
591+
for (auto arrayT : arrayCtxtInfo.getPossibleTypes()) {
592+
if (auto boundGenericT = arrayT->getAs<BoundGenericType>())
593+
if (boundGenericT->getDecl() == Context.getArrayDecl())
594+
recordPossibleType(boundGenericT->getGenericArgs()[0]);
586595
}
587596
break;
588597
}

test/IDE/complete_call_arg.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@
8282
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_AFTERPAREN_2 | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_AFTERPAREN_2
8383
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_SECOND | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_SECOND
8484
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_SKIPPED | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_SKIPPED
85+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_ARRAY_1_AFTERPAREN_1 | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_AFTERPAREN_1
86+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_ARRAY_1_AFTERPAREN_2 | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_AFTERPAREN_2
87+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_ARRAY_1_SECOND | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_SECOND
88+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_ARRAY_1_SKIPPED | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_SKIPPED
89+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_ARRAY_2_AFTERPAREN_1 | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_AFTERPAREN_1
90+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_ARRAY_2_AFTERPAREN_2 | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_AFTERPAREN_2
91+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_ARRAY_2_SECOND | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_SECOND
92+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICIT_MEMBER_ARRAY_2_SKIPPED | %FileCheck %s -check-prefix=IMPLICIT_MEMBER_SKIPPED
8593

8694
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ARCHETYPE_GENERIC_1 | %FileCheck %s -check-prefix=ARCHETYPE_GENERIC_1
8795

@@ -688,6 +696,39 @@ func testImplicitMember() {
688696
// IMPLICIT_MEMBER_SKIPPED: Keyword/ExprSpecific: arg4: [#Argument name#];
689697
// IMPLICIT_MEMBER_SKIPPED: End completions
690698
}
699+
func testImplicitMemberInArrayLiteral() {
700+
struct Receiver {
701+
init(_: [TestStaticMemberCall]) {}
702+
init(arg1: Int, arg2: [TestStaticMemberCall]) {}
703+
}
704+
705+
Receiver([
706+
.create1(x: 1),
707+
.create1(#^IMPLICIT_MEMBER_ARRAY_1_AFTERPAREN_1^#),
708+
// Same as IMPLICIT_MEMBER_AFTERPAREN_1.
709+
])
710+
Receiver([
711+
.create2(#^IMPLICIT_MEMBER_ARRAY_1_AFTERPAREN_2^#),
712+
// Same as IMPLICIT_MEMBER_AFTERPAREN_2.
713+
.create2(1, #^IMPLICIT_MEMBER_ARRAY_1_SECOND^#
714+
// Same as IMPLICIT_MEMBER_SECOND.
715+
])
716+
Receiver(arg1: 12, arg2: [
717+
.create2(1, arg3: 2, #^IMPLICIT_MEMBER_ARRAY_1_SKIPPED^#
718+
// Same as IMPLICIT_MEMBER_SKIPPED.
719+
.create1(x: 12)
720+
])
721+
let _: [TestStaticMemberCall] = [
722+
.create1(#^IMPLICIT_MEMBER_ARRAY_2_AFTERPAREN_1^#),
723+
// Same as STATIC_METHOD_AFTERPAREN_1.
724+
.create2(#^IMPLICIT_MEMBER_ARRAY_2_AFTERPAREN_2^#),
725+
// Same as STATIC_METHOD_AFTERPAREN_2.
726+
.create2(1, #^IMPLICIT_MEMBER_ARRAY_2_SECOND^#),
727+
// Same as STATIC_METHOD_SECOND.
728+
.create2(1, arg3: 2, #^IMPLICIT_MEMBER_ARRAY_2_SKIPPED^#),
729+
// Same as STATIC_METHOD_SKIPPED.
730+
]
731+
}
691732

692733
struct Wrap<T> {
693734
func method<U>(_ fn: (T) -> U) -> Wrap<U> {}

0 commit comments

Comments
 (0)