Skip to content

Commit 43df5a2

Browse files
committed
[SyntaxParse] Parse SuperRefExpr syntax
1 parent f5dd971 commit 43df5a2

File tree

4 files changed

+65
-37
lines changed

4 files changed

+65
-37
lines changed

include/swift/Parse/ASTGen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class ASTGen {
8181

8282
Expr *generate(const syntax::ExprSyntax &Expr, const SourceLoc Loc);
8383
Expr *generate(const syntax::IdentifierExprSyntax &Expr, const SourceLoc Loc);
84+
Expr *generate(const syntax::SuperRefExprSyntax &Expr, const SourceLoc Loc);
8485
Expr *generate(const syntax::EditorPlaceholderExprSyntax &Expr,
8586
const SourceLoc Loc);
8687
Expr *generate(const syntax::SpecializeExprSyntax &Expr, const SourceLoc Loc);

include/swift/Parse/Parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,7 @@ class Parser {
14541454
ParserResult<Expr> parseExprKeyPath();
14551455
ParserResult<Expr> parseExprSelector();
14561456
ParserResult<Expr> parseExprSuper();
1457+
ParsedSyntaxResult<ParsedExprSyntax> parseExprSuperSyntax();
14571458
ParserResult<Expr> parseExprStringLiteral();
14581459

14591460
// todo [gsoc]: create new result type for ParsedSyntax

lib/Parse/ASTGen.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
234234

235235
if (auto identifierExpr = E.getAs<IdentifierExprSyntax>())
236236
result = generate(*identifierExpr, Loc);
237+
else if (auto superRefExpr = E.getAs<SuperRefExprSyntax>())
238+
result = generate(*superRefExpr, Loc);
237239
else if (auto specializeExpr = E.getAs<SpecializeExprSyntax>())
238240
result = generate(*specializeExpr, Loc);
239241
else if (auto editorPlaceHolderExpr = E.getAs<EditorPlaceholderExprSyntax>())
@@ -256,8 +258,14 @@ Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
256258
result = generate(*poundFunctionExpr, Loc);
257259
else if (auto poundDsohandleExpr = E.getAs<PoundDsohandleExprSyntax>())
258260
result = generate(*poundDsohandleExpr, Loc);
259-
else
261+
else if (auto unknownExpr = E.getAs<UnknownExprSyntax>())
262+
result = generate(*unknownExpr, Loc);
263+
else {
264+
#ifndef NDEBUG
265+
E.dump();
260266
llvm_unreachable("unsupported expression");
267+
#endif
268+
}
261269

262270
return result;
263271
}
@@ -366,6 +374,39 @@ Expr *ASTGen::generate(const IdentifierExprSyntax &E, const SourceLoc Loc) {
366374
return new (Context) DeclRefExpr(D, nameLoc, /*implicit=*/false);
367375
}
368376

377+
static VarDecl *getImplicitSelfDeclForSuperContext(Parser &P,
378+
DeclContext *DC,
379+
SourceLoc Loc) {
380+
auto *methodContext = DC->getInnermostMethodContext();
381+
if (!methodContext) {
382+
P.diagnose(Loc, diag::super_not_in_class_method);
383+
return nullptr;
384+
}
385+
386+
// Do an actual lookup for 'self' in case it shows up in a capture list.
387+
auto *methodSelf = methodContext->getImplicitSelfDecl();
388+
auto *lookupSelf = P.lookupInScope(P.Context.Id_self);
389+
if (lookupSelf && lookupSelf != methodSelf) {
390+
// FIXME: This is the wrong diagnostic for if someone manually declares a
391+
// variable named 'self' using backticks.
392+
P.diagnose(Loc, diag::super_in_closure_with_capture);
393+
P.diagnose(lookupSelf->getLoc(), diag::super_in_closure_with_capture_here);
394+
return nullptr;
395+
}
396+
397+
return methodSelf;
398+
}
399+
400+
Expr *ASTGen::generate(const SuperRefExprSyntax &E, const SourceLoc Loc) {
401+
auto superLoc = advanceLocBegin(Loc, E.getSuperKeyword());
402+
VarDecl *selfDecl =
403+
getImplicitSelfDeclForSuperContext(P, P.CurDeclContext, superLoc);
404+
if (!selfDecl)
405+
return new (Context) ErrorExpr(superLoc);
406+
407+
return new (Context) SuperRefExpr(selfDecl, superLoc, /*Implicit=*/false);
408+
}
409+
369410
Expr *ASTGen::generate(const EditorPlaceholderExprSyntax &E, const SourceLoc Loc) {
370411
assert(!E.getIdentifier().isMissing());
371412

lib/Parse/ParseExpr.cpp

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -813,29 +813,6 @@ UnresolvedDeclRefExpr *Parser::parseExprOperator() {
813813
return new (Context) UnresolvedDeclRefExpr(name, refKind, DeclNameLoc(loc));
814814
}
815815

816-
static VarDecl *getImplicitSelfDeclForSuperContext(Parser &P,
817-
DeclContext *DC,
818-
SourceLoc Loc) {
819-
auto *methodContext = DC->getInnermostMethodContext();
820-
if (!methodContext) {
821-
P.diagnose(Loc, diag::super_not_in_class_method);
822-
return nullptr;
823-
}
824-
825-
// Do an actual lookup for 'self' in case it shows up in a capture list.
826-
auto *methodSelf = methodContext->getImplicitSelfDecl();
827-
auto *lookupSelf = P.lookupInScope(P.Context.Id_self);
828-
if (lookupSelf && lookupSelf != methodSelf) {
829-
// FIXME: This is the wrong diagnostic for if someone manually declares a
830-
// variable named 'self' using backticks.
831-
P.diagnose(Loc, diag::super_in_closure_with_capture);
832-
P.diagnose(lookupSelf->getLoc(), diag::super_in_closure_with_capture_here);
833-
return nullptr;
834-
}
835-
836-
return methodSelf;
837-
}
838-
839816
/// parseExprSuper
840817
///
841818
/// expr-super:
@@ -848,28 +825,36 @@ static VarDecl *getImplicitSelfDeclForSuperContext(Parser &P,
848825
/// 'super' '.' 'init'
849826
/// expr-super-subscript:
850827
/// 'super' '[' expr ']'
851-
ParserResult<Expr> Parser::parseExprSuper() {
852-
SyntaxParsingContext SuperCtxt(SyntaxContext, SyntaxContextKind::Expr);
853-
// Parse the 'super' reference.
854-
SourceLoc superLoc = consumeToken(tok::kw_super);
855-
SyntaxContext->createNodeInPlace(SyntaxKind::SuperRefExpr);
828+
ParsedSyntaxResult<ParsedExprSyntax> Parser::parseExprSuperSyntax() {
829+
auto superTok = consumeTokenSyntax(tok::kw_super);
856830

857831
// 'super.' must be followed by a member ref, explicit initializer ref, or
858832
// subscript call.
859833
if (!Tok.isAny(tok::period, tok::period_prefix, tok::code_complete) &&
860834
!Tok.isFollowingLSquare()) {
861-
if (!consumeIf(tok::unknown))
835+
SmallVector<ParsedSyntax, 2> junk;
836+
junk.emplace_back(std::move(superTok));
837+
if (auto unknown = consumeTokenSyntaxIf(tok::unknown)) {
838+
junk.emplace_back(std::move(*unknown));
839+
} else {
862840
diagnose(Tok, diag::expected_dot_or_subscript_after_super);
863-
return nullptr;
841+
}
842+
843+
return makeParsedError(
844+
ParsedSyntaxRecorder::makeUnknownExpr(junk, *SyntaxContext));
864845
}
865846

866-
VarDecl *selfDecl =
867-
getImplicitSelfDeclForSuperContext(*this, CurDeclContext, superLoc);
868-
if (!selfDecl)
869-
return makeParserResult(new (Context) ErrorExpr(superLoc));
847+
return makeParsedResult(ParsedSyntaxRecorder::makeSuperRefExpr(
848+
std::move(superTok), *SyntaxContext));
849+
}
870850

871-
return makeParserResult(new (Context) SuperRefExpr(selfDecl, superLoc,
872-
/*Implicit=*/false));
851+
ParserResult<Expr> Parser::parseExprSuper() {
852+
auto leadingLoc = leadingTriviaLoc();
853+
auto parsed = parseExprSuperSyntax();
854+
SyntaxContext->addSyntax(parsed.get());
855+
auto syntax = SyntaxContext->topNode<ExprSyntax>();
856+
auto expr = Generator.generate(syntax, leadingLoc);
857+
return makeParserResult(parsed.getStatus(), expr);
873858
}
874859

875860
StringRef Parser::copyAndStripUnderscores(StringRef orig) {

0 commit comments

Comments
 (0)