Skip to content

Commit

Permalink
Fix (doc-)line-too-long start location (#4006)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Apr 19, 2023
1 parent c0cf873 commit a3146ab
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 50 deletions.
60 changes: 48 additions & 12 deletions crates/ruff/src/rules/pycodestyle/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use ruff_python_ast::helpers::{create_expr, unparse_expr};
use ruff_python_ast::source_code::Stylist;
use rustpython_parser::ast::{Cmpop, Expr, ExprKind};
use unicode_width::UnicodeWidthStr;
use ruff_python_ast::types::Range;
use rustpython_parser::ast::{Cmpop, Expr, ExprKind, Location};
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};

pub fn is_ambiguous_name(name: &str) -> bool {
name == "l" || name == "I" || name == "O"
Expand All @@ -18,28 +19,40 @@ pub fn compare(left: &Expr, ops: &[Cmpop], comparators: &[Expr], stylist: &Styli
)
}

pub fn is_overlong(
pub(super) fn is_overlong(
line: &str,
line_width: usize,
limit: usize,
ignore_overlong_task_comments: bool,
task_tags: &[String],
) -> bool {
if line_width <= limit {
return false;
) -> Option<Overlong> {
let mut start_column = 0;
let mut width = 0;
let mut end = 0;

for c in line.chars() {
if width < limit {
start_column += 1;
}

width += c.width().unwrap_or(0);
end += 1;
}

if width <= limit {
return None;
}

let mut chunks = line.split_whitespace();
let (Some(first_chunk), Some(second_chunk)) = (chunks.next(), chunks.next()) else {
// Single word / no printable chars - no way to make the line shorter
return false;
return None;
};

if first_chunk == "#" {
if ignore_overlong_task_comments {
let second = second_chunk.trim_end_matches(':');
if task_tags.iter().any(|task_tag| task_tag == second) {
return false;
return None;
}
}
}
Expand All @@ -48,10 +61,33 @@ pub fn is_overlong(
// begins before the limit.
let last_chunk = chunks.last().unwrap_or(second_chunk);
if last_chunk.contains("://") {
if line_width - last_chunk.width() <= limit {
return false;
if width - last_chunk.width() <= limit {
return None;
}
}

true
Some(Overlong {
column: start_column,
end_column: end,
width,
})
}

pub(super) struct Overlong {
column: usize,
end_column: usize,
width: usize,
}

impl Overlong {
pub(super) fn range(&self, line_no: usize) -> Range {
Range::new(
Location::new(line_no + 1, self.column),
Location::new(line_no + 1, self.end_column),
)
}

pub(super) const fn width(&self) -> usize {
self.width
}
}
26 changes: 8 additions & 18 deletions crates/ruff/src/rules/pycodestyle/rules/doc_line_too_long.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
use rustpython_parser::ast::Location;
use unicode_width::UnicodeWidthStr;

use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::types::Range;

use crate::rules::pycodestyle::helpers::is_overlong;
use crate::settings::Settings;
Expand Down Expand Up @@ -46,22 +42,16 @@ pub fn doc_line_too_long(lineno: usize, line: &str, settings: &Settings) -> Opti
return None;
};

let line_width = line.width();
if is_overlong(
is_overlong(
line,
line_width,
limit,
settings.pycodestyle.ignore_overlong_task_comments,
&settings.task_tags,
) {
Some(Diagnostic::new(
DocLineTooLong(line_width, limit),
Range::new(
Location::new(lineno + 1, limit),
Location::new(lineno + 1, line.chars().count()),
),
))
} else {
None
}
)
.map(|overlong| {
Diagnostic::new(
DocLineTooLong(overlong.width(), limit),
overlong.range(lineno),
)
})
}
22 changes: 4 additions & 18 deletions crates/ruff/src/rules/pycodestyle/rules/line_too_long.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
use rustpython_parser::ast::Location;
use unicode_width::UnicodeWidthStr;

use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::types::Range;

use crate::rules::pycodestyle::helpers::is_overlong;
use crate::settings::Settings;
Expand Down Expand Up @@ -39,23 +35,13 @@ impl Violation for LineTooLong {

/// E501
pub fn line_too_long(lineno: usize, line: &str, settings: &Settings) -> Option<Diagnostic> {
let line_width = line.width();
let limit = settings.line_length;
if is_overlong(

is_overlong(
line,
line_width,
limit,
settings.pycodestyle.ignore_overlong_task_comments,
&settings.task_tags,
) {
Some(Diagnostic::new(
LineTooLong(line_width, limit),
Range::new(
Location::new(lineno + 1, limit),
Location::new(lineno + 1, line.chars().count()),
),
))
} else {
None
}
)
.map(|overlong| Diagnostic::new(LineTooLong(overlong.width(), limit), overlong.range(lineno)))
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ E501.py:5:89: E501 Line too long (123 > 88 characters)
8 | """
|

E501.py:16:89: E501 Line too long (95 > 88 characters)
E501.py:16:85: E501 Line too long (95 > 88 characters)
|
16 | _ = "---------------------------------------------------------------------------AAAAAAA"
17 | _ = "---------------------------------------------------------------------------亜亜亜亜亜亜亜"
| E501
| ^^^^^^^ E501
|

E501.py:25:89: E501 Line too long (127 > 88 characters)
Expand Down

0 comments on commit a3146ab

Please sign in to comment.