Change new() parser to make use of matching-) functionality
This commit is contained in:
parent
b1f0714483
commit
c58bcd4aac
@ -223,7 +223,7 @@ impl<'src, 'arena> Parser<'src, 'arena> {
|
||||
state: &mut NewArgumentListParseState<'src, 'arena>,
|
||||
) -> Option<NewClassSpecifierParseAction> {
|
||||
let has_parsed_all_allowed_arguments =
|
||||
state.call_argument_list_parse_state.parsed_slot_count > 2;
|
||||
state.call_argument_list_parse_state.parsed_slot_count >= 3;
|
||||
let likely_missing_comma = !self.next_token_definitely_cannot_start_expression()
|
||||
&& !has_parsed_all_allowed_arguments;
|
||||
if likely_missing_comma {
|
||||
@ -282,29 +282,42 @@ impl<'src, 'arena> Parser<'src, 'arena> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reports a missing closing `)` in a `new(...)` argument list and
|
||||
/// determines whether the class specifier should be parsed or skipped.
|
||||
/// Recovers from a missing closing `)` in a `new(...)` argument list.
|
||||
///
|
||||
/// Returns whether class-specifier parsing should continue after recovery.
|
||||
#[must_use]
|
||||
fn recover_from_missing_new_closing_parenthesis(
|
||||
&mut self,
|
||||
state: &NewArgumentListParseState<'src, 'arena>,
|
||||
) -> NewClassSpecifierParseAction {
|
||||
let mut error = self
|
||||
.make_error_at_last_consumed(ParseErrorKind::NewMissingClosingParenthesis)
|
||||
self.make_error_at_last_consumed(ParseErrorKind::NewMissingClosingParenthesis)
|
||||
.widen_error_span_from(state.left_parenthesis_position)
|
||||
.blame_token(self.peek_position_or_eof())
|
||||
.related_token("new_keyword", state.new_keyword_position)
|
||||
.related_token("left_parenthesis", state.left_parenthesis_position);
|
||||
let class_specifier_parse_action = if self.next_token_definitely_cannot_start_expression() {
|
||||
error = error.sync_error_at_matching_delimiter(self, state.left_parenthesis_position);
|
||||
// Skipping the class specifier avoids cascading errors when
|
||||
// the next token cannot start an expression anyway.
|
||||
.related_token("left_parenthesis", state.left_parenthesis_position)
|
||||
.report(self);
|
||||
// Missing-delimiter recovery normally syncs to the matching `)`.
|
||||
// `new(...) ClassName` is an exception: after a missing `)`, the next
|
||||
// expression may already be the class specifier, not another argument.
|
||||
let matching_right_parenthesis_ahead = self
|
||||
.file
|
||||
.matching_delimiter(state.left_parenthesis_position)
|
||||
.is_some_and(|right_parenthesis_position| {
|
||||
self.peek_position_or_eof() <= right_parenthesis_position
|
||||
});
|
||||
if matching_right_parenthesis_ahead {
|
||||
self.recover_at_matching_delimiter_or_sync(state.left_parenthesis_position);
|
||||
// After syncing through the matched `)`, the argument-list error is
|
||||
// contained, so class-specifier parsing can proceed normally.
|
||||
return NewClassSpecifierParseAction::Parse;
|
||||
}
|
||||
if self.next_token_definitely_cannot_start_expression() {
|
||||
// There is no plausible class specifier to parse, so skip it to
|
||||
// avoid error cascade.
|
||||
NewClassSpecifierParseAction::Skip
|
||||
} else {
|
||||
NewClassSpecifierParseAction::Parse
|
||||
};
|
||||
error.report_error(self);
|
||||
class_specifier_parse_action
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the class specifier of a `new` expression after argument-list
|
||||
|
||||
Loading…
Reference in New Issue
Block a user