mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-09 21:28:21 +00:00
ty_python_semantic: move some routines to FunctionType
These are, after all, specific to function types. The methods on `Type` are more like conveniences that return something when the type *happens* to be a function. But defining them on `FunctionType` itself makes it easy to call them when you have a `FunctionType` instead of a `Type`.
This commit is contained in:
parent
bd5b7f415f
commit
451c5db7a3
1 changed files with 79 additions and 28 deletions
|
@ -5372,16 +5372,7 @@ impl<'db> Type<'db> {
|
|||
/// a diagnostic.
|
||||
fn return_type_span(&self, db: &'db dyn Db) -> Option<(Span, Span)> {
|
||||
match *self {
|
||||
Type::FunctionLiteral(function) => {
|
||||
let function_scope = function.body_scope(db);
|
||||
let span = Span::from(function_scope.file(db));
|
||||
let node = function_scope.node(db);
|
||||
let func_def = node.as_function()?;
|
||||
let return_type_range = func_def.returns.as_ref()?.range();
|
||||
let name_span = span.clone().with_range(func_def.name.range);
|
||||
let return_type_span = span.with_range(return_type_range);
|
||||
Some((name_span, return_type_span))
|
||||
}
|
||||
Type::FunctionLiteral(function) => function.return_type_span(db),
|
||||
Type::BoundMethod(bound_method) => {
|
||||
Type::FunctionLiteral(bound_method.function(db)).return_type_span(db)
|
||||
}
|
||||
|
@ -5418,24 +5409,7 @@ impl<'db> Type<'db> {
|
|||
parameter_index: Option<usize>,
|
||||
) -> Option<(Span, Span)> {
|
||||
match *self {
|
||||
Type::FunctionLiteral(function) => {
|
||||
let function_scope = function.body_scope(db);
|
||||
let span = Span::from(function_scope.file(db));
|
||||
let node = function_scope.node(db);
|
||||
let func_def = node.as_function()?;
|
||||
let range = parameter_index
|
||||
.and_then(|parameter_index| {
|
||||
func_def
|
||||
.parameters
|
||||
.iter()
|
||||
.nth(parameter_index)
|
||||
.map(|param| param.range())
|
||||
})
|
||||
.unwrap_or(func_def.parameters.range);
|
||||
let name_span = span.clone().with_range(func_def.name.range);
|
||||
let parameter_span = span.with_range(range);
|
||||
Some((name_span, parameter_span))
|
||||
}
|
||||
Type::FunctionLiteral(function) => function.parameter_span(db, parameter_index),
|
||||
Type::BoundMethod(bound_method) => {
|
||||
Type::FunctionLiteral(bound_method.function(db)).parameter_span(db, parameter_index)
|
||||
}
|
||||
|
@ -6919,6 +6893,83 @@ impl<'db> FunctionType<'db> {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a tuple of two spans. The first is
|
||||
/// the span for the identifier of the function
|
||||
/// definition for `self`. The second is
|
||||
/// the span for the return type in the function
|
||||
/// definition for `self`.
|
||||
///
|
||||
/// If there are no meaningful spans, then this
|
||||
/// returns `None`. For example, when this type
|
||||
/// isn't callable or if the function has no
|
||||
/// declared return type.
|
||||
///
|
||||
/// # Performance
|
||||
///
|
||||
/// Note that this may introduce cross-module
|
||||
/// dependencies. This can have an impact on
|
||||
/// the effectiveness of incremental caching
|
||||
/// and should therefore be used judiciously.
|
||||
///
|
||||
/// An example of a good use case is to improve
|
||||
/// a diagnostic.
|
||||
fn return_type_span(&self, db: &'db dyn Db) -> Option<(Span, Span)> {
|
||||
let function_scope = self.body_scope(db);
|
||||
let span = Span::from(function_scope.file(db));
|
||||
let node = function_scope.node(db);
|
||||
let func_def = node.as_function()?;
|
||||
let return_type_range = func_def.returns.as_ref()?.range();
|
||||
let name_span = span.clone().with_range(func_def.name.range);
|
||||
let return_type_span = span.with_range(return_type_range);
|
||||
Some((name_span, return_type_span))
|
||||
}
|
||||
|
||||
/// Returns a tuple of two spans. The first is
|
||||
/// the span for the identifier of the function
|
||||
/// definition for `self`. The second is
|
||||
/// the span for the parameter in the function
|
||||
/// definition for `self`.
|
||||
///
|
||||
/// If there are no meaningful spans, then this
|
||||
/// returns `None`. For example, when this type
|
||||
/// isn't callable.
|
||||
///
|
||||
/// When `parameter_index` is `None`, then the
|
||||
/// second span returned covers the entire parameter
|
||||
/// list.
|
||||
///
|
||||
/// # Performance
|
||||
///
|
||||
/// Note that this may introduce cross-module
|
||||
/// dependencies. This can have an impact on
|
||||
/// the effectiveness of incremental caching
|
||||
/// and should therefore be used judiciously.
|
||||
///
|
||||
/// An example of a good use case is to improve
|
||||
/// a diagnostic.
|
||||
fn parameter_span(
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
parameter_index: Option<usize>,
|
||||
) -> Option<(Span, Span)> {
|
||||
let function_scope = self.body_scope(db);
|
||||
let span = Span::from(function_scope.file(db));
|
||||
let node = function_scope.node(db);
|
||||
let func_def = node.as_function()?;
|
||||
let range = parameter_index
|
||||
.and_then(|parameter_index| {
|
||||
func_def
|
||||
.parameters
|
||||
.iter()
|
||||
.nth(parameter_index)
|
||||
.map(|param| param.range())
|
||||
})
|
||||
.unwrap_or(func_def.parameters.range);
|
||||
let name_span = span.clone().with_range(func_def.name.range);
|
||||
let parameter_span = span.with_range(range);
|
||||
Some((name_span, parameter_span))
|
||||
}
|
||||
}
|
||||
|
||||
fn signature_cycle_recover<'db>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue