Skip to content

[SyntaxParse] Parse object literal and unresolved member expressions #27607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/swift/Parse/ASTGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class ASTGen {
Expr *generate(const syntax::ArrayExprSyntax &Expr, const SourceLoc Loc);
Expr *generate(const syntax::DictionaryExprSyntax &Expr, const SourceLoc Loc);
Expr *generate(const syntax::TupleExprSyntax &E, const SourceLoc Loc);
Expr *generate(const syntax::FunctionCallExprSyntax &E, const SourceLoc Loc);
Expr *generate(const syntax::MemberAccessExprSyntax &E, const SourceLoc Loc);
Expr *generate(const syntax::EditorPlaceholderExprSyntax &Expr,
const SourceLoc Loc);
Expr *generate(const syntax::SpecializeExprSyntax &Expr, const SourceLoc Loc);
Expand All @@ -106,6 +108,10 @@ class ASTGen {
const SourceLoc Loc);
Expr *generate(const syntax::PoundDsohandleExprSyntax &Expr,
const SourceLoc Loc);
Expr *generate(const syntax::ObjectLiteralExprSyntax &Expr,
const SourceLoc Loc);
Expr *generate(const syntax::CodeCompletionExprSyntax &Expr,
const SourceLoc Loc);
Expr *generate(const syntax::UnknownExprSyntax &Expr, const SourceLoc Loc);

std::pair<DeclName, DeclNameLoc> generateUnqualifiedDeclName(
Expand Down
20 changes: 14 additions & 6 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,9 @@ class Parser {
ParserResult<Expr> parseExprSelector();
ParserResult<Expr> parseExprSuper();
ParsedSyntaxResult<ParsedExprSyntax> parseExprSuperSyntax();
ParserResult<Expr> parseExprUnresolvedMember(bool isExprBasic);
ParsedSyntaxResult<ParsedExprSyntax>
parseExprUnresolvedMemberSyntax(bool isExprBasic);
ParserResult<Expr> parseExprStringLiteral();

// todo [gsoc]: create new result type for ParsedSyntax
Expand Down Expand Up @@ -1574,14 +1577,19 @@ class Parser {
SmallVectorImpl<SourceLoc> &exprLabelLocs,
SourceLoc &rightLoc,
Expr *&trailingClosure);

ParserStatus parseExprListSyntax(
tok leftK, tok rightK, bool isPostfix, bool isExprBasic,
llvm::function_ref<void(
ParsedTokenSyntax &&, ParsedTupleExprElementListSyntax &&,
Optional<ParsedTokenSyntax> &&, Optional<ParsedClosureExprSyntax> &&)>
callback);
ParserResult<Expr> parseTrailingClosure(SourceRange calleeRange);
ParsedSyntaxResult<ParsedClosureExprSyntax>
parseTrailingClosureSyntax(SourceRange calleeRange);

/// Parse an object literal.
///
/// \param LK The literal kind as determined by the first token.
ParserResult<Expr> parseExprObjectLiteral(ObjectLiteralExpr::LiteralKind LK,
bool isExprBasic);
ParserResult<Expr> parseExprObjectLiteral(bool isExprBasic);
ParsedSyntaxResult<ParsedExprSyntax>
parseExprObjectLiteralSyntax(bool isExprBasic);
ParserResult<Expr> parseExprCallSuffix(ParserResult<Expr> fn,
bool isExprBasic);
ParserResult<Expr> parseExprCollection();
Expand Down
127 changes: 127 additions & 0 deletions lib/Parse/ASTGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
result = generate(*dictionaryExpr, Loc);
else if (auto tupleExpr = E.getAs<TupleExprSyntax>())
result = generate(*tupleExpr, Loc);
else if (auto callExpr = E.getAs<FunctionCallExprSyntax>())
result = generate(*callExpr, Loc);
else if (auto memberExpr = E.getAs<MemberAccessExprSyntax>())
result = generate(*memberExpr, Loc);
else if (auto integerLiteralExpr = E.getAs<IntegerLiteralExprSyntax>())
result = generate(*integerLiteralExpr, Loc);
else if (auto floatLiteralExpr = E.getAs<FloatLiteralExprSyntax>())
Expand All @@ -268,6 +272,10 @@ Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
result = generate(*poundFunctionExpr, Loc);
else if (auto poundDsohandleExpr = E.getAs<PoundDsohandleExprSyntax>())
result = generate(*poundDsohandleExpr, Loc);
else if (auto objectLiteralExpr = E.getAs<ObjectLiteralExprSyntax>())
result = generate(*objectLiteralExpr, Loc);
else if (auto completionExpr = E.getAs<CodeCompletionExprSyntax>())
result = generate(*completionExpr, Loc);
else if (auto unknownExpr = E.getAs<UnknownExprSyntax>())
result = generate(*unknownExpr, Loc);
else {
Expand Down Expand Up @@ -593,6 +601,67 @@ void ASTGen::generateExprTupleElementList(const TupleExprElementListSyntax &elem
exprLabels.size() == exprLabelLocs.size());
}

Expr *ASTGen::generate(const FunctionCallExprSyntax &E, const SourceLoc Loc) {
auto callee = E.getCalledExpression();

SourceLoc LParenLoc, RParenLoc;
SmallVector<Expr *, 2> args;
SmallVector<Identifier, 2> argLabels;
SmallVector<SourceLoc, 2> argLabelLocs;
generateExprTupleElementList(E.getArgumentList(), Loc,
/*isForCallArguments=*/true, args, argLabels,
argLabelLocs);
Expr *trailingClosure = nullptr;
if (auto CE = E.getTrailingClosure())
trailingClosure = generate(*CE, Loc);
if (auto LParen = E.getLeftParen()) {
LParenLoc = advanceLocBegin(Loc, *LParen);
if (auto RParen = E.getRightParen())
RParenLoc = advanceLocBegin(Loc, *RParen);
else
RParenLoc = advanceLocEnd(Loc, E.getArgumentList());
}

if (auto memberAccess = callee.getAs<MemberAccessExprSyntax>()) {
if (!memberAccess->getBase()) {
// This is UnresolvedMemberExpr with call arguments.
if (memberAccess->getName().isMissing())
return nullptr;

SourceLoc dotLoc = advanceLocBegin(Loc, memberAccess->getDot());
DeclName name;
DeclNameLoc nameLoc;
std::tie(name, nameLoc) = generateUnqualifiedDeclName(
memberAccess->getName(), memberAccess->getDeclNameArguments(), Loc);

return UnresolvedMemberExpr::create(
Context, dotLoc, nameLoc, name, LParenLoc, args, argLabels,
argLabelLocs, RParenLoc, trailingClosure,
/*implicit=*/false);
}
}
llvm_unreachable("call expression not implemented");
return nullptr;
}

Expr *ASTGen::generate(const MemberAccessExprSyntax &E, const SourceLoc Loc) {
if (!E.getBase()) {
// This is an UnresolvedMemberExpr.
if (E.getName().isMissing())
return nullptr;

DeclName name;
DeclNameLoc nameLoc;
std::tie(name, nameLoc) =
generateUnqualifiedDeclName(E.getName(), E.getDeclNameArguments(), Loc);
SourceLoc dotLoc = advanceLocBegin(Loc, E.getDot());

return UnresolvedMemberExpr::create(Context, dotLoc, nameLoc, name,
/*implicit=*/false);
}
llvm_unreachable("member access expression not implemented");
return nullptr;
}

Expr *ASTGen::generate(const IntegerLiteralExprSyntax &Expr,
const SourceLoc Loc) {
Expand Down Expand Up @@ -647,6 +716,64 @@ Expr *ASTGen::generate(const PoundDsohandleExprSyntax &Expr,
Loc);
}

Expr *ASTGen::generate(const ObjectLiteralExprSyntax &E, const SourceLoc Loc) {
ObjectLiteralExpr::LiteralKind kind;
switch (E.getIdentifier().getTokenKind()) {
#define POUND_OBJECT_LITERAL(Name, Desc, Proto) \
case tok::pound_##Name: \
kind = ObjectLiteralExpr::Name; \
break;
#include "swift/Syntax/TokenKinds.def"
default:
llvm_unreachable("unknown token kind for object literal expression");
}

SmallVector<Expr *, 2> args;
SmallVector<Identifier, 2> argLabels;
SmallVector<SourceLoc, 2> argLabelLocs;
generateExprTupleElementList(E.getArguments(), Loc, true, args, argLabels,
argLabelLocs);

ClosureExpr *trailingClosure = nullptr;
if (auto CE = E.getTrailingClosure())
trailingClosure = dyn_cast_or_null<ClosureExpr>(generate(*CE, Loc));

if (E.getLeftParen().isMissing() || E.getRightParen().isMissing())
return nullptr;

SourceLoc poundLoc = advanceLocBegin(Loc, E.getIdentifier());
SourceLoc LParenLoc = advanceLocBegin(Loc, E.getLeftParen());
SourceLoc RParenLoc = advanceLocBegin(Loc, E.getRightParen());

return ObjectLiteralExpr::create(Context, poundLoc, kind, LParenLoc, args,
argLabels, argLabelLocs, RParenLoc,
trailingClosure, /*implicit=*/false);
}

Expr *ASTGen::generate(const CodeCompletionExprSyntax &E, const SourceLoc Loc) {
if (!E.getBase()) {
if (auto punctuator = E.getPeriodOrParen()) {
// '.' <cc-token>
if (punctuator->getTokenKind() == tok::period ||
punctuator->getTokenKind() == tok::period_prefix) {
auto ccLoc = advanceLocBegin(Loc, E.getCodeCompletionToken());
auto dotLoc = advanceLocBegin(Loc, *punctuator);

auto CCE = new (Context) CodeCompletionExpr(ccLoc);
if (P.CodeCompletion)
P.CodeCompletion->completeUnresolvedMember(CCE, dotLoc);
return CCE;
}
} else {
llvm_unreachable("'(' <cc-token> is not suppported");
}
} else {
// TODO: implement
}
llvm_unreachable("code completion expression not implemented");
return nullptr;
}

Expr *ASTGen::generate(const UnknownExprSyntax &Expr, const SourceLoc Loc) {
if (Expr.getNumChildren() == 1 && Expr.getChild(0)->isToken()) {
Syntax Token = *Expr.getChild(0);
Expand Down
Loading