Skip to content

Commit 114f473

Browse files
authored
Merge pull request swiftlang#25787 from rintaro/ide-completion-eliminatesuper
[CodeCompletion] Eliminate super related completion
2 parents 166d0fa + 257b617 commit 114f473

File tree

6 files changed

+41
-139
lines changed

6 files changed

+41
-139
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,6 @@ enum class CompletionKind {
485485
PostfixExprBeginning,
486486
PostfixExpr,
487487
PostfixExprParen,
488-
SuperExpr,
489-
SuperExprDot,
490488
KeyPathExprObjC,
491489
KeyPathExprSwift,
492490
TypeDeclResultBeginning,

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,6 @@ class CodeCompletionCallbacks {
143143
/// left parenthesis.
144144
virtual void completePostfixExprParen(Expr *E, Expr *CodeCompletionE) {};
145145

146-
/// Complete expr-super after we have consumed the 'super' keyword.
147-
virtual void completeExprSuper(SuperRefExpr *SRE) {};
148-
149-
/// Complete expr-super after we have consumed the 'super' keyword and
150-
/// a dot.
151-
virtual void completeExprSuperDot(SuperRefExpr *SRE) {};
152-
153146
/// Complete the argument to an Objective-C #keyPath
154147
/// expression.
155148
///

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,7 @@ class Parser {
13231323
ParserResult<Expr> parseExprKeyPathObjC();
13241324
ParserResult<Expr> parseExprKeyPath();
13251325
ParserResult<Expr> parseExprSelector();
1326-
ParserResult<Expr> parseExprSuper(bool isExprBasic);
1326+
ParserResult<Expr> parseExprSuper();
13271327
ParserResult<Expr> parseExprConfiguration();
13281328
ParserResult<Expr> parseExprStringLiteral();
13291329
ParserResult<Expr> parseExprTypeOf();

lib/IDE/CodeCompletion.cpp

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,8 +1329,6 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
13291329
void completeForEachSequenceBeginning(CodeCompletionExpr *E) override;
13301330
void completePostfixExpr(Expr *E, bool hasSpace) override;
13311331
void completePostfixExprParen(Expr *E, Expr *CodeCompletionE) override;
1332-
void completeExprSuper(SuperRefExpr *SRE) override;
1333-
void completeExprSuperDot(SuperRefExpr *SRE) override;
13341332
void completeExprKeyPath(KeyPathExpr *KPE, SourceLoc DotLoc) override;
13351333

13361334
void completeTypeDeclResultBeginning() override;
@@ -3256,6 +3254,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
32563254
}
32573255

32583256
void getPostfixKeywordCompletions(Type ExprType, Expr *ParsedExpr) {
3257+
if (IsSuperRefExpr)
3258+
return;
3259+
32593260
if (!ExprType->getAs<ModuleType>()) {
32603261
addKeyword(getTokenText(tok::kw_self), ExprType->getRValueType(),
32613262
SemanticContextKind::CurrentNominal,
@@ -3508,6 +3509,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
35083509
}
35093510

35103511
void getOperatorCompletions(Expr *LHS, ArrayRef<Expr *> leadingSequence) {
3512+
if (IsSuperRefExpr)
3513+
return;
3514+
35113515
Expr *foldedExpr = typeCheckLeadingSequence(LHS, leadingSequence);
35123516

35133517
std::vector<OperatorDecl *> operators = collectOperators();
@@ -4558,36 +4562,6 @@ void CodeCompletionCallbacksImpl::completePostfixExprParen(Expr *E,
45584562
}
45594563
}
45604564

4561-
void CodeCompletionCallbacksImpl::completeExprSuper(SuperRefExpr *SRE) {
4562-
// Don't produce any results in an enum element.
4563-
if (InEnumElementRawValue)
4564-
return;
4565-
4566-
Kind = CompletionKind::SuperExpr;
4567-
if (ParseExprSelectorContext != ObjCSelectorContext::None) {
4568-
PreferFunctionReferencesToCalls = true;
4569-
CompleteExprSelectorContext = ParseExprSelectorContext;
4570-
}
4571-
4572-
ParsedExpr = SRE;
4573-
CurDeclContext = P.CurDeclContext;
4574-
}
4575-
4576-
void CodeCompletionCallbacksImpl::completeExprSuperDot(SuperRefExpr *SRE) {
4577-
// Don't produce any results in an enum element.
4578-
if (InEnumElementRawValue)
4579-
return;
4580-
4581-
Kind = CompletionKind::SuperExprDot;
4582-
if (ParseExprSelectorContext != ObjCSelectorContext::None) {
4583-
PreferFunctionReferencesToCalls = true;
4584-
CompleteExprSelectorContext = ParseExprSelectorContext;
4585-
}
4586-
4587-
ParsedExpr = SRE;
4588-
CurDeclContext = P.CurDeclContext;
4589-
}
4590-
45914565
void CodeCompletionCallbacksImpl::completeExprKeyPath(KeyPathExpr *KPE,
45924566
SourceLoc DotLoc) {
45934567
Kind = (!KPE || KPE->isObjC()) ? CompletionKind::KeyPathExprObjC
@@ -4948,8 +4922,6 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
49484922

49494923
case CompletionKind::PostfixExpr:
49504924
case CompletionKind::PostfixExprParen:
4951-
case CompletionKind::SuperExpr:
4952-
case CompletionKind::SuperExprDot:
49534925
case CompletionKind::CaseStmtBeginning:
49544926
case CompletionKind::TypeIdentifierWithDot:
49554927
case CompletionKind::TypeIdentifierWithoutDot:
@@ -5172,6 +5144,8 @@ void CodeCompletionCallbacksImpl::doneParsing() {
51725144
}
51735145
if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(ParsedExpr)) {
51745146
Lookup.setIsSelfRefExpr(DRE->getDecl()->getFullName() == Context.Id_self);
5147+
} else if (auto *SRE = dyn_cast_or_null<SuperRefExpr>(ParsedExpr)) {
5148+
Lookup.setIsSuperRefExpr();
51755149
}
51765150

51775151
if (isInsideObjCSelector())
@@ -5299,19 +5273,6 @@ void CodeCompletionCallbacksImpl::doneParsing() {
52995273
break;
53005274
}
53015275

5302-
case CompletionKind::SuperExpr: {
5303-
Lookup.setIsSuperRefExpr();
5304-
Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
5305-
break;
5306-
}
5307-
5308-
case CompletionKind::SuperExprDot: {
5309-
Lookup.setIsSuperRefExpr();
5310-
Lookup.setHaveDot(SourceLoc());
5311-
Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
5312-
break;
5313-
}
5314-
53155276
case CompletionKind::KeyPathExprObjC: {
53165277
if (DotLoc.isValid())
53175278
Lookup.setHaveDot(DotLoc);

lib/Parse/ParseExpr.cpp

Lines changed: 21 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -866,89 +866,28 @@ static VarDecl *getImplicitSelfDeclForSuperContext(Parser &P,
866866
/// 'super' '.' 'init'
867867
/// expr-super-subscript:
868868
/// 'super' '[' expr ']'
869-
ParserResult<Expr> Parser::parseExprSuper(bool isExprBasic) {
869+
ParserResult<Expr> Parser::parseExprSuper() {
870870
SyntaxParsingContext SuperCtxt(SyntaxContext, SyntaxContextKind::Expr);
871871
// Parse the 'super' reference.
872872
SourceLoc superLoc = consumeToken(tok::kw_super);
873-
874-
VarDecl *selfDecl = getImplicitSelfDeclForSuperContext(*this,
875-
CurDeclContext,
876-
superLoc);
877-
bool ErrorOccurred = selfDecl == nullptr;
878-
879873
SyntaxContext->createNodeInPlace(SyntaxKind::SuperRefExpr);
880-
Expr *superRef = !ErrorOccurred
881-
? cast<Expr>(new (Context) SuperRefExpr(selfDecl, superLoc,
882-
/*Implicit=*/false))
883-
: cast<Expr>(new (Context) ErrorExpr(superLoc));
884-
885-
if (Tok.isAny(tok::period, tok::period_prefix)) {
886-
// 'super.' must be followed by a member or initializer ref.
887-
888-
SourceLoc dotLoc = consumeToken();
889-
890-
if (Tok.is(tok::code_complete)) {
891-
if (CodeCompletion) {
892-
if (auto *SRE = dyn_cast<SuperRefExpr>(superRef))
893-
CodeCompletion->completeExprSuperDot(SRE);
894-
}
895-
896-
// Eat the code completion token because we handled it.
897-
consumeToken(tok::code_complete);
898-
return makeParserCodeCompletionResult(superRef);
899-
}
900-
901-
DeclNameLoc nameLoc;
902-
DeclName name = parseUnqualifiedDeclName(/*afterDot=*/true, nameLoc,
903-
diag::expected_identifier_after_super_dot_expr);
904-
if (!name)
905-
return nullptr;
906874

907-
SyntaxContext->createNodeInPlace(SyntaxKind::MemberAccessExpr);
908-
return makeParserResult(
909-
new (Context) UnresolvedDotExpr(superRef, dotLoc, name, nameLoc,
910-
/*Implicit=*/false));
911-
}
912-
913-
if (Tok.isFollowingLSquare()) {
914-
// super[expr]
915-
SourceLoc lSquareLoc, rSquareLoc;
916-
SmallVector<Expr *, 2> indexArgs;
917-
SmallVector<Identifier, 2> indexArgLabels;
918-
SmallVector<SourceLoc, 2> indexArgLabelLocs;
919-
Expr *trailingClosure;
920-
921-
ParserStatus status = parseExprList(tok::l_square, tok::r_square,
922-
/*isPostfix=*/true, isExprBasic,
923-
lSquareLoc, indexArgs, indexArgLabels,
924-
indexArgLabelLocs,
925-
rSquareLoc,
926-
trailingClosure,
927-
SyntaxKind::FunctionCallArgumentList);
928-
SyntaxContext->createNodeInPlace(SyntaxKind::SubscriptExpr);
929-
return makeParserResult(
930-
status,
931-
SubscriptExpr::create(Context, superRef, lSquareLoc, indexArgs,
932-
indexArgLabels, indexArgLabelLocs, rSquareLoc,
933-
trailingClosure, ConcreteDeclRef(),
934-
/*implicit=*/false));
875+
// 'super.' must be followed by a member ref, explicit initializer ref, or
876+
// subscript call.
877+
if (Tok.isNot(tok::period, tok::period_prefix, tok::l_square,
878+
tok::code_complete)) {
879+
if (!consumeIf(tok::unknown))
880+
diagnose(Tok, diag::expected_dot_or_subscript_after_super);
881+
return nullptr;
935882
}
936883

937-
if (Tok.is(tok::code_complete)) {
938-
if (CodeCompletion) {
939-
if (auto *SRE = dyn_cast<SuperRefExpr>(superRef))
940-
CodeCompletion->completeExprSuper(SRE);
941-
}
942-
// Eat the code completion token because we handled it.
943-
consumeToken(tok::code_complete);
944-
return makeParserCodeCompletionResult(superRef);
945-
}
946-
947-
if (consumeIf(tok::unknown))
948-
return nullptr;
949-
950-
diagnose(Tok, diag::expected_dot_or_subscript_after_super);
951-
return nullptr;
884+
VarDecl *selfDecl =
885+
getImplicitSelfDeclForSuperContext(*this, CurDeclContext, superLoc);
886+
if (!selfDecl)
887+
return makeParserResult(new (Context) ErrorExpr(superLoc));
888+
889+
return makeParserResult(new (Context) SuperRefExpr(selfDecl, superLoc,
890+
/*Implicit=*/false));
952891
}
953892

954893
/// Copy a numeric literal value into AST-owned memory, stripping underscores
@@ -1188,8 +1127,10 @@ Parser::parseExprPostfixSuffix(ParserResult<Expr> Result, bool isExprBasic,
11881127
}
11891128

11901129
DeclNameLoc NameLoc;
1191-
DeclName Name = parseUnqualifiedDeclName(/*afterDot=*/true, NameLoc,
1192-
diag::expected_member_name);
1130+
Diag<> D = isa<SuperRefExpr>(Result.get())
1131+
? diag::expected_identifier_after_super_dot_expr
1132+
: diag::expected_member_name;
1133+
DeclName Name = parseUnqualifiedDeclName(/*afterDot=*/true, NameLoc, D);
11931134
if (!Name)
11941135
return nullptr;
11951136
SyntaxContext->createNodeInPlace(SyntaxKind::MemberAccessExpr);
@@ -1688,8 +1629,8 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
16881629
/*implicit=*/false));
16891630
}
16901631

1691-
case tok::kw_super: // super.foo or super[foo]
1692-
return parseExprSuper(isExprBasic);
1632+
case tok::kw_super: // 'super'
1633+
return parseExprSuper();
16931634

16941635
case tok::l_paren:
16951636
// Build a tuple expression syntax node.

test/IDE/complete_after_super.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
// RUN: %FileCheck %s -check-prefix=NO_CONSTRUCTORS < %t.super.txt
117117

118118
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLOSURE_2 > %t.super.txt
119-
// RUN: %FileCheck %s -check-prefix=COMMON_BASE_A_DOT < %t.super.txt
119+
// RUN: %FileCheck %s -check-prefix=COMMON_BASE_A_DOT_CONTEXT < %t.super.txt
120120
// RUN: %FileCheck %s -check-prefix=CLOSURE_2 < %t.super.txt
121121
// RUN: %FileCheck %s -check-prefix=NO_CONSTRUCTORS < %t.super.txt
122122

@@ -227,6 +227,15 @@ extension SuperBaseA {
227227
// COMMON_BASE_A_DOT-DAG: Decl[InstanceMethod]/CurrNominal: baseExtFunc0()[#Void#]{{; name=.+$}}
228228
// COMMON_BASE_A_DOT: End completions
229229

230+
// COMMON_BASE_A_DOT_CONTEXT: Begin completions
231+
// COMMON_BASE_A_DOT_CONTEXT-DAG: Decl[InstanceVar]/CurrNominal/TypeRelation[Identical]: baseInstanceVar[#Int#]{{; name=.+$}}
232+
// COMMON_BASE_A_DOT_CONTEXT-DAG: Decl[InstanceVar]/CurrNominal/TypeRelation[Identical]: baseProp[#Int#]{{; name=.+$}}
233+
// COMMON_BASE_A_DOT_CONTEXT-DAG: Decl[InstanceMethod]/CurrNominal: baseFunc0()[#Void#]{{; name=.+$}}
234+
// COMMON_BASE_A_DOT_CONTEXT-DAG: Decl[InstanceMethod]/CurrNominal: baseFunc1({#(a): Int#})[#Void#]{{; name=.+$}}
235+
// COMMON_BASE_A_DOT_CONTEXT-DAG: Decl[InstanceVar]/CurrNominal/TypeRelation[Identical]: baseExtProp[#Int#]{{; name=.+$}}
236+
// COMMON_BASE_A_DOT_CONTEXT-DAG: Decl[InstanceMethod]/CurrNominal: baseExtFunc0()[#Void#]{{; name=.+$}}
237+
// COMMON_BASE_A_DOT_CONTEXT: End completions
238+
230239
class SuperDerivedA : SuperBaseA {
231240
var derivedInstanceVar: Int
232241

@@ -514,7 +523,7 @@ class Closures : SuperBaseA {
514523
}
515524

516525
func bar() {
517-
let inner = { () -> Void in
526+
let inner = { () -> Int in
518527
// CLOSURE_2: Begin completions, 6 items
519528
// CLOSURE_2: End completions
520529
super.#^CLOSURE_2^#

0 commit comments

Comments
 (0)