mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:21 +00:00
Make Binding::range()
point to the range of a type parameter's name, not the full type parameter (#15935)
Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
This commit is contained in:
parent
ff87ea8d42
commit
f23802e219
2 changed files with 29 additions and 44 deletions
|
@ -1759,12 +1759,12 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
||||||
fn visit_type_param(&mut self, type_param: &'a ast::TypeParam) {
|
fn visit_type_param(&mut self, type_param: &'a ast::TypeParam) {
|
||||||
// Step 1: Binding
|
// Step 1: Binding
|
||||||
match type_param {
|
match type_param {
|
||||||
ast::TypeParam::TypeVar(ast::TypeParamTypeVar { name, range, .. })
|
ast::TypeParam::TypeVar(ast::TypeParamTypeVar { name, .. })
|
||||||
| ast::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple { name, range, .. })
|
| ast::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple { name, .. })
|
||||||
| ast::TypeParam::ParamSpec(ast::TypeParamParamSpec { name, range, .. }) => {
|
| ast::TypeParam::ParamSpec(ast::TypeParamParamSpec { name, .. }) => {
|
||||||
self.add_binding(
|
self.add_binding(
|
||||||
name.as_str(),
|
name.as_str(),
|
||||||
*range,
|
name.range(),
|
||||||
BindingKind::TypeParam,
|
BindingKind::TypeParam,
|
||||||
BindingFlags::empty(),
|
BindingFlags::empty(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -198,7 +198,7 @@ pub(crate) fn custom_type_var_instead_of_self(
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
CustomTypeVarForSelf {
|
CustomTypeVarForSelf {
|
||||||
typevar_name: custom_typevar.name.to_string(),
|
typevar_name: custom_typevar.name(checker).to_string(),
|
||||||
},
|
},
|
||||||
diagnostic_range,
|
diagnostic_range,
|
||||||
);
|
);
|
||||||
|
@ -207,7 +207,7 @@ pub(crate) fn custom_type_var_instead_of_self(
|
||||||
replace_custom_typevar_with_self(
|
replace_custom_typevar_with_self(
|
||||||
checker,
|
checker,
|
||||||
function_def,
|
function_def,
|
||||||
&custom_typevar,
|
custom_typevar,
|
||||||
self_or_cls_parameter,
|
self_or_cls_parameter,
|
||||||
self_or_cls_annotation,
|
self_or_cls_annotation,
|
||||||
function_header_end,
|
function_header_end,
|
||||||
|
@ -294,14 +294,9 @@ impl ClassMethod<'_> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let binding = semantic
|
semantic
|
||||||
.resolve_name(cls_annotation_typevar)
|
.resolve_name(cls_annotation_typevar)
|
||||||
.map(|binding_id| semantic.binding(binding_id))?;
|
.map(|binding_id| TypeVar(semantic.binding(binding_id)))
|
||||||
|
|
||||||
Some(TypeVar {
|
|
||||||
name: cls_annotation_typevar_name,
|
|
||||||
binding,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,14 +366,9 @@ impl InstanceMethod<'_> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let binding = semantic
|
semantic
|
||||||
.resolve_name(self_annotation)
|
.resolve_name(self_annotation)
|
||||||
.map(|binding_id| semantic.binding(binding_id))?;
|
.map(|binding_id| TypeVar(semantic.binding(binding_id)))
|
||||||
|
|
||||||
Some(TypeVar {
|
|
||||||
name: first_arg_type,
|
|
||||||
binding,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,10 +438,7 @@ fn custom_typevar_preview<'a>(
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(ast::TypeParam::as_type_var)
|
.filter_map(ast::TypeParam::as_type_var)
|
||||||
.any(|ast::TypeParamTypeVar { name, .. }| name.id == typevar_expr.id)
|
.any(|ast::TypeParamTypeVar { name, .. }| name.id == typevar_expr.id)
|
||||||
.then_some(TypeVar {
|
.then_some(TypeVar(binding));
|
||||||
name: &typevar_expr.id,
|
|
||||||
binding,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example:
|
// Example:
|
||||||
|
@ -471,10 +458,7 @@ fn custom_typevar_preview<'a>(
|
||||||
|
|
||||||
semantic
|
semantic
|
||||||
.match_typing_expr(&rhs_function.func, "TypeVar")
|
.match_typing_expr(&rhs_function.func, "TypeVar")
|
||||||
.then_some(TypeVar {
|
.then_some(TypeVar(binding))
|
||||||
name: &typevar_expr.id,
|
|
||||||
binding,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a "Replace with `Self`" fix that does the following:
|
/// Add a "Replace with `Self`" fix that does the following:
|
||||||
|
@ -486,7 +470,7 @@ fn custom_typevar_preview<'a>(
|
||||||
fn replace_custom_typevar_with_self(
|
fn replace_custom_typevar_with_self(
|
||||||
checker: &Checker,
|
checker: &Checker,
|
||||||
function_def: &ast::StmtFunctionDef,
|
function_def: &ast::StmtFunctionDef,
|
||||||
custom_typevar: &TypeVar,
|
custom_typevar: TypeVar,
|
||||||
self_or_cls_parameter: &ast::ParameterWithDefault,
|
self_or_cls_parameter: &ast::ParameterWithDefault,
|
||||||
self_or_cls_annotation: &ast::Expr,
|
self_or_cls_annotation: &ast::Expr,
|
||||||
function_header_end: TextSize,
|
function_header_end: TextSize,
|
||||||
|
@ -576,7 +560,7 @@ fn import_self(checker: &Checker, position: TextSize) -> Result<(Edit, String),
|
||||||
/// Only references within `editable_range` will be modified.
|
/// Only references within `editable_range` will be modified.
|
||||||
/// This ensures that no edit in this series will overlap with other edits.
|
/// This ensures that no edit in this series will overlap with other edits.
|
||||||
fn replace_typevar_usages_with_self<'a>(
|
fn replace_typevar_usages_with_self<'a>(
|
||||||
typevar: &'a TypeVar<'a>,
|
typevar: TypeVar<'a>,
|
||||||
self_or_cls_annotation_range: TextRange,
|
self_or_cls_annotation_range: TextRange,
|
||||||
self_symbol_binding: &'a str,
|
self_symbol_binding: &'a str,
|
||||||
editable_range: TextRange,
|
editable_range: TextRange,
|
||||||
|
@ -599,10 +583,10 @@ fn replace_typevar_usages_with_self<'a>(
|
||||||
/// Return `None` if we fail to find a `TypeVar` that matches the range of `typevar_binding`.
|
/// Return `None` if we fail to find a `TypeVar` that matches the range of `typevar_binding`.
|
||||||
fn remove_pep695_typevar_declaration(
|
fn remove_pep695_typevar_declaration(
|
||||||
type_params: &ast::TypeParams,
|
type_params: &ast::TypeParams,
|
||||||
custom_typevar: &TypeVar,
|
custom_typevar: TypeVar,
|
||||||
) -> Option<Edit> {
|
) -> Option<Edit> {
|
||||||
if let [sole_typevar] = &**type_params {
|
if let [sole_typevar] = &**type_params {
|
||||||
return (sole_typevar.range() == custom_typevar.range())
|
return (sole_typevar.name().range() == custom_typevar.range())
|
||||||
.then(|| Edit::range_deletion(type_params.range));
|
.then(|| Edit::range_deletion(type_params.range));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,22 +609,23 @@ fn remove_pep695_typevar_declaration(
|
||||||
Some(Edit::range_deletion(deletion_range))
|
Some(Edit::range_deletion(deletion_range))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
struct TypeVar<'a> {
|
struct TypeVar<'a>(&'a Binding<'a>);
|
||||||
name: &'a str,
|
|
||||||
binding: &'a Binding<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypeVar<'_> {
|
impl<'a> TypeVar<'a> {
|
||||||
const fn is_pep695_typevar(&self) -> bool {
|
const fn is_pep695_typevar(self) -> bool {
|
||||||
self.binding.kind.is_type_param()
|
self.0.kind.is_type_param()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn references<'a>(
|
fn name(self, checker: &'a Checker) -> &'a str {
|
||||||
&'a self,
|
self.0.name(checker.source())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn references(
|
||||||
|
self,
|
||||||
semantic: &'a SemanticModel<'a>,
|
semantic: &'a SemanticModel<'a>,
|
||||||
) -> impl Iterator<Item = &'a ResolvedReference> + 'a {
|
) -> impl Iterator<Item = &'a ResolvedReference> + 'a {
|
||||||
self.binding
|
self.0
|
||||||
.references()
|
.references()
|
||||||
.map(|reference_id| semantic.reference(reference_id))
|
.map(|reference_id| semantic.reference(reference_id))
|
||||||
}
|
}
|
||||||
|
@ -648,6 +633,6 @@ impl TypeVar<'_> {
|
||||||
|
|
||||||
impl Ranged for TypeVar<'_> {
|
impl Ranged for TypeVar<'_> {
|
||||||
fn range(&self) -> TextRange {
|
fn range(&self) -> TextRange {
|
||||||
self.binding.range()
|
self.0.range()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue