mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:12:22 +00:00
Rename end_of_statement
to end_of_last_statement
(#3775)
This commit is contained in:
parent
990b378c4d
commit
22d5b0071d
3 changed files with 39 additions and 32 deletions
|
@ -1,4 +1,8 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt};
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Location, Stmt};
|
||||
|
||||
use ruff_python_ast::helpers::to_absolute;
|
||||
use ruff_python_ast::newlines::StrExt;
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
|
||||
/// Return `true` if a function's return statement include at least one
|
||||
/// non-`None` value.
|
||||
|
@ -16,3 +20,32 @@ pub fn result_exists(returns: &[(&Stmt, Option<&Expr>)]) -> bool {
|
|||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
/// Given a statement, find its "logical end".
|
||||
///
|
||||
/// For example: the statement could be following by a trailing semicolon, by an end-of-line
|
||||
/// comment, or by any number of continuation lines (and then by a comment, and so on).
|
||||
///
|
||||
/// This method assumes that the statement is the last statement in its body; specifically, that
|
||||
/// the statement isn't followed by a semicolon, followed by a multi-line statement.
|
||||
pub fn end_of_last_statement(stmt: &Stmt, locator: &Locator) -> Location {
|
||||
let contents = locator.skip(stmt.end_location.unwrap());
|
||||
|
||||
// End-of-file, so just return the end of the statement.
|
||||
if contents.is_empty() {
|
||||
return stmt.end_location.unwrap();
|
||||
}
|
||||
|
||||
// Otherwise, find the end of the last line that's "part of" the statement.
|
||||
for (lineno, line) in contents.universal_newlines().enumerate() {
|
||||
if line.ends_with('\\') {
|
||||
continue;
|
||||
}
|
||||
return to_absolute(
|
||||
Location::new(lineno + 1, line.chars().count()),
|
||||
stmt.end_location.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
unreachable!("Expected to find end-of-statement")
|
||||
}
|
||||
|
|
|
@ -4,14 +4,15 @@ use rustpython_parser::ast::{Constant, Expr, ExprKind, Location, Stmt, StmtKind}
|
|||
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
||||
use ruff_diagnostics::{Diagnostic, Edit};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::helpers::elif_else_range;
|
||||
use ruff_python_ast::helpers::is_const_none;
|
||||
use ruff_python_ast::helpers::{elif_else_range, end_of_statement};
|
||||
use ruff_python_ast::types::Range;
|
||||
use ruff_python_ast::visitor::Visitor;
|
||||
use ruff_python_ast::whitespace::indentation;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::{AsRule, Rule};
|
||||
use crate::rules::flake8_return::helpers::end_of_last_statement;
|
||||
|
||||
use super::branch::Branch;
|
||||
use super::helpers::result_exists;
|
||||
|
@ -222,7 +223,7 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) {
|
|||
content.push_str("return None");
|
||||
diagnostic.set_fix(Edit::insertion(
|
||||
content,
|
||||
end_of_statement(stmt, checker.locator),
|
||||
end_of_last_statement(stmt, checker.locator),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -260,7 +261,7 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) {
|
|||
content.push_str("return None");
|
||||
diagnostic.set_fix(Edit::insertion(
|
||||
content,
|
||||
end_of_statement(stmt, checker.locator),
|
||||
end_of_last_statement(stmt, checker.locator),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +300,7 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) {
|
|||
content.push_str("return None");
|
||||
diagnostic.set_fix(Edit::insertion(
|
||||
content,
|
||||
end_of_statement(stmt, checker.locator),
|
||||
end_of_last_statement(stmt, checker.locator),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use rustpython_parser::{lexer, Mode, StringKind, Tok};
|
|||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::newlines::StrExt;
|
||||
use crate::scope::{Binding, BindingKind};
|
||||
use crate::source_code::{Generator, Indexer, Locator, Stylist};
|
||||
use crate::types::{CallPath, Range};
|
||||
|
@ -1139,32 +1138,6 @@ pub fn first_colon_range(range: Range, locator: &Locator) -> Option<Range> {
|
|||
range
|
||||
}
|
||||
|
||||
/// Given a statement, find its "logical end".
|
||||
///
|
||||
/// For example: the statement could be following by a trailing semicolon, by an end-of-line
|
||||
/// comment, or by any number of continuation lines (and then by a comment, and so on).
|
||||
pub fn end_of_statement(stmt: &Stmt, locator: &Locator) -> Location {
|
||||
let contents = locator.skip(stmt.end_location.unwrap());
|
||||
|
||||
// End-of-file, so just return the end of the statement.
|
||||
if contents.is_empty() {
|
||||
return stmt.end_location.unwrap();
|
||||
}
|
||||
|
||||
// Otherwise, find the end of the last line that's "part of" the statement.
|
||||
for (lineno, line) in contents.universal_newlines().enumerate() {
|
||||
if line.ends_with('\\') {
|
||||
continue;
|
||||
}
|
||||
return to_absolute(
|
||||
Location::new(lineno + 1, line.chars().count()),
|
||||
stmt.end_location.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
unreachable!("Expected to find end-of-statement")
|
||||
}
|
||||
|
||||
/// Return the `Range` of the first `Elif` or `Else` token in an `If` statement.
|
||||
pub fn elif_else_range(stmt: &Stmt, locator: &Locator) -> Option<Range> {
|
||||
let StmtKind::If { body, orelse, .. } = &stmt.node else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue