mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 18:28:24 +00:00
Reduce explcit clones (#3793)
This commit is contained in:
parent
b6f1fed424
commit
595cd065f3
73 changed files with 557 additions and 484 deletions
|
@ -8,40 +8,39 @@ use crate::types::RefEquality;
|
|||
|
||||
/// Return the common ancestor of `left` and `right` below `stop`, or `None`.
|
||||
fn common_ancestor<'a>(
|
||||
left: &'a RefEquality<'a, Stmt>,
|
||||
right: &'a RefEquality<'a, Stmt>,
|
||||
stop: Option<&'a RefEquality<'a, Stmt>>,
|
||||
left: RefEquality<'a, Stmt>,
|
||||
right: RefEquality<'a, Stmt>,
|
||||
stop: Option<RefEquality<'a, Stmt>>,
|
||||
depths: &'a FxHashMap<RefEquality<'a, Stmt>, usize>,
|
||||
child_to_parent: &'a FxHashMap<RefEquality<'a, Stmt>, RefEquality<'a, Stmt>>,
|
||||
) -> Option<&'a RefEquality<'a, Stmt>> {
|
||||
if let Some(stop) = stop {
|
||||
if left == stop || right == stop {
|
||||
return None;
|
||||
}
|
||||
) -> Option<RefEquality<'a, Stmt>> {
|
||||
if Some(left) == stop || Some(right) == stop {
|
||||
return None;
|
||||
}
|
||||
|
||||
if left == right {
|
||||
return Some(left);
|
||||
}
|
||||
|
||||
let left_depth = depths.get(left)?;
|
||||
let right_depth = depths.get(right)?;
|
||||
let left_depth = depths.get(&left)?;
|
||||
let right_depth = depths.get(&right)?;
|
||||
match left_depth.cmp(right_depth) {
|
||||
Ordering::Less => common_ancestor(
|
||||
left,
|
||||
child_to_parent.get(right)?,
|
||||
*child_to_parent.get(&right)?,
|
||||
stop,
|
||||
depths,
|
||||
child_to_parent,
|
||||
),
|
||||
Ordering::Equal => common_ancestor(
|
||||
child_to_parent.get(left)?,
|
||||
child_to_parent.get(right)?,
|
||||
*child_to_parent.get(&left)?,
|
||||
*child_to_parent.get(&right)?,
|
||||
stop,
|
||||
depths,
|
||||
child_to_parent,
|
||||
),
|
||||
Ordering::Greater => common_ancestor(
|
||||
child_to_parent.get(left)?,
|
||||
*child_to_parent.get(&left)?,
|
||||
right,
|
||||
stop,
|
||||
depths,
|
||||
|
@ -51,8 +50,8 @@ fn common_ancestor<'a>(
|
|||
}
|
||||
|
||||
/// Return the alternative branches for a given node.
|
||||
fn alternatives<'a>(stmt: &'a RefEquality<'a, Stmt>) -> Vec<Vec<RefEquality<'a, Stmt>>> {
|
||||
match &stmt.node {
|
||||
fn alternatives(stmt: RefEquality<Stmt>) -> Vec<Vec<RefEquality<Stmt>>> {
|
||||
match &stmt.as_ref().node {
|
||||
StmtKind::If { body, .. } => vec![body.iter().map(RefEquality).collect()],
|
||||
StmtKind::Try {
|
||||
body,
|
||||
|
@ -78,22 +77,22 @@ fn alternatives<'a>(stmt: &'a RefEquality<'a, Stmt>) -> Vec<Vec<RefEquality<'a,
|
|||
|
||||
/// Return `true` if `stmt` is a descendent of any of the nodes in `ancestors`.
|
||||
fn descendant_of<'a>(
|
||||
stmt: &RefEquality<'a, Stmt>,
|
||||
stmt: RefEquality<'a, Stmt>,
|
||||
ancestors: &[RefEquality<'a, Stmt>],
|
||||
stop: &RefEquality<'a, Stmt>,
|
||||
stop: RefEquality<'a, Stmt>,
|
||||
depths: &FxHashMap<RefEquality<'a, Stmt>, usize>,
|
||||
child_to_parent: &FxHashMap<RefEquality<'a, Stmt>, RefEquality<'a, Stmt>>,
|
||||
) -> bool {
|
||||
ancestors.iter().any(|ancestor| {
|
||||
common_ancestor(stmt, ancestor, Some(stop), depths, child_to_parent).is_some()
|
||||
common_ancestor(stmt, *ancestor, Some(stop), depths, child_to_parent).is_some()
|
||||
})
|
||||
}
|
||||
|
||||
/// Return `true` if `left` and `right` are on different branches of an `if` or
|
||||
/// `try` statement.
|
||||
pub fn different_forks<'a>(
|
||||
left: &RefEquality<'a, Stmt>,
|
||||
right: &RefEquality<'a, Stmt>,
|
||||
left: RefEquality<'a, Stmt>,
|
||||
right: RefEquality<'a, Stmt>,
|
||||
depths: &FxHashMap<RefEquality<'a, Stmt>, usize>,
|
||||
child_to_parent: &FxHashMap<RefEquality<'a, Stmt>, RefEquality<'a, Stmt>>,
|
||||
) -> bool {
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustpython_parser::ast::{
|
|||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableExprContext {
|
||||
Load,
|
||||
Store,
|
||||
|
@ -26,7 +26,7 @@ impl From<&ExprContext> for ComparableExprContext {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableBoolop {
|
||||
And,
|
||||
Or,
|
||||
|
@ -41,7 +41,7 @@ impl From<&Boolop> for ComparableBoolop {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableOperator {
|
||||
Add,
|
||||
Sub,
|
||||
|
@ -78,7 +78,7 @@ impl From<&Operator> for ComparableOperator {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableUnaryop {
|
||||
Invert,
|
||||
Not,
|
||||
|
@ -97,7 +97,7 @@ impl From<&Unaryop> for ComparableUnaryop {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableCmpop {
|
||||
Eq,
|
||||
NotEq,
|
||||
|
|
|
@ -206,13 +206,10 @@ impl<'a> Context<'a> {
|
|||
pub fn push_parent(&mut self, parent: &'a Stmt) {
|
||||
let num_existing = self.parents.len();
|
||||
self.parents.push(RefEquality(parent));
|
||||
self.depths
|
||||
.insert(self.parents[num_existing].clone(), num_existing);
|
||||
self.depths.insert(self.parents[num_existing], num_existing);
|
||||
if num_existing > 0 {
|
||||
self.child_to_parent.insert(
|
||||
self.parents[num_existing].clone(),
|
||||
self.parents[num_existing - 1].clone(),
|
||||
);
|
||||
self.child_to_parent
|
||||
.insert(self.parents[num_existing], self.parents[num_existing - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::scope::{Scope, ScopeKind};
|
|||
const CLASS_METHODS: [&str; 3] = ["__new__", "__init_subclass__", "__class_getitem__"];
|
||||
const METACLASS_BASES: [(&str, &str); 2] = [("", "type"), ("abc", "ABCMeta")];
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum FunctionType {
|
||||
Function,
|
||||
Method,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#[derive(Copy, Clone)]
|
||||
pub enum LoggingLevel {
|
||||
Debug,
|
||||
Critical,
|
||||
|
|
|
@ -215,8 +215,19 @@ impl ScopeStack {
|
|||
pub fn iter(&self) -> std::iter::Rev<std::slice::Iter<ScopeId>> {
|
||||
self.0.iter().rev()
|
||||
}
|
||||
|
||||
pub fn snapshot(&self) -> ScopeStackSnapshot {
|
||||
ScopeStackSnapshot(self.0.len())
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub fn restore(&mut self, snapshot: ScopeStackSnapshot) {
|
||||
self.0.truncate(snapshot.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScopeStackSnapshot(usize);
|
||||
|
||||
impl Default for ScopeStack {
|
||||
fn default() -> Self {
|
||||
Self(vec![ScopeId::global()])
|
||||
|
|
|
@ -65,7 +65,7 @@ pub struct Generator<'a> {
|
|||
/// The quote style to use for string literals.
|
||||
quote: Quote,
|
||||
/// The line ending to use.
|
||||
line_ending: &'a LineEnding,
|
||||
line_ending: LineEnding,
|
||||
buffer: String,
|
||||
indent_depth: usize,
|
||||
num_newlines: usize,
|
||||
|
@ -87,7 +87,7 @@ impl<'a> From<&'a Stylist<'a>> for Generator<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Generator<'a> {
|
||||
pub const fn new(indent: &'a Indentation, quote: Quote, line_ending: &'a LineEnding) -> Self {
|
||||
pub const fn new(indent: &'a Indentation, quote: Quote, line_ending: LineEnding) -> Self {
|
||||
Self {
|
||||
// Style preferences.
|
||||
indent,
|
||||
|
@ -128,7 +128,7 @@ impl<'a> Generator<'a> {
|
|||
fn p(&mut self, s: &str) {
|
||||
if self.num_newlines > 0 {
|
||||
for _ in 0..self.num_newlines {
|
||||
self.buffer += self.line_ending;
|
||||
self.buffer += &self.line_ending;
|
||||
}
|
||||
self.num_newlines = 0;
|
||||
}
|
||||
|
@ -1266,7 +1266,7 @@ mod tests {
|
|||
let line_ending = LineEnding::default();
|
||||
let program = parser::parse_program(contents, "<filename>").unwrap();
|
||||
let stmt = program.first().unwrap();
|
||||
let mut generator = Generator::new(&indentation, quote, &line_ending);
|
||||
let mut generator = Generator::new(&indentation, quote, line_ending);
|
||||
generator.unparse_stmt(stmt);
|
||||
generator.generate()
|
||||
}
|
||||
|
@ -1274,7 +1274,7 @@ mod tests {
|
|||
fn round_trip_with(
|
||||
indentation: &Indentation,
|
||||
quote: Quote,
|
||||
line_ending: &LineEnding,
|
||||
line_ending: LineEnding,
|
||||
contents: &str,
|
||||
) -> String {
|
||||
let program = parser::parse_program(contents, "<filename>").unwrap();
|
||||
|
@ -1449,7 +1449,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::default(),
|
||||
Quote::Double,
|
||||
&LineEnding::default(),
|
||||
LineEnding::default(),
|
||||
r#""hello""#
|
||||
),
|
||||
r#""hello""#
|
||||
|
@ -1458,7 +1458,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::default(),
|
||||
Quote::Single,
|
||||
&LineEnding::default(),
|
||||
LineEnding::default(),
|
||||
r#""hello""#
|
||||
),
|
||||
r#"'hello'"#
|
||||
|
@ -1467,7 +1467,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::default(),
|
||||
Quote::Double,
|
||||
&LineEnding::default(),
|
||||
LineEnding::default(),
|
||||
r#"'hello'"#
|
||||
),
|
||||
r#""hello""#
|
||||
|
@ -1476,7 +1476,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::default(),
|
||||
Quote::Single,
|
||||
&LineEnding::default(),
|
||||
LineEnding::default(),
|
||||
r#"'hello'"#
|
||||
),
|
||||
r#"'hello'"#
|
||||
|
@ -1489,7 +1489,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::new(" ".to_string()),
|
||||
Quote::default(),
|
||||
&LineEnding::default(),
|
||||
LineEnding::default(),
|
||||
r#"
|
||||
if True:
|
||||
pass
|
||||
|
@ -1507,7 +1507,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::new(" ".to_string()),
|
||||
Quote::default(),
|
||||
&LineEnding::default(),
|
||||
LineEnding::default(),
|
||||
r#"
|
||||
if True:
|
||||
pass
|
||||
|
@ -1525,7 +1525,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::new("\t".to_string()),
|
||||
Quote::default(),
|
||||
&LineEnding::default(),
|
||||
LineEnding::default(),
|
||||
r#"
|
||||
if True:
|
||||
pass
|
||||
|
@ -1547,7 +1547,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::default(),
|
||||
Quote::default(),
|
||||
&LineEnding::Lf,
|
||||
LineEnding::Lf,
|
||||
"if True:\n print(42)",
|
||||
),
|
||||
"if True:\n print(42)",
|
||||
|
@ -1557,7 +1557,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::default(),
|
||||
Quote::default(),
|
||||
&LineEnding::CrLf,
|
||||
LineEnding::CrLf,
|
||||
"if True:\n print(42)",
|
||||
),
|
||||
"if True:\r\n print(42)",
|
||||
|
@ -1567,7 +1567,7 @@ if True:
|
|||
round_trip_with(
|
||||
&Indentation::default(),
|
||||
Quote::default(),
|
||||
&LineEnding::Cr,
|
||||
LineEnding::Cr,
|
||||
"if True:\n print(42)",
|
||||
),
|
||||
"if True:\r print(42)",
|
||||
|
|
|
@ -56,8 +56,9 @@ impl<'a> Stylist<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn line_ending(&'a self) -> &'a LineEnding {
|
||||
self.line_ending
|
||||
pub fn line_ending(&'a self) -> LineEnding {
|
||||
*self
|
||||
.line_ending
|
||||
.get_or_init(|| detect_line_ending(self.locator.contents()).unwrap_or_default())
|
||||
}
|
||||
|
||||
|
@ -160,7 +161,7 @@ impl Deref for Indentation {
|
|||
|
||||
/// The line ending style used in Python source code.
|
||||
/// See <https://docs.python.org/3/reference/lexical_analysis.html#physical-lines>
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum LineEnding {
|
||||
Lf,
|
||||
Cr,
|
||||
|
|
|
@ -35,9 +35,32 @@ impl<T> From<&Box<Located<T>>> for Range {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct RefEquality<'a, T>(pub &'a T);
|
||||
|
||||
impl<'a, T> RefEquality<'a, T> {
|
||||
// More specific implementation that keeps the `'a` lifetime.
|
||||
// It's otherwise the same as [`AsRef::as_ref`]
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn as_ref(&self) -> &'a T {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> AsRef<T> for RefEquality<'a, T> {
|
||||
fn as_ref(&self) -> &T {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Clone for RefEquality<'a, T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Copy for RefEquality<'a, T> {}
|
||||
|
||||
impl<'a, T> std::hash::Hash for RefEquality<'a, T> {
|
||||
fn hash<H>(&self, state: &mut H)
|
||||
where
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::source_code::Locator;
|
|||
use crate::str;
|
||||
use crate::types::Range;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Callable {
|
||||
Cast,
|
||||
NewType,
|
||||
|
@ -19,6 +20,7 @@ pub enum Callable {
|
|||
MypyExtension,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum SubscriptKind {
|
||||
AnnotatedSubscript,
|
||||
PEP593AnnotatedSubscript,
|
||||
|
@ -72,7 +74,7 @@ pub fn is_pep585_builtin(expr: &Expr, context: &Context) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(is_macro::Is)]
|
||||
#[derive(is_macro::Is, Copy, Clone)]
|
||||
pub enum AnnotationKind {
|
||||
/// The annotation is defined as part a simple string literal,
|
||||
/// e.g. `x: "List[int]" = []`. Annotations within simple literals
|
||||
|
|
|
@ -6,20 +6,20 @@ use crate::context::Context;
|
|||
use crate::helpers::{collect_call_path, map_callable};
|
||||
use crate::types::CallPath;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Modifier {
|
||||
Module,
|
||||
Class,
|
||||
Function,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Visibility {
|
||||
Public,
|
||||
Private,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct VisibleScope {
|
||||
pub modifier: Modifier,
|
||||
pub visibility: Visibility,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue