diff --git a/crates/ruff_linter/resources/test/fixtures/eradicate/ERA001.py b/crates/ruff_linter/resources/test/fixtures/eradicate/ERA001.py index fa1680a728..e64ea4e409 100644 --- a/crates/ruff_linter/resources/test/fixtures/eradicate/ERA001.py +++ b/crates/ruff_linter/resources/test/fixtures/eradicate/ERA001.py @@ -36,3 +36,32 @@ dictionary = { # except: # except Foo: # except Exception as e: print(e) + + +# Script tag without an opening tag (Error) + +# requires-python = ">=3.11" +# dependencies = [ +# "requests<3", +# "rich", +# ] +# /// + +# Script tag (OK) + +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "requests<3", +# "rich", +# ] +# /// + +# Script tag without a closing tag (OK) + +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "requests<3", +# "rich", +# ] diff --git a/crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs b/crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs index 4cc38ff256..4c17871ae5 100644 --- a/crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs +++ b/crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs @@ -43,7 +43,49 @@ impl Violation for CommentedOutCode { } } -fn is_standalone_comment(line: &str) -> bool { +/// ERA001 +pub(crate) fn commented_out_code( + diagnostics: &mut Vec, + locator: &Locator, + indexer: &Indexer, + settings: &LinterSettings, +) { + // Skip comments within `/// script` tags. + let mut in_script_tag = false; + + // Iterate over all comments in the document. + for range in indexer.comment_ranges() { + let line = locator.lines(*range); + + // Detect `/// script` tags. + if in_script_tag { + if is_script_tag_end(line) { + in_script_tag = false; + } + } else { + if is_script_tag_start(line) { + in_script_tag = true; + } + } + + // Skip comments within `/// script` tags. + if in_script_tag { + continue; + } + + // Verify that the comment is on its own line, and that it contains code. + if is_own_line_comment(line) && comment_contains_code(line, &settings.task_tags[..]) { + let mut diagnostic = Diagnostic::new(CommentedOutCode, *range); + diagnostic.set_fix(Fix::display_only_edit(Edit::range_deletion( + locator.full_lines_range(*range), + ))); + diagnostics.push(diagnostic); + } + } +} + +/// Returns `true` if line contains an own-line comment. +fn is_own_line_comment(line: &str) -> bool { for char in line.chars() { if char == '#' { return true; @@ -55,23 +97,16 @@ fn is_standalone_comment(line: &str) -> bool { unreachable!("Comment should contain '#' character") } -/// ERA001 -pub(crate) fn commented_out_code( - diagnostics: &mut Vec, - locator: &Locator, - indexer: &Indexer, - settings: &LinterSettings, -) { - for range in indexer.comment_ranges() { - let line = locator.full_lines(*range); - - // Verify that the comment is on its own line, and that it contains code. - if is_standalone_comment(line) && comment_contains_code(line, &settings.task_tags[..]) { - let mut diagnostic = Diagnostic::new(CommentedOutCode, *range); - diagnostic.set_fix(Fix::display_only_edit(Edit::range_deletion( - locator.full_lines_range(*range), - ))); - diagnostics.push(diagnostic); - } - } +/// Returns `true` if the line appears to start a script tag. +/// +/// See: +fn is_script_tag_start(line: &str) -> bool { + line == "# /// script" +} + +/// Returns `true` if the line appears to start a script tag. +/// +/// See: +fn is_script_tag_end(line: &str) -> bool { + line == "# ///" } diff --git a/crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests__ERA001_ERA001.py.snap b/crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests__ERA001_ERA001.py.snap index 04bf4cf902..7dc46d961f 100644 --- a/crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests__ERA001_ERA001.py.snap +++ b/crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests__ERA001_ERA001.py.snap @@ -245,6 +245,7 @@ ERA001.py:36:1: ERA001 Found commented-out code 36 |-# except: 37 36 | # except Foo: 38 37 | # except Exception as e: print(e) +39 38 | ERA001.py:37:1: ERA001 Found commented-out code | @@ -262,6 +263,8 @@ ERA001.py:37:1: ERA001 Found commented-out code 36 36 | # except: 37 |-# except Foo: 38 37 | # except Exception as e: print(e) +39 38 | +40 39 | ERA001.py:38:1: ERA001 Found commented-out code | @@ -277,3 +280,44 @@ ERA001.py:38:1: ERA001 Found commented-out code 36 36 | # except: 37 37 | # except Foo: 38 |-# except Exception as e: print(e) +39 38 | +40 39 | +41 40 | # Script tag without an opening tag (Error) + +ERA001.py:44:1: ERA001 Found commented-out code + | +43 | # requires-python = ">=3.11" +44 | # dependencies = [ + | ^^^^^^^^^^^^^^^^^^ ERA001 +45 | # "requests<3", +46 | # "rich", + | + = help: Remove commented-out code + +ℹ Display-only fix +41 41 | # Script tag without an opening tag (Error) +42 42 | +43 43 | # requires-python = ">=3.11" +44 |-# dependencies = [ +45 44 | # "requests<3", +46 45 | # "rich", +47 46 | # ] + +ERA001.py:47:1: ERA001 Found commented-out code + | +45 | # "requests<3", +46 | # "rich", +47 | # ] + | ^^^ ERA001 +48 | # /// + | + = help: Remove commented-out code + +ℹ Display-only fix +44 44 | # dependencies = [ +45 45 | # "requests<3", +46 46 | # "rich", +47 |-# ] +48 47 | # /// +49 48 | +50 49 | # Script tag (OK)