Skip to content

[SyntaxParse] Adjust parseMatchingToken() #27531

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 8, 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
7 changes: 3 additions & 4 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -895,9 +895,9 @@ class Parser {
bool parseMatchingToken(tok K, SourceLoc &TokLoc, Diag<> ErrorDiag,
SourceLoc OtherLoc);

llvm::Optional<ParsedTokenSyntax>
parseMatchingTokenSyntax(tok K, SourceLoc &TokLoc, Diag<> ErrorDiag,
SourceLoc OtherLoc);
ParsedSyntaxResult<ParsedTokenSyntax>
parseMatchingTokenSyntax(tok K, Diag<> ErrorDiag, SourceLoc OtherLoc,
bool silenceDiag = false);

/// Returns the proper location for a missing right brace, parenthesis, etc.
SourceLoc getLocForMissingMatchingToken() const;
Expand All @@ -919,7 +919,6 @@ class Parser {
llvm::function_ref<ParserStatus()> callback);
ParserStatus parseListSyntax(tok RightK, SourceLoc LeftLoc,
llvm::Optional<ParsedTokenSyntax> &LastComma,
SourceLoc &RightLoc,
llvm::Optional<ParsedTokenSyntax> &Right,
llvm::SmallVectorImpl<ParsedSyntax>& Junk,
bool AllowSepAfterLast, Diag<> ErrorDiag,
Expand Down
23 changes: 9 additions & 14 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1999,13 +1999,11 @@ ParsedSyntaxResult<ParsedAttributeSyntax> Parser::parseTypeAttributeSyntax() {
}

// Parse ')'.
SourceLoc RParenLoc;
auto RParen = parseMatchingTokenSyntax(
tok::r_paren, RParenLoc, diag::convention_attribute_expected_rparen,
LParenLoc);
if (!RParen)
tok::r_paren, diag::convention_attribute_expected_rparen, LParenLoc);
if (RParen.isError())
return makeParserError();
builder.useRightParen(std::move(*RParen));
builder.useRightParen(RParen.get());

return makeParserSuccess();
}();
Expand Down Expand Up @@ -2033,13 +2031,11 @@ ParsedSyntaxResult<ParsedAttributeSyntax> Parser::parseTypeAttributeSyntax() {
builder.useArgument(consumeTokenSyntax(tok::string_literal));

// Parse ')'.
SourceLoc RParenLoc;
auto RParen = parseMatchingTokenSyntax(
tok::r_paren, RParenLoc, diag::opened_attribute_expected_rparen,
LParenLoc);
if (!RParen)
tok::r_paren, diag::opened_attribute_expected_rparen, LParenLoc);
if (RParen.isError())
return makeParserError();
builder.useRightParen(std::move(*RParen));
builder.useRightParen(RParen.get());

return makeParserSuccess();
}();
Expand Down Expand Up @@ -2085,12 +2081,11 @@ ParsedSyntaxResult<ParsedAttributeSyntax> Parser::parseTypeAttributeSyntax() {
builder.useArgument(argBuilder.build());

// Parse ')'.
SourceLoc RParenLoc;
auto RParen = parseMatchingTokenSyntax(
tok::r_paren, RParenLoc, diag::expected_rparen_expr_list, LParenLoc);
if (!RParen)
tok::r_paren, diag::expected_rparen_expr_list, LParenLoc);
if (RParen.isError())
return makeParserError();
builder.useRightParen(std::move(*RParen));
builder.useRightParen(RParen.get());

return makeParserSuccess();
}();
Expand Down
51 changes: 21 additions & 30 deletions lib/Parse/ParseType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,15 @@ Parser::parseLayoutConstraintSyntax() {
return false;
};

if (parseTrivialConstraintBody()) {
auto hasError = parseTrivialConstraintBody();
if (hasError)
ignoreUntil(tok::r_paren);
if (Tok.is(tok::r_paren))
builder.useRightParen(consumeTokenSyntax(tok::r_paren));
} else {
SourceLoc rParenLoc;
auto rParen = parseMatchingTokenSyntax(tok::r_paren, rParenLoc,
diag::expected_rparen_layout_constraint,
lParenLoc);
if (rParen)
builder.useRightParen(std::move(*rParen));
}
auto rParen = parseMatchingTokenSyntax(
tok::r_paren, diag::expected_rparen_layout_constraint, lParenLoc,
/*silenceDiag=*/hasError);
if (!rParen.isNull())
builder.useRightParen(rParen.get());

return makeParsedResult(builder.build());
}

Expand Down Expand Up @@ -979,11 +976,10 @@ ParsedSyntaxResult<ParsedTypeSyntax> Parser::parseTypeTupleBody() {

Optional<ParsedTokenSyntax> Comma;

SourceLoc RParenLoc;
Optional<ParsedTokenSyntax> RParen;

ParserStatus Status =
parseListSyntax(tok::r_paren, LParenLoc, Comma, RParenLoc, RParen, Junk,
parseListSyntax(tok::r_paren, LParenLoc, Comma, RParen, Junk,
false, diag::expected_rparen_tuple_type_list, [&]() {
Optional<BacktrackingScope> Backtracking;
SmallVector<ParsedSyntax, 0> LocalJunk;
Expand Down Expand Up @@ -1231,11 +1227,11 @@ Parser::parseTypeArray(ParsedTypeSyntax Base, SourceLoc BaseLoc) {
// Ignore integer literal between '[' and ']'
ignoreIf(tok::integer_literal);

SourceLoc RSquareLoc;
auto RSquareLoc = Tok.getLoc();
auto RSquare = parseMatchingTokenSyntax(
tok::r_square, RSquareLoc, diag::expected_rbracket_array_type, LSquareLoc);
tok::r_square, diag::expected_rbracket_array_type, LSquareLoc);

if (RSquare) {
if (!RSquare.isNull()) {
// If we parsed something valid, diagnose it with a fixit to rewrite it to
// Swift syntax.
diagnose(LSquareLoc, diag::new_array_syntax)
Expand All @@ -1247,11 +1243,9 @@ Parser::parseTypeArray(ParsedTypeSyntax Base, SourceLoc BaseLoc) {
ParserStatus status;

builder.useElementType(std::move(Base));
if (RSquare) {
builder.useRightSquareBracket(std::move(*RSquare));
} else {
status.setIsParseError();
}
if (!RSquare.isNull())
builder.useRightSquareBracket(RSquare.get());
status |= RSquare.getStatus();

return makeParsedResult(builder.build(), status);
}
Expand Down Expand Up @@ -1289,27 +1283,24 @@ ParsedSyntaxResult<ParsedTypeSyntax> Parser::parseTypeCollection() {
auto Diag = Colon ? diag::expected_rbracket_dictionary_type
: diag::expected_rbracket_array_type;

SourceLoc RSquareLoc;
auto RSquare =
parseMatchingTokenSyntax(tok::r_square, RSquareLoc, Diag, LSquareLoc);
if (!RSquare)
Status.setIsParseError();
auto RSquare = parseMatchingTokenSyntax(tok::r_square, Diag, LSquareLoc);
Status |= RSquare.getStatus();

if (Colon) {
ParsedDictionaryTypeSyntaxBuilder builder(*SyntaxContext);
builder.useLeftSquareBracket(std::move(LSquare));
builder.useKeyType(std::move(*ElementType));
builder.useColon(std::move(*Colon));
builder.useValueType(std::move(*ValueType));
if (RSquare)
builder.useRightSquareBracket(std::move(*RSquare));
if (!RSquare.isNull())
builder.useRightSquareBracket(RSquare.get());
return makeParsedResult(builder.build(), Status);
} else {
ParsedArrayTypeSyntaxBuilder builder(*SyntaxContext);
builder.useLeftSquareBracket(std::move(LSquare));
builder.useElementType(std::move(*ElementType));
if (RSquare)
builder.useRightSquareBracket(std::move(*RSquare));
if (!RSquare.isNull())
builder.useRightSquareBracket(RSquare.get());
return makeParsedResult(builder.build(), Status);
}
}
Expand Down
52 changes: 21 additions & 31 deletions lib/Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1254,22 +1254,26 @@ Optional<ParsedTokenSyntax> Parser::parseTokenSyntax(tok K, SourceLoc &TokLoc,
return None;
}

Optional<ParsedTokenSyntax>
Parser::parseMatchingTokenSyntax(tok K, SourceLoc &TokLoc, Diag<> ErrorDiag, SourceLoc OtherLoc) {
Diag<> OtherNote;
switch (K) {
case tok::r_paren: OtherNote = diag::opening_paren; break;
case tok::r_square: OtherNote = diag::opening_bracket; break;
case tok::r_brace: OtherNote = diag::opening_brace; break;
default: llvm_unreachable("unknown matching token!");
}
ParsedSyntaxResult<ParsedTokenSyntax>
Parser::parseMatchingTokenSyntax(tok K, Diag<> ErrorDiag, SourceLoc OtherLoc,
bool silenceDiag) {
if (Tok.is(K))
return makeParsedResult(consumeTokenSyntax(K));
checkForInputIncomplete();

auto Token = parseTokenSyntax(K, TokLoc, ErrorDiag);
if (!Token) {
TokLoc = getLocForMissingMatchingToken();
if (!silenceDiag) {
diagnose(Tok, ErrorDiag);

Diag<> OtherNote;
switch (K) {
case tok::r_paren: OtherNote = diag::opening_paren; break;
case tok::r_square: OtherNote = diag::opening_bracket; break;
case tok::r_brace: OtherNote = diag::opening_brace; break;
default: llvm_unreachable("unknown matching token!");
}
diagnose(OtherLoc, OtherNote);
}
return Token;
return makeParserError();
}

SourceLoc Parser::getLocForMissingMatchingToken() const {
Expand Down Expand Up @@ -1317,7 +1321,6 @@ static SyntaxKind getListElementKind(SyntaxKind ListKind) {
ParserStatus
Parser::parseListSyntax(tok RightK, SourceLoc LeftLoc,
Optional<ParsedTokenSyntax> &LastComma,
SourceLoc &RightLoc,
Optional<ParsedTokenSyntax> &Right,
SmallVectorImpl<ParsedSyntax>& Junk,
bool AllowSepAfterLast, Diag<> ErrorDiag,
Expand All @@ -1327,13 +1330,11 @@ Parser::parseListSyntax(tok RightK, SourceLoc LeftLoc,
};

if (Tok.is(RightK)) {
RightLoc = Tok.getLoc();
Right = consumeTokenSyntax(RightK);
return makeParserSuccess();
}
if (TokIsStringInterpolationEOF()) {
Tok.setKind(RightK);
RightLoc = Tok.getLoc();
Right = consumeTokenSyntax();
return makeParserSuccess();
}
Expand All @@ -1356,7 +1357,6 @@ Parser::parseListSyntax(tok RightK, SourceLoc LeftLoc,
// Just accept the ")" and build the tuple as we usually do.
if (TokIsStringInterpolationEOF()) {
Tok.setKind(RightK);
RightLoc = Tok.getLoc();
Right = consumeTokenSyntax();
return Status;
}
Expand Down Expand Up @@ -1393,20 +1393,10 @@ Parser::parseListSyntax(tok RightK, SourceLoc LeftLoc,
Status.setIsParseError();
}

if (Status.isError()) {
// If we've already got errors, don't emit missing RightK diagnostics.
if (Tok.is(RightK)) {
RightLoc = Tok.getLoc();
Right = consumeTokenSyntax(RightK);
} else {
RightLoc = getLocForMissingMatchingToken();
}
} else {
Right = parseMatchingTokenSyntax(RightK, RightLoc, ErrorDiag, LeftLoc);
if (!Right)
Status.setIsParseError();
}

auto RightResult = parseMatchingTokenSyntax(RightK, ErrorDiag, LeftLoc,
Status.isError());
Status |= RightResult.getStatus();
Right = RightResult.getOrNull();
return Status;
}

Expand Down