@@ -1061,14 +1061,72 @@ static SyntaxKind getListElementKind(SyntaxKind ListKind) {
10611061 }
10621062}
10631063
1064+ static bool tokIsStringInterpolationEOF (Token &Tok, tok RightK) {
1065+ return Tok.is (tok::eof) && Tok.getText () == " )" && RightK == tok::r_paren;
1066+ }
1067+
1068+ Parser::ParseListItemResult
1069+ Parser::parseListItem (ParserStatus &Status, tok RightK, SourceLoc LeftLoc,
1070+ SourceLoc &RightLoc, bool AllowSepAfterLast,
1071+ SyntaxKind ElementKind,
1072+ llvm::function_ref<ParserStatus()> callback) {
1073+ while (Tok.is (tok::comma)) {
1074+ diagnose (Tok, diag::unexpected_separator, " ," ).fixItRemove (Tok.getLoc ());
1075+ consumeToken ();
1076+ }
1077+ SourceLoc StartLoc = Tok.getLoc ();
1078+
1079+ SyntaxParsingContext ElementContext (SyntaxContext, ElementKind);
1080+ if (ElementKind == SyntaxKind::Unknown)
1081+ ElementContext.setTransparent ();
1082+ Status |= callback ();
1083+ if (Tok.is (RightK))
1084+ return ParseListItemResult::Finished;
1085+
1086+ // If the lexer stopped with an EOF token whose spelling is ")", then this
1087+ // is actually the tuple that is a string literal interpolation context.
1088+ // Just accept the ")" and build the tuple as we usually do.
1089+ if (tokIsStringInterpolationEOF (Tok, RightK)) {
1090+ RightLoc = Tok.getLoc ();
1091+ return ParseListItemResult::FinishedInStringInterpolation;
1092+ }
1093+ // If we haven't made progress, or seeing any error, skip ahead.
1094+ if (Tok.getLoc () == StartLoc || Status.isErrorOrHasCompletion ()) {
1095+ assert (Status.isErrorOrHasCompletion () && " no progress without error" );
1096+ skipListUntilDeclRBrace (LeftLoc, RightK, tok::comma);
1097+ if (Tok.is (RightK) || Tok.isNot (tok::comma))
1098+ return ParseListItemResult::Finished;
1099+ }
1100+ if (consumeIf (tok::comma)) {
1101+ if (Tok.isNot (RightK))
1102+ return ParseListItemResult::Continue;
1103+ if (!AllowSepAfterLast) {
1104+ diagnose (Tok, diag::unexpected_separator, " ," ).fixItRemove (PreviousLoc);
1105+ }
1106+ return ParseListItemResult::Finished;
1107+ }
1108+ // If we're in a comma-separated list, the next token is at the
1109+ // beginning of a new line and can never start an element, break.
1110+ if (Tok.isAtStartOfLine () &&
1111+ (Tok.is (tok::r_brace) || isStartOfSwiftDecl () || isStartOfStmt ())) {
1112+ return ParseListItemResult::Finished;
1113+ }
1114+ // If we found EOF or such, bailout.
1115+ if (Tok.isAny (tok::eof, tok::pound_endif)) {
1116+ IsInputIncomplete = true ;
1117+ return ParseListItemResult::Finished;
1118+ }
1119+
1120+ diagnose (Tok, diag::expected_separator, " ," )
1121+ .fixItInsertAfter (PreviousLoc, " ," );
1122+ Status.setIsParseError ();
1123+ return ParseListItemResult::Continue;
1124+ }
1125+
10641126ParserStatus
10651127Parser::parseList (tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
10661128 bool AllowSepAfterLast, Diag<> ErrorDiag, SyntaxKind Kind,
10671129 llvm::function_ref<ParserStatus()> callback) {
1068- auto TokIsStringInterpolationEOF = [&]() -> bool {
1069- return Tok.is (tok::eof) && Tok.getText () == " )" && RightK == tok::r_paren;
1070- };
1071-
10721130 llvm::Optional<SyntaxParsingContext> ListContext;
10731131 ListContext.emplace (SyntaxContext, Kind);
10741132 if (Kind == SyntaxKind::Unknown)
@@ -1081,64 +1139,20 @@ Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
10811139 RightLoc = consumeToken (RightK);
10821140 return makeParserSuccess ();
10831141 }
1084- if (TokIsStringInterpolationEOF ( )) {
1142+ if (tokIsStringInterpolationEOF (Tok, RightK )) {
10851143 RightLoc = Tok.getLoc ();
10861144 return makeParserSuccess ();
10871145 }
10881146
10891147 ParserStatus Status;
1090- while (true ) {
1091- while (Tok.is (tok::comma)) {
1092- diagnose (Tok, diag::unexpected_separator, " ," )
1093- .fixItRemove (Tok.getLoc ());
1094- consumeToken ();
1095- }
1096- SourceLoc StartLoc = Tok.getLoc ();
1097-
1098- SyntaxParsingContext ElementContext (SyntaxContext, ElementKind);
1099- if (ElementKind == SyntaxKind::Unknown)
1100- ElementContext.setTransparent ();
1101- Status |= callback ();
1102- if (Tok.is (RightK))
1103- break ;
1104- // If the lexer stopped with an EOF token whose spelling is ")", then this
1105- // is actually the tuple that is a string literal interpolation context.
1106- // Just accept the ")" and build the tuple as we usually do.
1107- if (TokIsStringInterpolationEOF ()) {
1108- RightLoc = Tok.getLoc ();
1109- return Status;
1110- }
1111- // If we haven't made progress, or seeing any error, skip ahead.
1112- if (Tok.getLoc () == StartLoc || Status.isErrorOrHasCompletion ()) {
1113- assert (Status.isErrorOrHasCompletion () && " no progress without error" );
1114- skipListUntilDeclRBrace (LeftLoc, RightK, tok::comma);
1115- if (Tok.is (RightK) || Tok.isNot (tok::comma))
1116- break ;
1117- }
1118- if (consumeIf (tok::comma)) {
1119- if (Tok.isNot (RightK))
1120- continue ;
1121- if (!AllowSepAfterLast) {
1122- diagnose (Tok, diag::unexpected_separator, " ," )
1123- .fixItRemove (PreviousLoc);
1124- }
1125- break ;
1126- }
1127- // If we're in a comma-separated list, the next token is at the
1128- // beginning of a new line and can never start an element, break.
1129- if (Tok.isAtStartOfLine () &&
1130- (Tok.is (tok::r_brace) || isStartOfSwiftDecl () || isStartOfStmt ())) {
1131- break ;
1132- }
1133- // If we found EOF or such, bailout.
1134- if (Tok.isAny (tok::eof, tok::pound_endif)) {
1135- IsInputIncomplete = true ;
1136- break ;
1137- }
1148+ ParseListItemResult Result;
1149+ do {
1150+ Result = parseListItem (Status, RightK, LeftLoc, RightLoc, AllowSepAfterLast,
1151+ ElementKind, callback);
1152+ } while (Result == ParseListItemResult::Continue);
11381153
1139- diagnose (Tok, diag::expected_separator, " ," )
1140- .fixItInsertAfter (PreviousLoc, " ," );
1141- Status.setIsParseError ();
1154+ if (Result == ParseListItemResult::FinishedInStringInterpolation) {
1155+ return Status;
11421156 }
11431157
11441158 ListContext.reset ();
0 commit comments