Skip to content

Commit 35f8686

Browse files
committed
[CodeCompletion] Remove getTypeContextEnumElementCompletions()
Use getUnresolvedmemberCompletion() instead. rdar://problem/45219937
1 parent 588d87b commit 35f8686

File tree

6 files changed

+27
-80
lines changed

6 files changed

+27
-80
lines changed

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class CodeCompletionCallbacks {
175175
virtual void completeCaseStmtKeyword() {};
176176

177177
/// Complete at the beginning of a case stmt pattern.
178-
virtual void completeCaseStmtBeginning() {};
178+
virtual void completeCaseStmtBeginning(CodeCompletionExpr *E) {};
179179

180180
/// Complete at the beginning of member of a nominal decl member -- no tokens
181181
/// provided by user.

lib/IDE/CodeCompletion.cpp

Lines changed: 8 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -338,44 +338,6 @@ std::string swift::ide::removeCodeCompletionTokens(
338338
return CleanFile;
339339
}
340340

341-
namespace {
342-
class StmtFinder : public ASTWalker {
343-
SourceManager &SM;
344-
SourceLoc Loc;
345-
StmtKind Kind;
346-
Stmt *Found = nullptr;
347-
348-
public:
349-
StmtFinder(SourceManager &SM, SourceLoc Loc, StmtKind Kind)
350-
: SM(SM), Loc(Loc), Kind(Kind) {}
351-
352-
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
353-
return { SM.rangeContainsTokenLoc(S->getSourceRange(), Loc), S };
354-
}
355-
356-
Stmt *walkToStmtPost(Stmt *S) override {
357-
if (S->getKind() == Kind) {
358-
Found = S;
359-
return nullptr;
360-
}
361-
return S;
362-
}
363-
364-
Stmt *getFoundStmt() const {
365-
return Found;
366-
}
367-
};
368-
} // end anonymous namespace
369-
370-
static Stmt *findNearestStmt(const DeclContext *DC, SourceLoc Loc,
371-
StmtKind Kind) {
372-
auto &SM = DC->getASTContext().SourceMgr;
373-
StmtFinder Finder(SM, Loc, Kind);
374-
// FIXME(thread-safety): the walker is mutating the AST.
375-
const_cast<DeclContext *>(DC)->walkContext(Finder);
376-
return Finder.getFoundStmt();
377-
}
378-
379341
CodeCompletionString::CodeCompletionString(ArrayRef<Chunk> Chunks) {
380342
std::uninitialized_copy(Chunks.begin(), Chunks.end(),
381343
getTrailingObjects<Chunk>());
@@ -1377,7 +1339,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
13771339
void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) override;
13781340

13791341
void completeCaseStmtKeyword() override;
1380-
void completeCaseStmtBeginning() override;
1342+
void completeCaseStmtBeginning(CodeCompletionExpr *E) override;
13811343
void completeDeclAttrBeginning(bool Sil, bool isIndependent) override;
13821344
void completeDeclAttrParam(DeclAttrKind DK, int Index) override;
13831345
void completeInPrecedenceGroup(SyntaxKind SK) override;
@@ -3907,27 +3869,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
39073869
}
39083870
}
39093871

3910-
void getTypeContextEnumElementCompletions(SourceLoc Loc) {
3911-
llvm::SaveAndRestore<LookupKind> ChangeLookupKind(
3912-
Kind, LookupKind::EnumElement);
3913-
NeedLeadingDot = !HaveDot;
3914-
3915-
auto *Switch = cast_or_null<SwitchStmt>(
3916-
findNearestStmt(CurrDeclContext, Loc, StmtKind::Switch));
3917-
if (!Switch)
3918-
return;
3919-
auto Ty = Switch->getSubjectExpr()->getType();
3920-
if (!Ty)
3921-
return;
3922-
ExprType = Ty;
3923-
auto *TheEnumDecl = dyn_cast_or_null<EnumDecl>(Ty->getAnyNominal());
3924-
if (!TheEnumDecl)
3925-
return;
3926-
for (auto Element : TheEnumDecl->getAllElements()) {
3927-
foundDecl(Element, DeclVisibilityKind::MemberOfCurrentNominal, {});
3928-
}
3929-
}
3930-
39313872
void getTypeCompletions(Type BaseType) {
39323873
Kind = LookupKind::Type;
39333874
this->BaseType = BaseType;
@@ -4719,11 +4660,12 @@ void CodeCompletionCallbacksImpl::completeCaseStmtKeyword() {
47194660
CurDeclContext = P.CurDeclContext;
47204661
}
47214662

4722-
void CodeCompletionCallbacksImpl::completeCaseStmtBeginning() {
4663+
void CodeCompletionCallbacksImpl::completeCaseStmtBeginning(CodeCompletionExpr *E) {
47234664
assert(!InEnumElementRawValue);
47244665

47254666
Kind = CompletionKind::CaseStmtBeginning;
47264667
CurDeclContext = P.CurDeclContext;
4668+
CodeCompleteTokenExpr = E;
47274669
}
47284670

47294671
void CodeCompletionCallbacksImpl::completeImportDecl(
@@ -5408,9 +5350,11 @@ void CodeCompletionCallbacksImpl::doneParsing() {
54085350
}
54095351

54105352
case CompletionKind::CaseStmtBeginning: {
5411-
SourceLoc Loc = P.Context.SourceMgr.getCodeCompletionLoc();
5412-
Lookup.getValueCompletionsInDeclContext(Loc);
5413-
Lookup.getTypeContextEnumElementCompletions(Loc);
5353+
ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
5354+
Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
5355+
ContextInfo.isSingleExpressionBody());
5356+
Lookup.getUnresolvedMemberCompletions(ContextInfo.getPossibleTypes());
5357+
DoPostfixExprBeginning();
54145358
break;
54155359
}
54165360

lib/IDE/TypeContextInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ContextInfoCallbacks : public CodeCompletionCallbacks {
3737

3838
void completePostfixExprBeginning(CodeCompletionExpr *E) override;
3939
void completeForEachSequenceBeginning(CodeCompletionExpr *E) override;
40-
void completeCaseStmtBeginning() override;
40+
void completeCaseStmtBeginning(CodeCompletionExpr *E) override;
4141

4242
void completeCallArg(CodeCompletionExpr *E, bool isFirst) override;
4343
void completeReturnStmt(CodeCompletionExpr *E) override;
@@ -80,7 +80,7 @@ void ContextInfoCallbacks::completeUnresolvedMember(CodeCompletionExpr *E,
8080
ParsedExpr = E;
8181
}
8282

83-
void ContextInfoCallbacks::completeCaseStmtBeginning() {
83+
void ContextInfoCallbacks::completeCaseStmtBeginning(CodeCompletionExpr *E) {
8484
// TODO: Implement?
8585
}
8686

lib/Parse/ParseStmt.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,18 +1081,19 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result,
10811081

10821082
// Do some special-case code completion for the start of the pattern.
10831083
if (P.Tok.is(tok::code_complete)) {
1084+
auto CCE = new (P.Context) CodeCompletionExpr(P.Tok.getLoc());
1085+
result.ThePattern = new (P.Context) ExprPattern(CCE);
10841086
if (P.CodeCompletion) {
10851087
switch (parsingContext) {
10861088
case GuardedPatternContext::Case:
1087-
P.CodeCompletion->completeCaseStmtBeginning();
1089+
P.CodeCompletion->completeCaseStmtBeginning(CCE);
10881090
break;
10891091
case GuardedPatternContext::Catch:
1090-
P.CodeCompletion->completePostfixExprBeginning(nullptr);
1092+
P.CodeCompletion->completePostfixExprBeginning(CCE);
10911093
break;
10921094
}
10931095
}
1094-
auto loc = P.consumeToken(tok::code_complete);
1095-
result.ThePattern = new (P.Context) AnyPattern(loc);
1096+
P.consumeToken(tok::code_complete);
10961097
status.setHasCodeCompletion();
10971098
return;
10981099
}

test/IDE/complete_enum_elements.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
// RUN: %FileCheck %s -check-prefix=FOO_ENUM_DOT < %t.enum.txt
3636

3737
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_SW_IN_PATTERN_1 > %t.enum.txt
38-
// RUN: %FileCheck %s -check-prefix=WITH_GLOBAL_RESULTS_INVALID < %t.enum.txt
38+
// RUN: %FileCheck %s -check-prefix=WITH_GLOBAL_RESULTS < %t.enum.txt
3939
// RUN: %FileCheck %s -check-prefix=ENUM_SW_IN_PATTERN_1 < %t.enum.txt
4040

4141
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_SW_IN_PATTERN_2 > %t.enum.txt
@@ -85,16 +85,19 @@
8585
enum FooEnum: CaseIterable {
8686
case Foo1
8787
case Foo2
88+
static var alias1: FooEnum { return .Foo1 }
8889
}
8990

9091
// FOO_ENUM_TYPE_CONTEXT: Begin completions
9192
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/ExprSpecific: .Foo1[#FooEnum#]{{; name=.+$}}
9293
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/ExprSpecific: .Foo2[#FooEnum#]{{; name=.+$}}
94+
// FOO_ENUM_TYPE_CONTEXT-DAG: Decl[StaticVar]/CurrNominal/TypeRelation[Identical]: .alias1[#FooEnum#]; name=alias1
9395
// FOO_ENUM_TYPE_CONTEXT: End completions
9496

9597
// FOO_ENUM_NO_DOT: Begin completions
9698
// FOO_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal: .Foo1[#FooEnum#]{{; name=.+$}}
9799
// FOO_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal: .Foo2[#FooEnum#]{{; name=.+$}}
100+
// FOO_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .alias1[#FooEnum#]{{; name=.+$}}
98101
// FOO_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .hash({#(self): FooEnum#})[#(into: inout Hasher) -> Void#]{{; name=.+$}}
99102
// FOO_ENUM_NO_DOT-NEXT: Decl[TypeAlias]/CurrNominal: .AllCases[#[FooEnum]#]{{; name=.+$}}
100103
// FOO_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .allCases[#[FooEnum]#]{{; name=.+$}}
@@ -107,6 +110,7 @@ enum FooEnum: CaseIterable {
107110
// FOO_ENUM_DOT-NEXT: Keyword/CurrNominal: Type[#FooEnum.Type#]; name=Type
108111
// FOO_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Foo1[#FooEnum#]{{; name=.+$}}
109112
// FOO_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Foo2[#FooEnum#]{{; name=.+$}}
113+
// FOO_ENUM_DOT-NEXT: Decl[StaticVar]/CurrNominal: alias1[#FooEnum#]{{; name=.+$}}
110114
// FOO_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: hash({#(self): FooEnum#})[#(into: inout Hasher) -> Void#]{{; name=.+$}}
111115
// FOO_ENUM_DOT-NEXT: Decl[TypeAlias]/CurrNominal: AllCases[#[FooEnum]#]{{; name=.+$}}
112116
// FOO_ENUM_DOT-NEXT: Decl[StaticVar]/CurrNominal: allCases[#[FooEnum]#]{{; name=.+$}}
@@ -117,14 +121,16 @@ enum FooEnum: CaseIterable {
117121
// FOO_ENUM_DOT_INVALID-NEXT: Keyword/CurrNominal: Type[#FooEnum.Type#]; name=Type
118122
// FOO_ENUM_DOT_INVALID-NEXT: Decl[EnumElement]/CurrNominal: Foo1[#FooEnum#]{{; name=.+$}}
119123
// FOO_ENUM_DOT_INVALID-NEXT: Decl[EnumElement]/CurrNominal: Foo2[#FooEnum#]{{; name=.+$}}
124+
// FOO_ENUM_DOT_INVALID-NEXT: Decl[StaticVar]/CurrNominal: alias1[#FooEnum#]{{; name=.+$}}
120125
// FOO_ENUM_DOT_INVALID-NEXT: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: hash({#(self): FooEnum#})[#(into: inout Hasher) -> Void#]{{; name=.+$}}
121126
// FOO_ENUM_DOT_INVALID-NEXT: Decl[TypeAlias]/CurrNominal: AllCases[#[FooEnum]#]{{; name=.+$}}
122127
// FOO_ENUM_DOT_INVALID-NEXT: Decl[StaticVar]/CurrNominal: allCases[#[FooEnum]#]{{; name=.+$}}
123128
// FOO_ENUM_DOT_INVALID-NEXT: End completions
124129

125-
// FOO_ENUM_DOT_ELEMENTS: Begin completions, 2 items
130+
// FOO_ENUM_DOT_ELEMENTS: Begin completions, 3 items
126131
// FOO_ENUM_DOT_ELEMENTS-NEXT: Decl[EnumElement]/ExprSpecific: Foo1[#FooEnum#]{{; name=.+$}}
127132
// FOO_ENUM_DOT_ELEMENTS-NEXT: Decl[EnumElement]/ExprSpecific: Foo2[#FooEnum#]{{; name=.+$}}
133+
// FOO_ENUM_DOT_ELEMENTS-NEXT: Decl[StaticVar]/CurrNominal/TypeRelation[Identical]: alias1[#FooEnum#]; name=alias1
128134
// FOO_ENUM_DOT_ELEMENTS-NEXT: End completions
129135

130136
enum BarEnum {
@@ -295,13 +301,9 @@ enum QuxEnum : Int {
295301
func freeFunc() {}
296302

297303
// WITH_GLOBAL_RESULTS: Begin completions
298-
// WITH_GLOBAL_RESULTS: Decl[FreeFunction]/CurrModule: freeFunc()[#Void#]{{; name=.+$}}
304+
// WITH_GLOBAL_RESULTS: Decl[FreeFunction]/CurrModule/NotRecommended/TypeRelation[Invalid]: freeFunc()[#Void#]{{; name=.+$}}
299305
// WITH_GLOBAL_RESULTS: End completions
300306

301-
// WITH_GLOBAL_RESULTS_INVALID: Begin completions
302-
// WITH_GLOBAL_RESULTS_INVALID: Decl[FreeFunction]/CurrModule/NotRecommended/TypeRelation[Invalid]: freeFunc()[#Void#]{{; name=.+$}}
303-
// WITH_GLOBAL_RESULTS_INVALID: End completions
304-
305307
//===--- Complete enum elements in 'switch'.
306308

307309
func testSwitch1(e: FooEnum) {

test/IDE/complete_value_expr.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,8 @@ func testSwitch1() {
637637
}
638638

639639
// IN_SWITCH_CASE: Begin completions
640-
// IN_SWITCH_CASE-DAG: Decl[GlobalVar]/CurrModule: fooObject[#FooStruct#]{{; name=.+$}}
641-
// IN_SWITCH_CASE-DAG: Decl[Struct]/CurrModule: FooStruct[#FooStruct#]{{; name=.+$}}
640+
// IN_SWITCH_CASE-DAG: Decl[GlobalVar]/CurrModule{{(/TypeRelation\[Identical\])?}}: fooObject[#FooStruct#]{{; name=.+$}}
641+
// IN_SWITCH_CASE-DAG: Decl[Struct]/CurrModule{{(/TypeRelation\[Identical\])?}}: FooStruct[#FooStruct#]{{; name=.+$}}
642642
// IN_SWITCH_CASE: End completions
643643

644644
//===--- Helper types that are used in this test

0 commit comments

Comments
 (0)