Skip to content

Commit bbc714d

Browse files
committed
[CodeComplete] Use ASTScope lookup in getStmtLabelCompletions
Use the same lookup logic that we use for regular compilation.
1 parent 26f91ca commit bbc714d

File tree

2 files changed

+21
-43
lines changed

2 files changed

+21
-43
lines changed

lib/IDE/CompletionLookup.cpp

+12-43
Original file line numberDiff line numberDiff line change
@@ -3500,54 +3500,23 @@ void CompletionLookup::lookupExternalModuleDecls(
35003500
}
35013501

35023502
void CompletionLookup::getStmtLabelCompletions(SourceLoc Loc, bool isContinue) {
3503-
class LabelFinder : public ASTWalker {
3504-
SourceManager &SM;
3505-
SourceLoc TargetLoc;
3506-
bool IsContinue;
3507-
3508-
public:
3509-
SmallVector<Identifier, 2> Result;
3510-
3511-
/// Walk only the arguments of a macro.
3512-
MacroWalking getMacroWalkingBehavior() const override {
3513-
return MacroWalking::Arguments;
3514-
}
3515-
3516-
LabelFinder(SourceManager &SM, SourceLoc TargetLoc, bool IsContinue)
3517-
: SM(SM), TargetLoc(TargetLoc), IsContinue(IsContinue) {}
3518-
3519-
PreWalkResult<Stmt *> walkToStmtPre(Stmt *S) override {
3520-
if (SM.isBeforeInBuffer(S->getEndLoc(), TargetLoc))
3521-
return Action::SkipNode(S);
3522-
3523-
if (LabeledStmt *LS = dyn_cast<LabeledStmt>(S)) {
3524-
if (LS->getLabelInfo()) {
3525-
if (!IsContinue || LS->isPossibleContinueTarget()) {
3526-
auto label = LS->getLabelInfo().Name;
3527-
if (!llvm::is_contained(Result, label))
3528-
Result.push_back(label);
3529-
}
3530-
}
3531-
}
3503+
auto *SF = CurrDeclContext->getParentSourceFile();
3504+
llvm::SmallPtrSet<Identifier, 4> labels;
3505+
for (auto *LS : ASTScope::lookupLabeledStmts(SF, Loc)) {
3506+
if (isContinue && !LS->isPossibleContinueTarget())
3507+
continue;
35323508

3533-
return Action::Continue(S);
3534-
}
3509+
auto labelInfo = LS->getLabelInfo();
3510+
if (!labelInfo)
3511+
continue;
35353512

3536-
PostWalkResult<Stmt *> walkToStmtPost(Stmt *S) override {
3537-
return Action::Stop();
3538-
}
3513+
auto label = labelInfo.Name;
3514+
if (!labels.insert(label).second)
3515+
continue;
35393516

3540-
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
3541-
if (SM.isBeforeInBuffer(E->getEndLoc(), TargetLoc))
3542-
return Action::SkipNode(E);
3543-
return Action::Continue(E);
3544-
}
3545-
} Finder(CurrDeclContext->getASTContext().SourceMgr, Loc, isContinue);
3546-
const_cast<DeclContext *>(CurrDeclContext)->walkContext(Finder);
3547-
for (auto name : Finder.Result) {
35483517
CodeCompletionResultBuilder Builder = makeResultBuilder(
35493518
CodeCompletionResultKind::Pattern, SemanticContextKind::Local);
3550-
Builder.addTextChunk(name.str());
3519+
Builder.addTextChunk(label.str());
35513520
}
35523521
}
35533522

test/IDE/complete_controltransfer.swift

+9
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ func test(subject: Int) {
5656
// LABEL_7: Begin completions, 1 items
5757
// LABEL_7-DAG: Pattern/Local: OUTER_FOR_1;
5858
}
59+
60+
// This is illegal, but make sure we don't duplicate in completion.
61+
DUPLICATE_LABEL: do {
62+
DUPLICATE_LABEL: do {
63+
break #^LABEL_8^#
64+
// LABEL_8: Begin completions, 1 items
65+
// LABEL_8-DAG: Pattern/Local: DUPLICATE_LABEL;
66+
}
67+
}
5968
}
6069

6170
TOP_IF_1: if true {}

0 commit comments

Comments
 (0)