Skip to content

Commit 0dfbf76

Browse files
committed
[CodeCompletion] Improve getReturnTypeFromContext()
* For methods, un-curry function interface type so we can get declared return type. * For closures, fall back to getting explicit result type in case we cannot retrieve it from the type of closure itself.
1 parent de6e280 commit 0dfbf76

File tree

2 files changed

+66
-10
lines changed

2 files changed

+66
-10
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,13 +1509,20 @@ static bool isTopLevelContext(const DeclContext *DC) {
15091509
static Type getReturnTypeFromContext(const DeclContext *DC) {
15101510
if (auto FD = dyn_cast<AbstractFunctionDecl>(DC)) {
15111511
if (FD->hasInterfaceType()) {
1512-
if (auto FT = FD->getInterfaceType()->getAs<FunctionType>()) {
1512+
auto Ty = FD->getInterfaceType();
1513+
if (FD->getDeclContext()->isTypeContext())
1514+
Ty = FD->getMethodInterfaceType();
1515+
if (auto FT = Ty->getAs<AnyFunctionType>())
15131516
return FT->getResult();
1514-
}
15151517
}
1516-
} else if (auto CE = dyn_cast<AbstractClosureExpr>(DC)) {
1517-
if (CE->getType()) {
1518-
return CE->getResultType();
1518+
} else if (auto ACE = dyn_cast<AbstractClosureExpr>(DC)) {
1519+
if (ACE->getType())
1520+
return ACE->getResultType();
1521+
if (auto CE = dyn_cast<ClosureExpr>(ACE)) {
1522+
if (CE->hasExplicitResultType())
1523+
return const_cast<ClosureExpr *>(CE)
1524+
->getExplicitResultTypeLoc()
1525+
.getType();
15191526
}
15201527
}
15211528
return Type();
@@ -5452,11 +5459,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
54525459

54535460
case CompletionKind::ReturnStmtExpr : {
54545461
SourceLoc Loc = P.Context.SourceMgr.getCodeCompletionLoc();
5455-
if (auto FD = dyn_cast<AbstractFunctionDecl>(CurDeclContext)) {
5456-
if (auto FT = FD->getInterfaceType()->getAs<FunctionType>()) {
5457-
Lookup.setExpectedTypes(FT->getResult());
5458-
}
5459-
}
5462+
Lookup.setExpectedTypes(getReturnTypeFromContext(CurDeclContext));
54605463
Lookup.getValueCompletionsInDeclContext(Loc);
54615464
break;
54625465
}

test/IDE/complete_return.swift

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR1 | %FileCheck %s -check-prefix=RETURN_TR1
88
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR2 | %FileCheck %s -check-prefix=RETURN_TR2
99
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR3 | %FileCheck %s -check-prefix=RETURN_TR3
10+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR1_METHOD | %FileCheck %s -check-prefix=RETURN_TR1
11+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR2_METHOD | %FileCheck %s -check-prefix=RETURN_TR2
12+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR3_METHOD | %FileCheck %s -check-prefix=RETURN_TR3
13+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR1_STATICMETHOD | %FileCheck %s -check-prefix=RETURN_TR1
14+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR2_STATICMETHOD | %FileCheck %s -check-prefix=RETURN_TR2
15+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR3_STATICMETHOD | %FileCheck %s -check-prefix=RETURN_TR3
16+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR1_CLOSURE | %FileCheck %s -check-prefix=RETURN_TR1
17+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR2_CLOSURE | %FileCheck %s -check-prefix=RETURN_TR2
18+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_TR3_CLOSURE | %FileCheck %s -check-prefix=RETURN_TR3
1019

1120
struct FooStruct {
1221
var instanceVar : Int
@@ -104,3 +113,47 @@ func testTR3(_ g : Gen) -> Int? {
104113
// RETURN_TR3-DAG: Decl[InstanceMethod]/CurrNominal: InternalStringOpGen()[#String?#]{{; name=.+$}}
105114
// RETURN_TR3-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: InternalIntTaker({#(i1): Int#}, {#i2: Int#})[#Void#]{{; name=.+$}}
106115
// RETURN_TR3-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: InternalStringTaker({#(s1): String#}, {#s2: String#})[#Void#]{{; name=.+$}}
116+
117+
struct TestStruct {
118+
func testTR1_method() -> Int? {
119+
var i : Int
120+
var oi : Int?
121+
var fs : FooStruct
122+
return #^RETURN_TR1_METHOD^#
123+
}
124+
func testTR2_method(_ g : Gen) -> Int? {
125+
return g.#^RETURN_TR2_METHOD^#
126+
}
127+
func testTR3_method(_ g : Gen) -> Int? {
128+
return g.IG.#^RETURN_TR3_METHOD^#
129+
}
130+
131+
static func testTR1_static() -> Int? {
132+
var i : Int
133+
var oi : Int?
134+
var fs : FooStruct
135+
return #^RETURN_TR1_STATICMETHOD^#
136+
}
137+
static func testTR2_static(_ g : Gen) -> Int? {
138+
return g.#^RETURN_TR2_STATICMETHOD^#
139+
}
140+
static func testTR3_static(_ g : Gen) -> Int? {
141+
return g.IG.#^RETURN_TR3_STATICMETHOD^#
142+
}
143+
}
144+
145+
func testClosures(_ g: Gen) {
146+
var i : Int
147+
var oi : Int?
148+
var fs : FooStruct
149+
150+
_ = { () -> Int? in
151+
return #^RETURN_TR1_CLOSURE^#
152+
}
153+
_ = { () -> Int? in
154+
return g.#^RETURN_TR2_CLOSURE^#
155+
}
156+
_ = { () -> Int? in
157+
return g.IG.#^RETURN_TR3_CLOSURE^#
158+
}
159+
}

0 commit comments

Comments
 (0)