Skip to content

Commit

Permalink
consolidate expand_indent
Browse files Browse the repository at this point in the history
  • Loading branch information
augustelalande committed May 19, 2024
1 parent 6e645e9 commit ab87a33
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 57 deletions.
21 changes: 2 additions & 19 deletions crates/ruff_linter/src/checkers/logical_lines.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::line_width::IndentWidth;
use crate::registry::Rule;
use ruff_diagnostics::Diagnostic;
use ruff_python_codegen::Stylist;
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -124,7 +107,7 @@ pub(crate) fn check_logical_lines(
continuation_lines(
&line,
indent_char,
indent_size,
settings.tab_size,
locator,
indexer,
&mut context,
Expand Down
17 changes: 17 additions & 0 deletions crates/ruff_linter/src/rules/pycodestyle/helpers.rs
Original file line number Diff line number Diff line change
@@ -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'\t' => indent = (indent / tab_size) * tab_size + tab_size,
b' ' => indent += 1,
_ => break,
}
}

indent
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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."),
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -211,32 +195,33 @@ 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).
let mut row = 0;
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<i64> = vec![0; nb_physical_lines];
let mut rel_indent: Vec<i16> = vec![0; nb_physical_lines];
// For each depth, collect a list of opening rows.
let mut open_rows: Vec<Vec<usize>> = Vec::with_capacity(max_depth + 1);
open_rows.push(vec![0]);
// For each depth, record the hanging indentation.
let mut hangs: Vec<Option<i64>> = Vec::with_capacity(max_depth + 1);
let mut hangs: Vec<Option<i16>> = 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;
Expand Down Expand Up @@ -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() {
Expand Down

0 comments on commit ab87a33

Please sign in to comment.