From c5e039f81f209565a9e4f5e18c20724436cacb33 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 16 May 2023 11:16:34 -0400 Subject: [PATCH] Avoid emitting empty logical lines --- .../resources/test/fixtures/pycodestyle/E11.py | 15 +++++++++++++++ crates/ruff/src/checkers/logical_lines.rs | 15 +++++++++++++++ .../rules/pycodestyle/rules/logical_lines/mod.rs | 15 ++++++++++----- crates/ruff_python_ast/src/token_kind.rs | 5 +++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/pycodestyle/E11.py b/crates/ruff/resources/test/fixtures/pycodestyle/E11.py index fbf18fa23599d..9f94aea1011c9 100644 --- a/crates/ruff/resources/test/fixtures/pycodestyle/E11.py +++ b/crates/ruff/resources/test/fixtures/pycodestyle/E11.py @@ -49,3 +49,18 @@ def start(): #: if False: # print() +#: +if False: + print() + + print() +#: +if False: + print() + if False: + + print() +#: +if False: + + print() diff --git a/crates/ruff/src/checkers/logical_lines.rs b/crates/ruff/src/checkers/logical_lines.rs index ca1a35c565aaa..6e32b87306e8b 100644 --- a/crates/ruff/src/checkers/logical_lines.rs +++ b/crates/ruff/src/checkers/logical_lines.rs @@ -250,5 +250,20 @@ f()"# "f()", ]; assert_eq!(actual, expected); + + let contents = r#" +if False: + + print() +"# + .trim(); + let lxr: Vec = lexer::lex(contents, Mode::Module).collect(); + let locator = Locator::new(contents); + let actual: Vec = LogicalLines::from_tokens(&lxr, &locator) + .into_iter() + .map(|line| line.text_trimmed().to_string()) + .collect(); + let expected = vec!["if False:", "print()", ""]; + assert_eq!(actual, expected); } } diff --git a/crates/ruff/src/rules/pycodestyle/rules/logical_lines/mod.rs b/crates/ruff/src/rules/pycodestyle/rules/logical_lines/mod.rs index c9e2aab2d0b1a..f6f4e94d04750 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/logical_lines/mod.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/logical_lines/mod.rs @@ -500,11 +500,16 @@ impl LogicalLinesBuilder { fn finish_line(&mut self) { let end = self.tokens.len() as u32; if self.current_line.tokens_start < end { - self.lines.push(Line { - flags: self.current_line.flags, - tokens_start: self.current_line.tokens_start, - tokens_end: end, - }); + let is_empty = self.tokens[self.current_line.tokens_start as usize..end as usize] + .iter() + .all(|token| token.kind.is_newline()); + if !is_empty { + self.lines.push(Line { + flags: self.current_line.flags, + tokens_start: self.current_line.tokens_start, + tokens_end: end, + }); + } self.current_line = CurrentLine { flags: TokenFlags::default(), diff --git a/crates/ruff_python_ast/src/token_kind.rs b/crates/ruff_python_ast/src/token_kind.rs index b465e39860824..2bcf3aeaa352c 100644 --- a/crates/ruff_python_ast/src/token_kind.rs +++ b/crates/ruff_python_ast/src/token_kind.rs @@ -167,6 +167,11 @@ pub enum TokenKind { } impl TokenKind { + #[inline] + pub const fn is_newline(&self) -> bool { + matches!(self, TokenKind::Newline | TokenKind::NonLogicalNewline) + } + #[inline] pub const fn is_unary(&self) -> bool { matches!(self, TokenKind::Plus | TokenKind::Minus | TokenKind::Star)