@@ -971,6 +971,96 @@ static bool isValidTrailingClosure(bool isExprBasic, Parser &P){
971
971
return true ;
972
972
}
973
973
974
+ ParsedSyntaxResult<ParsedExprSyntax>
975
+ Parser::parseExprUnresolvedMemberSyntax (bool isExprBasic) {
976
+ assert (Tok.isAny (tok::period, tok::period_prefix));
977
+
978
+ // Parse '.'
979
+ Tok.setKind (tok::period_prefix);
980
+ auto dotTok = consumeTokenSyntax (tok::period_prefix);
981
+
982
+ // Handle code completion; '.' <cc-token>
983
+ if (Tok.is (tok::code_complete)) {
984
+ ParsedCodeCompletionExprSyntaxBuilder ccBuilder (*SyntaxContext);
985
+ ccBuilder.usePeriodOrParen (std::move (dotTok));
986
+ ccBuilder.useCodeCompletionToken (consumeTokenSyntax (tok::code_complete));
987
+ return makeParsedCodeCompletion (ccBuilder.build ());
988
+ }
989
+
990
+ ParserStatus status;
991
+
992
+ // Parse the name.
993
+ Optional<ParsedTokenSyntax> identTok;
994
+ Optional<ParsedDeclNameArgumentsSyntax> declNameArgs;
995
+ status |=
996
+ parseUnqualifiedDeclNameSyntax (identTok, declNameArgs, /* afterDot=*/ true ,
997
+ diag::expected_identifier_after_dot_expr);
998
+ if (status.isError ()) {
999
+ // If the name is missing. It makes no sense to construct a member access
1000
+ // expression.
1001
+ assert (!identTok && !declNameArgs);
1002
+ return makeParsedError (
1003
+ ParsedSyntaxRecorder::makeUnknownExpr ({&dotTok, 1 }, *SyntaxContext));
1004
+ }
1005
+
1006
+ ParsedMemberAccessExprSyntaxBuilder builder (*SyntaxContext);
1007
+ builder.useDot (std::move (dotTok));
1008
+ builder.useName (std::move (*identTok));
1009
+ if (declNameArgs)
1010
+ builder.useDeclNameArguments (std::move (*declNameArgs));
1011
+
1012
+ // FIXME: These calling suffix parsings are not necessary for Syntax parsing.
1013
+ // Remove this block after full expression parsing migration.
1014
+
1015
+ // Check for a () suffix, which indicates a call when constructing
1016
+ // this member. Note that this cannot be the start of a new line.
1017
+ if (Tok.isFollowingLParen ()) {
1018
+ ParsedFunctionCallExprSyntaxBuilder callBuilder (*SyntaxContext);
1019
+ callBuilder.useCalledExpression (builder.build ());
1020
+
1021
+ status |= parseExprListSyntax (
1022
+ tok::l_paren, tok::r_paren,
1023
+ /* isPostfix=*/ true , isExprBasic,
1024
+ [&](ParsedTokenSyntax &&leftTok,
1025
+ ParsedTupleExprElementListSyntax &&args,
1026
+ Optional<ParsedTokenSyntax> &&rightTok,
1027
+ Optional<ParsedClosureExprSyntax> &&closure) {
1028
+ callBuilder.useLeftParen (std::move (leftTok));
1029
+ callBuilder.useArgumentList (std::move (args));
1030
+ if (rightTok)
1031
+ callBuilder.useRightParen (std::move (*rightTok));
1032
+ if (closure)
1033
+ callBuilder.useTrailingClosure (std::move (*closure));
1034
+ });
1035
+ return makeParsedResult (callBuilder.build (), status);
1036
+ }
1037
+
1038
+ // Check for a trailing closure, if allowed.
1039
+ if (Tok.is (tok::l_brace) && isValidTrailingClosure (isExprBasic, *this )) {
1040
+ ParsedFunctionCallExprSyntaxBuilder callBuilder (*SyntaxContext);
1041
+ callBuilder.useCalledExpression (builder.build ());
1042
+
1043
+ auto closure = parseTrailingClosureSyntax ({PreviousLoc, PreviousLoc});
1044
+ status |= closure.getStatus ();
1045
+ assert (!closure.isNull ());
1046
+ callBuilder.useTrailingClosure (closure.get ());
1047
+
1048
+ return makeParsedResult (callBuilder.build (), status);
1049
+ }
1050
+
1051
+ return makeParsedResult (builder.build (), status);
1052
+ }
1053
+
1054
+ ParserResult<Expr>
1055
+ Parser::parseExprUnresolvedMember (bool isExprBasic) {
1056
+ auto leadingLoc = leadingTriviaLoc ();
1057
+ auto parsed = parseExprUnresolvedMemberSyntax (isExprBasic);
1058
+ SyntaxContext->addSyntax (parsed.get ());
1059
+ auto syntax = SyntaxContext->topNode <ExprSyntax>();
1060
+ auto expr = Generator.generate (syntax, leadingLoc);
1061
+ return makeParserResult (parsed.getStatus (), expr);
1062
+ }
1063
+
974
1064
ParserResult<Expr>
975
1065
Parser::parseExprPostfixSuffix (ParserResult<Expr> Result, bool isExprBasic,
976
1066
bool periodHasKeyPathBehavior,
@@ -1532,13 +1622,12 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
1532
1622
1533
1623
case tok::period: // =.foo
1534
1624
case tok::period_prefix: { // .foo
1535
- Tok.setKind (tok::period_prefix);
1536
- SourceLoc DotLoc = consumeToken ();
1537
-
1538
1625
// Special case ".<integer_literal>" like ".4". This isn't valid, but the
1539
1626
// developer almost certainly meant to use "0.4". Diagnose this, and
1540
1627
// recover as if they wrote that.
1541
- if (Tok.is (tok::integer_literal) && !Tok.isAtStartOfLine ()) {
1628
+ if (peekToken ().is (tok::integer_literal) &&
1629
+ !peekToken ().isAtStartOfLine ()) {
1630
+ SourceLoc DotLoc = consumeToken ();
1542
1631
diagnose (DotLoc, diag::invalid_float_literal_missing_leading_zero,
1543
1632
Tok.getText ())
1544
1633
.fixItInsert (DotLoc, " 0" )
@@ -1554,76 +1643,8 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
1554
1643
FloatLiteralExpr (FltText, DotLoc,
1555
1644
/* Implicit=*/ false ));
1556
1645
}
1557
-
1558
- DeclName Name;
1559
- DeclNameLoc NameLoc;
1560
-
1561
- if (Tok.is (tok::code_complete)) {
1562
- auto CCE = new (Context) CodeCompletionExpr (Tok.getLoc ());
1563
- auto Result = makeParserResult (CCE);
1564
- Result.setHasCodeCompletion ();
1565
- if (CodeCompletion) {
1566
- CodeCompletion->completeUnresolvedMember (CCE, DotLoc);
1567
- }
1568
- consumeToken ();
1569
- return Result;
1570
- }
1571
-
1572
- Name = parseUnqualifiedDeclName (/* afterDot=*/ true , NameLoc,
1573
- diag::expected_identifier_after_dot_expr);
1574
- if (!Name) return nullptr ;
1575
- SyntaxContext->createNodeInPlace (SyntaxKind::MemberAccessExpr);
1576
-
1577
- // Check for a () suffix, which indicates a call when constructing
1578
- // this member. Note that this cannot be the start of a new line.
1579
- if (Tok.isFollowingLParen ()) {
1580
- SourceLoc lParenLoc, rParenLoc;
1581
- SmallVector<Expr *, 2 > args;
1582
- SmallVector<Identifier, 2 > argLabels;
1583
- SmallVector<SourceLoc, 2 > argLabelLocs;
1584
- Expr *trailingClosure;
1585
-
1586
- ParserStatus status = parseExprList (tok::l_paren, tok::r_paren,
1587
- /* isPostfix=*/ true , isExprBasic,
1588
- lParenLoc, args, argLabels,
1589
- argLabelLocs,
1590
- rParenLoc,
1591
- trailingClosure);
1592
- SyntaxContext->createNodeInPlace (SyntaxKind::FunctionCallExpr);
1593
- return makeParserResult (
1594
- status,
1595
- UnresolvedMemberExpr::create (Context, DotLoc, NameLoc, Name,
1596
- lParenLoc, args, argLabels,
1597
- argLabelLocs, rParenLoc,
1598
- trailingClosure,
1599
- /* implicit=*/ false ));
1600
- }
1601
1646
1602
- // Check for a trailing closure, if allowed.
1603
- if (Tok.is (tok::l_brace) && isValidTrailingClosure (isExprBasic, *this )) {
1604
- // Add dummy blank argument list to the call expression syntax.
1605
- SyntaxContext->addSyntax (
1606
- ParsedSyntaxRecorder::makeBlankTupleExprElementList (
1607
- Tok.getLoc (), *SyntaxContext));
1608
-
1609
- ParserResult<Expr> closure =
1610
- parseTrailingClosure (NameLoc.getSourceRange ());
1611
- if (closure.isNull ()) return nullptr ;
1612
-
1613
- SyntaxContext->createNodeInPlace (SyntaxKind::FunctionCallExpr);
1614
- // Handle .foo by just making an AST node.
1615
- return makeParserResult (
1616
- ParserStatus (closure),
1617
- UnresolvedMemberExpr::create (Context, DotLoc, NameLoc, Name,
1618
- SourceLoc (), { }, { }, { },
1619
- SourceLoc (), closure.get (),
1620
- /* implicit=*/ false ));
1621
- }
1622
-
1623
- // Handle .foo by just making an AST node.
1624
- return makeParserResult (
1625
- UnresolvedMemberExpr::create (Context, DotLoc, NameLoc, Name,
1626
- /* implicit=*/ false ));
1647
+ return parseExprUnresolvedMember (isExprBasic);
1627
1648
}
1628
1649
1629
1650
case tok::kw_super: // 'super'
0 commit comments