From 0db7670d2a5776b24ca2b811551815b7cabc622a Mon Sep 17 00:00:00 2001 From: augustelalande Date: Sun, 19 May 2024 00:50:16 -0400 Subject: [PATCH] consolidate expand_indent --- .../ruff_linter/src/checkers/logical_lines.rs | 21 +------ .../src/rules/pycodestyle/helpers.rs | 17 ++++++ .../rules/pycodestyle/rules/blank_lines.rs | 2 +- .../rules/logical_lines/continuation_lines.rs | 60 +++++++------------ 4 files changed, 43 insertions(+), 57 deletions(-) diff --git a/crates/ruff_linter/src/checkers/logical_lines.rs b/crates/ruff_linter/src/checkers/logical_lines.rs index dced500faf0974..0325498a98905a 100644 --- a/crates/ruff_linter/src/checkers/logical_lines.rs +++ b/crates/ruff_linter/src/checkers/logical_lines.rs @@ -1,4 +1,3 @@ -use crate::line_width::IndentWidth; use crate::registry::Rule; use ruff_diagnostics::Diagnostic; use ruff_python_codegen::Stylist; @@ -9,6 +8,7 @@ use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; use crate::registry::AsRule; +use crate::rules::pycodestyle::helpers::expand_indent; use crate::rules::pycodestyle::rules::logical_lines::{ continuation_lines, extraneous_whitespace, indentation, missing_whitespace, missing_whitespace_after_keyword, missing_whitespace_around_operator, redundant_backslash, @@ -18,23 +18,6 @@ use crate::rules::pycodestyle::rules::logical_lines::{ }; use crate::settings::LinterSettings; -/// Return the amount of indentation, expanding tabs to the next multiple of the settings' tab size. -pub(crate) fn expand_indent(line: &str, indent_width: IndentWidth) -> usize { - let line = line.trim_end_matches(['\n', '\r']); - - let mut indent = 0; - let tab_size = indent_width.as_usize(); - for c in line.bytes() { - match c { - b'\t' => indent = (indent / tab_size) * tab_size + tab_size, - b' ' => indent += 1, - _ => break, - } - } - - indent -} - pub(crate) fn check_logical_lines( tokens: &[LexResult], locator: &Locator, @@ -124,7 +107,7 @@ pub(crate) fn check_logical_lines( continuation_lines( &line, indent_char, - indent_size, + settings.tab_size, locator, indexer, &mut context, diff --git a/crates/ruff_linter/src/rules/pycodestyle/helpers.rs b/crates/ruff_linter/src/rules/pycodestyle/helpers.rs index 2b39a6dad110b0..7c0cd07ed62707 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/helpers.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/helpers.rs @@ -1,4 +1,21 @@ +use crate::line_width::IndentWidth; + /// Returns `true` if the name should be considered "ambiguous". pub(super) fn is_ambiguous_name(name: &str) -> bool { name == "l" || name == "I" || name == "O" } + +/// Return the amount of indentation, expanding tabs to the next multiple of the settings' tab size. +pub(crate) fn expand_indent(line: &str, indent_width: IndentWidth) -> usize { + let mut indent = 0; + let tab_size = indent_width.as_usize(); + for c in line.bytes() { + match c { + b' ' => indent += 1, + b'\t' => indent = (indent / tab_size) * tab_size + tab_size, + _ => break, + } + } + + indent +} diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/blank_lines.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/blank_lines.rs index 9aa19c5afddf7d..19c07fd6f7ebb8 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/blank_lines.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/blank_lines.rs @@ -20,8 +20,8 @@ use ruff_source_file::{Locator, UniversalNewlines}; use ruff_text_size::TextRange; use ruff_text_size::TextSize; -use crate::checkers::logical_lines::expand_indent; use crate::line_width::IndentWidth; +use crate::rules::pycodestyle::helpers::expand_indent; use ruff_python_trivia::PythonWhitespace; /// Number of blank lines around top level classes and functions. diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs index c20e03753cfe9e..704ddbfa6ebb31 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs @@ -3,6 +3,8 @@ use std::iter::zip; use super::{LogicalLine, LogicalLineToken}; use crate::checkers::logical_lines::LogicalLinesContext; +use crate::line_width::IndentWidth; +use crate::rules::pycodestyle::helpers::expand_indent; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_index::Indexer; @@ -43,8 +45,8 @@ impl Violation for MissingOrOutdentedIndentation { struct TokenInfo { start_physical_line_idx: usize, end_physical_line_idx: usize, - token_start_within_physical_line: i64, - token_end_within_physical_line: i64, + token_start_within_physical_line: i16, + token_end_within_physical_line: i16, } /// Compute the `TokenInfo` of each token. @@ -105,11 +107,11 @@ fn get_token_infos<'a>( token_infos.push(TokenInfo { start_physical_line_idx, end_physical_line_idx: current_line_idx, - token_start_within_physical_line: i64::try_from( + token_start_within_physical_line: i16::try_from( usize::from(token.range.start()) - first_physical_line_start, ) .expect("Lines are expected to be relatively short."), - token_end_within_physical_line: i64::try_from( + token_end_within_physical_line: i16::try_from( usize::from(token.range.end()) - current_physical_line_start, ) .expect("Lines are expected to be relatively short."), @@ -144,29 +146,6 @@ fn continuation_line_end( Some(locator.full_line_end(*continuation_line_start)) } -/// Return the amount of indentation of the given line. -/// Tabs are expanded to the next multiple of 8. -fn expand_indent(line: &str) -> i64 { - if !line.contains('\t') { - // If there are no tabs in the line, return the leading space count - return i64::try_from(line.len() - line.trim_start().len()) - .expect("Line length to be relatively small."); - } - let mut indent = 0; - - for ch in line.chars() { - if ch == '\t' { - indent = indent / 8 * 8 + 8; - } else if ch == ' ' { - indent += 1; - } else { - break; - } - } - - indent -} - fn calculate_max_depth(logical_line: &LogicalLine) -> usize { let mut depth = 0; let mut max_depth = 0; @@ -183,22 +162,27 @@ fn calculate_max_depth(logical_line: &LogicalLine) -> usize { max_depth } -fn valid_hang(hang: i64, indent_size: i64, indent_char: char) -> bool { +fn valid_hang(hang: i16, indent_size: i16, indent_char: char) -> bool { hang == indent_size || (indent_char == '\t' && hang == 2 * indent_size) } +fn expand_indent_i16(line: &str, indent_width: IndentWidth) -> i16 { + i16::try_from(expand_indent(line, indent_width)).expect("Indent to be relatively small.") +} + /// E122 pub(crate) fn continuation_lines( logical_line: &LogicalLine, indent_char: char, - indent_size: usize, + indent_width: IndentWidth, locator: &Locator, indexer: &Indexer, context: &mut LogicalLinesContext, ) { // The pycodestyle implementation makes use of negative values, // converting the indent_size type at the start avoids converting it multiple times later. - let indent_size = i64::try_from(indent_size).expect("Indent size to be relatively small."); + let indent_size = + i16::try_from(indent_width.as_usize()).expect("Indent size to be relatively small."); let token_infos = get_token_infos(logical_line, locator, indexer); let nb_physical_lines = if let Some(last_token_info) = token_infos.last() { 1 + last_token_info.start_physical_line_idx @@ -211,13 +195,14 @@ pub(crate) fn continuation_lines( } // Indent of the first physical line. - let start_indent_level = expand_indent( + let start_indent_level = expand_indent_i16( locator.line( logical_line .first_token() .expect("Would have returned earlier if the logical line was empty") .start(), ), + indent_width, ); // Here "row" is the physical line index (within the logical line). @@ -225,18 +210,18 @@ pub(crate) fn continuation_lines( let mut depth = 0; let max_depth = calculate_max_depth(logical_line); // Brackets opened on a line. - let mut brackets_opened = 0u32; + let mut brackets_opened = 0u8; // In fstring - let mut fstrings_opened = 0u32; + let mut fstrings_opened = 0u8; // Relative indents of physical lines. - let mut rel_indent: Vec = vec![0; nb_physical_lines]; + let mut rel_indent: Vec = vec![0; nb_physical_lines]; // For each depth, collect a list of opening rows. let mut open_rows: Vec> = Vec::with_capacity(max_depth + 1); open_rows.push(vec![0]); // For each depth, record the hanging indentation. - let mut hangs: Vec> = Vec::with_capacity(max_depth + 1); + let mut hangs: Vec> = Vec::with_capacity(max_depth + 1); hangs.push(None); - let mut hang: i64 = 0; + let mut hang = 0i16; // Visual indents let mut last_indent = start_indent_level; let mut last_token_multiline = false; @@ -267,7 +252,8 @@ pub(crate) fn continuation_lines( // Record the initial indent. let indent_range = TextRange::new(locator.line_start(token.start()), token.start()); - rel_indent[row] = expand_indent(locator.slice(indent_range)) - start_indent_level; + rel_indent[row] = + expand_indent_i16(locator.slice(indent_range), indent_width) - start_indent_level; // Is the indent relative to an opening bracket line ? for open_row in open_rows[depth].iter().rev() {