mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 04:19:18 +00:00
Fix isolation groups for unused imports (#6774)
## Summary The isolation group for unused imports was relying on `checker.semantic().current_statement()`, which isn't valid for that rule, since it runs over the _scope_, not the statement. Instead, we need to lookup the isolation group based on the `NodeId` of the statement. Our tests didn't catch this, because we mostly have cases that look like this: ```python if TYPE_CHECKING: import shelve import importlib ``` In this case, the two fixes to remove the two unused imports are considered overlapping (since we delete the _full_ line, and the two _full_ lines touch, and we consider exactly-adjacent fixes to be overlapping), and so they don't run in a single pass due to the non-overlapping-fixes requirement. That is: the isolation groups aren't required for this case. They are, however, required for cases like: ```python if TYPE_CHECKING: import shelve import importlib ``` ...where the fixes don't overlap. Closes https://github.com/astral-sh/ruff/issues/6758. ## Test Plan `cargo test`
This commit is contained in:
parent
d2eace3377
commit
749da6589a
18 changed files with 221 additions and 39 deletions
|
@ -99,3 +99,16 @@ import foo.bar as bop
|
||||||
import foo.bar.baz
|
import foo.bar.baz
|
||||||
|
|
||||||
print(bop.baz.read_csv("test.csv"))
|
print(bop.baz.read_csv("test.csv"))
|
||||||
|
|
||||||
|
# Test: isolated deletions.
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
import a1
|
||||||
|
|
||||||
|
import a2
|
||||||
|
|
||||||
|
|
||||||
|
match *0, 1, *2:
|
||||||
|
case 0,:
|
||||||
|
import b1
|
||||||
|
|
||||||
|
import b2
|
||||||
|
|
|
@ -154,3 +154,14 @@ def f() -> None:
|
||||||
print("hello")
|
print("hello")
|
||||||
except A as e :
|
except A as e :
|
||||||
print("oh no!")
|
print("oh no!")
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
x = 1
|
||||||
|
y = 2
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
x = 1
|
||||||
|
|
||||||
|
y = 2
|
||||||
|
|
|
@ -52,7 +52,8 @@ use ruff_python_parser::typing::{parse_type_annotation, AnnotationKind};
|
||||||
use ruff_python_semantic::analyze::{typing, visibility};
|
use ruff_python_semantic::analyze::{typing, visibility};
|
||||||
use ruff_python_semantic::{
|
use ruff_python_semantic::{
|
||||||
BindingFlags, BindingId, BindingKind, Exceptions, Export, FromImport, Globals, Import, Module,
|
BindingFlags, BindingId, BindingKind, Exceptions, Export, FromImport, Globals, Import, Module,
|
||||||
ModuleKind, ScopeId, ScopeKind, SemanticModel, SemanticModelFlags, StarImport, SubmoduleImport,
|
ModuleKind, NodeId, ScopeId, ScopeKind, SemanticModel, SemanticModelFlags, StarImport,
|
||||||
|
SubmoduleImport,
|
||||||
};
|
};
|
||||||
use ruff_python_stdlib::builtins::{BUILTINS, MAGIC_GLOBALS};
|
use ruff_python_stdlib::builtins::{BUILTINS, MAGIC_GLOBALS};
|
||||||
use ruff_source_file::Locator;
|
use ruff_source_file::Locator;
|
||||||
|
@ -193,24 +194,6 @@ impl<'a> Checker<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`IsolationLevel`] to isolate fixes for the current statement.
|
|
||||||
///
|
|
||||||
/// The primary use-case for fix isolation is to ensure that we don't delete all statements
|
|
||||||
/// in a given indented block, which would cause a syntax error. We therefore need to ensure
|
|
||||||
/// that we delete at most one statement per indented block per fixer pass. Fix isolation should
|
|
||||||
/// thus be applied whenever we delete a statement, but can otherwise be omitted.
|
|
||||||
pub(crate) fn statement_isolation(&self) -> IsolationLevel {
|
|
||||||
IsolationLevel::Group(self.semantic.current_statement_id().into())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the [`IsolationLevel`] to isolate fixes in the current statement's parent.
|
|
||||||
pub(crate) fn parent_isolation(&self) -> IsolationLevel {
|
|
||||||
self.semantic
|
|
||||||
.current_statement_parent_id()
|
|
||||||
.map(|node_id| IsolationLevel::Group(node_id.into()))
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The [`Locator`] for the current file, which enables extraction of source code from byte
|
/// The [`Locator`] for the current file, which enables extraction of source code from byte
|
||||||
/// offsets.
|
/// offsets.
|
||||||
pub(crate) const fn locator(&self) -> &'a Locator<'a> {
|
pub(crate) const fn locator(&self) -> &'a Locator<'a> {
|
||||||
|
@ -259,6 +242,18 @@ impl<'a> Checker<'a> {
|
||||||
pub(crate) const fn any_enabled(&self, rules: &[Rule]) -> bool {
|
pub(crate) const fn any_enabled(&self, rules: &[Rule]) -> bool {
|
||||||
self.settings.rules.any_enabled(rules)
|
self.settings.rules.any_enabled(rules)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the [`IsolationLevel`] to isolate fixes for a given node.
|
||||||
|
///
|
||||||
|
/// The primary use-case for fix isolation is to ensure that we don't delete all statements
|
||||||
|
/// in a given indented block, which would cause a syntax error. We therefore need to ensure
|
||||||
|
/// that we delete at most one statement per indented block per fixer pass. Fix isolation should
|
||||||
|
/// thus be applied whenever we delete a statement, but can otherwise be omitted.
|
||||||
|
pub(crate) fn isolation(node_id: Option<NodeId>) -> IsolationLevel {
|
||||||
|
node_id
|
||||||
|
.map(|node_id| IsolationLevel::Group(node_id.into()))
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> Visitor<'b> for Checker<'a>
|
impl<'a, 'b> Visitor<'b> for Checker<'a>
|
||||||
|
|
|
@ -85,7 +85,9 @@ pub(crate) fn duplicate_class_field_definition(checker: &mut Checker, body: &[St
|
||||||
checker.locator(),
|
checker.locator(),
|
||||||
checker.indexer(),
|
checker.indexer(),
|
||||||
);
|
);
|
||||||
diagnostic.set_fix(Fix::suggested(edit).isolate(checker.statement_isolation()));
|
diagnostic.set_fix(Fix::suggested(edit).isolate(Checker::isolation(Some(
|
||||||
|
checker.semantic().current_statement_id(),
|
||||||
|
))));
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,9 @@ pub(crate) fn ellipsis_in_non_empty_class_body(checker: &mut Checker, body: &[St
|
||||||
checker.locator(),
|
checker.locator(),
|
||||||
checker.indexer(),
|
checker.indexer(),
|
||||||
);
|
);
|
||||||
diagnostic.set_fix(Fix::automatic(edit).isolate(checker.statement_isolation()));
|
diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(Some(
|
||||||
|
checker.semantic().current_statement_id(),
|
||||||
|
))));
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,9 @@ pub(crate) fn pass_in_class_body(checker: &mut Checker, class_def: &ast::StmtCla
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let edit =
|
let edit =
|
||||||
autofix::edits::delete_stmt(stmt, Some(stmt), checker.locator(), checker.indexer());
|
autofix::edits::delete_stmt(stmt, Some(stmt), checker.locator(), checker.indexer());
|
||||||
diagnostic.set_fix(Fix::automatic(edit).isolate(checker.statement_isolation()));
|
diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(Some(
|
||||||
|
checker.semantic().current_statement_id(),
|
||||||
|
))));
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,9 @@ pub(crate) fn str_or_repr_defined_in_stub(checker: &mut Checker, stmt: &Stmt) {
|
||||||
let stmt = checker.semantic().current_statement();
|
let stmt = checker.semantic().current_statement();
|
||||||
let parent = checker.semantic().current_statement_parent();
|
let parent = checker.semantic().current_statement_parent();
|
||||||
let edit = delete_stmt(stmt, parent, checker.locator(), checker.indexer());
|
let edit = delete_stmt(stmt, parent, checker.locator(), checker.indexer());
|
||||||
diagnostic.set_fix(Fix::automatic(edit).isolate(checker.parent_isolation()));
|
diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(
|
||||||
|
checker.semantic().current_statement_parent_id(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,9 @@ pub(crate) fn empty_type_checking_block(checker: &mut Checker, stmt: &ast::StmtI
|
||||||
let stmt = checker.semantic().current_statement();
|
let stmt = checker.semantic().current_statement();
|
||||||
let parent = checker.semantic().current_statement_parent();
|
let parent = checker.semantic().current_statement_parent();
|
||||||
let edit = autofix::edits::delete_stmt(stmt, parent, checker.locator(), checker.indexer());
|
let edit = autofix::edits::delete_stmt(stmt, parent, checker.locator(), checker.indexer());
|
||||||
diagnostic.set_fix(Fix::automatic(edit).isolate(checker.parent_isolation()));
|
diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(
|
||||||
|
checker.semantic().current_statement_parent_id(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,8 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) ->
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(
|
Ok(
|
||||||
Fix::suggested_edits(remove_import_edit, add_import_edit.into_edits())
|
Fix::suggested_edits(remove_import_edit, add_import_edit.into_edits()).isolate(
|
||||||
.isolate(checker.parent_isolation()),
|
Checker::isolation(checker.semantic().parent_statement_id(node_id)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,7 +486,8 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) ->
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(
|
Ok(
|
||||||
Fix::suggested_edits(remove_import_edit, add_import_edit.into_edits())
|
Fix::suggested_edits(remove_import_edit, add_import_edit.into_edits()).isolate(
|
||||||
.isolate(checker.parent_isolation()),
|
Checker::isolation(checker.semantic().parent_statement_id(node_id)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,6 +217,7 @@ pub(crate) fn unused_import(checker: &Checker, scope: &Scope, diagnostics: &mut
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An unused import with its surrounding context.
|
/// An unused import with its surrounding context.
|
||||||
|
#[derive(Debug)]
|
||||||
struct ImportBinding<'a> {
|
struct ImportBinding<'a> {
|
||||||
/// The qualified name of the import (e.g., `typing.List` for `from typing import List`).
|
/// The qualified name of the import (e.g., `typing.List` for `from typing import List`).
|
||||||
import: AnyImport<'a>,
|
import: AnyImport<'a>,
|
||||||
|
@ -251,5 +252,7 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) ->
|
||||||
checker.stylist(),
|
checker.stylist(),
|
||||||
checker.indexer(),
|
checker.indexer(),
|
||||||
)?;
|
)?;
|
||||||
Ok(Fix::automatic(edit).isolate(checker.parent_isolation()))
|
Ok(Fix::automatic(edit).isolate(Checker::isolation(
|
||||||
|
checker.semantic().parent_statement_id(node_id),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, IsolationLevel, Violation};
|
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::helpers::contains_effect;
|
use ruff_python_ast::helpers::contains_effect;
|
||||||
use ruff_python_ast::{self as ast, PySourceType, Ranged, Stmt};
|
use ruff_python_ast::{self as ast, PySourceType, Ranged, Stmt};
|
||||||
|
@ -206,11 +206,7 @@ fn remove_unused_variable(binding: &Binding, checker: &Checker) -> Option<Fix> {
|
||||||
let node_id = binding.source?;
|
let node_id = binding.source?;
|
||||||
let statement = checker.semantic().statement(node_id);
|
let statement = checker.semantic().statement(node_id);
|
||||||
let parent = checker.semantic().parent_statement(node_id);
|
let parent = checker.semantic().parent_statement(node_id);
|
||||||
let isolation = checker
|
let isolation = Checker::isolation(checker.semantic().parent_statement_id(node_id));
|
||||||
.semantic()
|
|
||||||
.parent_statement_id(node_id)
|
|
||||||
.map(|node_id| IsolationLevel::Group(node_id.into()))
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
// First case: simple assignment (`x = 1`)
|
// First case: simple assignment (`x = 1`)
|
||||||
if let Stmt::Assign(ast::StmtAssign { targets, value, .. }) = statement {
|
if let Stmt::Assign(ast::StmtAssign { targets, value, .. }) = statement {
|
||||||
|
|
|
@ -190,5 +190,78 @@ F401_0.py:99:8: F401 [*] `foo.bar.baz` imported but unused
|
||||||
99 |-import foo.bar.baz
|
99 |-import foo.bar.baz
|
||||||
100 99 |
|
100 99 |
|
||||||
101 100 | print(bop.baz.read_csv("test.csv"))
|
101 100 | print(bop.baz.read_csv("test.csv"))
|
||||||
|
102 101 |
|
||||||
|
|
||||||
|
F401_0.py:105:12: F401 [*] `a1` imported but unused
|
||||||
|
|
|
||||||
|
103 | # Test: isolated deletions.
|
||||||
|
104 | if TYPE_CHECKING:
|
||||||
|
105 | import a1
|
||||||
|
| ^^ F401
|
||||||
|
106 |
|
||||||
|
107 | import a2
|
||||||
|
|
|
||||||
|
= help: Remove unused import: `a1`
|
||||||
|
|
||||||
|
ℹ Fix
|
||||||
|
102 102 |
|
||||||
|
103 103 | # Test: isolated deletions.
|
||||||
|
104 104 | if TYPE_CHECKING:
|
||||||
|
105 |- import a1
|
||||||
|
106 105 |
|
||||||
|
107 106 | import a2
|
||||||
|
108 107 |
|
||||||
|
|
||||||
|
F401_0.py:107:12: F401 [*] `a2` imported but unused
|
||||||
|
|
|
||||||
|
105 | import a1
|
||||||
|
106 |
|
||||||
|
107 | import a2
|
||||||
|
| ^^ F401
|
||||||
|
|
|
||||||
|
= help: Remove unused import: `a2`
|
||||||
|
|
||||||
|
ℹ Fix
|
||||||
|
104 104 | if TYPE_CHECKING:
|
||||||
|
105 105 | import a1
|
||||||
|
106 106 |
|
||||||
|
107 |- import a2
|
||||||
|
108 107 |
|
||||||
|
109 108 |
|
||||||
|
110 109 | match *0, 1, *2:
|
||||||
|
|
||||||
|
F401_0.py:112:16: F401 [*] `b1` imported but unused
|
||||||
|
|
|
||||||
|
110 | match *0, 1, *2:
|
||||||
|
111 | case 0,:
|
||||||
|
112 | import b1
|
||||||
|
| ^^ F401
|
||||||
|
113 |
|
||||||
|
114 | import b2
|
||||||
|
|
|
||||||
|
= help: Remove unused import: `b1`
|
||||||
|
|
||||||
|
ℹ Fix
|
||||||
|
109 109 |
|
||||||
|
110 110 | match *0, 1, *2:
|
||||||
|
111 111 | case 0,:
|
||||||
|
112 |- import b1
|
||||||
|
113 112 |
|
||||||
|
114 113 | import b2
|
||||||
|
|
||||||
|
F401_0.py:114:16: F401 [*] `b2` imported but unused
|
||||||
|
|
|
||||||
|
112 | import b1
|
||||||
|
113 |
|
||||||
|
114 | import b2
|
||||||
|
| ^^ F401
|
||||||
|
|
|
||||||
|
= help: Remove unused import: `b2`
|
||||||
|
|
||||||
|
ℹ Fix
|
||||||
|
111 111 | case 0,:
|
||||||
|
112 112 | import b1
|
||||||
|
113 113 |
|
||||||
|
114 |- import b2
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -601,5 +601,76 @@ F841_3.py:155:17: F841 [*] Local variable `e` is assigned to but never used
|
||||||
155 |- except A as e :
|
155 |- except A as e :
|
||||||
155 |+ except A:
|
155 |+ except A:
|
||||||
156 156 | print("oh no!")
|
156 156 | print("oh no!")
|
||||||
|
157 157 |
|
||||||
|
158 158 |
|
||||||
|
|
||||||
|
F841_3.py:160:5: F841 [*] Local variable `x` is assigned to but never used
|
||||||
|
|
|
||||||
|
159 | def f():
|
||||||
|
160 | x = 1
|
||||||
|
| ^ F841
|
||||||
|
161 | y = 2
|
||||||
|
|
|
||||||
|
= help: Remove assignment to unused variable `x`
|
||||||
|
|
||||||
|
ℹ Suggested fix
|
||||||
|
157 157 |
|
||||||
|
158 158 |
|
||||||
|
159 159 | def f():
|
||||||
|
160 |- x = 1
|
||||||
|
161 160 | y = 2
|
||||||
|
162 161 |
|
||||||
|
163 162 |
|
||||||
|
|
||||||
|
F841_3.py:161:5: F841 [*] Local variable `y` is assigned to but never used
|
||||||
|
|
|
||||||
|
159 | def f():
|
||||||
|
160 | x = 1
|
||||||
|
161 | y = 2
|
||||||
|
| ^ F841
|
||||||
|
|
|
||||||
|
= help: Remove assignment to unused variable `y`
|
||||||
|
|
||||||
|
ℹ Suggested fix
|
||||||
|
158 158 |
|
||||||
|
159 159 | def f():
|
||||||
|
160 160 | x = 1
|
||||||
|
161 |- y = 2
|
||||||
|
162 161 |
|
||||||
|
163 162 |
|
||||||
|
164 163 | def f():
|
||||||
|
|
||||||
|
F841_3.py:165:5: F841 [*] Local variable `x` is assigned to but never used
|
||||||
|
|
|
||||||
|
164 | def f():
|
||||||
|
165 | x = 1
|
||||||
|
| ^ F841
|
||||||
|
166 |
|
||||||
|
167 | y = 2
|
||||||
|
|
|
||||||
|
= help: Remove assignment to unused variable `x`
|
||||||
|
|
||||||
|
ℹ Suggested fix
|
||||||
|
162 162 |
|
||||||
|
163 163 |
|
||||||
|
164 164 | def f():
|
||||||
|
165 |- x = 1
|
||||||
|
166 165 |
|
||||||
|
167 166 | y = 2
|
||||||
|
|
||||||
|
F841_3.py:167:5: F841 [*] Local variable `y` is assigned to but never used
|
||||||
|
|
|
||||||
|
165 | x = 1
|
||||||
|
166 |
|
||||||
|
167 | y = 2
|
||||||
|
| ^ F841
|
||||||
|
|
|
||||||
|
= help: Remove assignment to unused variable `y`
|
||||||
|
|
||||||
|
ℹ Suggested fix
|
||||||
|
164 164 | def f():
|
||||||
|
165 165 | x = 1
|
||||||
|
166 166 |
|
||||||
|
167 |- y = 2
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,9 @@ pub(crate) fn useless_return(
|
||||||
checker.locator(),
|
checker.locator(),
|
||||||
checker.indexer(),
|
checker.indexer(),
|
||||||
);
|
);
|
||||||
diagnostic.set_fix(Fix::automatic(edit).isolate(checker.statement_isolation()));
|
diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(Some(
|
||||||
|
checker.semantic().current_statement_id(),
|
||||||
|
))));
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,9 @@ pub(crate) fn unnecessary_builtin_import(
|
||||||
checker.stylist(),
|
checker.stylist(),
|
||||||
checker.indexer(),
|
checker.indexer(),
|
||||||
)?;
|
)?;
|
||||||
Ok(Fix::suggested(edit).isolate(checker.parent_isolation()))
|
Ok(Fix::suggested(edit).isolate(Checker::isolation(
|
||||||
|
checker.semantic().current_statement_parent_id(),
|
||||||
|
)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
|
|
|
@ -124,7 +124,9 @@ pub(crate) fn unnecessary_future_import(checker: &mut Checker, stmt: &Stmt, name
|
||||||
checker.stylist(),
|
checker.stylist(),
|
||||||
checker.indexer(),
|
checker.indexer(),
|
||||||
)?;
|
)?;
|
||||||
Ok(Fix::suggested(edit).isolate(checker.parent_isolation()))
|
Ok(Fix::suggested(edit).isolate(Checker::isolation(
|
||||||
|
checker.semantic().current_statement_parent_id(),
|
||||||
|
)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
|
|
|
@ -66,7 +66,9 @@ pub(crate) fn useless_metaclass_type(
|
||||||
let stmt = checker.semantic().current_statement();
|
let stmt = checker.semantic().current_statement();
|
||||||
let parent = checker.semantic().current_statement_parent();
|
let parent = checker.semantic().current_statement_parent();
|
||||||
let edit = autofix::edits::delete_stmt(stmt, parent, checker.locator(), checker.indexer());
|
let edit = autofix::edits::delete_stmt(stmt, parent, checker.locator(), checker.indexer());
|
||||||
diagnostic.set_fix(Fix::automatic(edit).isolate(checker.parent_isolation()));
|
diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(
|
||||||
|
checker.semantic().current_statement_parent_id(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue