Skip to content

Commit 65ec365

Browse files
authored
Merge pull request #11059 from benlangmuir/cc-foreach-seq
[code-completion] Add a new custom completion context for a for-each sequence
2 parents a689b34 + 93d22c9 commit 65ec365

File tree

10 files changed

+51
-0
lines changed

10 files changed

+51
-0
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@ enum class CompletionKind {
501501
AssignmentRHS,
502502
CallArg,
503503
ReturnStmtExpr,
504+
ForEachSequence,
504505
AfterPound,
505506
GenericParams,
506507
SwiftKeyPath,

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ class CodeCompletionCallbacks {
151151
/// by user.
152152
virtual void completePostfixExprBeginning(CodeCompletionExpr *E) = 0;
153153

154+
/// \brief Complete the beginning of expr-postfix in a for-each loop sequqence
155+
/// -- no tokens provided by user.
156+
virtual void completeForEachSequenceBeginning(CodeCompletionExpr *E) = 0;
157+
154158
/// \brief Complete a given expr-postfix.
155159
virtual void completePostfixExpr(Expr *E, bool hasSpace) = 0;
156160

lib/IDE/CodeCompletion.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
14401440
void completeDotExpr(Expr *E, SourceLoc DotLoc) override;
14411441
void completeStmtOrExpr() override;
14421442
void completePostfixExprBeginning(CodeCompletionExpr *E) override;
1443+
void completeForEachSequenceBeginning(CodeCompletionExpr *E) override;
14431444
void completePostfixExpr(Expr *E, bool hasSpace) override;
14441445
void completePostfixExprParen(Expr *E, Expr *CodeCompletionE) override;
14451446
void completeExprSuper(SuperRefExpr *SRE) override;
@@ -4479,6 +4480,14 @@ void CodeCompletionCallbacksImpl::completePostfixExprBeginning(CodeCompletionExp
44794480
CodeCompleteTokenExpr = E;
44804481
}
44814482

4483+
void CodeCompletionCallbacksImpl::completeForEachSequenceBeginning(
4484+
CodeCompletionExpr *E) {
4485+
assert(P.Tok.is(tok::code_complete));
4486+
Kind = CompletionKind::ForEachSequence;
4487+
CurDeclContext = P.CurDeclContext;
4488+
CodeCompleteTokenExpr = E;
4489+
}
4490+
44824491
void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E, bool hasSpace) {
44834492
assert(P.Tok.is(tok::code_complete));
44844493

@@ -4840,6 +4849,7 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
48404849
case CompletionKind::AssignmentRHS:
48414850
case CompletionKind::ReturnStmtExpr:
48424851
case CompletionKind::PostfixExprBeginning:
4852+
case CompletionKind::ForEachSequence:
48434853
addSuperKeyword(Sink);
48444854
addLetVarKeywords(Sink);
48454855
addExprKeywords(Sink);
@@ -5191,6 +5201,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
51915201
DoPostfixExprBeginning();
51925202
break;
51935203

5204+
case CompletionKind::ForEachSequence:
51945205
case CompletionKind::PostfixExprBeginning: {
51955206
::CodeCompletionTypeContextAnalyzer Analyzer(CurDeclContext,
51965207
CodeCompleteTokenExpr);

lib/Parse/ParseStmt.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,6 +2098,15 @@ ParserResult<Stmt> Parser::parseStmtForEach(SourceLoc ForLoc,
20982098
SourceLoc LBraceLoc = Tok.getLoc();
20992099
diagnose(LBraceLoc, diag::expected_foreach_container);
21002100
Container = makeParserErrorResult(new (Context) ErrorExpr(LBraceLoc));
2101+
} else if (Tok.is(tok::code_complete)) {
2102+
Container =
2103+
makeParserResult(new (Context) CodeCompletionExpr(Tok.getLoc()));
2104+
Container.setHasCodeCompletion();
2105+
Status |= Container;
2106+
if (CodeCompletion)
2107+
CodeCompletion->completeForEachSequenceBeginning(
2108+
cast<CodeCompletionExpr>(Container.get()));
2109+
consumeToken(tok::code_complete);
21012110
} else {
21022111
Container = parseExprBasic(diag::expected_foreach_container);
21032112
if (Container.isNull())

test/SourceKit/CodeComplete/Inputs/custom-completion/custom.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
source.lang.swift.stmt,
2525
source.lang.swift.type
2626
]
27+
},
28+
{
29+
key.name: "customForEach",
30+
key.kind: myuid.customForEach,
31+
key.context: [
32+
source.lang.swift.foreach.sequence,
33+
]
2734
}
2835
]
2936
}

test/SourceKit/CodeComplete/complete_custom.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ func test() {
22
// stmt
33
()
44
let foo: // type
5+
for x in { } // foreach.sequence
56
}
67

78
// ===--- Errors
@@ -62,6 +63,14 @@ func test() {
6263
// TYPE-NEXT: key.name: "customType"
6364
// TYPE-NOT: myuid
6465

66+
// RUN: %sourcekitd-test -json-request-path %S/Inputs/custom-completion/custom.json == \
67+
// RUN: -req=complete.open -pos=5:12 %s -- %s | %FileCheck %s -check-prefix=FOREACH
68+
69+
// FOREACH-NOT: myuid
70+
// FOREACH: myuid.customForEach
71+
// FOREACH-NEXT: key.name: "customForEach"
72+
// FOREACH-NOT: myuid
73+
6574
// ===--- Filtering.
6675

6776
// RUN: %sourcekitd-test -json-request-path %S/Inputs/custom-completion/custom.json == \

tools/SourceKit/include/SourceKit/Core/LangSupport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ struct CustomCompletionInfo {
141141
Stmt = 1 << 0,
142142
Expr = 1 << 1,
143143
Type = 1 << 2,
144+
ForEachSequence = 1 << 3,
144145
};
145146
swift::OptionSet<Context> Contexts;
146147
};

tools/SourceKit/include/SourceKit/Core/ProtocolUIDs.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ KIND(ObjectLiteral, "source.lang.swift.syntaxtype.objectliteral")
276276
KIND(Expr, "source.lang.swift.expr")
277277
KIND(Stmt, "source.lang.swift.stmt")
278278
KIND(Type, "source.lang.swift.type")
279+
KIND(ForEachSequence, "source.lang.swift.foreach.sequence")
279280

280281
KIND(DiagNote, "source.diagnostic.severity.note")
281282
KIND(DiagWarning, "source.diagnostic.severity.warning")

tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ bool SourceKit::CodeCompletion::addCustomCompletions(
184184
addCompletion(custom);
185185
}
186186
break;
187+
case CompletionKind::ForEachSequence:
188+
if (custom.Contexts.contains(CustomCompletionInfo::ForEachSequence)) {
189+
changed = true;
190+
addCompletion(custom);
191+
}
192+
break;
187193
case CompletionKind::TypeSimpleBeginning:
188194
if (custom.Contexts.contains(CustomCompletionInfo::Type)) {
189195
changed = true;

tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ void handleRequestImpl(sourcekitd_object_t ReqObj, ResponseReceiver Rec) {
593593
CCInfo.Contexts |= CustomCompletionInfo::Stmt;
594594
} else if (context == KindType) {
595595
CCInfo.Contexts |= CustomCompletionInfo::Type;
596+
} else if (context == KindForEachSequence) {
597+
CCInfo.Contexts |= CustomCompletionInfo::ForEachSequence;
596598
} else {
597599
err = createErrorRequestInvalid("invalid value for 'key.context'");
598600
return true;

0 commit comments

Comments
 (0)