mirror of https://github.com/astral-sh/ruff
[ty] Add `with_type` convenience to display code (#21563)
Code is much more readable.
This commit is contained in:
parent
629258241f
commit
a9b3caf181
|
|
@ -190,6 +190,11 @@ impl<'a, 'b, 'db> TypeWriter<'a, 'b, 'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convenience for `with_detail(TypeDetail::Type(ty))`
|
||||||
|
fn with_type<'c>(&'c mut self, ty: Type<'db>) -> TypeDetailGuard<'a, 'b, 'c, 'db> {
|
||||||
|
self.with_detail(TypeDetail::Type(ty))
|
||||||
|
}
|
||||||
|
|
||||||
fn join<'c>(&'c mut self, separator: &'static str) -> Join<'a, 'b, 'c, 'db> {
|
fn join<'c>(&'c mut self, separator: &'static str) -> Join<'a, 'b, 'c, 'db> {
|
||||||
Join {
|
Join {
|
||||||
fmt: self,
|
fmt: self,
|
||||||
|
|
@ -469,10 +474,8 @@ impl<'db> FmtDetailed<'db> for DisplayType<'db> {
|
||||||
| Type::StringLiteral(_)
|
| Type::StringLiteral(_)
|
||||||
| Type::BytesLiteral(_)
|
| Type::BytesLiteral(_)
|
||||||
| Type::EnumLiteral(_) => {
|
| Type::EnumLiteral(_) => {
|
||||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(
|
f.with_type(Type::SpecialForm(SpecialFormType::Literal))
|
||||||
SpecialFormType::Literal,
|
.write_str("Literal")?;
|
||||||
)))
|
|
||||||
.write_str("Literal")?;
|
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
representation.fmt_detailed(f)?;
|
representation.fmt_detailed(f)?;
|
||||||
f.write_str("]")
|
f.write_str("]")
|
||||||
|
|
@ -565,7 +568,7 @@ impl<'db> FmtDetailed<'db> for ClassDisplay<'db> {
|
||||||
f.write_char('.')?;
|
f.write_char('.')?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.with_detail(TypeDetail::Type(Type::ClassLiteral(self.class)))
|
f.with_type(Type::ClassLiteral(self.class))
|
||||||
.write_str(self.class.name(self.db))?;
|
.write_str(self.class.name(self.db))?;
|
||||||
if qualification_level == Some(&QualificationLevel::FileAndLineNumber) {
|
if qualification_level == Some(&QualificationLevel::FileAndLineNumber) {
|
||||||
let file = self.class.file(self.db);
|
let file = self.class.file(self.db);
|
||||||
|
|
@ -611,14 +614,14 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
||||||
match self.ty {
|
match self.ty {
|
||||||
Type::Dynamic(dynamic) => write!(f.with_detail(TypeDetail::Type(self.ty)), "{dynamic}"),
|
Type::Dynamic(dynamic) => write!(f.with_type(self.ty), "{dynamic}"),
|
||||||
Type::Never => f.with_detail(TypeDetail::Type(self.ty)).write_str("Never"),
|
Type::Never => f.with_type(self.ty).write_str("Never"),
|
||||||
Type::NominalInstance(instance) => {
|
Type::NominalInstance(instance) => {
|
||||||
let class = instance.class(self.db);
|
let class = instance.class(self.db);
|
||||||
|
|
||||||
match (class, class.known(self.db)) {
|
match (class, class.known(self.db)) {
|
||||||
(_, Some(KnownClass::NoneType)) => f.with_detail(TypeDetail::Type(self.ty)).write_str("None"),
|
(_, Some(KnownClass::NoneType)) => f.with_type(self.ty).write_str("None"),
|
||||||
(_, Some(KnownClass::NoDefaultType)) => f.with_detail(TypeDetail::Type(self.ty)).write_str("NoDefault"),
|
(_, Some(KnownClass::NoDefaultType)) => f.with_type(self.ty).write_str("NoDefault"),
|
||||||
(ClassType::Generic(alias), Some(KnownClass::Tuple)) => alias
|
(ClassType::Generic(alias), Some(KnownClass::Tuple)) => alias
|
||||||
.specialization(self.db)
|
.specialization(self.db)
|
||||||
.tuple(self.db)
|
.tuple(self.db)
|
||||||
|
|
@ -642,10 +645,8 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
},
|
},
|
||||||
Protocol::Synthesized(synthetic) => {
|
Protocol::Synthesized(synthetic) => {
|
||||||
f.write_char('<')?;
|
f.write_char('<')?;
|
||||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(
|
f.with_type(Type::SpecialForm(SpecialFormType::Protocol))
|
||||||
SpecialFormType::Protocol,
|
.write_str("Protocol")?;
|
||||||
)))
|
|
||||||
.write_str("Protocol")?;
|
|
||||||
f.write_str(" with members ")?;
|
f.write_str(" with members ")?;
|
||||||
let interface = synthetic.interface();
|
let interface = synthetic.interface();
|
||||||
let member_list = interface.members(self.db);
|
let member_list = interface.members(self.db);
|
||||||
|
|
@ -660,18 +661,16 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
f.write_char('>')
|
f.write_char('>')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Type::PropertyInstance(_) => f
|
Type::PropertyInstance(_) => f.with_type(self.ty).write_str("property"),
|
||||||
.with_detail(TypeDetail::Type(self.ty))
|
|
||||||
.write_str("property"),
|
|
||||||
Type::ModuleLiteral(module) => {
|
Type::ModuleLiteral(module) => {
|
||||||
write!(
|
write!(
|
||||||
f.with_detail(TypeDetail::Type(self.ty)),
|
f.with_type(self.ty),
|
||||||
"<module '{}'>",
|
"<module '{}'>",
|
||||||
module.module(self.db).name(self.db)
|
module.module(self.db).name(self.db)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Type::ClassLiteral(class) => {
|
Type::ClassLiteral(class) => {
|
||||||
let mut f = f.with_detail(TypeDetail::Type(self.ty));
|
let mut f = f.with_type(self.ty);
|
||||||
f.write_str("<class '")?;
|
f.write_str("<class '")?;
|
||||||
class
|
class
|
||||||
.display_with(self.db, self.settings.clone())
|
.display_with(self.db, self.settings.clone())
|
||||||
|
|
@ -679,7 +678,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
f.write_str("'>")
|
f.write_str("'>")
|
||||||
}
|
}
|
||||||
Type::GenericAlias(generic) => {
|
Type::GenericAlias(generic) => {
|
||||||
let mut f = f.with_detail(TypeDetail::Type(self.ty));
|
let mut f = f.with_type(self.ty);
|
||||||
f.write_str("<class '")?;
|
f.write_str("<class '")?;
|
||||||
generic
|
generic
|
||||||
.display_with(self.db, self.settings.clone())
|
.display_with(self.db, self.settings.clone())
|
||||||
|
|
@ -688,7 +687,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
}
|
}
|
||||||
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)) => {
|
||||||
f.with_detail(TypeDetail::Type(KnownClass::Type.to_class_literal(self.db)))
|
f.with_type(KnownClass::Type.to_class_literal(self.db))
|
||||||
.write_str("type")?;
|
.write_str("type")?;
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
class
|
class
|
||||||
|
|
@ -697,7 +696,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
f.write_char(']')
|
f.write_char(']')
|
||||||
}
|
}
|
||||||
SubclassOfInner::Class(ClassType::Generic(alias)) => {
|
SubclassOfInner::Class(ClassType::Generic(alias)) => {
|
||||||
f.with_detail(TypeDetail::Type(KnownClass::Type.to_class_literal(self.db)))
|
f.with_type(KnownClass::Type.to_class_literal(self.db))
|
||||||
.write_str("type")?;
|
.write_str("type")?;
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
alias
|
alias
|
||||||
|
|
@ -706,24 +705,19 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
f.write_char(']')
|
f.write_char(']')
|
||||||
}
|
}
|
||||||
SubclassOfInner::Dynamic(dynamic) => {
|
SubclassOfInner::Dynamic(dynamic) => {
|
||||||
f.with_detail(TypeDetail::Type(KnownClass::Type.to_class_literal(self.db)))
|
f.with_type(KnownClass::Type.to_class_literal(self.db))
|
||||||
.write_str("type")?;
|
.write_str("type")?;
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
write!(
|
write!(f.with_type(Type::Dynamic(dynamic)), "{dynamic}")?;
|
||||||
f.with_detail(TypeDetail::Type(Type::Dynamic(dynamic))),
|
|
||||||
"{dynamic}"
|
|
||||||
)?;
|
|
||||||
f.write_char(']')
|
f.write_char(']')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Type::SpecialForm(special_form) => {
|
Type::SpecialForm(special_form) => {
|
||||||
write!(f.with_detail(TypeDetail::Type(self.ty)), "{special_form}")
|
write!(f.with_type(self.ty), "{special_form}")
|
||||||
|
}
|
||||||
|
Type::KnownInstance(known_instance) => {
|
||||||
|
write!(f.with_type(self.ty), "{}", known_instance.repr(self.db))
|
||||||
}
|
}
|
||||||
Type::KnownInstance(known_instance) => write!(
|
|
||||||
f.with_detail(TypeDetail::Type(self.ty)),
|
|
||||||
"{}",
|
|
||||||
known_instance.repr(self.db)
|
|
||||||
),
|
|
||||||
Type::FunctionLiteral(function) => function
|
Type::FunctionLiteral(function) => function
|
||||||
.display_with(self.db, self.settings.clone())
|
.display_with(self.db, self.settings.clone())
|
||||||
.fmt_detailed(f),
|
.fmt_detailed(f),
|
||||||
|
|
@ -748,8 +742,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
.display_with(self.db, self.settings.singleline())
|
.display_with(self.db, self.settings.singleline())
|
||||||
.fmt_detailed(f)?;
|
.fmt_detailed(f)?;
|
||||||
f.write_char('.')?;
|
f.write_char('.')?;
|
||||||
f.with_detail(TypeDetail::Type(self.ty))
|
f.with_type(self.ty).write_str(function.name(self.db))?;
|
||||||
.write_str(function.name(self.db))?;
|
|
||||||
type_parameters.fmt_detailed(f)?;
|
type_parameters.fmt_detailed(f)?;
|
||||||
signature
|
signature
|
||||||
.bind_self(self.db, Some(typing_self_ty))
|
.bind_self(self.db, Some(typing_self_ty))
|
||||||
|
|
@ -845,13 +838,14 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
Type::Intersection(intersection) => intersection
|
Type::Intersection(intersection) => intersection
|
||||||
.display_with(self.db, self.settings.clone())
|
.display_with(self.db, self.settings.clone())
|
||||||
.fmt_detailed(f),
|
.fmt_detailed(f),
|
||||||
Type::IntLiteral(n) => write!(f.with_detail(TypeDetail::Type(self.ty)), "{n}"),
|
Type::IntLiteral(n) => write!(f.with_type(self.ty), "{n}"),
|
||||||
Type::BooleanLiteral(boolean) => f
|
Type::BooleanLiteral(boolean) => {
|
||||||
.with_detail(TypeDetail::Type(self.ty))
|
f.with_type(self.ty)
|
||||||
.write_str(if boolean { "True" } else { "False" }),
|
.write_str(if boolean { "True" } else { "False" })
|
||||||
|
}
|
||||||
Type::StringLiteral(string) => {
|
Type::StringLiteral(string) => {
|
||||||
write!(
|
write!(
|
||||||
f.with_detail(TypeDetail::Type(self.ty)),
|
f.with_type(self.ty),
|
||||||
"{}",
|
"{}",
|
||||||
string.display_with(self.db, self.settings.clone())
|
string.display_with(self.db, self.settings.clone())
|
||||||
)
|
)
|
||||||
|
|
@ -861,14 +855,12 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
// inlay hint, but that seems less useful than the definition of `str` for a variable that is
|
// inlay hint, but that seems less useful than the definition of `str` for a variable that is
|
||||||
// inferred as an *inhabitant* of `LiteralString` (since that variable will just be a string
|
// inferred as an *inhabitant* of `LiteralString` (since that variable will just be a string
|
||||||
// at runtime)
|
// at runtime)
|
||||||
Type::LiteralString => f
|
Type::LiteralString => f.with_type(self.ty).write_str("LiteralString"),
|
||||||
.with_detail(TypeDetail::Type(self.ty))
|
|
||||||
.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);
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
f.with_detail(TypeDetail::Type(self.ty)),
|
f.with_type(self.ty),
|
||||||
"{}",
|
"{}",
|
||||||
escape.bytes_repr(TripleQuotes::No)
|
escape.bytes_repr(TripleQuotes::No)
|
||||||
)
|
)
|
||||||
|
|
@ -883,12 +875,8 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
Type::TypeVar(bound_typevar) => {
|
Type::TypeVar(bound_typevar) => {
|
||||||
write!(f, "{}", bound_typevar.identity(self.db).display(self.db))
|
write!(f, "{}", bound_typevar.identity(self.db).display(self.db))
|
||||||
}
|
}
|
||||||
Type::AlwaysTruthy => f
|
Type::AlwaysTruthy => f.with_type(self.ty).write_str("AlwaysTruthy"),
|
||||||
.with_detail(TypeDetail::Type(self.ty))
|
Type::AlwaysFalsy => f.with_type(self.ty).write_str("AlwaysFalsy"),
|
||||||
.write_str("AlwaysTruthy"),
|
|
||||||
Type::AlwaysFalsy => f
|
|
||||||
.with_detail(TypeDetail::Type(self.ty))
|
|
||||||
.write_str("AlwaysFalsy"),
|
|
||||||
Type::BoundSuper(bound_super) => {
|
Type::BoundSuper(bound_super) => {
|
||||||
f.write_str("<super: ")?;
|
f.write_str("<super: ")?;
|
||||||
Type::from(bound_super.pivot_class(self.db))
|
Type::from(bound_super.pivot_class(self.db))
|
||||||
|
|
@ -901,7 +889,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
f.write_str(">")
|
f.write_str(">")
|
||||||
}
|
}
|
||||||
Type::TypeIs(type_is) => {
|
Type::TypeIs(type_is) => {
|
||||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(SpecialFormType::TypeIs)))
|
f.with_type(Type::SpecialForm(SpecialFormType::TypeIs))
|
||||||
.write_str("TypeIs")?;
|
.write_str("TypeIs")?;
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
type_is
|
type_is
|
||||||
|
|
@ -929,9 +917,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
.fmt_detailed(f),
|
.fmt_detailed(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Type::NewTypeInstance(newtype) => f
|
Type::NewTypeInstance(newtype) => f.with_type(self.ty).write_str(newtype.name(self.db)),
|
||||||
.with_detail(TypeDetail::Type(self.ty))
|
|
||||||
.write_str(newtype.name(self.db)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -982,10 +968,8 @@ pub(crate) struct DisplayTuple<'a, 'db> {
|
||||||
|
|
||||||
impl<'db> FmtDetailed<'db> for DisplayTuple<'_, 'db> {
|
impl<'db> FmtDetailed<'db> for DisplayTuple<'_, 'db> {
|
||||||
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
||||||
f.with_detail(TypeDetail::Type(
|
f.with_type(KnownClass::Tuple.to_class_literal(self.db))
|
||||||
KnownClass::Tuple.to_class_literal(self.db),
|
.write_str("tuple")?;
|
||||||
))
|
|
||||||
.write_str("tuple")?;
|
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
match self.tuple {
|
match self.tuple {
|
||||||
TupleSpec::Fixed(tuple) => {
|
TupleSpec::Fixed(tuple) => {
|
||||||
|
|
@ -1024,10 +1008,8 @@ impl<'db> FmtDetailed<'db> for DisplayTuple<'_, 'db> {
|
||||||
if !tuple.prefix.is_empty() || !tuple.suffix.is_empty() {
|
if !tuple.prefix.is_empty() || !tuple.suffix.is_empty() {
|
||||||
f.write_char('*')?;
|
f.write_char('*')?;
|
||||||
// Might as well link the type again here too
|
// Might as well link the type again here too
|
||||||
f.with_detail(TypeDetail::Type(
|
f.with_type(KnownClass::Tuple.to_class_literal(self.db))
|
||||||
KnownClass::Tuple.to_class_literal(self.db),
|
.write_str("tuple")?;
|
||||||
))
|
|
||||||
.write_str("tuple")?;
|
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
}
|
}
|
||||||
tuple
|
tuple
|
||||||
|
|
@ -1218,8 +1200,7 @@ impl<'db> FmtDetailed<'db> for DisplayGenericAlias<'db> {
|
||||||
Some(_) => "]",
|
Some(_) => "]",
|
||||||
};
|
};
|
||||||
if let Some((name, form)) = prefix_details {
|
if let Some((name, form)) = prefix_details {
|
||||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(form)))
|
f.with_type(Type::SpecialForm(form)).write_str(name)?;
|
||||||
.write_str(name)?;
|
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
}
|
}
|
||||||
self.origin
|
self.origin
|
||||||
|
|
@ -1890,10 +1871,8 @@ const LITERAL_POLICY: TruncationPolicy = TruncationPolicy {
|
||||||
|
|
||||||
impl<'db> FmtDetailed<'db> for DisplayLiteralGroup<'db> {
|
impl<'db> FmtDetailed<'db> for DisplayLiteralGroup<'db> {
|
||||||
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
||||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(
|
f.with_type(Type::SpecialForm(SpecialFormType::Literal))
|
||||||
SpecialFormType::Literal,
|
.write_str("Literal")?;
|
||||||
)))
|
|
||||||
.write_str("Literal")?;
|
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
|
|
||||||
let total_entries = self.literals.len();
|
let total_entries = self.literals.len();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue