mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:10 +00:00
Make the statement
vector private on SemanticModel
(#6348)
## Summary Instead, expose these as methods, now that we can use a reasonable nomenclature on the API.
This commit is contained in:
parent
bae87fa016
commit
61d3977f95
10 changed files with 55 additions and 25 deletions
|
@ -115,7 +115,7 @@ pub(crate) fn deferred_scopes(checker: &mut Checker) {
|
||||||
branch_detection::different_forks(
|
branch_detection::different_forks(
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
&checker.semantic.statements,
|
checker.semantic.statements(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}) {
|
}) {
|
||||||
|
@ -172,12 +172,14 @@ pub(crate) fn deferred_scopes(checker: &mut Checker) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Some(source) = shadowed.source else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
// If this is an overloaded function, abort.
|
// If this is an overloaded function, abort.
|
||||||
if shadowed.kind.is_function_definition()
|
if shadowed.kind.is_function_definition()
|
||||||
&& visibility::is_overload(
|
&& visibility::is_overload(
|
||||||
cast::decorator_list(
|
cast::decorator_list(checker.semantic.statement(source)),
|
||||||
checker.semantic.statements[shadowed.source.unwrap()],
|
|
||||||
),
|
|
||||||
&checker.semantic,
|
&checker.semantic,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +204,7 @@ pub(crate) fn deferred_scopes(checker: &mut Checker) {
|
||||||
branch_detection::different_forks(
|
branch_detection::different_forks(
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
&checker.semantic.statements,
|
checker.semantic.statements(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -202,7 +202,7 @@ impl<'a> Checker<'a> {
|
||||||
/// thus be applied whenever we delete a statement, but can otherwise be omitted.
|
/// thus be applied whenever we delete a statement, but can otherwise be omitted.
|
||||||
pub(crate) fn isolation(&self, parent: Option<&Stmt>) -> IsolationLevel {
|
pub(crate) fn isolation(&self, parent: Option<&Stmt>) -> IsolationLevel {
|
||||||
parent
|
parent
|
||||||
.and_then(|stmt| self.semantic.statements.node_id(stmt))
|
.and_then(|stmt| self.semantic.statement_id(stmt))
|
||||||
.map_or(IsolationLevel::default(), |node_id| {
|
.map_or(IsolationLevel::default(), |node_id| {
|
||||||
IsolationLevel::Group(node_id.into())
|
IsolationLevel::Group(node_id.into())
|
||||||
})
|
})
|
||||||
|
|
|
@ -174,7 +174,7 @@ pub(crate) fn unused_private_type_var(
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let Stmt::Assign(ast::StmtAssign { targets, value, .. }) =
|
let Stmt::Assign(ast::StmtAssign { targets, value, .. }) =
|
||||||
checker.semantic().statements[source]
|
checker.semantic().statement(source)
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -218,7 +218,7 @@ pub(crate) fn unused_private_protocol(
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Stmt::ClassDef(class_def) = checker.semantic().statements[source] else {
|
let Stmt::ClassDef(class_def) = checker.semantic().statement(source) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ pub(crate) fn unused_private_type_alias(
|
||||||
};
|
};
|
||||||
let Stmt::AnnAssign(ast::StmtAnnAssign {
|
let Stmt::AnnAssign(ast::StmtAnnAssign {
|
||||||
target, annotation, ..
|
target, annotation, ..
|
||||||
}) = checker.semantic().statements[source]
|
}) = checker.semantic().statement(source)
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -305,7 +305,7 @@ pub(crate) fn unused_private_typed_dict(
|
||||||
let Some(source) = binding.source else {
|
let Some(source) = binding.source else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let Stmt::ClassDef(class_def) = checker.semantic().statements[source] else {
|
let Stmt::ClassDef(class_def) = checker.semantic().statement(source) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -193,11 +193,13 @@ struct ImportBinding<'a> {
|
||||||
|
|
||||||
/// Generate a [`Fix`] to remove runtime imports from a type-checking block.
|
/// Generate a [`Fix`] to remove runtime imports from a type-checking block.
|
||||||
fn fix_imports(checker: &Checker, statement_id: NodeId, imports: &[ImportBinding]) -> Result<Fix> {
|
fn fix_imports(checker: &Checker, statement_id: NodeId, imports: &[ImportBinding]) -> Result<Fix> {
|
||||||
let statement = checker.semantic().statements[statement_id];
|
let statement = checker.semantic().statement(statement_id);
|
||||||
let parent = checker.semantic().statements.parent(statement);
|
let parent = checker.semantic().parent_statement(statement);
|
||||||
|
|
||||||
let member_names: Vec<Cow<'_, str>> = imports
|
let member_names: Vec<Cow<'_, str>> = imports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ImportBinding { import, .. }| import.member_name())
|
.map(|ImportBinding { import, .. }| import)
|
||||||
|
.map(Imported::member_name)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Find the first reference across all imports.
|
// Find the first reference across all imports.
|
||||||
|
|
|
@ -403,11 +403,13 @@ fn is_exempt(name: &str, exempt_modules: &[&str]) -> bool {
|
||||||
|
|
||||||
/// Generate a [`Fix`] to remove typing-only imports from a runtime context.
|
/// Generate a [`Fix`] to remove typing-only imports from a runtime context.
|
||||||
fn fix_imports(checker: &Checker, statement_id: NodeId, imports: &[ImportBinding]) -> Result<Fix> {
|
fn fix_imports(checker: &Checker, statement_id: NodeId, imports: &[ImportBinding]) -> Result<Fix> {
|
||||||
let statement = checker.semantic().statements[statement_id];
|
let statement = checker.semantic().statement(statement_id);
|
||||||
let parent = checker.semantic().statements.parent(statement);
|
let parent = checker.semantic().parent_statement(statement);
|
||||||
|
|
||||||
let member_names: Vec<Cow<'_, str>> = imports
|
let member_names: Vec<Cow<'_, str>> = imports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ImportBinding { import, .. }| import.member_name())
|
.map(|ImportBinding { import, .. }| import)
|
||||||
|
.map(Imported::member_name)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Find the first reference across all imports.
|
// Find the first reference across all imports.
|
||||||
|
|
|
@ -107,7 +107,7 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr) {
|
||||||
let binding = checker.semantic().binding(binding_id);
|
let binding = checker.semantic().binding(binding_id);
|
||||||
if binding.kind.is_assignment() || binding.kind.is_named_expr_assignment() {
|
if binding.kind.is_assignment() || binding.kind.is_named_expr_assignment() {
|
||||||
if let Some(parent_id) = binding.source {
|
if let Some(parent_id) = binding.source {
|
||||||
let parent = checker.semantic().statements[parent_id];
|
let parent = checker.semantic().statement(parent_id);
|
||||||
if let Stmt::Assign(ast::StmtAssign { value, .. })
|
if let Stmt::Assign(ast::StmtAssign { value, .. })
|
||||||
| Stmt::AnnAssign(ast::StmtAnnAssign {
|
| Stmt::AnnAssign(ast::StmtAnnAssign {
|
||||||
value: Some(value), ..
|
value: Some(value), ..
|
||||||
|
|
|
@ -226,12 +226,13 @@ struct ImportBinding<'a> {
|
||||||
|
|
||||||
/// Generate a [`Fix`] to remove unused imports from a statement.
|
/// Generate a [`Fix`] to remove unused imports from a statement.
|
||||||
fn fix_imports(checker: &Checker, statement_id: NodeId, imports: &[ImportBinding]) -> Result<Fix> {
|
fn fix_imports(checker: &Checker, statement_id: NodeId, imports: &[ImportBinding]) -> Result<Fix> {
|
||||||
let statement = checker.semantic().statements[statement_id];
|
let statement = checker.semantic().statement(statement_id);
|
||||||
let parent = checker.semantic().statements.parent(statement);
|
let parent = checker.semantic().parent_statement(statement);
|
||||||
|
|
||||||
let member_names: Vec<Cow<'_, str>> = imports
|
let member_names: Vec<Cow<'_, str>> = imports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ImportBinding { import, .. }| import.member_name())
|
.map(|ImportBinding { import, .. }| import)
|
||||||
|
.map(Imported::member_name)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let edit = autofix::edits::remove_unused_imports(
|
let edit = autofix::edits::remove_unused_imports(
|
||||||
|
|
|
@ -326,9 +326,9 @@ pub(crate) fn unused_variable(checker: &Checker, scope: &Scope, diagnostics: &mu
|
||||||
let mut diagnostic = Diagnostic::new(UnusedVariable { name }, range);
|
let mut diagnostic = Diagnostic::new(UnusedVariable { name }, range);
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(source) = source {
|
if let Some(source) = source {
|
||||||
let stmt = checker.semantic().statements[source];
|
let statement = checker.semantic().statement(source);
|
||||||
let parent = checker.semantic().statements.parent(stmt);
|
let parent = checker.semantic().parent_statement(statement);
|
||||||
if let Some(fix) = remove_unused_variable(stmt, parent, range, checker) {
|
if let Some(fix) = remove_unused_variable(statement, parent, range, checker) {
|
||||||
diagnostic.set_fix(fix);
|
diagnostic.set_fix(fix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,7 @@ impl<'a> Binding<'a> {
|
||||||
/// Returns the range of the binding's parent.
|
/// Returns the range of the binding's parent.
|
||||||
pub fn parent_range(&self, semantic: &SemanticModel) -> Option<TextRange> {
|
pub fn parent_range(&self, semantic: &SemanticModel) -> Option<TextRange> {
|
||||||
self.source
|
self.source
|
||||||
.map(|node_id| semantic.statements[node_id])
|
.map(|statement_id| semantic.statement(statement_id))
|
||||||
.and_then(|parent| {
|
.and_then(|parent| {
|
||||||
if parent.is_import_from_stmt() {
|
if parent.is_import_from_stmt() {
|
||||||
Some(parent.range())
|
Some(parent.range())
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub struct SemanticModel<'a> {
|
||||||
module_path: Option<&'a [String]>,
|
module_path: Option<&'a [String]>,
|
||||||
|
|
||||||
/// Stack of all visited statements.
|
/// Stack of all visited statements.
|
||||||
pub statements: Nodes<'a, Stmt>,
|
statements: Nodes<'a, Stmt>,
|
||||||
|
|
||||||
/// The identifier of the current statement.
|
/// The identifier of the current statement.
|
||||||
statement_id: Option<NodeId>,
|
statement_id: Option<NodeId>,
|
||||||
|
@ -919,6 +919,29 @@ impl<'a> SemanticModel<'a> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the [`Nodes`] vector of all statements.
|
||||||
|
pub const fn statements(&self) -> &Nodes<'a, Stmt> {
|
||||||
|
&self.statements
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the [`NodeId`] corresponding to the given [`Stmt`].
|
||||||
|
#[inline]
|
||||||
|
pub fn statement_id(&self, statement: &Stmt) -> Option<NodeId> {
|
||||||
|
self.statements.node_id(statement)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the [`Stmt]` corresponding to the given [`NodeId`].
|
||||||
|
#[inline]
|
||||||
|
pub fn statement(&self, statement_id: NodeId) -> &'a Stmt {
|
||||||
|
self.statements[statement_id]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a [`Stmt`], return its parent, if any.
|
||||||
|
#[inline]
|
||||||
|
pub fn parent_statement(&self, statement: &'a Stmt) -> Option<&'a Stmt> {
|
||||||
|
self.statements.parent(statement)
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the [`Globals`] for the current [`Scope`].
|
/// Set the [`Globals`] for the current [`Scope`].
|
||||||
pub fn set_globals(&mut self, globals: Globals<'a>) {
|
pub fn set_globals(&mut self, globals: Globals<'a>) {
|
||||||
// If any global bindings don't already exist in the global scope, add them.
|
// If any global bindings don't already exist in the global scope, add them.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue