Skip to content

Commit 837ce17

Browse files
authored
Merge pull request #60207 from simanerush/code-completion-foreach
2 parents 5494161 + 90984b7 commit 837ce17

File tree

5 files changed

+47
-8
lines changed

5 files changed

+47
-8
lines changed

include/swift/IDE/CodeCompletionResult.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ enum class CompletionKind : uint8_t {
214214
ReturnStmtExpr,
215215
YieldStmtExpr,
216216
ForEachSequence,
217+
218+
/// The \c in keyword in a for-each loop.
219+
ForEachInKw,
217220
AfterPoundExpr,
218221
AfterPoundDirective,
219222
PlatformConditon,

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ class CodeCompletionCallbacks {
137137
/// -- no tokens provided by user.
138138
virtual void completeForEachSequenceBeginning(CodeCompletionExpr *E) {};
139139

140+
/// Complete the \c in keyword in a for-each loop.
141+
virtual void completeForEachInKeyword(){};
142+
140143
/// Complete a given expr-postfix.
141144
virtual void completePostfixExpr(Expr *E, bool hasSpace) {};
142145

lib/IDE/CodeCompletion.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
242242
void completeStmtOrExpr(CodeCompletionExpr *E) override;
243243
void completePostfixExprBeginning(CodeCompletionExpr *E) override;
244244
void completeForEachSequenceBeginning(CodeCompletionExpr *E) override;
245+
void completeForEachInKeyword() override;
245246
void completePostfixExpr(Expr *E, bool hasSpace) override;
246247
void completePostfixExprParen(Expr *E, Expr *CodeCompletionE) override;
247248
void completeExprKeyPath(KeyPathExpr *KPE, SourceLoc DotLoc) override;
@@ -365,6 +366,12 @@ void CodeCompletionCallbacksImpl::completeForEachSequenceBeginning(
365366
CodeCompleteTokenExpr = E;
366367
}
367368

369+
void CodeCompletionCallbacksImpl::completeForEachInKeyword() {
370+
assert(P.Tok.is(tok::code_complete));
371+
Kind = CompletionKind::ForEachInKw;
372+
CurDeclContext = P.CurDeclContext;
373+
}
374+
368375
void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E, bool hasSpace) {
369376
assert(P.Tok.is(tok::code_complete));
370377

@@ -1069,6 +1076,9 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
10691076
addKeyword(Sink, "await", CodeCompletionKeywordKind::None);
10701077
addKeyword(Sink, "var", CodeCompletionKeywordKind::kw_var);
10711078
addKeyword(Sink, "case", CodeCompletionKeywordKind::kw_case);
1079+
break;
1080+
case CompletionKind::ForEachInKw:
1081+
addKeyword(Sink, "in", CodeCompletionKeywordKind::kw_in);
10721082
}
10731083
}
10741084

@@ -1960,6 +1970,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
19601970
case CompletionKind::CaseStmtKeyword:
19611971
case CompletionKind::EffectsSpecifier:
19621972
case CompletionKind::ForEachPatternBeginning:
1973+
case CompletionKind::ForEachInKw:
19631974
// Handled earlier by keyword completions.
19641975
break;
19651976
}

lib/Parse/ParseStmt.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,14 +2292,23 @@ ParserResult<Stmt> Parser::parseStmtForEach(LabeledStmtInfo LabelInfo) {
22922292
diagnose(LBraceLoc, diag::expected_foreach_container);
22932293
Container = makeParserErrorResult(new (Context) ErrorExpr(LBraceLoc));
22942294
} else if (Tok.is(tok::code_complete)) {
2295-
Container =
2296-
makeParserResult(new (Context) CodeCompletionExpr(Tok.getLoc()));
2297-
Container.setHasCodeCompletionAndIsError();
2298-
Status |= Container;
2299-
if (CodeCompletion)
2300-
CodeCompletion->completeForEachSequenceBeginning(
2301-
cast<CodeCompletionExpr>(Container.get()));
2302-
consumeToken(tok::code_complete);
2295+
// If there is no "in" keyword, suggest it. Otherwise, complete the
2296+
// sequence.
2297+
if (InLoc.isInvalid()) {
2298+
if (CodeCompletion)
2299+
CodeCompletion->completeForEachInKeyword();
2300+
consumeToken(tok::code_complete);
2301+
return makeParserCodeCompletionStatus();
2302+
} else {
2303+
Container =
2304+
makeParserResult(new (Context) CodeCompletionExpr(Tok.getLoc()));
2305+
Container.setHasCodeCompletionAndIsError();
2306+
Status |= Container;
2307+
if (CodeCompletion)
2308+
CodeCompletion->completeForEachSequenceBeginning(
2309+
cast<CodeCompletionExpr>(Container.get()));
2310+
consumeToken(tok::code_complete);
2311+
}
23032312
} else {
23042313
Container = parseExprBasic(diag::expected_foreach_container);
23052314
Status |= Container;

test/IDE/complete_loop.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LOOP_3 | %FileCheck %s -check-prefix=LOOP_3
66
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LOOP_4 | %FileCheck %s -check-prefix=LOOP_4
77
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LOOP_5 | %FileCheck %s -check-prefix=LOOP_5
8+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LOOP_6 | %FileCheck %s -check-prefix=LOOP_6
9+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LOOP_7 | %FileCheck %s -check-prefix=LOOP_6
810

911
class Gen {
1012
func IntGen() -> Int { return 0 }
@@ -67,3 +69,14 @@ class C {
6769
}
6870
// LOOP_5: Begin completions
6971
}
72+
73+
// https://github.com/apple/swift/issues/58633
74+
do {
75+
for value #^LOOP_6^#
76+
}
77+
do {
78+
for value #^LOOP_7^# 1..<7 {}
79+
}
80+
// LOOP_6: Begin completions, 1 items
81+
// LOOP_6-CHECK-NEXT: Keyword[in]/None: in; name=in
82+
// LOOP_6-CHECK-NEXT: End completions

0 commit comments

Comments
 (0)