diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index 54948a23cd..33e59c3841 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -366,9 +366,7 @@ where } if self.enabled(Rule::AmbiguousFunctionName) { if let Some(diagnostic) = - pycodestyle::rules::ambiguous_function_name(name, || { - stmt.identifier(self.locator) - }) + pycodestyle::rules::ambiguous_function_name(name, || stmt.identifier()) { self.diagnostics.push(diagnostic); } @@ -383,7 +381,6 @@ where decorator_list, &self.settings.pep8_naming.ignore_names, &self.semantic, - self.locator, ) { self.diagnostics.push(diagnostic); } @@ -452,7 +449,6 @@ where stmt, name, &self.settings.pep8_naming.ignore_names, - self.locator, ) { self.diagnostics.push(diagnostic); } @@ -503,7 +499,6 @@ where name, body, self.settings.mccabe.max_complexity, - self.locator, ) { self.diagnostics.push(diagnostic); } @@ -523,7 +518,6 @@ where stmt, body, self.settings.pylint.max_returns, - self.locator, ) { self.diagnostics.push(diagnostic); } @@ -533,7 +527,6 @@ where stmt, body, self.settings.pylint.max_branches, - self.locator, ) { self.diagnostics.push(diagnostic); } @@ -543,7 +536,6 @@ where stmt, body, self.settings.pylint.max_statements, - self.locator, ) { self.diagnostics.push(diagnostic); } @@ -605,7 +597,6 @@ where name, decorator_list, args, - self.locator, ); } if self.enabled(Rule::FStringDocstring) { @@ -693,9 +684,9 @@ where pyupgrade::rules::unnecessary_class_parentheses(self, class_def, stmt); } if self.enabled(Rule::AmbiguousClassName) { - if let Some(diagnostic) = pycodestyle::rules::ambiguous_class_name(name, || { - stmt.identifier(self.locator) - }) { + if let Some(diagnostic) = + pycodestyle::rules::ambiguous_class_name(name, || stmt.identifier()) + { self.diagnostics.push(diagnostic); } } @@ -704,7 +695,6 @@ where stmt, name, &self.settings.pep8_naming.ignore_names, - self.locator, ) { self.diagnostics.push(diagnostic); } @@ -714,7 +704,6 @@ where stmt, bases, name, - self.locator, &self.settings.pep8_naming.ignore_names, ) { self.diagnostics.push(diagnostic); @@ -813,7 +802,7 @@ where let qualified_name = &alias.name; self.add_binding( name, - alias.identifier(self.locator), + alias.identifier(), BindingKind::SubmoduleImport(SubmoduleImport { qualified_name }), BindingFlags::EXTERNAL, ); @@ -834,7 +823,7 @@ where let qualified_name = &alias.name; self.add_binding( name, - alias.identifier(self.locator), + alias.identifier(), BindingKind::Import(Import { qualified_name }), flags, ); @@ -1052,7 +1041,7 @@ where self.add_binding( name, - alias.identifier(self.locator), + alias.identifier(), BindingKind::FutureImport, BindingFlags::empty(), ); @@ -1123,7 +1112,7 @@ where helpers::format_import_from_member(level, module, &alias.name); self.add_binding( name, - alias.identifier(self.locator), + alias.identifier(), BindingKind::FromImport(FromImport { qualified_name }), flags, ); @@ -1804,7 +1793,7 @@ where self.add_binding( name, - stmt.identifier(self.locator), + stmt.identifier(), BindingKind::FunctionDefinition, BindingFlags::empty(), ); @@ -2029,7 +2018,7 @@ where self.semantic.pop_definition(); self.add_binding( name, - stmt.identifier(self.locator), + stmt.identifier(), BindingKind::ClassDefinition, BindingFlags::empty(), ); @@ -3846,7 +3835,7 @@ where } match name { Some(name) => { - let range = except_handler.try_identifier(self.locator).unwrap(); + let range = except_handler.try_identifier().unwrap(); if self.enabled(Rule::AmbiguousVariableName) { if let Some(diagnostic) = @@ -3961,7 +3950,7 @@ where // upstream. self.add_binding( &arg.arg, - arg.identifier(self.locator), + arg.identifier(), BindingKind::Argument, BindingFlags::empty(), ); @@ -4001,7 +3990,7 @@ where { self.add_binding( name, - pattern.try_identifier(self.locator).unwrap(), + pattern.try_identifier().unwrap(), BindingKind::Assignment, BindingFlags::empty(), ); diff --git a/crates/ruff/src/rules/flake8_annotations/rules/definition.rs b/crates/ruff/src/rules/flake8_annotations/rules/definition.rs index b22555ce78..5fdb814dab 100644 --- a/crates/ruff/src/rules/flake8_annotations/rules/definition.rs +++ b/crates/ruff/src/rules/flake8_annotations/rules/definition.rs @@ -653,7 +653,7 @@ pub(crate) fn definition( MissingReturnTypeClassMethod { name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } else if is_method @@ -664,7 +664,7 @@ pub(crate) fn definition( MissingReturnTypeStaticMethod { name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } else if is_method && visibility::is_init(name) { @@ -676,7 +676,7 @@ pub(crate) fn definition( MissingReturnTypeSpecialMethod { name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), ); if checker.patch(diagnostic.kind.rule()) { diagnostic.try_set_fix(|| { @@ -693,7 +693,7 @@ pub(crate) fn definition( MissingReturnTypeSpecialMethod { name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), ); if checker.patch(diagnostic.kind.rule()) { if let Some(return_type) = simple_magic_return_type(name) { @@ -713,7 +713,7 @@ pub(crate) fn definition( MissingReturnTypeUndocumentedPublicFunction { name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } @@ -723,7 +723,7 @@ pub(crate) fn definition( MissingReturnTypePrivateFunction { name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs b/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs index 16606d08ff..679e68e782 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs @@ -134,7 +134,7 @@ pub(crate) fn abstract_base_class( AbstractBaseClassWithoutAbstractMethod { name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/f_string_docstring.rs b/crates/ruff/src/rules/flake8_bugbear/rules/f_string_docstring.rs index 8556160ba5..ad48483bda 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/f_string_docstring.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/f_string_docstring.rs @@ -29,8 +29,7 @@ pub(crate) fn f_string_docstring(checker: &mut Checker, body: &[Stmt]) { let Expr::JoinedStr ( _) = value.as_ref() else { return; }; - checker.diagnostics.push(Diagnostic::new( - FStringDocstring, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(FStringDocstring, stmt.identifier())); } diff --git a/crates/ruff/src/rules/flake8_builtins/helpers.rs b/crates/ruff/src/rules/flake8_builtins/helpers.rs index 2280f084c5..1fe69e0cb4 100644 --- a/crates/ruff/src/rules/flake8_builtins/helpers.rs +++ b/crates/ruff/src/rules/flake8_builtins/helpers.rs @@ -1,8 +1,7 @@ use ruff_text_size::TextRange; use rustpython_parser::ast::{ExceptHandler, Expr, Ranged, Stmt}; -use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; +use ruff_python_ast::identifier::{Identifier, TryIdentifier}; use ruff_python_stdlib::builtins::BUILTINS; pub(super) fn shadows_builtin(name: &str, ignorelist: &[String]) -> bool { @@ -16,12 +15,12 @@ pub(crate) enum AnyShadowing<'a> { ExceptHandler(&'a ExceptHandler), } -impl AnyShadowing<'_> { - pub(crate) fn range(self, locator: &Locator) -> TextRange { +impl Identifier for AnyShadowing<'_> { + fn identifier(&self) -> TextRange { match self { AnyShadowing::Expression(expr) => expr.range(), - AnyShadowing::Statement(stmt) => stmt.identifier(locator), - AnyShadowing::ExceptHandler(handler) => handler.range(), + AnyShadowing::Statement(stmt) => stmt.identifier(), + AnyShadowing::ExceptHandler(handler) => handler.try_identifier().unwrap(), } } } diff --git a/crates/ruff/src/rules/flake8_builtins/rules/builtin_attribute_shadowing.rs b/crates/ruff/src/rules/flake8_builtins/rules/builtin_attribute_shadowing.rs index 2adb257426..45edcb2ef7 100644 --- a/crates/ruff/src/rules/flake8_builtins/rules/builtin_attribute_shadowing.rs +++ b/crates/ruff/src/rules/flake8_builtins/rules/builtin_attribute_shadowing.rs @@ -1,6 +1,7 @@ use ruff_diagnostics::Diagnostic; use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::identifier::Identifier; use rustpython_parser::ast; use crate::checkers::ast::Checker; @@ -83,7 +84,7 @@ pub(crate) fn builtin_attribute_shadowing( BuiltinAttributeShadowing { name: name.to_string(), }, - shadowing.range(checker.locator), + shadowing.identifier(), )); } } diff --git a/crates/ruff/src/rules/flake8_builtins/rules/builtin_variable_shadowing.rs b/crates/ruff/src/rules/flake8_builtins/rules/builtin_variable_shadowing.rs index d604a29df2..d61aff2e57 100644 --- a/crates/ruff/src/rules/flake8_builtins/rules/builtin_variable_shadowing.rs +++ b/crates/ruff/src/rules/flake8_builtins/rules/builtin_variable_shadowing.rs @@ -1,6 +1,7 @@ use ruff_diagnostics::Diagnostic; use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::identifier::Identifier; use crate::checkers::ast::Checker; @@ -68,7 +69,7 @@ pub(crate) fn builtin_variable_shadowing( BuiltinVariableShadowing { name: name.to_string(), }, - shadowing.range(checker.locator), + shadowing.identifier(), )); } } diff --git a/crates/ruff/src/rules/flake8_builtins/snapshots/ruff__rules__flake8_builtins__tests__A001_A001.py.snap b/crates/ruff/src/rules/flake8_builtins/snapshots/ruff__rules__flake8_builtins__tests__A001_A001.py.snap index f62577f0f3..4aa57c119f 100644 --- a/crates/ruff/src/rules/flake8_builtins/snapshots/ruff__rules__flake8_builtins__tests__A001_A001.py.snap +++ b/crates/ruff/src/rules/flake8_builtins/snapshots/ruff__rules__flake8_builtins__tests__A001_A001.py.snap @@ -122,15 +122,13 @@ A001.py:16:7: A001 Variable `slice` is shadowing a Python builtin 17 | pass | -A001.py:21:1: A001 Variable `ValueError` is shadowing a Python builtin +A001.py:21:23: A001 Variable `ValueError` is shadowing a Python builtin | -19 | try: -20 | ... -21 | / except ImportError as ValueError: -22 | | ... - | |_______^ A001 -23 | -24 | for memoryview, *bytearray in []: +19 | try: +20 | ... +21 | except ImportError as ValueError: + | ^^^^^^^^^^ A001 +22 | ... | A001.py:24:5: A001 Variable `memoryview` is shadowing a Python builtin diff --git a/crates/ruff/src/rules/flake8_builtins/snapshots/ruff__rules__flake8_builtins__tests__A001_A001.py_builtins_ignorelist.snap b/crates/ruff/src/rules/flake8_builtins/snapshots/ruff__rules__flake8_builtins__tests__A001_A001.py_builtins_ignorelist.snap index 4c47bb5f0c..591ee6781f 100644 --- a/crates/ruff/src/rules/flake8_builtins/snapshots/ruff__rules__flake8_builtins__tests__A001_A001.py_builtins_ignorelist.snap +++ b/crates/ruff/src/rules/flake8_builtins/snapshots/ruff__rules__flake8_builtins__tests__A001_A001.py_builtins_ignorelist.snap @@ -102,15 +102,13 @@ A001.py:16:7: A001 Variable `slice` is shadowing a Python builtin 17 | pass | -A001.py:21:1: A001 Variable `ValueError` is shadowing a Python builtin +A001.py:21:23: A001 Variable `ValueError` is shadowing a Python builtin | -19 | try: -20 | ... -21 | / except ImportError as ValueError: -22 | | ... - | |_______^ A001 -23 | -24 | for memoryview, *bytearray in []: +19 | try: +20 | ... +21 | except ImportError as ValueError: + | ^^^^^^^^^^ A001 +22 | ... | A001.py:24:5: A001 Variable `memoryview` is shadowing a Python builtin diff --git a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__custom.snap b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__custom.snap index 8552fb09ea..1b7779d90d 100644 --- a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__custom.snap +++ b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__custom.snap @@ -16,7 +16,7 @@ custom.py:4:8: ICN001 `dask.array` should be imported as `da` | 3 | import altair # unconventional 4 | import dask.array # unconventional - | ^^^^ ICN001 + | ^^^^^^^^^^ ICN001 5 | import dask.dataframe # unconventional 6 | import matplotlib.pyplot # unconventional | @@ -27,7 +27,7 @@ custom.py:5:8: ICN001 `dask.dataframe` should be imported as `dd` 3 | import altair # unconventional 4 | import dask.array # unconventional 5 | import dask.dataframe # unconventional - | ^^^^ ICN001 + | ^^^^^^^^^^^^^^ ICN001 6 | import matplotlib.pyplot # unconventional 7 | import numpy # unconventional | @@ -38,7 +38,7 @@ custom.py:6:8: ICN001 `matplotlib.pyplot` should be imported as `plt` 4 | import dask.array # unconventional 5 | import dask.dataframe # unconventional 6 | import matplotlib.pyplot # unconventional - | ^^^^^^^^^^ ICN001 + | ^^^^^^^^^^^^^^^^^ ICN001 7 | import numpy # unconventional 8 | import pandas # unconventional | @@ -115,7 +115,7 @@ custom.py:13:8: ICN001 `plotly.express` should be imported as `px` 11 | import holoviews # unconventional 12 | import panel # unconventional 13 | import plotly.express # unconventional - | ^^^^^^ ICN001 + | ^^^^^^^^^^^^^^ ICN001 14 | import matplotlib # unconventional 15 | import polars # unconventional | diff --git a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__defaults.snap b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__defaults.snap index 89782e181f..42f1d32909 100644 --- a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__defaults.snap +++ b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__defaults.snap @@ -16,7 +16,7 @@ defaults.py:4:8: ICN001 `matplotlib.pyplot` should be imported as `plt` | 3 | import altair # unconventional 4 | import matplotlib.pyplot # unconventional - | ^^^^^^^^^^ ICN001 + | ^^^^^^^^^^^^^^^^^ ICN001 5 | import numpy # unconventional 6 | import pandas # unconventional | diff --git a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__from_imports.snap b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__from_imports.snap index f69e23b91c..bda73c8ac3 100644 --- a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__from_imports.snap +++ b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__from_imports.snap @@ -6,7 +6,7 @@ from_imports.py:3:8: ICN001 `xml.dom.minidom` should be imported as `md` 1 | # Test absolute imports 2 | # Violation cases 3 | import xml.dom.minidom - | ^^^ ICN001 + | ^^^^^^^^^^^^^^^ ICN001 4 | import xml.dom.minidom as wrong 5 | from xml.dom import minidom as wrong | diff --git a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__override_default.snap b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__override_default.snap index 267ed836dd..a0e6bef88c 100644 --- a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__override_default.snap +++ b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__override_default.snap @@ -16,7 +16,7 @@ override_default.py:4:8: ICN001 `matplotlib.pyplot` should be imported as `plt` | 3 | import altair # unconventional 4 | import matplotlib.pyplot # unconventional - | ^^^^^^^^^^ ICN001 + | ^^^^^^^^^^^^^^^^^ ICN001 5 | import numpy # unconventional 6 | import pandas # unconventional | diff --git a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__remove_default.snap b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__remove_default.snap index 60ce87e652..b02135a6cb 100644 --- a/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__remove_default.snap +++ b/crates/ruff/src/rules/flake8_import_conventions/snapshots/ruff__rules__flake8_import_conventions__tests__remove_default.snap @@ -16,7 +16,7 @@ remove_default.py:4:8: ICN001 `matplotlib.pyplot` should be imported as `plt` | 3 | import altair # unconventional 4 | import matplotlib.pyplot # unconventional - | ^^^^^^^^^^ ICN001 + | ^^^^^^^^^^^^^^^^^ ICN001 5 | import numpy # not checked 6 | import pandas # unconventional | diff --git a/crates/ruff/src/rules/flake8_pyi/rules/non_self_return_type.rs b/crates/ruff/src/rules/flake8_pyi/rules/non_self_return_type.rs index 78155686c9..04d76b4fb0 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/non_self_return_type.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/non_self_return_type.rs @@ -148,7 +148,7 @@ pub(crate) fn non_self_return_type( class_name: class_def.name.to_string(), method_name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } return; @@ -162,7 +162,7 @@ pub(crate) fn non_self_return_type( class_name: class_def.name.to_string(), method_name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } return; @@ -177,7 +177,7 @@ pub(crate) fn non_self_return_type( class_name: class_def.name.to_string(), method_name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } return; @@ -193,7 +193,7 @@ pub(crate) fn non_self_return_type( class_name: class_def.name.to_string(), method_name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } @@ -206,7 +206,7 @@ pub(crate) fn non_self_return_type( class_name: class_def.name.to_string(), method_name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } diff --git a/crates/ruff/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs b/crates/ruff/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs index 54611b75e3..47d1f9f177 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs @@ -90,7 +90,7 @@ pub(crate) fn str_or_repr_defined_in_stub(checker: &mut Checker, stmt: &Stmt) { StrOrReprDefinedInStub { name: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), ); if checker.patch(diagnostic.kind.rule()) { let stmt = checker.semantic().stmt(); diff --git a/crates/ruff/src/rules/flake8_pyi/rules/stub_body_multiple_statements.rs b/crates/ruff/src/rules/flake8_pyi/rules/stub_body_multiple_statements.rs index bfc0e70857..62872ecc9a 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/stub_body_multiple_statements.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/stub_body_multiple_statements.rs @@ -32,6 +32,6 @@ pub(crate) fn stub_body_multiple_statements(checker: &mut Checker, stmt: &Stmt, checker.diagnostics.push(Diagnostic::new( StubBodyMultipleStatements, - stmt.identifier(checker.locator), + stmt.identifier(), )); } diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs index 502cfb59ea..a34832a93f 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs @@ -379,7 +379,7 @@ fn check_fixture_returns(checker: &mut Checker, stmt: &Stmt, name: &str, body: & PytestIncorrectFixtureNameUnderscore { function: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } else if checker.enabled(Rule::PytestMissingFixtureNameUnderscore) && !visitor.has_return_with_value @@ -390,7 +390,7 @@ fn check_fixture_returns(checker: &mut Checker, stmt: &Stmt, name: &str, body: & PytestMissingFixtureNameUnderscore { function: name.to_string(), }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } diff --git a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_namedtuple_subclass.rs b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_namedtuple_subclass.rs index 3a56fc07c6..37ec291eab 100644 --- a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_namedtuple_subclass.rs +++ b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_namedtuple_subclass.rs @@ -77,7 +77,7 @@ pub(crate) fn no_slots_in_namedtuple_subclass( if !has_slots(&class.body) { checker.diagnostics.push(Diagnostic::new( NoSlotsInNamedtupleSubclass, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } diff --git a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_str_subclass.rs b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_str_subclass.rs index a1a5182c61..8d5aa7f886 100644 --- a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_str_subclass.rs +++ b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_str_subclass.rs @@ -59,10 +59,9 @@ pub(crate) fn no_slots_in_str_subclass(checker: &mut Checker, stmt: &Stmt, class }) }) { if !has_slots(&class.body) { - checker.diagnostics.push(Diagnostic::new( - NoSlotsInStrSubclass, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(NoSlotsInStrSubclass, stmt.identifier())); } } } diff --git a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_tuple_subclass.rs b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_tuple_subclass.rs index c57cd510b1..bb0cc7e376 100644 --- a/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_tuple_subclass.rs +++ b/crates/ruff/src/rules/flake8_slots/rules/no_slots_in_tuple_subclass.rs @@ -63,10 +63,9 @@ pub(crate) fn no_slots_in_tuple_subclass(checker: &mut Checker, stmt: &Stmt, cla }) }) { if !has_slots(&class.body) { - checker.diagnostics.push(Diagnostic::new( - NoSlotsInTupleSubclass, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(NoSlotsInTupleSubclass, stmt.identifier())); } } } diff --git a/crates/ruff/src/rules/mccabe/rules/function_is_too_complex.rs b/crates/ruff/src/rules/mccabe/rules/function_is_too_complex.rs index de18d78153..d67de8efc1 100644 --- a/crates/ruff/src/rules/mccabe/rules/function_is_too_complex.rs +++ b/crates/ruff/src/rules/mccabe/rules/function_is_too_complex.rs @@ -3,7 +3,6 @@ use rustpython_parser::ast::{self, ExceptHandler, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; /// ## What it does /// Checks for functions with a high `McCabe` complexity. @@ -142,7 +141,6 @@ pub(crate) fn function_is_too_complex( name: &str, body: &[Stmt], max_complexity: usize, - locator: &Locator, ) -> Option { let complexity = get_complexity_number(body) + 1; if complexity > max_complexity { @@ -152,7 +150,7 @@ pub(crate) fn function_is_too_complex( complexity, max_complexity, }, - stmt.identifier(locator), + stmt.identifier(), )) } else { None diff --git a/crates/ruff/src/rules/pep8_naming/rules/dunder_function_name.rs b/crates/ruff/src/rules/pep8_naming/rules/dunder_function_name.rs index 4f248b2040..2e0b708469 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/dunder_function_name.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/dunder_function_name.rs @@ -3,7 +3,6 @@ use rustpython_parser::ast::Stmt; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; use ruff_python_semantic::{Scope, ScopeKind}; use crate::settings::types::IdentifierPattern; @@ -48,7 +47,6 @@ pub(crate) fn dunder_function_name( stmt: &Stmt, name: &str, ignore_names: &[IdentifierPattern], - locator: &Locator, ) -> Option { if matches!(scope.kind, ScopeKind::Class(_)) { return None; @@ -67,8 +65,5 @@ pub(crate) fn dunder_function_name( return None; } - Some(Diagnostic::new( - DunderFunctionName, - stmt.identifier(locator), - )) + Some(Diagnostic::new(DunderFunctionName, stmt.identifier())) } diff --git a/crates/ruff/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs b/crates/ruff/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs index 182ba1e404..82edff98eb 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs @@ -3,7 +3,6 @@ use rustpython_parser::ast::{self, Expr, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; use crate::settings::types::IdentifierPattern; @@ -48,7 +47,6 @@ pub(crate) fn error_suffix_on_exception_name( class_def: &Stmt, bases: &[Expr], name: &str, - locator: &Locator, ignore_names: &[IdentifierPattern], ) -> Option { if ignore_names @@ -75,6 +73,6 @@ pub(crate) fn error_suffix_on_exception_name( ErrorSuffixOnExceptionName { name: name.to_string(), }, - class_def.identifier(locator), + class_def.identifier(), )) } diff --git a/crates/ruff/src/rules/pep8_naming/rules/invalid_class_name.rs b/crates/ruff/src/rules/pep8_naming/rules/invalid_class_name.rs index c6d7e72e99..e1bd799d9f 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/invalid_class_name.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/invalid_class_name.rs @@ -3,7 +3,6 @@ use rustpython_parser::ast::Stmt; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; use crate::settings::types::IdentifierPattern; @@ -54,7 +53,6 @@ pub(crate) fn invalid_class_name( class_def: &Stmt, name: &str, ignore_names: &[IdentifierPattern], - locator: &Locator, ) -> Option { if ignore_names .iter() @@ -69,7 +67,7 @@ pub(crate) fn invalid_class_name( InvalidClassName { name: name.to_string(), }, - class_def.identifier(locator), + class_def.identifier(), )); } None diff --git a/crates/ruff/src/rules/pep8_naming/rules/invalid_function_name.rs b/crates/ruff/src/rules/pep8_naming/rules/invalid_function_name.rs index f14ba2c709..71ca191d40 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/invalid_function_name.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/invalid_function_name.rs @@ -3,7 +3,6 @@ use rustpython_parser::ast::{Decorator, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; use ruff_python_semantic::analyze::visibility; use ruff_python_semantic::SemanticModel; use ruff_python_stdlib::str; @@ -57,7 +56,6 @@ pub(crate) fn invalid_function_name( decorator_list: &[Decorator], ignore_names: &[IdentifierPattern], semantic: &SemanticModel, - locator: &Locator, ) -> Option { // Ignore any explicitly-ignored function names. if ignore_names @@ -82,6 +80,6 @@ pub(crate) fn invalid_function_name( InvalidFunctionName { name: name.to_string(), }, - stmt.identifier(locator), + stmt.identifier(), )) } diff --git a/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs b/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs index 0f531d8d74..a109e51ea5 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs @@ -30,8 +30,7 @@ pub(crate) fn if_needed(checker: &mut Checker, docstring: &Docstring) { if !is_overload(cast::decorator_list(stmt), checker.semantic()) { return; } - checker.diagnostics.push(Diagnostic::new( - OverloadWithDocstring, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(OverloadWithDocstring, stmt.identifier())); } diff --git a/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs b/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs index 1d78d99444..9db7d71e23 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs @@ -133,10 +133,9 @@ pub(crate) fn not_missing( .. }) => { if checker.enabled(Rule::UndocumentedPublicClass) { - checker.diagnostics.push(Diagnostic::new( - UndocumentedPublicClass, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(UndocumentedPublicClass, stmt.identifier())); } false } @@ -148,7 +147,7 @@ pub(crate) fn not_missing( if checker.enabled(Rule::UndocumentedPublicNestedClass) { checker.diagnostics.push(Diagnostic::new( UndocumentedPublicNestedClass, - stmt.identifier(checker.locator), + stmt.identifier(), )); } false @@ -164,7 +163,7 @@ pub(crate) fn not_missing( if checker.enabled(Rule::UndocumentedPublicFunction) { checker.diagnostics.push(Diagnostic::new( UndocumentedPublicFunction, - stmt.identifier(checker.locator), + stmt.identifier(), )); } false @@ -181,34 +180,30 @@ pub(crate) fn not_missing( true } else if is_init(cast::name(stmt)) { if checker.enabled(Rule::UndocumentedPublicInit) { - checker.diagnostics.push(Diagnostic::new( - UndocumentedPublicInit, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(UndocumentedPublicInit, stmt.identifier())); } true } else if is_new(cast::name(stmt)) || is_call(cast::name(stmt)) { if checker.enabled(Rule::UndocumentedPublicMethod) { - checker.diagnostics.push(Diagnostic::new( - UndocumentedPublicMethod, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(UndocumentedPublicMethod, stmt.identifier())); } true } else if is_magic(cast::name(stmt)) { if checker.enabled(Rule::UndocumentedMagicMethod) { - checker.diagnostics.push(Diagnostic::new( - UndocumentedMagicMethod, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(UndocumentedMagicMethod, stmt.identifier())); } true } else { if checker.enabled(Rule::UndocumentedPublicMethod) { - checker.diagnostics.push(Diagnostic::new( - UndocumentedPublicMethod, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(UndocumentedPublicMethod, stmt.identifier())); } true } diff --git a/crates/ruff/src/rules/pydocstyle/rules/sections.rs b/crates/ruff/src/rules/pydocstyle/rules/sections.rs index 464b87ded5..2050c5f973 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/sections.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/sections.rs @@ -763,7 +763,7 @@ fn missing_args(checker: &mut Checker, docstring: &Docstring, docstrings_args: & let names = missing_arg_names.into_iter().sorted().collect(); checker.diagnostics.push(Diagnostic::new( UndocumentedParam { names }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } diff --git a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F401_F401_0.py.snap b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F401_F401_0.py.snap index d7ce627b24..67c97bb6ba 100644 --- a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F401_F401_0.py.snap +++ b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F401_F401_0.py.snap @@ -44,7 +44,7 @@ F401_0.py:12:8: F401 [*] `logging.handlers` imported but unused 10 | import multiprocessing.process 11 | import logging.config 12 | import logging.handlers - | ^^^^^^^ F401 + | ^^^^^^^^^^^^^^^^ F401 13 | from typing import ( 14 | TYPE_CHECKING, | diff --git a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F401_F401_5.py.snap b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F401_F401_5.py.snap index 2800a738ed..7be6dbbe89 100644 --- a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F401_F401_5.py.snap +++ b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F401_F401_5.py.snap @@ -41,7 +41,7 @@ F401_5.py:4:8: F401 [*] `h.i` imported but unused 2 | from a.b import c 3 | from d.e import f as g 4 | import h.i - | ^ F401 + | ^^^ F401 5 | import j.k as l | = help: Remove unused import: `h.i` diff --git a/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs b/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs index 9f826bf3a3..f88f99d50e 100644 --- a/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs +++ b/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs @@ -68,9 +68,8 @@ pub(crate) fn property_with_parameters( > 1 && checker.semantic().is_builtin("property") { - checker.diagnostics.push(Diagnostic::new( - PropertyWithParameters, - stmt.identifier(checker.locator), - )); + checker + .diagnostics + .push(Diagnostic::new(PropertyWithParameters, stmt.identifier())); } } diff --git a/crates/ruff/src/rules/pylint/rules/too_many_arguments.rs b/crates/ruff/src/rules/pylint/rules/too_many_arguments.rs index c5b396588e..4db54ced09 100644 --- a/crates/ruff/src/rules/pylint/rules/too_many_arguments.rs +++ b/crates/ruff/src/rules/pylint/rules/too_many_arguments.rs @@ -72,7 +72,7 @@ pub(crate) fn too_many_arguments(checker: &mut Checker, arguments: &Arguments, s c_args: num_arguments, max_args: checker.settings.pylint.max_args, }, - stmt.identifier(checker.locator), + stmt.identifier(), )); } } diff --git a/crates/ruff/src/rules/pylint/rules/too_many_branches.rs b/crates/ruff/src/rules/pylint/rules/too_many_branches.rs index a0330cb8cf..5d997ab843 100644 --- a/crates/ruff/src/rules/pylint/rules/too_many_branches.rs +++ b/crates/ruff/src/rules/pylint/rules/too_many_branches.rs @@ -3,7 +3,6 @@ use rustpython_parser::ast::{self, ExceptHandler, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; /// ## What it does /// Checks for functions or methods with too many branches. @@ -166,7 +165,6 @@ pub(crate) fn too_many_branches( stmt: &Stmt, body: &[Stmt], max_branches: usize, - locator: &Locator, ) -> Option { let branches = num_branches(body); if branches > max_branches { @@ -175,7 +173,7 @@ pub(crate) fn too_many_branches( branches, max_branches, }, - stmt.identifier(locator), + stmt.identifier(), )) } else { None diff --git a/crates/ruff/src/rules/pylint/rules/too_many_return_statements.rs b/crates/ruff/src/rules/pylint/rules/too_many_return_statements.rs index ef5e45d2d3..6b7f7de10a 100644 --- a/crates/ruff/src/rules/pylint/rules/too_many_return_statements.rs +++ b/crates/ruff/src/rules/pylint/rules/too_many_return_statements.rs @@ -4,7 +4,6 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::ReturnStatementVisitor; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; use ruff_python_ast::statement_visitor::StatementVisitor; /// ## What it does @@ -81,7 +80,6 @@ pub(crate) fn too_many_return_statements( stmt: &Stmt, body: &[Stmt], max_returns: usize, - locator: &Locator, ) -> Option { let returns = num_returns(body); if returns > max_returns { @@ -90,7 +88,7 @@ pub(crate) fn too_many_return_statements( returns, max_returns, }, - stmt.identifier(locator), + stmt.identifier(), )) } else { None diff --git a/crates/ruff/src/rules/pylint/rules/too_many_statements.rs b/crates/ruff/src/rules/pylint/rules/too_many_statements.rs index 2fd832459f..b22bffdbd8 100644 --- a/crates/ruff/src/rules/pylint/rules/too_many_statements.rs +++ b/crates/ruff/src/rules/pylint/rules/too_many_statements.rs @@ -3,7 +3,6 @@ use rustpython_parser::ast::{self, ExceptHandler, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; /// ## What it does /// Checks for functions or methods with too many statements. @@ -149,7 +148,6 @@ pub(crate) fn too_many_statements( stmt: &Stmt, body: &[Stmt], max_statements: usize, - locator: &Locator, ) -> Option { let statements = num_statements(body); if statements > max_statements { @@ -158,7 +156,7 @@ pub(crate) fn too_many_statements( statements, max_statements, }, - stmt.identifier(locator), + stmt.identifier(), )) } else { None diff --git a/crates/ruff/src/rules/pylint/rules/unexpected_special_method_signature.rs b/crates/ruff/src/rules/pylint/rules/unexpected_special_method_signature.rs index e7b25da4a5..eb02b3cc9f 100644 --- a/crates/ruff/src/rules/pylint/rules/unexpected_special_method_signature.rs +++ b/crates/ruff/src/rules/pylint/rules/unexpected_special_method_signature.rs @@ -5,7 +5,6 @@ use rustpython_parser::ast::{Arguments, Decorator, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; -use ruff_python_ast::source_code::Locator; use ruff_python_semantic::analyze::visibility::is_staticmethod; use crate::checkers::ast::Checker; @@ -143,7 +142,6 @@ pub(crate) fn unexpected_special_method_signature( name: &str, decorator_list: &[Decorator], args: &Arguments, - locator: &Locator, ) { if !checker.semantic().scope().kind.is_class() { return; @@ -188,7 +186,7 @@ pub(crate) fn unexpected_special_method_signature( expected_params, actual_params, }, - stmt.identifier(locator), + stmt.identifier(), )); } } diff --git a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs index cd2483fd65..5fcb60fa8c 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs @@ -53,7 +53,7 @@ pub(crate) fn unnecessary_class_parentheses( return; } - let offset = stmt.identifier(checker.locator).start(); + let offset = stmt.identifier().start(); let contents = checker.locator.after(offset); // Find the open and closing parentheses between the class name and the colon, if they exist. diff --git a/crates/ruff/src/rules/pyupgrade/rules/useless_object_inheritance.rs b/crates/ruff/src/rules/pyupgrade/rules/useless_object_inheritance.rs index ad61c35c8b..aa6ec0e31b 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/useless_object_inheritance.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/useless_object_inheritance.rs @@ -73,7 +73,7 @@ pub(crate) fn useless_object_inheritance( diagnostic.try_set_fix(|| { let edit = remove_argument( checker.locator, - stmt.identifier(checker.locator).start(), + stmt.identifier().start(), expr.range(), &class_def.bases, &class_def.keywords, diff --git a/crates/ruff_python_ast/src/identifier.rs b/crates/ruff_python_ast/src/identifier.rs index 4babb87717..4af761ae83 100644 --- a/crates/ruff_python_ast/src/identifier.rs +++ b/crates/ruff_python_ast/src/identifier.rs @@ -29,13 +29,13 @@ use crate::source_code::Locator; pub trait Identifier { /// Return the [`TextRange`] of the identifier in the given AST node. - fn identifier(&self, locator: &Locator) -> TextRange; + fn identifier(&self) -> TextRange; } pub trait TryIdentifier { /// Return the [`TextRange`] of the identifier in the given AST node, or `None` if /// the node does not have an identifier. - fn try_identifier(&self, locator: &Locator) -> Option; + fn try_identifier(&self) -> Option; } impl Identifier for Stmt { @@ -46,44 +46,11 @@ impl Identifier for Stmt { /// def f(): /// ... /// ``` - fn identifier(&self, locator: &Locator) -> TextRange { + fn identifier(&self) -> TextRange { match self { - Stmt::ClassDef(ast::StmtClassDef { - decorator_list, - range, - .. - }) - | Stmt::FunctionDef(ast::StmtFunctionDef { - decorator_list, - range, - .. - }) => { - let range = decorator_list.last().map_or(*range, |last_decorator| { - TextRange::new(last_decorator.end(), range.end()) - }); - - // The first "identifier" is the `def` or `class` keyword. - // The second "identifier" is the function or class name. - IdentifierTokenizer::starts_at(range.start(), locator.contents()) - .nth(1) - .expect("Unable to identify identifier in function or class definition") - } - Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef { - decorator_list, - range, - .. - }) => { - let range = decorator_list.last().map_or(*range, |last_decorator| { - TextRange::new(last_decorator.end(), range.end()) - }); - - // The first "identifier" is the `async` keyword. - // The second "identifier" is the `def` or `class` keyword. - // The third "identifier" is the function or class name. - IdentifierTokenizer::starts_at(range.start(), locator.contents()) - .nth(2) - .expect("Unable to identify identifier in function or class definition") - } + Stmt::ClassDef(ast::StmtClassDef { name, .. }) + | Stmt::FunctionDef(ast::StmtFunctionDef { name, .. }) + | Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, .. }) => name.range(), _ => self.range(), } } @@ -97,10 +64,8 @@ impl Identifier for Arg { /// def f(x: int): /// ... /// ``` - fn identifier(&self, locator: &Locator) -> TextRange { - IdentifierTokenizer::new(locator.contents(), self.range()) - .next() - .expect("Failed to find argument identifier") + fn identifier(&self) -> TextRange { + self.arg.range() } } @@ -112,8 +77,8 @@ impl Identifier for ArgWithDefault { /// def f(x: int = 0): /// ... /// ``` - fn identifier(&self, locator: &Locator) -> TextRange { - self.def.identifier(locator) + fn identifier(&self) -> TextRange { + self.def.identifier() } } @@ -124,22 +89,10 @@ impl Identifier for Alias { /// ```python /// from foo import bar as x /// ``` - fn identifier(&self, locator: &Locator) -> TextRange { - if matches!(self.name.as_str(), "*") { - self.range() - } else if self.asname.is_none() { - // The first identifier is the module name. - IdentifierTokenizer::new(locator.contents(), self.range()) - .next() - .expect("Failed to find alias identifier") - } else { - // The first identifier is the module name. - // The second identifier is the "as" keyword. - // The third identifier is the alias name. - IdentifierTokenizer::new(locator.contents(), self.range()) - .last() - .expect("Failed to find alias identifier") - } + fn identifier(&self) -> TextRange { + self.asname + .as_ref() + .map_or_else(|| self.name.range(), Ranged::range) } } @@ -177,78 +130,20 @@ impl TryIdentifier for Pattern { /// case *z: /// ... /// ``` - fn try_identifier(&self, locator: &Locator) -> Option { - match self { + fn try_identifier(&self) -> Option { + let name = match self { Pattern::MatchAs(ast::PatternMatchAs { - name: Some(_), - pattern, - range, - }) => { - Some(if let Some(pattern) = pattern { - // Identify `z` in: - // ```python - // match x: - // case Foo(bar) as z: - // ... - // ``` - IdentifierTokenizer::starts_at(pattern.end(), locator.contents()) - .nth(1) - .expect("Unable to identify identifier in pattern") - } else { - // Identify `z` in: - // ```python - // match x: - // case z: - // ... - // ``` - *range - }) - } + name: Some(name), .. + }) => Some(name), Pattern::MatchMapping(ast::PatternMatchMapping { - patterns, - rest: Some(_), - .. - }) => { - Some(if let Some(pattern) = patterns.last() { - // Identify `z` in: - // ```python - // match x: - // case {"a": 1, **z} - // ... - // ``` - // - // A mapping pattern can contain at most one double-star pattern, - // and it must be the last pattern in the mapping. - IdentifierTokenizer::starts_at(pattern.end(), locator.contents()) - .next() - .expect("Unable to identify identifier in pattern") - } else { - // Identify `z` in: - // ```python - // match x: - // case {**z} - // ... - // ``` - IdentifierTokenizer::starts_at(self.start(), locator.contents()) - .next() - .expect("Unable to identify identifier in pattern") - }) - } - Pattern::MatchStar(ast::PatternMatchStar { name: Some(_), .. }) => { - // Identify `z` in: - // ```python - // match x: - // case *z: - // ... - // ``` - Some( - IdentifierTokenizer::starts_at(self.start(), locator.contents()) - .next() - .expect("Unable to identify identifier in pattern"), - ) - } + rest: Some(rest), .. + }) => Some(rest), + Pattern::MatchStar(ast::PatternMatchStar { + name: Some(name), .. + }) => Some(name), _ => None, - } + }; + name.map(Ranged::range) } } @@ -262,24 +157,9 @@ impl TryIdentifier for ExceptHandler { /// except ValueError as e: /// ... /// ``` - fn try_identifier(&self, locator: &Locator) -> Option { - let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, name, .. }) = - self; - - if name.is_none() { - return None; - } - - let Some(type_) = type_ else { - return None; - }; - - // The exception name is the first identifier token after the `as` keyword. - Some( - IdentifierTokenizer::starts_at(type_.end(), locator.contents()) - .nth(1) - .expect("Failed to find exception identifier in exception handler"), - ) + fn try_identifier(&self) -> Option { + let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { name, .. }) = self; + name.as_ref().map(Ranged::range) } } @@ -481,137 +361,8 @@ mod tests { use rustpython_parser::Parse; use crate::identifier; - use crate::identifier::Identifier; use crate::source_code::Locator; - #[test] - fn extract_arg_range() -> Result<()> { - let contents = "def f(x): pass".trim(); - let stmt = Stmt::parse(contents, "")?; - let function_def = stmt.as_function_def_stmt().unwrap(); - let args = &function_def.args.args; - let arg = &args[0]; - let locator = Locator::new(contents); - assert_eq!( - arg.identifier(&locator), - TextRange::new(TextSize::from(6), TextSize::from(7)) - ); - - let contents = "def f(x: int): pass".trim(); - let stmt = Stmt::parse(contents, "")?; - let function_def = stmt.as_function_def_stmt().unwrap(); - let args = &function_def.args.args; - let arg = &args[0]; - let locator = Locator::new(contents); - assert_eq!( - arg.identifier(&locator), - TextRange::new(TextSize::from(6), TextSize::from(7)) - ); - - let contents = r#" -def f( - x: int, # Comment -): - pass -"# - .trim(); - let stmt = Stmt::parse(contents, "")?; - let function_def = stmt.as_function_def_stmt().unwrap(); - let args = &function_def.args.args; - let arg = &args[0]; - let locator = Locator::new(contents); - assert_eq!( - arg.identifier(&locator), - TextRange::new(TextSize::from(11), TextSize::from(12)) - ); - - Ok(()) - } - - #[test] - fn extract_identifier_range() -> Result<()> { - let contents = "def f(): pass".trim(); - let stmt = Stmt::parse(contents, "")?; - let locator = Locator::new(contents); - assert_eq!( - stmt.identifier(&locator), - TextRange::new(TextSize::from(4), TextSize::from(5)) - ); - - let contents = "async def f(): pass".trim(); - let stmt = Stmt::parse(contents, "")?; - let locator = Locator::new(contents); - assert_eq!( - stmt.identifier(&locator), - TextRange::new(TextSize::from(10), TextSize::from(11)) - ); - - let contents = r#" -def \ - f(): - pass -"# - .trim(); - let stmt = Stmt::parse(contents, "")?; - let locator = Locator::new(contents); - assert_eq!( - stmt.identifier(&locator), - TextRange::new(TextSize::from(8), TextSize::from(9)) - ); - - let contents = "class Class(): pass".trim(); - let stmt = Stmt::parse(contents, "")?; - let locator = Locator::new(contents); - assert_eq!( - stmt.identifier(&locator), - TextRange::new(TextSize::from(6), TextSize::from(11)) - ); - - let contents = "class Class: pass".trim(); - let stmt = Stmt::parse(contents, "")?; - let locator = Locator::new(contents); - assert_eq!( - stmt.identifier(&locator), - TextRange::new(TextSize::from(6), TextSize::from(11)) - ); - - let contents = r#" -@decorator() -class Class(): - pass -"# - .trim(); - let stmt = Stmt::parse(contents, "")?; - let locator = Locator::new(contents); - assert_eq!( - stmt.identifier(&locator), - TextRange::new(TextSize::from(19), TextSize::from(24)) - ); - - let contents = r#" -@decorator() # Comment -class Class(): - pass -"# - .trim(); - let stmt = Stmt::parse(contents, "")?; - let locator = Locator::new(contents); - assert_eq!( - stmt.identifier(&locator), - TextRange::new(TextSize::from(30), TextSize::from(35)) - ); - - let contents = r#"x = y + 1"#.trim(); - let stmt = Stmt::parse(contents, "")?; - let locator = Locator::new(contents); - assert_eq!( - stmt.identifier(&locator), - TextRange::new(TextSize::from(0), TextSize::from(9)) - ); - - Ok(()) - } - #[test] fn extract_else_range() -> Result<()> { let contents = r#"