Skip to content

Commit df5c4b5

Browse files
committed
[CodeComplete] Handle ternary expression in sequence completion
Follow-up to f577578. The same treatment for ternary expression (IfExpr). Plus, fix a regression introduced in f577578 where infix operators were disappeard from results.
1 parent 20a2a23 commit df5c4b5

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,10 +3468,13 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
34683468
prepareForRetypechecking(SE);
34693469

34703470
for (auto &element : sequence.drop_back(2)) {
3471-
// Unfold AssignExpr for re-typechecking sequence.
3472-
if (auto *AE = dyn_cast_or_null<AssignExpr>(element)) {
3473-
AE->setSrc(nullptr);
3474-
AE->setDest(nullptr);
3471+
// Unfold expressions for re-typechecking sequence.
3472+
if (auto *assignExpr = dyn_cast_or_null<AssignExpr>(element)) {
3473+
assignExpr->setSrc(nullptr);
3474+
assignExpr->setDest(nullptr);
3475+
} else if (auto *ifExpr = dyn_cast_or_null<IfExpr>(element)) {
3476+
ifExpr->setCondExpr(nullptr);
3477+
ifExpr->setElseExpr(nullptr);
34753478
}
34763479

34773480
// Reset any references to operators in types, so they are properly
@@ -3522,6 +3525,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
35223525
flattenBinaryExpr(assignExpr->getSrc(), sequence);
35233526
assignExpr->setDest(nullptr);
35243527
assignExpr->setSrc(nullptr);
3528+
} else if (auto ifExpr = dyn_cast<IfExpr>(expr)) {
3529+
flattenBinaryExpr(ifExpr->getCondExpr(), sequence);
3530+
sequence.push_back(ifExpr);
3531+
flattenBinaryExpr(ifExpr->getElseExpr(), sequence);
3532+
ifExpr->setCondExpr(nullptr);
3533+
ifExpr->setElseExpr(nullptr);
35253534
} else if (auto tryExpr = dyn_cast<AnyTryExpr>(expr)) {
35263535
// Strip out try expression. It doesn't affect completion.
35273536
flattenBinaryExpr(tryExpr->getSubExpr(), sequence);

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,11 +2106,20 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
21062106
expr = foldSequence(SE, DC);
21072107

21082108
// Find the code-completion expression and operator again.
2109-
BinaryExpr *exprAsBinOp = nullptr;
2110-
while (auto *binExpr = dyn_cast<BinaryExpr>(expr)) {
2111-
auto *RHS = binExpr->getArg()->getElement(1);
2109+
Expr *exprAsBinOp = nullptr;
2110+
while (true) {
2111+
Expr *RHS;
2112+
if (auto *binExpr = dyn_cast<BinaryExpr>(expr))
2113+
RHS = binExpr->getArg()->getElement(1);
2114+
else if (auto *assignExpr = dyn_cast<AssignExpr>(expr))
2115+
RHS = assignExpr->getSrc();
2116+
else if (auto *ifExpr = dyn_cast<IfExpr>(expr))
2117+
RHS = ifExpr->getElseExpr();
2118+
else
2119+
break;
2120+
21122121
if (RHS == CCE) {
2113-
exprAsBinOp = binExpr;
2122+
exprAsBinOp = expr;
21142123
break;
21152124
}
21162125
expr = RHS;
@@ -2119,7 +2128,7 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
21192128
return true;
21202129

21212130
// Ensure the output expression is up to date.
2122-
assert(exprAsBinOp == expr && "found wrong expr?");
2131+
assert(exprAsBinOp == expr && isa<BinaryExpr>(expr) && "found wrong expr?");
21232132

21242133
// Add type variable for the code-completion expression.
21252134
auto tvRHS =

test/IDE/complete_crashes.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,10 @@ protocol Bar_38149042 {
220220
func foo_38149042(bar: Bar_38149042) {
221221
_ = bar.foo? #^RDAR_38149042^# .x
222222
}
223-
224223
// RDAR_38149042: Begin completions
225224
// RDAR_38149042-DAG: Decl[InstanceVar]/CurrNominal: .x[#Int#]; name=x
225+
// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']=== {#AnyObject?#}[#Bool#]; name==== AnyObject?
226+
// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']!== {#AnyObject?#}[#Bool#]; name=!== AnyObject?
226227
// RDAR_38149042: End completions
227228

228229
// rdar://problem/38272904
@@ -274,18 +275,22 @@ func foo(x: RDAR41159258_MyResult1) {
274275

275276

276277
// rdar://problem/41232519
277-
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41232519 | %FileCheck %s -check-prefix=RDAR_41232519
278+
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41232519_1 | %FileCheck %s -check-prefix=RDAR_41232519
279+
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41232519_2 | %FileCheck %s -check-prefix=RDAR_41232519
278280
public protocol IntProvider {
279281
func nextInt() -> Int
280282
}
281283

282284
public final class IntStore {
283285
public var myInt: Int = 0
284286
func readNextInt(from provider: IntProvider) {
285-
myInt = provider.nextInt() #^RDAR41232519^#
287+
myInt = provider.nextInt() #^RDAR41232519_1^#
288+
_ = true ? 1 : provider.nextInt() #^RDAR41232519_2^#
286289
}
287290
}
288291
// RDAR_41232519: Begin completions
292+
// RDAR_41232519: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']+ {#Int#}[#Int#]; name=+ Int
293+
// RDAR_41232519: End completions
289294

290295
// rdar://problem/28188259
291296
// RUN: %target-swift-ide-test -code-completion -code-completion-token=RDAR_28188259 -source-filename=%s | %FileCheck %s -check-prefix=RDAR_28188259

0 commit comments

Comments
 (0)