Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/IDE/CodeCompletion.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ enum class CompletionKind {
TypeSimpleBeginning,
TypeIdentifierWithDot,
TypeIdentifierWithoutDot,
CaseStmtKeyword,
CaseStmtBeginning,
CaseStmtDotPrefix,
NominalMemberBeginning,
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Parse/CodeCompletionCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ class CodeCompletionCallbacks {
/// Complete a given type-identifier when there is no trailing dot.
virtual void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) {};

/// Complete the beginning of a case statement at the top of switch stmt.
virtual void completeCaseStmtKeyword() {};

/// Complete at the beginning of a case stmt pattern.
virtual void completeCaseStmtBeginning() {};

Expand Down
22 changes: 19 additions & 3 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
void completeTypeIdentifierWithDot(IdentTypeRepr *ITR) override;
void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) override;

void completeCaseStmtKeyword() override;
void completeCaseStmtBeginning() override;
void completeCaseStmtDotPrefix() override;
void completeDeclAttrKeyword(Decl *D, bool Sil, bool Param) override;
Expand Down Expand Up @@ -4417,6 +4418,11 @@ void CodeCompletionCallbacksImpl::completeTypeIdentifierWithoutDot(
CurDeclContext = P.CurDeclContext;
}

void CodeCompletionCallbacksImpl::completeCaseStmtKeyword() {
Kind = CompletionKind::CaseStmtKeyword;
CurDeclContext = P.CurDeclContext;
}

void CodeCompletionCallbacksImpl::completeCaseStmtBeginning() {
assert(!InEnumElementRawValue);

Expand Down Expand Up @@ -4598,6 +4604,11 @@ static void addStmtKeywords(CodeCompletionResultSink &Sink, bool MaybeFuncBody)
#include "swift/Syntax/TokenKinds.def"
}

static void addCaseStmtKeywords(CodeCompletionResultSink &Sink) {
addKeyword(Sink, "case", CodeCompletionKeywordKind::kw_case);
addKeyword(Sink, "default", CodeCompletionKeywordKind::kw_default);
}

static void addLetVarKeywords(CodeCompletionResultSink &Sink) {
addKeyword(Sink, "let", CodeCompletionKeywordKind::kw_let);
addKeyword(Sink, "var", CodeCompletionKeywordKind::kw_var);
Expand Down Expand Up @@ -4687,6 +4698,10 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
addAnyTypeKeyword(Sink);
break;

case CompletionKind::CaseStmtKeyword:
addCaseStmtKeywords(Sink);
break;

case CompletionKind::PostfixExpr:
case CompletionKind::PostfixExprParen:
case CompletionKind::SuperExpr:
Expand Down Expand Up @@ -5189,12 +5204,13 @@ void CodeCompletionCallbacksImpl::doneParsing() {
}
}
break;
case CompletionKind::AfterIfStmtElse:
// Handled earlier by keyword completions.
break;
case CompletionKind::PrecedenceGroup:
Lookup.getPrecedenceGroupCompletions(SyntxKind);
break;
case CompletionKind::AfterIfStmtElse:
case CompletionKind::CaseStmtKeyword:
// Handled earlier by keyword completions.
break;
}

for (auto &Request: Lookup.RequestedCachedResults) {
Expand Down
5 changes: 5 additions & 0 deletions lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2274,6 +2274,11 @@ Parser::parseStmtCases(SmallVectorImpl<ASTNode> &cases, bool IsActive) {
if (auto PDD = PoundDiagnosticResult.getPtrOrNull()) {
cases.emplace_back(PDD);
}
} else if (Tok.is(tok::code_complete)) {
if (CodeCompletion)
CodeCompletion->completeCaseStmtKeyword();
consumeToken(tok::code_complete);
return makeParserCodeCompletionStatus();
} else {
// If there are non-case-label statements at the start of the switch body,
// raise an error and recover by discarding them.
Expand Down
16 changes: 16 additions & 0 deletions test/IDE/complete_keywords.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
// RUN: %FileCheck %s -check-prefix=KW_EXPR < %t.expr6
// RUN: %FileCheck %s -check-prefix=KW_EXPR_NEG < %t.expr6

// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=SWITCH_TOP | %FileCheck %s -check-prefix=KW_CASE
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=SWITCH_IN_CASE | %FileCheck %s -check-prefix=KW_CASE

// KW_RETURN: Keyword[return]/None: return{{; name=.+$}}
// KW_NO_RETURN-NOT: Keyword[return]

Expand Down Expand Up @@ -401,3 +404,16 @@ func inExpr5() {
func inExpr6() -> Int {
return #^EXPR_6^#
}

func inSwitch(val: Int) {
switch val {
#^SWITCH_TOP^#
case 1:
foo()
#^SWITCH_IN_CASE^#
}
// Begin completions
// KW_CASE-DAG: Keyword[case]/None: case; name=case
// KW_CASE-DAG: Keyword[default]/None: default; name=default
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bonus points (starter bug?): refuse to private default unless the completion's happening at the end of the switch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should implement syntactic context aware keyword completion mechanism. Currently we provide fallthrough, break, et al. even in top-level.

// End completions
}