mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-31 23:57:35 +00:00
Split Constant
to individual literal nodes (#8064)
## Summary This PR splits the `Constant` enum as individual literal nodes. It introduces the following new nodes for each variant: * `ExprStringLiteral` * `ExprBytesLiteral` * `ExprNumberLiteral` * `ExprBooleanLiteral` * `ExprNoneLiteral` * `ExprEllipsisLiteral` The main motivation behind this refactor is to introduce the new AST node for implicit string concatenation in the coming PR. The elements of that node will be either a string literal, bytes literal or a f-string which can be implemented using an enum. This means that a string or bytes literal cannot be represented by `Constant::Str` / `Constant::Bytes` which creates an inconsistency. This PR avoids that inconsistency by splitting the constant nodes into it's own literal nodes, literal being the more appropriate naming convention from a static analysis tool perspective. This also makes working with literals in the linter and formatter much more ergonomic like, for example, if one would want to check if this is a string literal, it can be done easily using `Expr::is_string_literal_expr` or matching against `Expr::StringLiteral` as oppose to matching against the `ExprConstant` and enum `Constant`. A few AST helper methods can be simplified as well which will be done in a follow-up PR. This introduces a new `Expr::is_literal_expr` method which is the same as `Expr::is_constant_expr`. There are also intermediary changes related to implicit string concatenation which are quiet less. This is done so as to avoid having a huge PR which this already is. ## Test Plan 1. Verify and update all of the existing snapshots (parser, visitor) 2. Verify that the ecosystem check output remains **unchanged** for both the linter and formatter ### Formatter ecosystem check #### `main` | project | similarity index | total files | changed files | |----------------|------------------:|------------------:|------------------:| | cpython | 0.75803 | 1799 | 1647 | | django | 0.99983 | 2772 | 34 | | home-assistant | 0.99953 | 10596 | 186 | | poetry | 0.99891 | 317 | 17 | | transformers | 0.99966 | 2657 | 330 | | twine | 1.00000 | 33 | 0 | | typeshed | 0.99978 | 3669 | 20 | | warehouse | 0.99977 | 654 | 13 | | zulip | 0.99970 | 1459 | 22 | #### `dhruv/constant-to-literal` | project | similarity index | total files | changed files | |----------------|------------------:|------------------:|------------------:| | cpython | 0.75803 | 1799 | 1647 | | django | 0.99983 | 2772 | 34 | | home-assistant | 0.99953 | 10596 | 186 | | poetry | 0.99891 | 317 | 17 | | transformers | 0.99966 | 2657 | 330 | | twine | 1.00000 | 33 | 0 | | typeshed | 0.99978 | 3669 | 20 | | warehouse | 0.99977 | 654 | 13 | | zulip | 0.99970 | 1459 | 22 |
This commit is contained in:
parent
78bbf6d403
commit
230c9ce236
268 changed files with 6663 additions and 6741 deletions
|
@ -377,9 +377,9 @@ IpyHelpEndEscapeCommandStatement: ast::Stmt = {
|
|||
buffer.push_str(id.as_str());
|
||||
},
|
||||
ast::Expr::Subscript(ast::ExprSubscript { value, slice, range, .. }) => {
|
||||
let ast::Expr::Constant(ast::ExprConstant { value: ast::Constant::Int(integer), .. }) = slice.as_ref() else {
|
||||
let ast::Expr::NumberLiteral(ast::ExprNumberLiteral { value: ast::Number::Int(integer), .. }) = slice.as_ref() else {
|
||||
return Err(LexicalError {
|
||||
error: LexicalErrorType::OtherError("only integer constants are allowed in Subscript expressions in help end escape command".to_string()),
|
||||
error: LexicalErrorType::OtherError("only integer literals are allowed in Subscript expressions in help end escape command".to_string()),
|
||||
location: range.start(),
|
||||
});
|
||||
};
|
||||
|
@ -627,15 +627,15 @@ StarPattern: ast::Pattern = {
|
|||
}.into(),
|
||||
}
|
||||
|
||||
ConstantAtom: ast::ParenthesizedExpr = {
|
||||
<location:@L> <value:Constant> <end_location:@R> => ast::Expr::Constant(
|
||||
ast::ExprConstant { value, range: (location..end_location).into() }
|
||||
NumberAtom: ast::ParenthesizedExpr = {
|
||||
<location:@L> <value:Number> <end_location:@R> => ast::Expr::NumberLiteral(
|
||||
ast::ExprNumberLiteral { value, range: (location..end_location).into() }
|
||||
).into(),
|
||||
}
|
||||
|
||||
ConstantExpr: ast::ParenthesizedExpr = {
|
||||
ConstantAtom,
|
||||
<location:@L> "-" <operand:ConstantAtom> <end_location:@R> => ast::Expr::UnaryOp(
|
||||
NumberExpr: ast::ParenthesizedExpr = {
|
||||
NumberAtom,
|
||||
<location:@L> "-" <operand:NumberAtom> <end_location:@R> => ast::Expr::UnaryOp(
|
||||
ast::ExprUnaryOp {
|
||||
op: ast::UnaryOp::USub,
|
||||
operand: Box::new(operand.into()),
|
||||
|
@ -645,7 +645,7 @@ ConstantExpr: ast::ParenthesizedExpr = {
|
|||
}
|
||||
|
||||
AddOpExpr: ast::ParenthesizedExpr = {
|
||||
<location:@L> <left:ConstantExpr> <op:AddOp> <right:ConstantAtom> <end_location:@R> => ast::ExprBinOp {
|
||||
<location:@L> <left:NumberExpr> <op:AddOp> <right:NumberAtom> <end_location:@R> => ast::ExprBinOp {
|
||||
left: Box::new(left.into()),
|
||||
op,
|
||||
right: Box::new(right.into()),
|
||||
|
@ -666,7 +666,7 @@ LiteralPattern: ast::Pattern = {
|
|||
value: false.into(),
|
||||
range: (location..end_location).into()
|
||||
}.into(),
|
||||
<location:@L> <value:ConstantExpr> <end_location:@R> => ast::PatternMatchValue {
|
||||
<location:@L> <value:NumberExpr> <end_location:@R> => ast::PatternMatchValue {
|
||||
value: Box::new(value.into()),
|
||||
range: (location..end_location).into()
|
||||
}.into(),
|
||||
|
@ -718,18 +718,17 @@ ValuePattern: ast::Pattern = {
|
|||
|
||||
MappingKey: ast::Expr = {
|
||||
MatchNameOrAttr,
|
||||
<e:ConstantExpr> => e.into(),
|
||||
<e:NumberExpr> => e.into(),
|
||||
<e:AddOpExpr> => e.into(),
|
||||
<location:@L> "None" <end_location:@R> => ast::ExprConstant {
|
||||
value: ast::Constant::None,
|
||||
<location:@L> "None" <end_location:@R> => ast::ExprNoneLiteral {
|
||||
range: (location..end_location).into()
|
||||
}.into(),
|
||||
<location:@L> "True" <end_location:@R> => ast::ExprConstant {
|
||||
value: true.into(),
|
||||
<location:@L> "True" <end_location:@R> => ast::ExprBooleanLiteral {
|
||||
value: true,
|
||||
range: (location..end_location).into()
|
||||
}.into(),
|
||||
<location:@L> "False" <end_location:@R> => ast::ExprConstant {
|
||||
value: false.into(),
|
||||
<location:@L> "False" <end_location:@R> => ast::ExprBooleanLiteral {
|
||||
value: false,
|
||||
range: (location..end_location).into()
|
||||
}.into(),
|
||||
<location:@L> <strings:StringLiteralOrFString+> <end_location:@R> =>? Ok(concatenate_strings(strings, (location..end_location).into())?),
|
||||
|
@ -1684,7 +1683,7 @@ FStringConversion: (TextSize, ast::ConversionFlag) = {
|
|||
|
||||
Atom<Goal>: ast::ParenthesizedExpr = {
|
||||
<location:@L> <strings:StringLiteralOrFString+> <end_location:@R> =>? Ok(concatenate_strings(strings, (location..end_location).into())?.into()),
|
||||
<location:@L> <value:Constant> <end_location:@R> => ast::ExprConstant {
|
||||
<location:@L> <value:Number> <end_location:@R> => ast::ExprNumberLiteral {
|
||||
value,
|
||||
range: (location..end_location).into(),
|
||||
}.into(),
|
||||
|
@ -1776,10 +1775,10 @@ Atom<Goal>: ast::ParenthesizedExpr = {
|
|||
generators,
|
||||
range: (location..end_location).into(),
|
||||
}.into(),
|
||||
<location:@L> "True" <end_location:@R> => ast::ExprConstant { value: true.into(), range: (location..end_location).into() }.into(),
|
||||
<location:@L> "False" <end_location:@R> => ast::ExprConstant { value: false.into(), range: (location..end_location).into() }.into(),
|
||||
<location:@L> "None" <end_location:@R> => ast::ExprConstant { value: ast::Constant::None, range: (location..end_location).into() }.into(),
|
||||
<location:@L> "..." <end_location:@R> => ast::ExprConstant { value: ast::Constant::Ellipsis, range: (location..end_location).into() }.into(),
|
||||
<location:@L> "True" <end_location:@R> => ast::ExprBooleanLiteral { value: true, range: (location..end_location).into() }.into(),
|
||||
<location:@L> "False" <end_location:@R> => ast::ExprBooleanLiteral { value: false, range: (location..end_location).into() }.into(),
|
||||
<location:@L> "None" <end_location:@R> => ast::ExprNoneLiteral { range: (location..end_location).into() }.into(),
|
||||
<location:@L> "..." <end_location:@R> => ast::ExprEllipsisLiteral { range: (location..end_location).into() }.into(),
|
||||
};
|
||||
|
||||
ListLiteralValues: Vec<ast::ParenthesizedExpr> = {
|
||||
|
@ -1932,10 +1931,10 @@ TwoOrMore<T, Sep>: Vec<T> = {
|
|||
}
|
||||
};
|
||||
|
||||
Constant: ast::Constant = {
|
||||
<value:int> => ast::Constant::Int(value),
|
||||
<value:float> => ast::Constant::Float(value),
|
||||
<s:complex> => ast::Constant::Complex { real: s.0, imag: s.1 },
|
||||
Number: ast::Number = {
|
||||
<value:int> => ast::Number::Int(value),
|
||||
<value:float> => ast::Number::Float(value),
|
||||
<s:complex> => ast::Number::Complex { real: s.0, imag: s.1 },
|
||||
};
|
||||
|
||||
Identifier: ast::Identifier = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue