mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 21:15:19 +00:00
Refactor unary expression parsing (#11088)
## Summary This PR refactors unary expression parsing with the following changes: * Ability to get `OperatorPrecedence` from a unary operator (`UnaryOp`) * Implement methods on `TokenKind` * Add `as_unary_operator` which returns an `Option<UnaryOp>` * Add `as_unary_arithmetic_operator` which returns an `Option<UnaryOp>` (used for pattern parsing) * Rename `is_unary` to `is_unary_arithmetic_operator` (used in the linter) resolves: #10752 ## Test Plan Verify that the existing test cases pass, no ecosystem changes, run the Python based fuzzer on 3000 random inputs and run it on dozens of open-source repositories.
This commit is contained in:
parent
7eba967e16
commit
38d2562f41
4 changed files with 125 additions and 85 deletions
|
@ -478,30 +478,34 @@ impl<'src> Parser<'src> {
|
|||
},
|
||||
})
|
||||
}
|
||||
// The `+` is only for better error recovery.
|
||||
TokenKind::Minus | TokenKind::Plus
|
||||
if matches!(
|
||||
self.peek(),
|
||||
TokenKind::Int | TokenKind::Float | TokenKind::Complex
|
||||
) =>
|
||||
{
|
||||
let unary_expr = self.parse_unary_expression(ExpressionContext::default());
|
||||
kind => {
|
||||
// The `+` is only for better error recovery.
|
||||
if let Some(unary_arithmetic_op) = kind.as_unary_arithmetic_operator() {
|
||||
if matches!(
|
||||
self.peek(),
|
||||
TokenKind::Int | TokenKind::Float | TokenKind::Complex
|
||||
) {
|
||||
let unary_expr = self.parse_unary_expression(
|
||||
unary_arithmetic_op,
|
||||
ExpressionContext::default(),
|
||||
);
|
||||
|
||||
if unary_expr.op.is_u_add() {
|
||||
self.add_error(
|
||||
ParseErrorType::OtherError(
|
||||
"Unary '+' is not allowed as a literal pattern".to_string(),
|
||||
),
|
||||
&unary_expr,
|
||||
);
|
||||
if unary_expr.op.is_u_add() {
|
||||
self.add_error(
|
||||
ParseErrorType::OtherError(
|
||||
"Unary '+' is not allowed as a literal pattern".to_string(),
|
||||
),
|
||||
&unary_expr,
|
||||
);
|
||||
}
|
||||
|
||||
return Pattern::MatchValue(ast::PatternMatchValue {
|
||||
value: Box::new(Expr::UnaryOp(unary_expr)),
|
||||
range: self.node_range(start),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Pattern::MatchValue(ast::PatternMatchValue {
|
||||
value: Box::new(Expr::UnaryOp(unary_expr)),
|
||||
range: self.node_range(start),
|
||||
})
|
||||
}
|
||||
kind => {
|
||||
// Upon encountering an unexpected token, return a `Pattern::MatchValue` containing
|
||||
// an empty `Expr::Name`.
|
||||
let invalid_node = if kind.is_keyword() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue