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>,
|
state: &mut NewArgumentListParseState<'src, 'arena>,
|
||||||
) -> Option<NewClassSpecifierParseAction> {
|
) -> Option<NewClassSpecifierParseAction> {
|
||||||
let has_parsed_all_allowed_arguments =
|
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()
|
let likely_missing_comma = !self.next_token_definitely_cannot_start_expression()
|
||||||
&& !has_parsed_all_allowed_arguments;
|
&& !has_parsed_all_allowed_arguments;
|
||||||
if likely_missing_comma {
|
if likely_missing_comma {
|
||||||
@ -282,29 +282,42 @@ impl<'src, 'arena> Parser<'src, 'arena> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reports a missing closing `)` in a `new(...)` argument list and
|
/// Recovers from a missing closing `)` in a `new(...)` argument list.
|
||||||
/// determines whether the class specifier should be parsed or skipped.
|
///
|
||||||
|
/// Returns whether class-specifier parsing should continue after recovery.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn recover_from_missing_new_closing_parenthesis(
|
fn recover_from_missing_new_closing_parenthesis(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &NewArgumentListParseState<'src, 'arena>,
|
state: &NewArgumentListParseState<'src, 'arena>,
|
||||||
) -> NewClassSpecifierParseAction {
|
) -> NewClassSpecifierParseAction {
|
||||||
let mut error = self
|
self.make_error_at_last_consumed(ParseErrorKind::NewMissingClosingParenthesis)
|
||||||
.make_error_at_last_consumed(ParseErrorKind::NewMissingClosingParenthesis)
|
|
||||||
.widen_error_span_from(state.left_parenthesis_position)
|
.widen_error_span_from(state.left_parenthesis_position)
|
||||||
.blame_token(self.peek_position_or_eof())
|
.blame_token(self.peek_position_or_eof())
|
||||||
.related_token("new_keyword", state.new_keyword_position)
|
.related_token("new_keyword", state.new_keyword_position)
|
||||||
.related_token("left_parenthesis", state.left_parenthesis_position);
|
.related_token("left_parenthesis", state.left_parenthesis_position)
|
||||||
let class_specifier_parse_action = if self.next_token_definitely_cannot_start_expression() {
|
.report(self);
|
||||||
error = error.sync_error_at_matching_delimiter(self, state.left_parenthesis_position);
|
// Missing-delimiter recovery normally syncs to the matching `)`.
|
||||||
// Skipping the class specifier avoids cascading errors when
|
// `new(...) ClassName` is an exception: after a missing `)`, the next
|
||||||
// the next token cannot start an expression anyway.
|
// 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
|
NewClassSpecifierParseAction::Skip
|
||||||
} else {
|
} else {
|
||||||
NewClassSpecifierParseAction::Parse
|
NewClassSpecifierParseAction::Parse
|
||||||
};
|
}
|
||||||
error.report_error(self);
|
|
||||||
class_specifier_parse_action
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the class specifier of a `new` expression after argument-list
|
/// Parses the class specifier of a `new` expression after argument-list
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user