Compare commits

...

1 Commits

Author SHA1 Message Date
konstin
7f97547b5f Add increment/decrement 2024-03-14 16:56:06 +01:00
15 changed files with 23614 additions and 23203 deletions

View File

@@ -141,15 +141,15 @@ impl<'src, 'loc> UselessSuppressionComments<'src, 'loc> {
if comment.kind == SuppressionKind::Off || comment.kind == SuppressionKind::On {
if let Some(
AnyNodeRef::StmtClassDef(StmtClassDef {
name,
decorator_list,
..
})
name,
decorator_list,
..
})
| AnyNodeRef::StmtFunctionDef(StmtFunctionDef {
name,
decorator_list,
..
}),
name,
decorator_list,
..
}),
) = comment.enclosing
{
if comment.line_position.is_own_line() && comment.range.start() < name.start() {
@@ -196,7 +196,7 @@ impl<'src, 'loc> UselessSuppressionComments<'src, 'loc> {
self.captured.sort_by_key(|(t, _)| t.start());
}
fn ignored_comments(&self) -> impl Iterator<Item = (TextRange, IgnoredReason)> + '_ {
fn ignored_comments(&self) -> impl Iterator<Item=(TextRange, IgnoredReason)> + '_ {
self.captured.iter().map(|(r, i)| (*r, *i))
}
}
@@ -276,7 +276,8 @@ const fn is_valid_enclosing_node(node: AnyNodeRef) -> bool {
| AnyNodeRef::StmtIpyEscapeCommand(_)
| AnyNodeRef::ExceptHandlerExceptHandler(_)
| AnyNodeRef::MatchCase(_)
| AnyNodeRef::ElifElseClause(_) => true,
| AnyNodeRef::ElifElseClause(_)
| AnyNodeRef::StmtCrement(_) => true,
AnyNodeRef::ExprBoolOp(_)
| AnyNodeRef::ExprNamed(_)

View File

@@ -1543,6 +1543,9 @@ impl<'a> From<&'a ast::Stmt> for ComparableStmt<'a> {
ast::Stmt::Pass(_) => Self::Pass,
ast::Stmt::Break(_) => Self::Break,
ast::Stmt::Continue(_) => Self::Continue,
ast::Stmt::Crement(_) => {
todo!()
}
}
}
}

View File

@@ -432,6 +432,7 @@ pub fn any_over_stmt(stmt: &Stmt, func: &dyn Fn(&Expr) -> bool) -> bool {
Stmt::AugAssign(ast::StmtAugAssign { target, value, .. }) => {
any_over_expr(target, func) || any_over_expr(value, func)
}
Stmt::Crement(ast::StmtCrement { target, .. }) => any_over_expr(target, func),
Stmt::AnnAssign(ast::StmtAnnAssign {
target,
annotation,

View File

@@ -36,6 +36,7 @@ pub enum AnyNode {
StmtTypeAlias(ast::StmtTypeAlias),
StmtAssign(ast::StmtAssign),
StmtAugAssign(ast::StmtAugAssign),
StmtCrement(ast::StmtCrement),
StmtAnnAssign(ast::StmtAnnAssign),
StmtFor(ast::StmtFor),
StmtWhile(ast::StmtWhile),
@@ -130,6 +131,7 @@ impl AnyNode {
AnyNode::StmtTypeAlias(node) => Some(Stmt::TypeAlias(node)),
AnyNode::StmtAssign(node) => Some(Stmt::Assign(node)),
AnyNode::StmtAugAssign(node) => Some(Stmt::AugAssign(node)),
AnyNode::StmtCrement(node) => Some(Stmt::Crement(node)),
AnyNode::StmtAnnAssign(node) => Some(Stmt::AnnAssign(node)),
AnyNode::StmtFor(node) => Some(Stmt::For(node)),
AnyNode::StmtWhile(node) => Some(Stmt::While(node)),
@@ -262,6 +264,7 @@ impl AnyNode {
| AnyNode::StmtTypeAlias(_)
| AnyNode::StmtAssign(_)
| AnyNode::StmtAugAssign(_)
| AnyNode::StmtCrement(_)
| AnyNode::StmtAnnAssign(_)
| AnyNode::StmtFor(_)
| AnyNode::StmtWhile(_)
@@ -327,6 +330,7 @@ impl AnyNode {
| AnyNode::StmtTypeAlias(_)
| AnyNode::StmtAssign(_)
| AnyNode::StmtAugAssign(_)
| AnyNode::StmtCrement(_)
| AnyNode::StmtAnnAssign(_)
| AnyNode::StmtFor(_)
| AnyNode::StmtWhile(_)
@@ -432,6 +436,7 @@ impl AnyNode {
| AnyNode::StmtTypeAlias(_)
| AnyNode::StmtAssign(_)
| AnyNode::StmtAugAssign(_)
| AnyNode::StmtCrement(_)
| AnyNode::StmtAnnAssign(_)
| AnyNode::StmtFor(_)
| AnyNode::StmtWhile(_)
@@ -522,6 +527,7 @@ impl AnyNode {
| AnyNode::StmtTypeAlias(_)
| AnyNode::StmtAssign(_)
| AnyNode::StmtAugAssign(_)
| AnyNode::StmtCrement(_)
| AnyNode::StmtAnnAssign(_)
| AnyNode::StmtFor(_)
| AnyNode::StmtWhile(_)
@@ -637,6 +643,7 @@ impl AnyNode {
Self::StmtTypeAlias(node) => AnyNodeRef::StmtTypeAlias(node),
Self::StmtAssign(node) => AnyNodeRef::StmtAssign(node),
Self::StmtAugAssign(node) => AnyNodeRef::StmtAugAssign(node),
Self::StmtCrement(node) => AnyNodeRef::StmtCrement(node),
Self::StmtAnnAssign(node) => AnyNodeRef::StmtAnnAssign(node),
Self::StmtFor(node) => AnyNodeRef::StmtFor(node),
Self::StmtWhile(node) => AnyNodeRef::StmtWhile(node),
@@ -1125,6 +1132,48 @@ impl AstNode for ast::StmtAugAssign {
visitor.visit_expr(value);
}
}
impl AstNode for ast::StmtCrement {
fn cast(kind: AnyNode) -> Option<Self>
where
Self: Sized,
{
if let AnyNode::StmtCrement(node) = kind {
Some(node)
} else {
None
}
}
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
if let AnyNodeRef::StmtCrement(node) = kind {
Some(node)
} else {
None
}
}
fn as_any_node_ref(&self) -> AnyNodeRef {
AnyNodeRef::from(self)
}
fn into_any_node(self) -> AnyNode {
AnyNode::from(self)
}
fn visit_preorder<'a, V>(&'a self, visitor: &mut V)
where
V: PreorderVisitor<'a> + ?Sized,
{
let ast::StmtCrement {
target,
op: _,
range: _,
} = self;
visitor.visit_expr(target);
// TODO(konstin): visitor.visit_operator(op);
}
}
impl AstNode for ast::StmtAnnAssign {
fn cast(kind: AnyNode) -> Option<Self>
where
@@ -4538,6 +4587,7 @@ impl From<Stmt> for AnyNode {
Stmt::Break(node) => AnyNode::StmtBreak(node),
Stmt::Continue(node) => AnyNode::StmtContinue(node),
Stmt::IpyEscapeCommand(node) => AnyNode::StmtIpyEscapeCommand(node),
Stmt::Crement(node) => AnyNode::StmtCrement(node),
}
}
}
@@ -4676,6 +4726,12 @@ impl From<ast::StmtAugAssign> for AnyNode {
}
}
impl From<ast::StmtCrement> for AnyNode {
fn from(node: ast::StmtCrement) -> Self {
AnyNode::StmtCrement(node)
}
}
impl From<ast::StmtAnnAssign> for AnyNode {
fn from(node: ast::StmtAnnAssign) -> Self {
AnyNode::StmtAnnAssign(node)
@@ -5251,6 +5307,7 @@ impl Ranged for AnyNode {
AnyNode::StringLiteral(node) => node.range(),
AnyNode::BytesLiteral(node) => node.range(),
AnyNode::ElifElseClause(node) => node.range(),
AnyNode::StmtCrement(node) => node.range(),
}
}
}
@@ -5266,6 +5323,7 @@ pub enum AnyNodeRef<'a> {
StmtTypeAlias(&'a ast::StmtTypeAlias),
StmtAssign(&'a ast::StmtAssign),
StmtAugAssign(&'a ast::StmtAugAssign),
StmtCrement(&'a ast::StmtCrement),
StmtAnnAssign(&'a ast::StmtAnnAssign),
StmtFor(&'a ast::StmtFor),
StmtWhile(&'a ast::StmtWhile),
@@ -5444,6 +5502,7 @@ impl<'a> AnyNodeRef<'a> {
AnyNodeRef::StringLiteral(node) => NonNull::from(*node).cast(),
AnyNodeRef::BytesLiteral(node) => NonNull::from(*node).cast(),
AnyNodeRef::ElifElseClause(node) => NonNull::from(*node).cast(),
AnyNodeRef::StmtCrement(node) => NonNull::from(*node).cast(),
}
}
@@ -5546,6 +5605,7 @@ impl<'a> AnyNodeRef<'a> {
AnyNodeRef::StringLiteral(_) => NodeKind::StringLiteral,
AnyNodeRef::BytesLiteral(_) => NodeKind::BytesLiteral,
AnyNodeRef::ElifElseClause(_) => NodeKind::ElifElseClause,
AnyNodeRef::StmtCrement(_) => NodeKind::StmtCrement,
}
}
@@ -5558,6 +5618,7 @@ impl<'a> AnyNodeRef<'a> {
| AnyNodeRef::StmtTypeAlias(_)
| AnyNodeRef::StmtAssign(_)
| AnyNodeRef::StmtAugAssign(_)
| AnyNodeRef::StmtCrement(_)
| AnyNodeRef::StmtAnnAssign(_)
| AnyNodeRef::StmtFor(_)
| AnyNodeRef::StmtWhile(_)
@@ -5690,6 +5751,7 @@ impl<'a> AnyNodeRef<'a> {
| AnyNodeRef::StmtTypeAlias(_)
| AnyNodeRef::StmtAssign(_)
| AnyNodeRef::StmtAugAssign(_)
| AnyNodeRef::StmtCrement(_)
| AnyNodeRef::StmtAnnAssign(_)
| AnyNodeRef::StmtFor(_)
| AnyNodeRef::StmtWhile(_)
@@ -5754,6 +5816,7 @@ impl<'a> AnyNodeRef<'a> {
| AnyNodeRef::StmtTypeAlias(_)
| AnyNodeRef::StmtAssign(_)
| AnyNodeRef::StmtAugAssign(_)
| AnyNodeRef::StmtCrement(_)
| AnyNodeRef::StmtAnnAssign(_)
| AnyNodeRef::StmtFor(_)
| AnyNodeRef::StmtWhile(_)
@@ -5859,6 +5922,7 @@ impl<'a> AnyNodeRef<'a> {
| AnyNodeRef::StmtTypeAlias(_)
| AnyNodeRef::StmtAssign(_)
| AnyNodeRef::StmtAugAssign(_)
| AnyNodeRef::StmtCrement(_)
| AnyNodeRef::StmtAnnAssign(_)
| AnyNodeRef::StmtFor(_)
| AnyNodeRef::StmtWhile(_)
@@ -5949,6 +6013,7 @@ impl<'a> AnyNodeRef<'a> {
| AnyNodeRef::StmtTypeAlias(_)
| AnyNodeRef::StmtAssign(_)
| AnyNodeRef::StmtAugAssign(_)
| AnyNodeRef::StmtCrement(_)
| AnyNodeRef::StmtAnnAssign(_)
| AnyNodeRef::StmtFor(_)
| AnyNodeRef::StmtWhile(_)
@@ -6058,6 +6123,7 @@ impl<'a> AnyNodeRef<'a> {
AnyNodeRef::StmtTypeAlias(node) => node.visit_preorder(visitor),
AnyNodeRef::StmtAssign(node) => node.visit_preorder(visitor),
AnyNodeRef::StmtAugAssign(node) => node.visit_preorder(visitor),
AnyNodeRef::StmtCrement(node) => node.visit_preorder(visitor),
AnyNodeRef::StmtAnnAssign(node) => node.visit_preorder(visitor),
AnyNodeRef::StmtFor(node) => node.visit_preorder(visitor),
AnyNodeRef::StmtWhile(node) => node.visit_preorder(visitor),
@@ -6372,6 +6438,12 @@ impl<'a> From<&'a ast::StmtAugAssign> for AnyNodeRef<'a> {
}
}
impl<'a> From<&'a ast::StmtCrement> for AnyNodeRef<'a> {
fn from(node: &'a ast::StmtCrement) -> Self {
AnyNodeRef::StmtCrement(node)
}
}
impl<'a> From<&'a ast::StmtAnnAssign> for AnyNodeRef<'a> {
fn from(node: &'a ast::StmtAnnAssign) -> Self {
AnyNodeRef::StmtAnnAssign(node)
@@ -6837,6 +6909,7 @@ impl<'a> From<&'a Stmt> for AnyNodeRef<'a> {
Stmt::Break(node) => AnyNodeRef::StmtBreak(node),
Stmt::Continue(node) => AnyNodeRef::StmtContinue(node),
Stmt::IpyEscapeCommand(node) => AnyNodeRef::StmtIpyEscapeCommand(node),
Stmt::Crement(node) => AnyNodeRef::StmtCrement(node),
}
}
}
@@ -7073,6 +7146,7 @@ impl Ranged for AnyNodeRef<'_> {
AnyNodeRef::FString(node) => node.range(),
AnyNodeRef::StringLiteral(node) => node.range(),
AnyNodeRef::BytesLiteral(node) => node.range(),
AnyNodeRef::StmtCrement(node) => node.range(),
}
}
}
@@ -7173,4 +7247,5 @@ pub enum NodeKind {
FString,
StringLiteral,
BytesLiteral,
StmtCrement,
}

View File

@@ -101,6 +101,8 @@ pub enum Stmt {
// Jupyter notebook specific
#[is(name = "ipy_escape_command_stmt")]
IpyEscapeCommand(StmtIpyEscapeCommand),
#[is(name = "crement_stmt")]
Crement(StmtCrement),
}
/// An AST node used to represent a IPython escape command at the statement level.
@@ -297,6 +299,26 @@ impl From<StmtAugAssign> for Stmt {
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum CrementKind {
Increment,
Decrement,
}
/// `++` or `--`
#[derive(Clone, Debug, PartialEq)]
pub struct StmtCrement {
pub range: TextRange,
pub target: Box<Expr>,
pub op: CrementKind,
}
impl From<StmtCrement> for Stmt {
fn from(payload: StmtCrement) -> Self {
Stmt::Crement(payload)
}
}
/// See also [AnnAssign](https://docs.python.org/3/library/ast.html#ast.AnnAssign)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAnnAssign {
@@ -3693,6 +3715,11 @@ impl Ranged for crate::nodes::StmtAugAssign {
self.range
}
}
impl Ranged for crate::nodes::StmtCrement {
fn range(&self) -> TextRange {
self.range
}
}
impl Ranged for crate::nodes::StmtAnnAssign {
fn range(&self) -> TextRange {
self.range
@@ -3816,6 +3843,7 @@ impl Ranged for crate::Stmt {
Self::Break(node) => node.range(),
Self::Continue(node) => node.range(),
Stmt::IpyEscapeCommand(node) => node.range(),
Stmt::Crement(node) => node.range(),
}
}
}

View File

@@ -203,6 +203,14 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
visitor.visit_operator(op);
visitor.visit_expr(target);
}
Stmt::Crement(ast::StmtCrement {
target,
op: _,
range: _,
}) => {
// TODO(konstin): visitor.visit_operator(op);
visitor.visit_expr(target);
}
Stmt::AnnAssign(ast::StmtAnnAssign {
target,
annotation,

View File

@@ -209,6 +209,7 @@ where
Stmt::TypeAlias(stmt) => stmt.visit_preorder(visitor),
Stmt::Assign(stmt) => stmt.visit_preorder(visitor),
Stmt::AugAssign(stmt) => stmt.visit_preorder(visitor),
Stmt::Crement(stmt) => stmt.visit_preorder(visitor),
Stmt::AnnAssign(stmt) => stmt.visit_preorder(visitor),
Stmt::For(stmt) => stmt.visit_preorder(visitor),
Stmt::While(stmt) => stmt.visit_preorder(visitor),

View File

@@ -306,6 +306,7 @@ pub fn walk_stmt<V: Transformer + ?Sized>(visitor: &V, stmt: &mut Stmt) {
Stmt::Nonlocal(_) => {}
Stmt::Expr(ast::StmtExpr { value, range: _ }) => visitor.visit_expr(value),
Stmt::Pass(_) | Stmt::Break(_) | Stmt::Continue(_) | Stmt::IpyEscapeCommand(_) => {}
Stmt::Crement(_) => {}
}
}

View File

@@ -4,10 +4,10 @@ use std::ops::Deref;
use ruff_python_ast::str::Quote;
use ruff_python_ast::{
self as ast, Alias, ArgOrKeyword, BoolOp, CmpOp, Comprehension, ConversionFlag, DebugText,
ExceptHandler, Expr, Identifier, MatchCase, Operator, Parameter, Parameters, Pattern,
Singleton, Stmt, Suite, TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple,
WithItem,
self as ast, Alias, ArgOrKeyword, BoolOp, CmpOp, Comprehension, ConversionFlag, CrementKind,
DebugText, ExceptHandler, Expr, Identifier, MatchCase, Operator, Parameter, Parameters,
Pattern, Singleton, Stmt, Suite, TypeParam, TypeParamParamSpec, TypeParamTypeVar,
TypeParamTypeVarTuple, WithItem,
};
use ruff_python_ast::{ParameterWithDefault, TypeParams};
use ruff_python_literal::escape::{AsciiEscape, Escape, UnicodeEscape};
@@ -345,6 +345,20 @@ impl<'a> Generator<'a> {
self.unparse_expr(value, precedence::AUG_ASSIGN);
});
}
Stmt::Crement(ast::StmtCrement {
target,
op,
range: _,
}) => {
statement!({
self.unparse_expr(target, precedence::AUG_ASSIGN);
self.p(" ");
self.p(match op {
CrementKind::Increment => "+= 1",
CrementKind::Decrement => "-= 1",
});
});
}
Stmt::AnnAssign(ast::StmtAnnAssign {
target,
annotation,

View File

@@ -706,7 +706,8 @@ impl Format<PyFormatContext<'_>> for FormatEnclosingNode<'_> {
| AnyNodeRef::TypeParamTypeVar(_)
| AnyNodeRef::TypeParamTypeVarTuple(_)
| AnyNodeRef::TypeParamParamSpec(_)
| AnyNodeRef::BytesLiteral(_) => {
| AnyNodeRef::BytesLiteral(_)
| AnyNodeRef::StmtCrement(_) => {
panic!("Range formatting only supports formatting logical lines")
}
}

View File

@@ -45,6 +45,19 @@ impl FormatRule<Stmt, PyFormatContext<'_>> for FormatStmt {
Stmt::Delete(x) => x.format().fmt(f),
Stmt::Assign(x) => x.format().fmt(f),
Stmt::AugAssign(x) => x.format().fmt(f),
Stmt::Crement(x) => {
x.target.format().fmt(f)?;
use ruff_formatter::prelude::*;
match x.op {
ruff_python_ast::CrementKind::Increment => {
ruff_formatter::write!(f, [space(), text("+="), space(), text("1")])?;
}
ruff_python_ast::CrementKind::Decrement => {
ruff_formatter::write!(f, [space(), text("-="), space(), text("1")])?;
}
}
Ok(())
}
Stmt::AnnAssign(x) => x.format().fmt(f),
Stmt::For(x) => x.format().fmt(f),
Stmt::While(x) => x.format().fmt(f),

View File

@@ -1079,7 +1079,9 @@ impl<'source> Lexer<'source> {
}
}
'+' => {
if self.cursor.eat_char('=') {
if self.cursor.eat_char('+') {
Tok::Increment
} else if self.cursor.eat_char('=') {
Tok::PlusEqual
} else {
Tok::Plus
@@ -1166,7 +1168,9 @@ impl<'source> Lexer<'source> {
}
}
'-' => {
if self.cursor.eat_char('=') {
if self.cursor.eat_char('-') {
Tok::Increment
} else if self.cursor.eat_char('=') {
Tok::MinusEqual
} else if self.cursor.eat_char('>') {
Tok::Rarrow

View File

@@ -110,6 +110,16 @@ DelStatement: ast::Stmt = {
};
ExpressionStatement: ast::Stmt = {
<location:@L> <target:TestOrStarExprList> <op:Crement> <end_location:@R> =>? {
invalid::assignment_target(&target.expr)?;
Ok(ast::Stmt::Crement(
ast::StmtCrement {
target: Box::new(set_context(target.into(), ast::ExprContext::Store)),
op,
range: (location..end_location).into()
},
))
},
<location:@L> <expression:TestOrStarExprList> <suffix:AssignSuffix*> <end_location:@R> =>? {
// Just an expression, no assignment:
if suffix.is_empty() {
@@ -204,6 +214,11 @@ AugAssign: ast::Operator = {
"//=" => ast::Operator::FloorDiv,
};
Crement: ast::CrementKind = {
"++" => ast::CrementKind::Increment,
"--" => ast::CrementKind::Decrement,
};
FlowStatement: ast::Stmt = {
<location:@L> "break" <end_location:@R> => {
@@ -2033,6 +2048,8 @@ extern {
">" => token::Tok::Greater,
">=" => token::Tok::GreaterEqual,
"->" => token::Tok::Rarrow,
"++" => token::Tok::Increment,
"--" => token::Tok::Decrement,
"and" => token::Tok::And,
"as" => token::Tok::As,
"assert" => token::Tok::Assert,

File diff suppressed because it is too large Load Diff

View File

@@ -157,6 +157,10 @@ pub enum Tok {
VbarEqual,
/// Token value for caret equal `^=`.
CircumflexEqual,
/// Token value for `++`.
Increment,
/// Token value for `--`.
Decrement,
/// Token value for left shift equal `<<=`.
LeftShiftEqual,
/// Token value for right shift equal `>>=`.
@@ -343,6 +347,8 @@ impl fmt::Display for Tok {
With => f.write_str("'with'"),
Yield => f.write_str("'yield'"),
ColonEqual => f.write_str("':='"),
Increment => f.write_str("++"),
Decrement => f.write_str("--"),
}
}
}
@@ -526,6 +532,8 @@ pub enum TokenKind {
StartModule,
StartInteractive,
StartExpression,
Increment,
Decrement,
}
impl TokenKind {
@@ -620,6 +628,8 @@ impl TokenKind {
| TokenKind::AmperEqual
| TokenKind::VbarEqual
| TokenKind::CircumflexEqual
| TokenKind::Increment
| TokenKind::Decrement
| TokenKind::LeftShiftEqual
| TokenKind::RightShiftEqual
| TokenKind::DoubleStarEqual
@@ -799,6 +809,8 @@ impl TokenKind {
Tok::Yield => TokenKind::Yield,
Tok::StartModule => TokenKind::StartModule,
Tok::StartExpression => TokenKind::StartExpression,
Tok::Increment => TokenKind::Increment,
Tok::Decrement => TokenKind::Decrement,
}
}
}