Skip to content

Commit 2babbc3

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 4c0892f commit 2babbc3

File tree

3 files changed

+36
-12
lines changed

3 files changed

+36
-12
lines changed

lib/IDE/CodeCompletion.cpp

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

33883388
for (auto &element : sequence.drop_back(2)) {
3389-
// Unfold AssignExpr for re-typechecking sequence.
3390-
if (auto *AE = dyn_cast_or_null<AssignExpr>(element)) {
3391-
AE->setSrc(nullptr);
3392-
AE->setDest(nullptr);
3389+
// Unfold expressions for re-typechecking sequence.
3390+
if (auto *assignExpr = dyn_cast_or_null<AssignExpr>(element)) {
3391+
assignExpr->setSrc(nullptr);
3392+
assignExpr->setDest(nullptr);
3393+
} else if (auto *ifExpr = dyn_cast_or_null<IfExpr>(element)) {
3394+
ifExpr->setCondExpr(nullptr);
3395+
ifExpr->setElseExpr(nullptr);
33933396
}
33943397

33953398
// Reset any references to operators in types, so they are properly
@@ -3440,6 +3443,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
34403443
flattenBinaryExpr(assignExpr->getSrc(), sequence);
34413444
assignExpr->setDest(nullptr);
34423445
assignExpr->setSrc(nullptr);
3446+
} else if (auto ifExpr = dyn_cast<IfExpr>(expr)) {
3447+
flattenBinaryExpr(ifExpr->getCondExpr(), sequence);
3448+
sequence.push_back(ifExpr);
3449+
flattenBinaryExpr(ifExpr->getElseExpr(), sequence);
3450+
ifExpr->setCondExpr(nullptr);
3451+
ifExpr->setElseExpr(nullptr);
34433452
} else if (auto tryExpr = dyn_cast<AnyTryExpr>(expr)) {
34443453
// Strip out try expression. It doesn't affect completion.
34453454
flattenBinaryExpr(tryExpr->getSubExpr(), sequence);

lib/Sema/TypeCheckConstraints.cpp

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

22472247
// Find the code-completion expression and operator again.
2248-
BinaryExpr *exprAsBinOp = nullptr;
2249-
while (auto *binExpr = dyn_cast<BinaryExpr>(expr)) {
2250-
auto *RHS = binExpr->getArg()->getElement(1);
2248+
Expr *exprAsBinOp = nullptr;
2249+
while (true) {
2250+
Expr *RHS;
2251+
if (auto *binExpr = dyn_cast<BinaryExpr>(expr))
2252+
RHS = binExpr->getArg()->getElement(1);
2253+
else if (auto *assignExpr = dyn_cast<AssignExpr>(expr))
2254+
RHS = assignExpr->getSrc();
2255+
else if (auto *ifExpr = dyn_cast<IfExpr>(expr))
2256+
RHS = ifExpr->getElseExpr();
2257+
else
2258+
break;
2259+
22512260
if (RHS == CCE) {
2252-
exprAsBinOp = binExpr;
2261+
exprAsBinOp = expr;
22532262
break;
22542263
}
22552264
expr = RHS;
@@ -2258,7 +2267,7 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
22582267
return true;
22592268

22602269
// Ensure the output expression is up to date.
2261-
assert(exprAsBinOp == expr && "found wrong expr?");
2270+
assert(exprAsBinOp == expr && isa<BinaryExpr>(expr) && "found wrong expr?");
22622271

22632272
// Add type variable for the code-completion expression.
22642273
CCE->setActivated();

test/IDE/complete_crashes.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,11 @@ protocol Bar_38149042 {
220220
func foo_38149042(bar: Bar_38149042) {
221221
_ = bar.foo? #^RDAR_38149042^# .x
222222
}
223-
// RDAR_38149042: Begin completions, 2 items
223+
// RDAR_38149042: Begin completions
224224
// RDAR_38149042-DAG: Decl[InstanceVar]/CurrNominal: .x[#Int#]; name=x
225225
// RDAR_38149042-DAG: Keyword[self]/CurrNominal: .self[#Baz_38149042#]; name=self
226+
// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']=== {#AnyObject?#}[#Bool#]; name==== AnyObject?
227+
// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']!== {#AnyObject?#}[#Bool#]; name=!== AnyObject?
226228
// RDAR_38149042: End completions
227229

228230
// rdar://problem/38272904
@@ -274,18 +276,22 @@ func foo(x: RDAR41159258_MyResult1) {
274276

275277

276278
// rdar://problem/41232519
277-
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41232519 | %FileCheck %s -check-prefix=RDAR_41232519
279+
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41232519_1 | %FileCheck %s -check-prefix=RDAR_41232519
280+
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41232519_2 | %FileCheck %s -check-prefix=RDAR_41232519
278281
public protocol IntProvider {
279282
func nextInt() -> Int
280283
}
281284

282285
public final class IntStore {
283286
public var myInt: Int = 0
284287
func readNextInt(from provider: IntProvider) {
285-
myInt = provider.nextInt() #^RDAR41232519^#
288+
myInt = provider.nextInt() #^RDAR41232519_1^#
289+
_ = true ? 1 : provider.nextInt() #^RDAR41232519_2^#
286290
}
287291
}
288292
// RDAR_41232519: Begin completions
293+
// RDAR_41232519: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']+ {#Int#}[#Int#]; name=+ Int
294+
// RDAR_41232519: End completions
289295

290296
// rdar://problem/28188259
291297
// 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)