Skip to content

Commit cdfd1ab

Browse files
authored
Merge pull request #27592 from rintaro/syntaxparse-exprtuple
[SyntaxParse] Parse tuple/paren expression syntax
2 parents eb02f20 + 33e561a commit cdfd1ab

File tree

16 files changed

+260
-149
lines changed

16 files changed

+260
-149
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,8 @@ ERROR(expected_expr_throw,PointsToFirstBadToken,
970970
// Yield Statment
971971
ERROR(expected_expr_yield,PointsToFirstBadToken,
972972
"expected expression in 'yield' statement", ())
973+
ERROR(unexpected_arg_label_yield,none,
974+
"unexpected argument label in 'yield' statement", ())
973975

974976
// Defer Statement
975977
ERROR(expected_lbrace_after_defer,PointsToFirstBadToken,

include/swift/Parse/ASTGen.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class ASTGen {
8787
Expr *generate(const syntax::SuperRefExprSyntax &Expr, const SourceLoc Loc);
8888
Expr *generate(const syntax::ArrayExprSyntax &Expr, const SourceLoc Loc);
8989
Expr *generate(const syntax::DictionaryExprSyntax &Expr, const SourceLoc Loc);
90+
Expr *generate(const syntax::TupleExprSyntax &E, const SourceLoc Loc);
9091
Expr *generate(const syntax::EditorPlaceholderExprSyntax &Expr,
9192
const SourceLoc Loc);
9293
Expr *generate(const syntax::SpecializeExprSyntax &Expr, const SourceLoc Loc);
@@ -112,6 +113,12 @@ class ASTGen {
112113
const Optional<syntax::DeclNameArgumentsSyntax> &args,
113114
const SourceLoc Loc);
114115

116+
void generateExprTupleElementList(const syntax::TupleExprElementListSyntax &elements,
117+
const SourceLoc Loc, bool isForCallArguments,
118+
SmallVectorImpl<Expr *> &exprs,
119+
SmallVectorImpl<Identifier> &exprLabels,
120+
SmallVectorImpl<SourceLoc> &exprLabelLocs);
121+
115122
private:
116123
void validateCollectionElement(Expr *elementExpr);
117124

include/swift/Parse/Parser.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,8 +1558,11 @@ class Parser {
15581558
SourceLoc &inLoc);
15591559

15601560
Expr *parseExprAnonClosureArg();
1561-
ParserResult<Expr> parseExprList(tok LeftTok, tok RightTok,
1562-
syntax::SyntaxKind Kind);
1561+
ParserResult<Expr> parseExprParenOrTuple();
1562+
ParsedSyntaxResult<ParsedExprSyntax> parseExprTupleSyntax();
1563+
ParserStatus parseExprTupleElementListSyntax(
1564+
SmallVectorImpl<ParsedTupleExprElementSyntax> &elements,
1565+
llvm::function_ref<bool()> isAtCloseTok);
15631566

15641567
/// Parse an expression list, keeping all of the pieces separated.
15651568
ParserStatus parseExprList(tok leftTok, tok rightTok,
@@ -1570,8 +1573,7 @@ class Parser {
15701573
SmallVectorImpl<Identifier> &exprLabels,
15711574
SmallVectorImpl<SourceLoc> &exprLabelLocs,
15721575
SourceLoc &rightLoc,
1573-
Expr *&trailingClosure,
1574-
syntax::SyntaxKind Kind);
1576+
Expr *&trailingClosure);
15751577

15761578
ParserResult<Expr> parseTrailingClosure(SourceRange calleeRange);
15771579

lib/Parse/ASTGen.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
248248
result = generate(*arrayExpr, Loc);
249249
else if (auto dictionaryExpr = E.getAs<DictionaryExprSyntax>())
250250
result = generate(*dictionaryExpr, Loc);
251+
else if (auto tupleExpr = E.getAs<TupleExprSyntax>())
252+
result = generate(*tupleExpr, Loc);
251253
else if (auto integerLiteralExpr = E.getAs<IntegerLiteralExprSyntax>())
252254
result = generate(*integerLiteralExpr, Loc);
253255
else if (auto floatLiteralExpr = E.getAs<FloatLiteralExprSyntax>())
@@ -526,6 +528,72 @@ Expr *ASTGen::generate(const DictionaryExprSyntax &E, const SourceLoc Loc) {
526528
RSquareLoc);
527529
}
528530

531+
Expr *ASTGen::generate(const TupleExprSyntax &E, const SourceLoc Loc) {
532+
SmallVector<Expr *, 2> exprs;
533+
SmallVector<Identifier, 2> exprLabels;
534+
SmallVector<SourceLoc, 2> exprLabelLocs;
535+
generateExprTupleElementList(E.getElementList(), Loc,
536+
/*isForCallArguments=*/false, exprs, exprLabels,
537+
exprLabelLocs);
538+
539+
SourceLoc leftLoc = advanceLocBegin(Loc, E.getLeftParen());
540+
SourceLoc rightLoc = advanceLocEnd(Loc, E);
541+
542+
// A tuple with a single, unlabeled element is just parentheses.
543+
if (exprs.size() == 1 && exprLabels.empty()) {
544+
return new (Context) ParenExpr(leftLoc, exprs[0], rightLoc,
545+
/*hasTrailingClosure=*/false);
546+
}
547+
548+
return TupleExpr::create(Context, leftLoc, exprs, exprLabels, exprLabelLocs,
549+
rightLoc, /*HasTrailingClosure=*/false,
550+
/*Implicit=*/false);
551+
}
552+
553+
void ASTGen::generateExprTupleElementList(const TupleExprElementListSyntax &elements,
554+
const SourceLoc Loc, bool isForCallArguments,
555+
SmallVectorImpl<Expr *> &exprs,
556+
SmallVectorImpl<Identifier> &exprLabels,
557+
SmallVectorImpl<SourceLoc> &exprLabelLocs) {
558+
auto isFirst = true;
559+
for (auto elem : elements) {
560+
auto *subExpr = generate(elem.getExpression(), Loc);
561+
if (!subExpr)
562+
continue;
563+
564+
// Handle call arguments specially because it may need argument labels.
565+
if (P.CodeCompletion && isForCallArguments && !elem.getLabel())
566+
if (auto CCExpr = elem.getExpression().getAs<CodeCompletionExprSyntax>())
567+
if (!CCExpr->getBase() && !CCExpr->getPeriodOrParen())
568+
P.CodeCompletion->completeCallArg(cast<CodeCompletionExpr>(subExpr),
569+
isFirst);
570+
isFirst = false;
571+
572+
Identifier fieldName;
573+
SourceLoc fieldNameLoc;
574+
if (auto label = elem.getLabel()) {
575+
fieldNameLoc = advanceLocBegin(Loc, *label);
576+
if (label->getTokenKind() == tok::identifier)
577+
fieldName = Context.getIdentifier(label->getIdentifierText());
578+
}
579+
580+
// Don't populate label vectors unless we see at least one label.
581+
if (!exprLabels.empty()) {
582+
exprLabels.push_back(fieldName);
583+
exprLabelLocs.push_back(fieldNameLoc);
584+
} else if (fieldNameLoc.isValid()) {
585+
exprLabels.resize(exprs.size());
586+
exprLabelLocs.resize(exprs.size());
587+
exprLabels.push_back(fieldName);
588+
exprLabelLocs.push_back(fieldNameLoc);
589+
}
590+
exprs.push_back(subExpr);
591+
}
592+
assert((exprLabels.size() == 0 || exprs.size() == exprLabels.size()) &&
593+
exprLabels.size() == exprLabelLocs.size());
594+
}
595+
596+
529597
Expr *ASTGen::generate(const IntegerLiteralExprSyntax &Expr,
530598
const SourceLoc Loc) {
531599
auto Digits = Expr.getDigits();

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,8 +1784,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc At
17841784
status |= parseExprList(tok::l_paren, tok::r_paren,
17851785
/*isPostfix=*/false, /*isExprBasic=*/true,
17861786
lParenLoc, args, argLabels, argLabelLocs,
1787-
rParenLoc, trailingClosure,
1788-
SyntaxKind::TupleExprElementList);
1787+
rParenLoc, trailingClosure);
17891788
assert(!trailingClosure && "Cannot parse a trailing closure here");
17901789
hasInitializer = true;
17911790
}

0 commit comments

Comments
 (0)