Skip to content

Commit 5e1f790

Browse files
authored
Merge pull request #27607 from rintaro/syntaxparse-exprunresolvedmember
[SyntaxParse] Parse object literal and unresolved member expressions
2 parents 1846a59 + 6a9b252 commit 5e1f790

File tree

5 files changed

+354
-113
lines changed

5 files changed

+354
-113
lines changed

include/swift/Parse/ASTGen.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ class ASTGen {
8888
Expr *generate(const syntax::ArrayExprSyntax &Expr, const SourceLoc Loc);
8989
Expr *generate(const syntax::DictionaryExprSyntax &Expr, const SourceLoc Loc);
9090
Expr *generate(const syntax::TupleExprSyntax &E, const SourceLoc Loc);
91+
Expr *generate(const syntax::FunctionCallExprSyntax &E, const SourceLoc Loc);
92+
Expr *generate(const syntax::MemberAccessExprSyntax &E, const SourceLoc Loc);
9193
Expr *generate(const syntax::EditorPlaceholderExprSyntax &Expr,
9294
const SourceLoc Loc);
9395
Expr *generate(const syntax::SpecializeExprSyntax &Expr, const SourceLoc Loc);
@@ -106,6 +108,10 @@ class ASTGen {
106108
const SourceLoc Loc);
107109
Expr *generate(const syntax::PoundDsohandleExprSyntax &Expr,
108110
const SourceLoc Loc);
111+
Expr *generate(const syntax::ObjectLiteralExprSyntax &Expr,
112+
const SourceLoc Loc);
113+
Expr *generate(const syntax::CodeCompletionExprSyntax &Expr,
114+
const SourceLoc Loc);
109115
Expr *generate(const syntax::UnknownExprSyntax &Expr, const SourceLoc Loc);
110116

111117
std::pair<DeclName, DeclNameLoc> generateUnqualifiedDeclName(

include/swift/Parse/Parser.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,9 @@ class Parser {
14561456
ParserResult<Expr> parseExprSelector();
14571457
ParserResult<Expr> parseExprSuper();
14581458
ParsedSyntaxResult<ParsedExprSyntax> parseExprSuperSyntax();
1459+
ParserResult<Expr> parseExprUnresolvedMember(bool isExprBasic);
1460+
ParsedSyntaxResult<ParsedExprSyntax>
1461+
parseExprUnresolvedMemberSyntax(bool isExprBasic);
14591462
ParserResult<Expr> parseExprStringLiteral();
14601463

14611464
// todo [gsoc]: create new result type for ParsedSyntax
@@ -1574,14 +1577,19 @@ class Parser {
15741577
SmallVectorImpl<SourceLoc> &exprLabelLocs,
15751578
SourceLoc &rightLoc,
15761579
Expr *&trailingClosure);
1577-
1580+
ParserStatus parseExprListSyntax(
1581+
tok leftK, tok rightK, bool isPostfix, bool isExprBasic,
1582+
llvm::function_ref<void(
1583+
ParsedTokenSyntax &&, ParsedTupleExprElementListSyntax &&,
1584+
Optional<ParsedTokenSyntax> &&, Optional<ParsedClosureExprSyntax> &&)>
1585+
callback);
15781586
ParserResult<Expr> parseTrailingClosure(SourceRange calleeRange);
1587+
ParsedSyntaxResult<ParsedClosureExprSyntax>
1588+
parseTrailingClosureSyntax(SourceRange calleeRange);
15791589

1580-
/// Parse an object literal.
1581-
///
1582-
/// \param LK The literal kind as determined by the first token.
1583-
ParserResult<Expr> parseExprObjectLiteral(ObjectLiteralExpr::LiteralKind LK,
1584-
bool isExprBasic);
1590+
ParserResult<Expr> parseExprObjectLiteral(bool isExprBasic);
1591+
ParsedSyntaxResult<ParsedExprSyntax>
1592+
parseExprObjectLiteralSyntax(bool isExprBasic);
15851593
ParserResult<Expr> parseExprCallSuffix(ParserResult<Expr> fn,
15861594
bool isExprBasic);
15871595
ParserResult<Expr> parseExprCollection();

lib/Parse/ASTGen.cpp

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
250250
result = generate(*dictionaryExpr, Loc);
251251
else if (auto tupleExpr = E.getAs<TupleExprSyntax>())
252252
result = generate(*tupleExpr, Loc);
253+
else if (auto callExpr = E.getAs<FunctionCallExprSyntax>())
254+
result = generate(*callExpr, Loc);
255+
else if (auto memberExpr = E.getAs<MemberAccessExprSyntax>())
256+
result = generate(*memberExpr, Loc);
253257
else if (auto integerLiteralExpr = E.getAs<IntegerLiteralExprSyntax>())
254258
result = generate(*integerLiteralExpr, Loc);
255259
else if (auto floatLiteralExpr = E.getAs<FloatLiteralExprSyntax>())
@@ -268,6 +272,10 @@ Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
268272
result = generate(*poundFunctionExpr, Loc);
269273
else if (auto poundDsohandleExpr = E.getAs<PoundDsohandleExprSyntax>())
270274
result = generate(*poundDsohandleExpr, Loc);
275+
else if (auto objectLiteralExpr = E.getAs<ObjectLiteralExprSyntax>())
276+
result = generate(*objectLiteralExpr, Loc);
277+
else if (auto completionExpr = E.getAs<CodeCompletionExprSyntax>())
278+
result = generate(*completionExpr, Loc);
271279
else if (auto unknownExpr = E.getAs<UnknownExprSyntax>())
272280
result = generate(*unknownExpr, Loc);
273281
else {
@@ -593,6 +601,67 @@ void ASTGen::generateExprTupleElementList(const TupleExprElementListSyntax &elem
593601
exprLabels.size() == exprLabelLocs.size());
594602
}
595603

604+
Expr *ASTGen::generate(const FunctionCallExprSyntax &E, const SourceLoc Loc) {
605+
auto callee = E.getCalledExpression();
606+
607+
SourceLoc LParenLoc, RParenLoc;
608+
SmallVector<Expr *, 2> args;
609+
SmallVector<Identifier, 2> argLabels;
610+
SmallVector<SourceLoc, 2> argLabelLocs;
611+
generateExprTupleElementList(E.getArgumentList(), Loc,
612+
/*isForCallArguments=*/true, args, argLabels,
613+
argLabelLocs);
614+
Expr *trailingClosure = nullptr;
615+
if (auto CE = E.getTrailingClosure())
616+
trailingClosure = generate(*CE, Loc);
617+
if (auto LParen = E.getLeftParen()) {
618+
LParenLoc = advanceLocBegin(Loc, *LParen);
619+
if (auto RParen = E.getRightParen())
620+
RParenLoc = advanceLocBegin(Loc, *RParen);
621+
else
622+
RParenLoc = advanceLocEnd(Loc, E.getArgumentList());
623+
}
624+
625+
if (auto memberAccess = callee.getAs<MemberAccessExprSyntax>()) {
626+
if (!memberAccess->getBase()) {
627+
// This is UnresolvedMemberExpr with call arguments.
628+
if (memberAccess->getName().isMissing())
629+
return nullptr;
630+
631+
SourceLoc dotLoc = advanceLocBegin(Loc, memberAccess->getDot());
632+
DeclName name;
633+
DeclNameLoc nameLoc;
634+
std::tie(name, nameLoc) = generateUnqualifiedDeclName(
635+
memberAccess->getName(), memberAccess->getDeclNameArguments(), Loc);
636+
637+
return UnresolvedMemberExpr::create(
638+
Context, dotLoc, nameLoc, name, LParenLoc, args, argLabels,
639+
argLabelLocs, RParenLoc, trailingClosure,
640+
/*implicit=*/false);
641+
}
642+
}
643+
llvm_unreachable("call expression not implemented");
644+
return nullptr;
645+
}
646+
647+
Expr *ASTGen::generate(const MemberAccessExprSyntax &E, const SourceLoc Loc) {
648+
if (!E.getBase()) {
649+
// This is an UnresolvedMemberExpr.
650+
if (E.getName().isMissing())
651+
return nullptr;
652+
653+
DeclName name;
654+
DeclNameLoc nameLoc;
655+
std::tie(name, nameLoc) =
656+
generateUnqualifiedDeclName(E.getName(), E.getDeclNameArguments(), Loc);
657+
SourceLoc dotLoc = advanceLocBegin(Loc, E.getDot());
658+
659+
return UnresolvedMemberExpr::create(Context, dotLoc, nameLoc, name,
660+
/*implicit=*/false);
661+
}
662+
llvm_unreachable("member access expression not implemented");
663+
return nullptr;
664+
}
596665

597666
Expr *ASTGen::generate(const IntegerLiteralExprSyntax &Expr,
598667
const SourceLoc Loc) {
@@ -647,6 +716,64 @@ Expr *ASTGen::generate(const PoundDsohandleExprSyntax &Expr,
647716
Loc);
648717
}
649718

719+
Expr *ASTGen::generate(const ObjectLiteralExprSyntax &E, const SourceLoc Loc) {
720+
ObjectLiteralExpr::LiteralKind kind;
721+
switch (E.getIdentifier().getTokenKind()) {
722+
#define POUND_OBJECT_LITERAL(Name, Desc, Proto) \
723+
case tok::pound_##Name: \
724+
kind = ObjectLiteralExpr::Name; \
725+
break;
726+
#include "swift/Syntax/TokenKinds.def"
727+
default:
728+
llvm_unreachable("unknown token kind for object literal expression");
729+
}
730+
731+
SmallVector<Expr *, 2> args;
732+
SmallVector<Identifier, 2> argLabels;
733+
SmallVector<SourceLoc, 2> argLabelLocs;
734+
generateExprTupleElementList(E.getArguments(), Loc, true, args, argLabels,
735+
argLabelLocs);
736+
737+
ClosureExpr *trailingClosure = nullptr;
738+
if (auto CE = E.getTrailingClosure())
739+
trailingClosure = dyn_cast_or_null<ClosureExpr>(generate(*CE, Loc));
740+
741+
if (E.getLeftParen().isMissing() || E.getRightParen().isMissing())
742+
return nullptr;
743+
744+
SourceLoc poundLoc = advanceLocBegin(Loc, E.getIdentifier());
745+
SourceLoc LParenLoc = advanceLocBegin(Loc, E.getLeftParen());
746+
SourceLoc RParenLoc = advanceLocBegin(Loc, E.getRightParen());
747+
748+
return ObjectLiteralExpr::create(Context, poundLoc, kind, LParenLoc, args,
749+
argLabels, argLabelLocs, RParenLoc,
750+
trailingClosure, /*implicit=*/false);
751+
}
752+
753+
Expr *ASTGen::generate(const CodeCompletionExprSyntax &E, const SourceLoc Loc) {
754+
if (!E.getBase()) {
755+
if (auto punctuator = E.getPeriodOrParen()) {
756+
// '.' <cc-token>
757+
if (punctuator->getTokenKind() == tok::period ||
758+
punctuator->getTokenKind() == tok::period_prefix) {
759+
auto ccLoc = advanceLocBegin(Loc, E.getCodeCompletionToken());
760+
auto dotLoc = advanceLocBegin(Loc, *punctuator);
761+
762+
auto CCE = new (Context) CodeCompletionExpr(ccLoc);
763+
if (P.CodeCompletion)
764+
P.CodeCompletion->completeUnresolvedMember(CCE, dotLoc);
765+
return CCE;
766+
}
767+
} else {
768+
llvm_unreachable("'(' <cc-token> is not suppported");
769+
}
770+
} else {
771+
// TODO: implement
772+
}
773+
llvm_unreachable("code completion expression not implemented");
774+
return nullptr;
775+
}
776+
650777
Expr *ASTGen::generate(const UnknownExprSyntax &Expr, const SourceLoc Loc) {
651778
if (Expr.getNumChildren() == 1 && Expr.getChild(0)->isToken()) {
652779
Syntax Token = *Expr.getChild(0);

0 commit comments

Comments
 (0)