mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[ty] Improve disambiguation of class names in diagnostics (#20603)
This commit is contained in:
parent
81f43a1fc8
commit
3f640dacd4
6 changed files with 243 additions and 154 deletions
|
@ -43,8 +43,7 @@ import b
|
||||||
df: a.DataFrame = b.DataFrame() # error: [invalid-assignment] "Object of type `b.DataFrame` is not assignable to `a.DataFrame`"
|
df: a.DataFrame = b.DataFrame() # error: [invalid-assignment] "Object of type `b.DataFrame` is not assignable to `a.DataFrame`"
|
||||||
|
|
||||||
def _(dfs: list[b.DataFrame]):
|
def _(dfs: list[b.DataFrame]):
|
||||||
# TODO should be"Object of type `list[b.DataFrame]` is not assignable to `list[a.DataFrame]`
|
# error: [invalid-assignment] "Object of type `list[b.DataFrame]` is not assignable to `list[a.DataFrame]`"
|
||||||
# error: [invalid-assignment] "Object of type `list[DataFrame]` is not assignable to `list[DataFrame]`"
|
|
||||||
dataframes: list[a.DataFrame] = dfs
|
dataframes: list[a.DataFrame] = dfs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -228,3 +227,21 @@ from typing import TypedDict
|
||||||
class Person(TypedDict):
|
class Person(TypedDict):
|
||||||
name: bytes
|
name: bytes
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Tuple specializations
|
||||||
|
|
||||||
|
`module.py`:
|
||||||
|
|
||||||
|
```py
|
||||||
|
class Model: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```py
|
||||||
|
class Model: ...
|
||||||
|
|
||||||
|
def get_models_tuple() -> tuple[Model]:
|
||||||
|
from module import Model
|
||||||
|
|
||||||
|
# error: [invalid-return-type] "Return type does not match returned value: expected `tuple[mdtest_snippet.Model]`, found `tuple[module.Model]`"
|
||||||
|
return (Model(),)
|
||||||
|
```
|
||||||
|
|
|
@ -339,7 +339,7 @@ class A: ...
|
||||||
|
|
||||||
def f(x: A):
|
def f(x: A):
|
||||||
# TODO: no error
|
# TODO: no error
|
||||||
# error: [invalid-assignment] "Object of type `A | A` is not assignable to `A`"
|
# error: [invalid-assignment] "Object of type `mdtest_snippet.A | mdtest_snippet.A` is not assignable to `mdtest_snippet.A`"
|
||||||
x = A()
|
x = A()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -7065,7 +7065,11 @@ impl<'db> KnownInstanceType<'db> {
|
||||||
if let Some(specialization) = alias.specialization(self.db) {
|
if let Some(specialization) = alias.specialization(self.db) {
|
||||||
f.write_str(alias.name(self.db))?;
|
f.write_str(alias.name(self.db))?;
|
||||||
specialization
|
specialization
|
||||||
.display_short(self.db, TupleSpecialization::No)
|
.display_short(
|
||||||
|
self.db,
|
||||||
|
TupleSpecialization::No,
|
||||||
|
DisplaySettings::default(),
|
||||||
|
)
|
||||||
.fmt(f)
|
.fmt(f)
|
||||||
} else {
|
} else {
|
||||||
f.write_str("typing.TypeAliasType")
|
f.write_str("typing.TypeAliasType")
|
||||||
|
|
|
@ -1986,7 +1986,7 @@ pub(super) fn report_invalid_assignment<'db>(
|
||||||
target_ty,
|
target_ty,
|
||||||
format_args!(
|
format_args!(
|
||||||
"Object of type `{}` is not assignable to `{}`",
|
"Object of type `{}` is not assignable to `{}`",
|
||||||
source_ty.display_with(context.db(), settings),
|
source_ty.display_with(context.db(), settings.clone()),
|
||||||
target_ty.display_with(context.db(), settings)
|
target_ty.display_with(context.db(), settings)
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -2068,8 +2068,8 @@ pub(super) fn report_invalid_return_type(
|
||||||
let mut diag = builder.into_diagnostic("Return type does not match returned value");
|
let mut diag = builder.into_diagnostic("Return type does not match returned value");
|
||||||
diag.set_primary_message(format_args!(
|
diag.set_primary_message(format_args!(
|
||||||
"expected `{expected_ty}`, found `{actual_ty}`",
|
"expected `{expected_ty}`, found `{actual_ty}`",
|
||||||
expected_ty = expected_ty.display_with(context.db(), settings),
|
expected_ty = expected_ty.display_with(context.db(), settings.clone()),
|
||||||
actual_ty = actual_ty.display_with(context.db(), settings),
|
actual_ty = actual_ty.display_with(context.db(), settings.clone()),
|
||||||
));
|
));
|
||||||
diag.annotate(
|
diag.annotate(
|
||||||
Annotation::secondary(return_type_span).message(format_args!(
|
Annotation::secondary(return_type_span).message(format_args!(
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
//! Display implementations for types.
|
//! Display implementations for types.
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
use std::fmt::{self, Display, Formatter, Write};
|
use std::fmt::{self, Display, Formatter, Write};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use ruff_db::display::FormatterJoinExtension;
|
use ruff_db::display::FormatterJoinExtension;
|
||||||
use ruff_python_ast::str::{Quote, TripleQuotes};
|
use ruff_python_ast::str::{Quote, TripleQuotes};
|
||||||
use ruff_python_literal::escape::AsciiEscape;
|
use ruff_python_literal::escape::AsciiEscape;
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use crate::Db;
|
use crate::Db;
|
||||||
use crate::module_resolver::file_to_module;
|
use crate::module_resolver::file_to_module;
|
||||||
|
@ -15,117 +19,149 @@ use crate::types::function::{FunctionType, OverloadLiteral};
|
||||||
use crate::types::generics::{GenericContext, Specialization};
|
use crate::types::generics::{GenericContext, Specialization};
|
||||||
use crate::types::signatures::{CallableSignature, Parameter, Parameters, Signature};
|
use crate::types::signatures::{CallableSignature, Parameter, Parameters, Signature};
|
||||||
use crate::types::tuple::TupleSpec;
|
use crate::types::tuple::TupleSpec;
|
||||||
|
use crate::types::visitor::TypeVisitor;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
BoundTypeVarInstance, CallableType, IntersectionType, KnownBoundMethodType, KnownClass,
|
BoundTypeVarInstance, CallableType, IntersectionType, KnownBoundMethodType, KnownClass,
|
||||||
MaterializationKind, Protocol, ProtocolInstanceType, StringLiteralType, SubclassOfInner, Type,
|
MaterializationKind, Protocol, StringLiteralType, SubclassOfInner, Type, UnionType,
|
||||||
UnionType, WrapperDescriptorKind,
|
WrapperDescriptorKind, visitor,
|
||||||
};
|
};
|
||||||
use ruff_db::parsed::parsed_module;
|
use ruff_db::parsed::parsed_module;
|
||||||
|
|
||||||
/// Settings for displaying types and signatures
|
/// Settings for displaying types and signatures
|
||||||
#[derive(Debug, Copy, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct DisplaySettings {
|
pub struct DisplaySettings<'db> {
|
||||||
/// Whether rendering can be multiline
|
/// Whether rendering can be multiline
|
||||||
pub multiline: bool,
|
pub multiline: bool,
|
||||||
/// Whether rendering will show qualified display (e.g., module.class)
|
/// Class names that should be displayed fully qualified
|
||||||
pub qualified: bool,
|
/// (e.g., `module.ClassName` instead of just `ClassName`)
|
||||||
|
pub qualified: Rc<FxHashSet<&'db str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisplaySettings {
|
impl<'db> DisplaySettings<'db> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn multiline(self) -> Self {
|
pub fn multiline(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
multiline: true,
|
multiline: true,
|
||||||
..self
|
..self.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn singleline(self) -> Self {
|
pub fn singleline(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
multiline: false,
|
multiline: false,
|
||||||
..self
|
..self.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn qualified(self) -> Self {
|
pub fn from_possibly_ambiguous_type_pair(
|
||||||
Self {
|
|
||||||
qualified: true,
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn from_possibly_ambiguous_type_pair<'db>(
|
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
type_1: Type<'db>,
|
type_1: Type<'db>,
|
||||||
type_2: Type<'db>,
|
type_2: Type<'db>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let result = Self::default();
|
let collector = AmbiguousClassCollector::default();
|
||||||
|
collector.visit_type(db, type_1);
|
||||||
|
collector.visit_type(db, type_2);
|
||||||
|
|
||||||
let Some(class_1) = type_to_class_literal(db, type_1) else {
|
Self {
|
||||||
return result;
|
qualified: Rc::new(
|
||||||
};
|
collector
|
||||||
|
.class_names
|
||||||
let Some(class_2) = type_to_class_literal(db, type_2) else {
|
.borrow()
|
||||||
return result;
|
.iter()
|
||||||
};
|
.filter_map(|(name, ambiguity)| ambiguity.is_ambiguous().then_some(*name))
|
||||||
|
.collect(),
|
||||||
if class_1 == class_2 {
|
),
|
||||||
return result;
|
..Self::default()
|
||||||
}
|
|
||||||
|
|
||||||
if class_1.name(db) == class_2.name(db) {
|
|
||||||
result.qualified()
|
|
||||||
} else {
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: generalize this to a method that takes any two types, walks them recursively, and returns
|
#[derive(Debug, Default)]
|
||||||
// a set of types with ambiguous names whose display should be qualified. Then we can use this in
|
struct AmbiguousClassCollector<'db> {
|
||||||
// any diagnostic that displays two types.
|
visited_types: RefCell<FxHashSet<Type<'db>>>,
|
||||||
fn type_to_class_literal<'db>(db: &'db dyn Db, ty: Type<'db>) -> Option<ClassLiteral<'db>> {
|
class_names: RefCell<FxHashMap<&'db str, AmbiguityState<'db>>>,
|
||||||
match ty {
|
}
|
||||||
Type::ClassLiteral(class) => Some(class),
|
|
||||||
Type::NominalInstance(instance) => Some(instance.class_literal(db)),
|
impl<'db> AmbiguousClassCollector<'db> {
|
||||||
Type::EnumLiteral(enum_literal) => Some(enum_literal.enum_class(db)),
|
fn record_class(&self, db: &'db dyn Db, class: ClassLiteral<'db>) {
|
||||||
Type::GenericAlias(alias) => Some(alias.origin(db)),
|
match self.class_names.borrow_mut().entry(class.name(db)) {
|
||||||
Type::ProtocolInstance(ProtocolInstanceType {
|
Entry::Vacant(entry) => {
|
||||||
inner: Protocol::FromClass(class),
|
entry.insert(AmbiguityState::Unambiguous(class));
|
||||||
..
|
}
|
||||||
}) => type_to_class_literal(db, Type::from(class)),
|
Entry::Occupied(mut entry) => {
|
||||||
Type::TypedDict(typed_dict) => {
|
let value = entry.get_mut();
|
||||||
type_to_class_literal(db, Type::from(typed_dict.defining_class()))
|
if let AmbiguityState::Unambiguous(existing) = value
|
||||||
|
&& *existing != class
|
||||||
|
{
|
||||||
|
*value = AmbiguityState::Ambiguous;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Type::SubclassOf(subclass_of) => {
|
}
|
||||||
type_to_class_literal(db, Type::from(subclass_of.subclass_of().into_class()?))
|
}
|
||||||
|
|
||||||
|
/// Whether or not a class can be unambiguously identified by its *unqualified* name
|
||||||
|
/// given the other types that are present in the same context.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
enum AmbiguityState<'db> {
|
||||||
|
/// The class can be displayed unambiguously using its unqualified name
|
||||||
|
Unambiguous(ClassLiteral<'db>),
|
||||||
|
/// The class must be displayed using its fully qualified name to avoid ambiguity.
|
||||||
|
Ambiguous,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AmbiguityState<'_> {
|
||||||
|
const fn is_ambiguous(self) -> bool {
|
||||||
|
matches!(self, AmbiguityState::Ambiguous)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'db> super::visitor::TypeVisitor<'db> for AmbiguousClassCollector<'db> {
|
||||||
|
fn should_visit_lazy_type_attributes(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_type(&self, db: &'db dyn Db, ty: Type<'db>) {
|
||||||
|
match ty {
|
||||||
|
Type::ClassLiteral(class) => self.record_class(db, class),
|
||||||
|
Type::EnumLiteral(literal) => self.record_class(db, literal.enum_class(db)),
|
||||||
|
Type::GenericAlias(alias) => self.record_class(db, alias.origin(db)),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let visitor::TypeKind::NonAtomic(t) = visitor::TypeKind::from(ty) {
|
||||||
|
if !self.visited_types.borrow_mut().insert(ty) {
|
||||||
|
// If we have already seen this type, we can skip it.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
visitor::walk_non_atomic_type(db, t, self);
|
||||||
}
|
}
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> Type<'db> {
|
impl<'db> Type<'db> {
|
||||||
pub fn display(&self, db: &'db dyn Db) -> DisplayType<'_> {
|
pub fn display(self, db: &'db dyn Db) -> DisplayType<'db> {
|
||||||
DisplayType {
|
DisplayType {
|
||||||
ty: self,
|
ty: self,
|
||||||
settings: DisplaySettings::default(),
|
settings: DisplaySettings::default(),
|
||||||
db,
|
db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn display_with(&self, db: &'db dyn Db, settings: DisplaySettings) -> DisplayType<'_> {
|
|
||||||
|
pub fn display_with(self, db: &'db dyn Db, settings: DisplaySettings<'db>) -> DisplayType<'db> {
|
||||||
DisplayType {
|
DisplayType {
|
||||||
ty: self,
|
ty: self,
|
||||||
db,
|
db,
|
||||||
settings,
|
settings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn representation(
|
fn representation(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayRepresentation<'db> {
|
) -> DisplayRepresentation<'db> {
|
||||||
DisplayRepresentation {
|
DisplayRepresentation {
|
||||||
db,
|
db,
|
||||||
|
@ -135,16 +171,15 @@ impl<'db> Type<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct DisplayType<'db> {
|
pub struct DisplayType<'db> {
|
||||||
ty: &'db Type<'db>,
|
ty: Type<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayType<'_> {
|
impl Display for DisplayType<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
let representation = self.ty.representation(self.db, self.settings);
|
let representation = self.ty.representation(self.db, self.settings.clone());
|
||||||
match self.ty {
|
match self.ty {
|
||||||
Type::IntLiteral(_)
|
Type::IntLiteral(_)
|
||||||
| Type::BooleanLiteral(_)
|
| Type::BooleanLiteral(_)
|
||||||
|
@ -165,7 +200,7 @@ impl fmt::Debug for DisplayType<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> ClassLiteral<'db> {
|
impl<'db> ClassLiteral<'db> {
|
||||||
fn display_with(self, db: &'db dyn Db, settings: DisplaySettings) -> ClassDisplay<'db> {
|
fn display_with(self, db: &'db dyn Db, settings: DisplaySettings<'db>) -> ClassDisplay<'db> {
|
||||||
ClassDisplay {
|
ClassDisplay {
|
||||||
db,
|
db,
|
||||||
class: self,
|
class: self,
|
||||||
|
@ -177,7 +212,7 @@ impl<'db> ClassLiteral<'db> {
|
||||||
struct ClassDisplay<'db> {
|
struct ClassDisplay<'db> {
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
class: ClassLiteral<'db>,
|
class: ClassLiteral<'db>,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClassDisplay<'_> {
|
impl ClassDisplay<'_> {
|
||||||
|
@ -224,7 +259,11 @@ impl ClassDisplay<'_> {
|
||||||
|
|
||||||
impl Display for ClassDisplay<'_> {
|
impl Display for ClassDisplay<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
if self.settings.qualified {
|
if self
|
||||||
|
.settings
|
||||||
|
.qualified
|
||||||
|
.contains(&**self.class.name(self.db))
|
||||||
|
{
|
||||||
for parent in self.class_parents() {
|
for parent in self.class_parents() {
|
||||||
f.write_str(&parent)?;
|
f.write_str(&parent)?;
|
||||||
f.write_char('.')?;
|
f.write_char('.')?;
|
||||||
|
@ -240,7 +279,7 @@ impl Display for ClassDisplay<'_> {
|
||||||
struct DisplayRepresentation<'db> {
|
struct DisplayRepresentation<'db> {
|
||||||
ty: Type<'db>,
|
ty: Type<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayRepresentation<'_> {
|
impl Display for DisplayRepresentation<'_> {
|
||||||
|
@ -258,20 +297,20 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
.specialization(self.db)
|
.specialization(self.db)
|
||||||
.tuple(self.db)
|
.tuple(self.db)
|
||||||
.expect("Specialization::tuple() should always return `Some()` for `KnownClass::Tuple`")
|
.expect("Specialization::tuple() should always return `Some()` for `KnownClass::Tuple`")
|
||||||
.display_with(self.db, self.settings)
|
.display_with(self.db, self.settings.clone())
|
||||||
.fmt(f),
|
.fmt(f),
|
||||||
(ClassType::NonGeneric(class), _) => {
|
(ClassType::NonGeneric(class), _) => {
|
||||||
class.display_with(self.db, self.settings).fmt(f)
|
class.display_with(self.db, self.settings.clone()).fmt(f)
|
||||||
},
|
},
|
||||||
(ClassType::Generic(alias), _) => alias.display_with(self.db, self.settings).fmt(f),
|
(ClassType::Generic(alias), _) => alias.display_with(self.db, self.settings.clone()).fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Type::ProtocolInstance(protocol) => match protocol.inner {
|
Type::ProtocolInstance(protocol) => match protocol.inner {
|
||||||
Protocol::FromClass(ClassType::NonGeneric(class)) => {
|
Protocol::FromClass(ClassType::NonGeneric(class)) => {
|
||||||
class.display_with(self.db, self.settings).fmt(f)
|
class.display_with(self.db, self.settings.clone()).fmt(f)
|
||||||
}
|
}
|
||||||
Protocol::FromClass(ClassType::Generic(alias)) => {
|
Protocol::FromClass(ClassType::Generic(alias)) => {
|
||||||
alias.display_with(self.db, self.settings).fmt(f)
|
alias.display_with(self.db, self.settings.clone()).fmt(f)
|
||||||
}
|
}
|
||||||
Protocol::Synthesized(synthetic) => {
|
Protocol::Synthesized(synthetic) => {
|
||||||
f.write_str("<Protocol with members ")?;
|
f.write_str("<Protocol with members ")?;
|
||||||
|
@ -295,7 +334,7 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
Type::ClassLiteral(class) => write!(
|
Type::ClassLiteral(class) => write!(
|
||||||
f,
|
f,
|
||||||
"<class '{}'>",
|
"<class '{}'>",
|
||||||
class.display_with(self.db, self.settings)
|
class.display_with(self.db, self.settings.clone())
|
||||||
),
|
),
|
||||||
Type::GenericAlias(generic) => write!(
|
Type::GenericAlias(generic) => write!(
|
||||||
f,
|
f,
|
||||||
|
@ -304,7 +343,11 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
),
|
),
|
||||||
Type::SubclassOf(subclass_of_ty) => match subclass_of_ty.subclass_of() {
|
Type::SubclassOf(subclass_of_ty) => match subclass_of_ty.subclass_of() {
|
||||||
SubclassOfInner::Class(ClassType::NonGeneric(class)) => {
|
SubclassOfInner::Class(ClassType::NonGeneric(class)) => {
|
||||||
write!(f, "type[{}]", class.display_with(self.db, self.settings))
|
write!(
|
||||||
|
f,
|
||||||
|
"type[{}]",
|
||||||
|
class.display_with(self.db, self.settings.clone())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
SubclassOfInner::Class(ClassType::Generic(alias)) => {
|
SubclassOfInner::Class(ClassType::Generic(alias)) => {
|
||||||
write!(
|
write!(
|
||||||
|
@ -317,8 +360,12 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
},
|
},
|
||||||
Type::SpecialForm(special_form) => special_form.fmt(f),
|
Type::SpecialForm(special_form) => special_form.fmt(f),
|
||||||
Type::KnownInstance(known_instance) => known_instance.repr(self.db).fmt(f),
|
Type::KnownInstance(known_instance) => known_instance.repr(self.db).fmt(f),
|
||||||
Type::FunctionLiteral(function) => function.display_with(self.db, self.settings).fmt(f),
|
Type::FunctionLiteral(function) => {
|
||||||
Type::Callable(callable) => callable.display_with(self.db, self.settings).fmt(f),
|
function.display_with(self.db, self.settings.clone()).fmt(f)
|
||||||
|
}
|
||||||
|
Type::Callable(callable) => {
|
||||||
|
callable.display_with(self.db, self.settings.clone()).fmt(f)
|
||||||
|
}
|
||||||
Type::BoundMethod(bound_method) => {
|
Type::BoundMethod(bound_method) => {
|
||||||
let function = bound_method.function(self.db);
|
let function = bound_method.function(self.db);
|
||||||
let self_ty = bound_method.self_instance(self.db);
|
let self_ty = bound_method.self_instance(self.db);
|
||||||
|
@ -329,7 +376,7 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
let type_parameters = DisplayOptionalGenericContext {
|
let type_parameters = DisplayOptionalGenericContext {
|
||||||
generic_context: signature.generic_context.as_ref(),
|
generic_context: signature.generic_context.as_ref(),
|
||||||
db: self.db,
|
db: self.db,
|
||||||
settings: self.settings,
|
settings: self.settings.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
|
@ -340,7 +387,7 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
type_parameters = type_parameters,
|
type_parameters = type_parameters,
|
||||||
signature = signature
|
signature = signature
|
||||||
.bind_self(self.db, Some(typing_self_ty))
|
.bind_self(self.db, Some(typing_self_ty))
|
||||||
.display_with(self.db, self.settings)
|
.display_with(self.db, self.settings.clone())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
signatures => {
|
signatures => {
|
||||||
|
@ -354,7 +401,7 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
join.entry(
|
join.entry(
|
||||||
&signature
|
&signature
|
||||||
.bind_self(self.db, Some(typing_self_ty))
|
.bind_self(self.db, Some(typing_self_ty))
|
||||||
.display_with(self.db, self.settings),
|
.display_with(self.db, self.settings.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if !self.settings.multiline {
|
if !self.settings.multiline {
|
||||||
|
@ -404,13 +451,15 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
Type::DataclassTransformer(_) => {
|
Type::DataclassTransformer(_) => {
|
||||||
f.write_str("<decorator produced by typing.dataclass_transform>")
|
f.write_str("<decorator produced by typing.dataclass_transform>")
|
||||||
}
|
}
|
||||||
Type::Union(union) => union.display_with(self.db, self.settings).fmt(f),
|
Type::Union(union) => union.display_with(self.db, self.settings.clone()).fmt(f),
|
||||||
Type::Intersection(intersection) => {
|
Type::Intersection(intersection) => intersection
|
||||||
intersection.display_with(self.db, self.settings).fmt(f)
|
.display_with(self.db, self.settings.clone())
|
||||||
}
|
.fmt(f),
|
||||||
Type::IntLiteral(n) => n.fmt(f),
|
Type::IntLiteral(n) => n.fmt(f),
|
||||||
Type::BooleanLiteral(boolean) => f.write_str(if boolean { "True" } else { "False" }),
|
Type::BooleanLiteral(boolean) => f.write_str(if boolean { "True" } else { "False" }),
|
||||||
Type::StringLiteral(string) => string.display_with(self.db, self.settings).fmt(f),
|
Type::StringLiteral(string) => {
|
||||||
|
string.display_with(self.db, self.settings.clone()).fmt(f)
|
||||||
|
}
|
||||||
Type::LiteralString => f.write_str("LiteralString"),
|
Type::LiteralString => f.write_str("LiteralString"),
|
||||||
Type::BytesLiteral(bytes) => {
|
Type::BytesLiteral(bytes) => {
|
||||||
let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db), Quote::Double);
|
let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db), Quote::Double);
|
||||||
|
@ -422,7 +471,7 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
"{enum_class}.{literal_name}",
|
"{enum_class}.{literal_name}",
|
||||||
enum_class = enum_literal
|
enum_class = enum_literal
|
||||||
.enum_class(self.db)
|
.enum_class(self.db)
|
||||||
.display_with(self.db, self.settings),
|
.display_with(self.db, self.settings.clone()),
|
||||||
literal_name = enum_literal.name(self.db)
|
literal_name = enum_literal.name(self.db)
|
||||||
),
|
),
|
||||||
Type::NonInferableTypeVar(bound_typevar) | Type::TypeVar(bound_typevar) => {
|
Type::NonInferableTypeVar(bound_typevar) | Type::TypeVar(bound_typevar) => {
|
||||||
|
@ -458,7 +507,7 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
.defining_class()
|
.defining_class()
|
||||||
.class_literal(self.db)
|
.class_literal(self.db)
|
||||||
.0
|
.0
|
||||||
.display_with(self.db, self.settings)
|
.display_with(self.db, self.settings.clone())
|
||||||
.fmt(f),
|
.fmt(f),
|
||||||
Type::TypeAlias(alias) => f.write_str(alias.name(self.db)),
|
Type::TypeAlias(alias) => f.write_str(alias.name(self.db)),
|
||||||
}
|
}
|
||||||
|
@ -493,7 +542,7 @@ impl<'db> TupleSpec<'db> {
|
||||||
pub(crate) fn display_with(
|
pub(crate) fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayTuple<'db> {
|
) -> DisplayTuple<'db> {
|
||||||
DisplayTuple {
|
DisplayTuple {
|
||||||
tuple: self,
|
tuple: self,
|
||||||
|
@ -506,7 +555,7 @@ impl<'db> TupleSpec<'db> {
|
||||||
pub(crate) struct DisplayTuple<'db> {
|
pub(crate) struct DisplayTuple<'db> {
|
||||||
tuple: &'db TupleSpec<'db>,
|
tuple: &'db TupleSpec<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayTuple<'_> {
|
impl Display for DisplayTuple<'_> {
|
||||||
|
@ -580,7 +629,7 @@ impl<'db> OverloadLiteral<'db> {
|
||||||
pub(crate) fn display_with(
|
pub(crate) fn display_with(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayOverloadLiteral<'db> {
|
) -> DisplayOverloadLiteral<'db> {
|
||||||
DisplayOverloadLiteral {
|
DisplayOverloadLiteral {
|
||||||
literal: self,
|
literal: self,
|
||||||
|
@ -593,7 +642,7 @@ impl<'db> OverloadLiteral<'db> {
|
||||||
pub(crate) struct DisplayOverloadLiteral<'db> {
|
pub(crate) struct DisplayOverloadLiteral<'db> {
|
||||||
literal: OverloadLiteral<'db>,
|
literal: OverloadLiteral<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayOverloadLiteral<'_> {
|
impl Display for DisplayOverloadLiteral<'_> {
|
||||||
|
@ -602,7 +651,7 @@ impl Display for DisplayOverloadLiteral<'_> {
|
||||||
let type_parameters = DisplayOptionalGenericContext {
|
let type_parameters = DisplayOptionalGenericContext {
|
||||||
generic_context: signature.generic_context.as_ref(),
|
generic_context: signature.generic_context.as_ref(),
|
||||||
db: self.db,
|
db: self.db,
|
||||||
settings: self.settings,
|
settings: self.settings.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
|
@ -610,7 +659,7 @@ impl Display for DisplayOverloadLiteral<'_> {
|
||||||
"def {name}{type_parameters}{signature}",
|
"def {name}{type_parameters}{signature}",
|
||||||
name = self.literal.name(self.db),
|
name = self.literal.name(self.db),
|
||||||
type_parameters = type_parameters,
|
type_parameters = type_parameters,
|
||||||
signature = signature.display_with(self.db, self.settings)
|
signature = signature.display_with(self.db, self.settings.clone())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,7 +668,7 @@ impl<'db> FunctionType<'db> {
|
||||||
pub(crate) fn display_with(
|
pub(crate) fn display_with(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayFunctionType<'db> {
|
) -> DisplayFunctionType<'db> {
|
||||||
DisplayFunctionType {
|
DisplayFunctionType {
|
||||||
ty: self,
|
ty: self,
|
||||||
|
@ -632,7 +681,7 @@ impl<'db> FunctionType<'db> {
|
||||||
pub(crate) struct DisplayFunctionType<'db> {
|
pub(crate) struct DisplayFunctionType<'db> {
|
||||||
ty: FunctionType<'db>,
|
ty: FunctionType<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayFunctionType<'_> {
|
impl Display for DisplayFunctionType<'_> {
|
||||||
|
@ -644,7 +693,7 @@ impl Display for DisplayFunctionType<'_> {
|
||||||
let type_parameters = DisplayOptionalGenericContext {
|
let type_parameters = DisplayOptionalGenericContext {
|
||||||
generic_context: signature.generic_context.as_ref(),
|
generic_context: signature.generic_context.as_ref(),
|
||||||
db: self.db,
|
db: self.db,
|
||||||
settings: self.settings,
|
settings: self.settings.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
|
@ -652,7 +701,7 @@ impl Display for DisplayFunctionType<'_> {
|
||||||
"def {name}{type_parameters}{signature}",
|
"def {name}{type_parameters}{signature}",
|
||||||
name = self.ty.name(self.db),
|
name = self.ty.name(self.db),
|
||||||
type_parameters = type_parameters,
|
type_parameters = type_parameters,
|
||||||
signature = signature.display_with(self.db, self.settings)
|
signature = signature.display_with(self.db, self.settings.clone())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
signatures => {
|
signatures => {
|
||||||
|
@ -663,7 +712,7 @@ impl Display for DisplayFunctionType<'_> {
|
||||||
let separator = if self.settings.multiline { "\n" } else { ", " };
|
let separator = if self.settings.multiline { "\n" } else { ", " };
|
||||||
let mut join = f.join(separator);
|
let mut join = f.join(separator);
|
||||||
for signature in signatures {
|
for signature in signatures {
|
||||||
join.entry(&signature.display_with(self.db, self.settings));
|
join.entry(&signature.display_with(self.db, self.settings.clone()));
|
||||||
}
|
}
|
||||||
if !self.settings.multiline {
|
if !self.settings.multiline {
|
||||||
f.write_str("]")?;
|
f.write_str("]")?;
|
||||||
|
@ -678,7 +727,7 @@ impl<'db> GenericAlias<'db> {
|
||||||
pub(crate) fn display_with(
|
pub(crate) fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayGenericAlias<'db> {
|
) -> DisplayGenericAlias<'db> {
|
||||||
DisplayGenericAlias {
|
DisplayGenericAlias {
|
||||||
origin: self.origin(db),
|
origin: self.origin(db),
|
||||||
|
@ -693,13 +742,13 @@ pub(crate) struct DisplayGenericAlias<'db> {
|
||||||
origin: ClassLiteral<'db>,
|
origin: ClassLiteral<'db>,
|
||||||
specialization: Specialization<'db>,
|
specialization: Specialization<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayGenericAlias<'_> {
|
impl Display for DisplayGenericAlias<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
if let Some(tuple) = self.specialization.tuple(self.db) {
|
if let Some(tuple) = self.specialization.tuple(self.db) {
|
||||||
tuple.display_with(self.db, self.settings).fmt(f)
|
tuple.display_with(self.db, self.settings.clone()).fmt(f)
|
||||||
} else {
|
} else {
|
||||||
let prefix = match self.specialization.materialization_kind(self.db) {
|
let prefix = match self.specialization.materialization_kind(self.db) {
|
||||||
None => "",
|
None => "",
|
||||||
|
@ -714,10 +763,11 @@ impl Display for DisplayGenericAlias<'_> {
|
||||||
f,
|
f,
|
||||||
"{prefix}{origin}{specialization}{suffix}",
|
"{prefix}{origin}{specialization}{suffix}",
|
||||||
prefix = prefix,
|
prefix = prefix,
|
||||||
origin = self.origin.display_with(self.db, self.settings),
|
origin = self.origin.display_with(self.db, self.settings.clone()),
|
||||||
specialization = self.specialization.display_short(
|
specialization = self.specialization.display_short(
|
||||||
self.db,
|
self.db,
|
||||||
TupleSpecialization::from_class(self.db, self.origin)
|
TupleSpecialization::from_class(self.db, self.origin),
|
||||||
|
self.settings.clone()
|
||||||
),
|
),
|
||||||
suffix = suffix,
|
suffix = suffix,
|
||||||
)
|
)
|
||||||
|
@ -732,7 +782,7 @@ impl<'db> GenericContext<'db> {
|
||||||
pub fn display_with(
|
pub fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayGenericContext<'db> {
|
) -> DisplayGenericContext<'db> {
|
||||||
DisplayGenericContext {
|
DisplayGenericContext {
|
||||||
generic_context: self,
|
generic_context: self,
|
||||||
|
@ -745,7 +795,7 @@ impl<'db> GenericContext<'db> {
|
||||||
struct DisplayOptionalGenericContext<'db> {
|
struct DisplayOptionalGenericContext<'db> {
|
||||||
generic_context: Option<&'db GenericContext<'db>>,
|
generic_context: Option<&'db GenericContext<'db>>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayOptionalGenericContext<'_> {
|
impl Display for DisplayOptionalGenericContext<'_> {
|
||||||
|
@ -754,7 +804,7 @@ impl Display for DisplayOptionalGenericContext<'_> {
|
||||||
DisplayGenericContext {
|
DisplayGenericContext {
|
||||||
generic_context,
|
generic_context,
|
||||||
db: self.db,
|
db: self.db,
|
||||||
settings: self.settings,
|
settings: self.settings.clone(),
|
||||||
}
|
}
|
||||||
.fmt(f)
|
.fmt(f)
|
||||||
} else {
|
} else {
|
||||||
|
@ -767,7 +817,7 @@ pub struct DisplayGenericContext<'db> {
|
||||||
generic_context: &'db GenericContext<'db>,
|
generic_context: &'db GenericContext<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
#[expect(dead_code)]
|
#[expect(dead_code)]
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayGenericContext<'_> {
|
impl Display for DisplayGenericContext<'_> {
|
||||||
|
@ -800,12 +850,13 @@ impl<'db> Specialization<'db> {
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
tuple_specialization: TupleSpecialization,
|
tuple_specialization: TupleSpecialization,
|
||||||
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplaySpecialization<'db> {
|
) -> DisplaySpecialization<'db> {
|
||||||
DisplaySpecialization {
|
DisplaySpecialization {
|
||||||
types: self.types(db),
|
types: self.types(db),
|
||||||
db,
|
db,
|
||||||
tuple_specialization,
|
tuple_specialization,
|
||||||
settings: DisplaySettings::default(),
|
settings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -814,7 +865,7 @@ pub struct DisplaySpecialization<'db> {
|
||||||
types: &'db [Type<'db>],
|
types: &'db [Type<'db>],
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
tuple_specialization: TupleSpecialization,
|
tuple_specialization: TupleSpecialization,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplaySpecialization<'_> {
|
impl Display for DisplaySpecialization<'_> {
|
||||||
|
@ -824,7 +875,7 @@ impl Display for DisplaySpecialization<'_> {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
f.write_str(", ")?;
|
f.write_str(", ")?;
|
||||||
}
|
}
|
||||||
ty.display_with(self.db, self.settings).fmt(f)?;
|
ty.display_with(self.db, self.settings.clone()).fmt(f)?;
|
||||||
}
|
}
|
||||||
if self.tuple_specialization.is_yes() {
|
if self.tuple_specialization.is_yes() {
|
||||||
f.write_str(", ...")?;
|
f.write_str(", ...")?;
|
||||||
|
@ -861,7 +912,7 @@ impl<'db> CallableType<'db> {
|
||||||
pub(crate) fn display_with(
|
pub(crate) fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayCallableType<'db> {
|
) -> DisplayCallableType<'db> {
|
||||||
DisplayCallableType {
|
DisplayCallableType {
|
||||||
signatures: self.signatures(db),
|
signatures: self.signatures(db),
|
||||||
|
@ -874,13 +925,15 @@ impl<'db> CallableType<'db> {
|
||||||
pub(crate) struct DisplayCallableType<'db> {
|
pub(crate) struct DisplayCallableType<'db> {
|
||||||
signatures: &'db CallableSignature<'db>,
|
signatures: &'db CallableSignature<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayCallableType<'_> {
|
impl Display for DisplayCallableType<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
match self.signatures.overloads.as_slice() {
|
match self.signatures.overloads.as_slice() {
|
||||||
[signature] => signature.display_with(self.db, self.settings).fmt(f),
|
[signature] => signature
|
||||||
|
.display_with(self.db, self.settings.clone())
|
||||||
|
.fmt(f),
|
||||||
signatures => {
|
signatures => {
|
||||||
// TODO: How to display overloads?
|
// TODO: How to display overloads?
|
||||||
if !self.settings.multiline {
|
if !self.settings.multiline {
|
||||||
|
@ -889,7 +942,7 @@ impl Display for DisplayCallableType<'_> {
|
||||||
let separator = if self.settings.multiline { "\n" } else { ", " };
|
let separator = if self.settings.multiline { "\n" } else { ", " };
|
||||||
let mut join = f.join(separator);
|
let mut join = f.join(separator);
|
||||||
for signature in signatures {
|
for signature in signatures {
|
||||||
join.entry(&signature.display_with(self.db, self.settings));
|
join.entry(&signature.display_with(self.db, self.settings.clone()));
|
||||||
}
|
}
|
||||||
join.finish()?;
|
join.finish()?;
|
||||||
if !self.settings.multiline {
|
if !self.settings.multiline {
|
||||||
|
@ -909,7 +962,7 @@ impl<'db> Signature<'db> {
|
||||||
pub(crate) fn display_with(
|
pub(crate) fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplaySignature<'db> {
|
) -> DisplaySignature<'db> {
|
||||||
DisplaySignature {
|
DisplaySignature {
|
||||||
parameters: self.parameters(),
|
parameters: self.parameters(),
|
||||||
|
@ -924,7 +977,7 @@ pub(crate) struct DisplaySignature<'db> {
|
||||||
parameters: &'db Parameters<'db>,
|
parameters: &'db Parameters<'db>,
|
||||||
return_ty: Option<Type<'db>>,
|
return_ty: Option<Type<'db>>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisplaySignature<'_> {
|
impl DisplaySignature<'_> {
|
||||||
|
@ -1128,7 +1181,7 @@ impl<'db> Parameter<'db> {
|
||||||
fn display_with(
|
fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayParameter<'db> {
|
) -> DisplayParameter<'db> {
|
||||||
DisplayParameter {
|
DisplayParameter {
|
||||||
param: self,
|
param: self,
|
||||||
|
@ -1141,7 +1194,7 @@ impl<'db> Parameter<'db> {
|
||||||
struct DisplayParameter<'db> {
|
struct DisplayParameter<'db> {
|
||||||
param: &'db Parameter<'db>,
|
param: &'db Parameter<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayParameter<'_> {
|
impl Display for DisplayParameter<'_> {
|
||||||
|
@ -1152,21 +1205,29 @@ impl Display for DisplayParameter<'_> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
": {}",
|
": {}",
|
||||||
annotated_type.display_with(self.db, self.settings)
|
annotated_type.display_with(self.db, self.settings.clone())
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
// Default value can only be specified if `name` is given.
|
// Default value can only be specified if `name` is given.
|
||||||
if let Some(default_ty) = self.param.default_type() {
|
if let Some(default_ty) = self.param.default_type() {
|
||||||
if self.param.annotated_type().is_some() {
|
if self.param.annotated_type().is_some() {
|
||||||
write!(f, " = {}", default_ty.display_with(self.db, self.settings))?;
|
write!(
|
||||||
|
f,
|
||||||
|
" = {}",
|
||||||
|
default_ty.display_with(self.db, self.settings.clone())
|
||||||
|
)?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "={}", default_ty.display_with(self.db, self.settings))?;
|
write!(
|
||||||
|
f,
|
||||||
|
"={}",
|
||||||
|
default_ty.display_with(self.db, self.settings.clone())
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(ty) = self.param.annotated_type() {
|
} else if let Some(ty) = self.param.annotated_type() {
|
||||||
// This case is specifically for the `Callable` signature where name and default value
|
// This case is specifically for the `Callable` signature where name and default value
|
||||||
// cannot be provided.
|
// cannot be provided.
|
||||||
ty.display_with(self.db, self.settings).fmt(f)?;
|
ty.display_with(self.db, self.settings.clone()).fmt(f)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1237,7 @@ impl<'db> UnionType<'db> {
|
||||||
fn display_with(
|
fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayUnionType<'db> {
|
) -> DisplayUnionType<'db> {
|
||||||
DisplayUnionType {
|
DisplayUnionType {
|
||||||
db,
|
db,
|
||||||
|
@ -1189,7 +1250,7 @@ impl<'db> UnionType<'db> {
|
||||||
struct DisplayUnionType<'db> {
|
struct DisplayUnionType<'db> {
|
||||||
ty: &'db UnionType<'db>,
|
ty: &'db UnionType<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayUnionType<'_> {
|
impl Display for DisplayUnionType<'_> {
|
||||||
|
@ -1249,7 +1310,7 @@ impl fmt::Debug for DisplayUnionType<'_> {
|
||||||
struct DisplayLiteralGroup<'db> {
|
struct DisplayLiteralGroup<'db> {
|
||||||
literals: Vec<Type<'db>>,
|
literals: Vec<Type<'db>>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayLiteralGroup<'_> {
|
impl Display for DisplayLiteralGroup<'_> {
|
||||||
|
@ -1270,7 +1331,7 @@ impl<'db> IntersectionType<'db> {
|
||||||
fn display_with(
|
fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayIntersectionType<'db> {
|
) -> DisplayIntersectionType<'db> {
|
||||||
DisplayIntersectionType {
|
DisplayIntersectionType {
|
||||||
db,
|
db,
|
||||||
|
@ -1283,7 +1344,7 @@ impl<'db> IntersectionType<'db> {
|
||||||
struct DisplayIntersectionType<'db> {
|
struct DisplayIntersectionType<'db> {
|
||||||
ty: &'db IntersectionType<'db>,
|
ty: &'db IntersectionType<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayIntersectionType<'_> {
|
impl Display for DisplayIntersectionType<'_> {
|
||||||
|
@ -1323,7 +1384,7 @@ struct DisplayMaybeNegatedType<'db> {
|
||||||
ty: Type<'db>,
|
ty: Type<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
negated: bool,
|
negated: bool,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayMaybeNegatedType<'_> {
|
impl Display for DisplayMaybeNegatedType<'_> {
|
||||||
|
@ -1334,7 +1395,7 @@ impl Display for DisplayMaybeNegatedType<'_> {
|
||||||
DisplayMaybeParenthesizedType {
|
DisplayMaybeParenthesizedType {
|
||||||
ty: self.ty,
|
ty: self.ty,
|
||||||
db: self.db,
|
db: self.db,
|
||||||
settings: self.settings,
|
settings: self.settings.clone(),
|
||||||
}
|
}
|
||||||
.fmt(f)
|
.fmt(f)
|
||||||
}
|
}
|
||||||
|
@ -1343,13 +1404,18 @@ impl Display for DisplayMaybeNegatedType<'_> {
|
||||||
struct DisplayMaybeParenthesizedType<'db> {
|
struct DisplayMaybeParenthesizedType<'db> {
|
||||||
ty: Type<'db>,
|
ty: Type<'db>,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayMaybeParenthesizedType<'_> {
|
impl Display for DisplayMaybeParenthesizedType<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
let write_parentheses =
|
let write_parentheses = |f: &mut Formatter<'_>| {
|
||||||
|f: &mut Formatter<'_>| write!(f, "({})", self.ty.display_with(self.db, self.settings));
|
write!(
|
||||||
|
f,
|
||||||
|
"({})",
|
||||||
|
self.ty.display_with(self.db, self.settings.clone())
|
||||||
|
)
|
||||||
|
};
|
||||||
match self.ty {
|
match self.ty {
|
||||||
Type::Callable(_)
|
Type::Callable(_)
|
||||||
| Type::KnownBoundMethod(_)
|
| Type::KnownBoundMethod(_)
|
||||||
|
@ -1359,21 +1425,24 @@ impl Display for DisplayMaybeParenthesizedType<'_> {
|
||||||
Type::Intersection(intersection) if !intersection.has_one_element(self.db) => {
|
Type::Intersection(intersection) if !intersection.has_one_element(self.db) => {
|
||||||
write_parentheses(f)
|
write_parentheses(f)
|
||||||
}
|
}
|
||||||
_ => self.ty.display_with(self.db, self.settings).fmt(f),
|
_ => self.ty.display_with(self.db, self.settings.clone()).fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait TypeArrayDisplay<'db> {
|
pub(crate) trait TypeArrayDisplay<'db> {
|
||||||
fn display_with(&self, db: &'db dyn Db, settings: DisplaySettings)
|
fn display_with(
|
||||||
-> DisplayTypeArray<'_, 'db>;
|
&self,
|
||||||
|
db: &'db dyn Db,
|
||||||
|
settings: DisplaySettings<'db>,
|
||||||
|
) -> DisplayTypeArray<'_, 'db>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> TypeArrayDisplay<'db> for Box<[Type<'db>]> {
|
impl<'db> TypeArrayDisplay<'db> for Box<[Type<'db>]> {
|
||||||
fn display_with(
|
fn display_with(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayTypeArray<'_, 'db> {
|
) -> DisplayTypeArray<'_, 'db> {
|
||||||
DisplayTypeArray {
|
DisplayTypeArray {
|
||||||
types: self,
|
types: self,
|
||||||
|
@ -1387,7 +1456,7 @@ impl<'db> TypeArrayDisplay<'db> for Vec<Type<'db>> {
|
||||||
fn display_with(
|
fn display_with(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayTypeArray<'_, 'db> {
|
) -> DisplayTypeArray<'_, 'db> {
|
||||||
DisplayTypeArray {
|
DisplayTypeArray {
|
||||||
types: self,
|
types: self,
|
||||||
|
@ -1401,7 +1470,7 @@ impl<'db> TypeArrayDisplay<'db> for [Type<'db>] {
|
||||||
fn display_with(
|
fn display_with(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayTypeArray<'_, 'db> {
|
) -> DisplayTypeArray<'_, 'db> {
|
||||||
DisplayTypeArray {
|
DisplayTypeArray {
|
||||||
types: self,
|
types: self,
|
||||||
|
@ -1414,7 +1483,7 @@ impl<'db> TypeArrayDisplay<'db> for [Type<'db>] {
|
||||||
pub(crate) struct DisplayTypeArray<'b, 'db> {
|
pub(crate) struct DisplayTypeArray<'b, 'db> {
|
||||||
types: &'b [Type<'db>],
|
types: &'b [Type<'db>],
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayTypeArray<'_, '_> {
|
impl Display for DisplayTypeArray<'_, '_> {
|
||||||
|
@ -1433,20 +1502,19 @@ impl<'db> StringLiteralType<'db> {
|
||||||
fn display_with(
|
fn display_with(
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
) -> DisplayStringLiteralType<'db> {
|
) -> DisplayStringLiteralType<'db> {
|
||||||
display_quoted_string(self.value(db), settings)
|
DisplayStringLiteralType {
|
||||||
|
string: self.value(db),
|
||||||
|
settings,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_quoted_string(string: &str, settings: DisplaySettings) -> DisplayStringLiteralType<'_> {
|
|
||||||
DisplayStringLiteralType { string, settings }
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DisplayStringLiteralType<'db> {
|
struct DisplayStringLiteralType<'db> {
|
||||||
string: &'db str,
|
string: &'db str,
|
||||||
#[expect(dead_code)]
|
#[expect(dead_code)]
|
||||||
settings: DisplaySettings,
|
settings: DisplaySettings<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayStringLiteralType<'_> {
|
impl Display for DisplayStringLiteralType<'_> {
|
||||||
|
|
|
@ -107,7 +107,7 @@ pub(crate) trait TypeVisitor<'db> {
|
||||||
|
|
||||||
/// Enumeration of types that may contain other types, such as unions, intersections, and generics.
|
/// Enumeration of types that may contain other types, such as unions, intersections, and generics.
|
||||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
||||||
enum NonAtomicType<'db> {
|
pub(super) enum NonAtomicType<'db> {
|
||||||
Union(UnionType<'db>),
|
Union(UnionType<'db>),
|
||||||
Intersection(IntersectionType<'db>),
|
Intersection(IntersectionType<'db>),
|
||||||
FunctionLiteral(FunctionType<'db>),
|
FunctionLiteral(FunctionType<'db>),
|
||||||
|
@ -128,7 +128,7 @@ enum NonAtomicType<'db> {
|
||||||
TypeAlias(TypeAliasType<'db>),
|
TypeAlias(TypeAliasType<'db>),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TypeKind<'db> {
|
pub(super) enum TypeKind<'db> {
|
||||||
Atomic,
|
Atomic,
|
||||||
NonAtomic(NonAtomicType<'db>),
|
NonAtomic(NonAtomicType<'db>),
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ impl<'db> From<Type<'db>> for TypeKind<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_non_atomic_type<'db, V: TypeVisitor<'db> + ?Sized>(
|
pub(super) fn walk_non_atomic_type<'db, V: TypeVisitor<'db> + ?Sized>(
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
non_atomic_type: NonAtomicType<'db>,
|
non_atomic_type: NonAtomicType<'db>,
|
||||||
visitor: &V,
|
visitor: &V,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue