Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 46 additions & 67 deletions crates/ty_python_semantic/src/types/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Join {
fmt: self,
Expand Down Expand Up @@ -469,10 +474,8 @@ impl<'db> FmtDetailed<'db> for DisplayType<'db> {
| Type::StringLiteral(_)
| Type::BytesLiteral(_)
| Type::EnumLiteral(_) => {
f.with_detail(TypeDetail::Type(Type::SpecialForm(
SpecialFormType::Literal,
)))
.write_str("Literal")?;
f.with_type(Type::SpecialForm(SpecialFormType::Literal))
.write_str("Literal")?;
f.write_char('[')?;
representation.fmt_detailed(f)?;
f.write_str("]")
Expand Down Expand Up @@ -565,7 +568,7 @@ impl<'db> FmtDetailed<'db> for ClassDisplay<'db> {
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))?;
if qualification_level == Some(&QualificationLevel::FileAndLineNumber) {
let file = self.class.file(self.db);
Expand Down Expand Up @@ -611,14 +614,14 @@ impl Display for DisplayRepresentation<'_> {
impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
match self.ty {
Type::Dynamic(dynamic) => write!(f.with_detail(TypeDetail::Type(self.ty)), "{dynamic}"),
Type::Never => f.with_detail(TypeDetail::Type(self.ty)).write_str("Never"),
Type::Dynamic(dynamic) => write!(f.with_type(self.ty), "{dynamic}"),
Type::Never => f.with_type(self.ty).write_str("Never"),
Type::NominalInstance(instance) => {
let class = instance.class(self.db);

match (class, class.known(self.db)) {
(_, Some(KnownClass::NoneType)) => f.with_detail(TypeDetail::Type(self.ty)).write_str("None"),
(_, Some(KnownClass::NoDefaultType)) => f.with_detail(TypeDetail::Type(self.ty)).write_str("NoDefault"),
(_, Some(KnownClass::NoneType)) => f.with_type(self.ty).write_str("None"),
(_, Some(KnownClass::NoDefaultType)) => f.with_type(self.ty).write_str("NoDefault"),
(ClassType::Generic(alias), Some(KnownClass::Tuple)) => alias
.specialization(self.db)
.tuple(self.db)
Expand All @@ -642,10 +645,8 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
},
Protocol::Synthesized(synthetic) => {
f.write_char('<')?;
f.with_detail(TypeDetail::Type(Type::SpecialForm(
SpecialFormType::Protocol,
)))
.write_str("Protocol")?;
f.with_type(Type::SpecialForm(SpecialFormType::Protocol))
.write_str("Protocol")?;
f.write_str(" with members ")?;
let interface = synthetic.interface();
let member_list = interface.members(self.db);
Expand All @@ -660,26 +661,24 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
f.write_char('>')
}
},
Type::PropertyInstance(_) => f
.with_detail(TypeDetail::Type(self.ty))
.write_str("property"),
Type::PropertyInstance(_) => f.with_type(self.ty).write_str("property"),
Type::ModuleLiteral(module) => {
write!(
f.with_detail(TypeDetail::Type(self.ty)),
f.with_type(self.ty),
"<module '{}'>",
module.module(self.db).name(self.db)
)
}
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 '")?;
class
.display_with(self.db, self.settings.clone())
.fmt_detailed(&mut f)?;
f.write_str("'>")
}
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 '")?;
generic
.display_with(self.db, self.settings.clone())
Expand All @@ -688,7 +687,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
}
Type::SubclassOf(subclass_of_ty) => match subclass_of_ty.subclass_of() {
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")?;
f.write_char('[')?;
class
Expand All @@ -697,7 +696,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
f.write_char(']')
}
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")?;
f.write_char('[')?;
alias
Expand All @@ -706,24 +705,19 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
f.write_char(']')
}
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")?;
f.write_char('[')?;
write!(
f.with_detail(TypeDetail::Type(Type::Dynamic(dynamic))),
"{dynamic}"
)?;
write!(f.with_type(Type::Dynamic(dynamic)), "{dynamic}")?;
f.write_char(']')
}
},
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
.display_with(self.db, self.settings.clone())
.fmt_detailed(f),
Expand All @@ -748,8 +742,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
.display_with(self.db, self.settings.singleline())
.fmt_detailed(f)?;
f.write_char('.')?;
f.with_detail(TypeDetail::Type(self.ty))
.write_str(function.name(self.db))?;
f.with_type(self.ty).write_str(function.name(self.db))?;
type_parameters.fmt_detailed(f)?;
signature
.bind_self(self.db, Some(typing_self_ty))
Expand Down Expand Up @@ -845,13 +838,14 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
Type::Intersection(intersection) => intersection
.display_with(self.db, self.settings.clone())
.fmt_detailed(f),
Type::IntLiteral(n) => write!(f.with_detail(TypeDetail::Type(self.ty)), "{n}"),
Type::BooleanLiteral(boolean) => f
.with_detail(TypeDetail::Type(self.ty))
.write_str(if boolean { "True" } else { "False" }),
Type::IntLiteral(n) => write!(f.with_type(self.ty), "{n}"),
Type::BooleanLiteral(boolean) => {
f.with_type(self.ty)
.write_str(if boolean { "True" } else { "False" })
}
Type::StringLiteral(string) => {
write!(
f.with_detail(TypeDetail::Type(self.ty)),
f.with_type(self.ty),
"{}",
string.display_with(self.db, self.settings.clone())
)
Expand All @@ -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
// inferred as an *inhabitant* of `LiteralString` (since that variable will just be a string
// at runtime)
Type::LiteralString => f
.with_detail(TypeDetail::Type(self.ty))
.write_str("LiteralString"),
Type::LiteralString => f.with_type(self.ty).write_str("LiteralString"),
Type::BytesLiteral(bytes) => {
let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db), Quote::Double);

write!(
f.with_detail(TypeDetail::Type(self.ty)),
f.with_type(self.ty),
"{}",
escape.bytes_repr(TripleQuotes::No)
)
Expand All @@ -883,12 +875,8 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
Type::TypeVar(bound_typevar) => {
write!(f, "{}", bound_typevar.identity(self.db).display(self.db))
}
Type::AlwaysTruthy => f
.with_detail(TypeDetail::Type(self.ty))
.write_str("AlwaysTruthy"),
Type::AlwaysFalsy => f
.with_detail(TypeDetail::Type(self.ty))
.write_str("AlwaysFalsy"),
Type::AlwaysTruthy => f.with_type(self.ty).write_str("AlwaysTruthy"),
Type::AlwaysFalsy => f.with_type(self.ty).write_str("AlwaysFalsy"),
Type::BoundSuper(bound_super) => {
f.write_str("<super: ")?;
Type::from(bound_super.pivot_class(self.db))
Expand All @@ -901,7 +889,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
f.write_str(">")
}
Type::TypeIs(type_is) => {
f.with_detail(TypeDetail::Type(Type::SpecialForm(SpecialFormType::TypeIs)))
f.with_type(Type::SpecialForm(SpecialFormType::TypeIs))
.write_str("TypeIs")?;
f.write_char('[')?;
type_is
Expand Down Expand Up @@ -929,9 +917,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
.fmt_detailed(f),
}
}
Type::NewTypeInstance(newtype) => f
.with_detail(TypeDetail::Type(self.ty))
.write_str(newtype.name(self.db)),
Type::NewTypeInstance(newtype) => f.with_type(self.ty).write_str(newtype.name(self.db)),
}
}
}
Expand Down Expand Up @@ -982,10 +968,8 @@ pub(crate) struct DisplayTuple<'a, 'db> {

impl<'db> FmtDetailed<'db> for DisplayTuple<'_, 'db> {
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
f.with_detail(TypeDetail::Type(
KnownClass::Tuple.to_class_literal(self.db),
))
.write_str("tuple")?;
f.with_type(KnownClass::Tuple.to_class_literal(self.db))
.write_str("tuple")?;
f.write_char('[')?;
match self.tuple {
TupleSpec::Fixed(tuple) => {
Expand Down Expand Up @@ -1024,10 +1008,8 @@ impl<'db> FmtDetailed<'db> for DisplayTuple<'_, 'db> {
if !tuple.prefix.is_empty() || !tuple.suffix.is_empty() {
f.write_char('*')?;
// Might as well link the type again here too
f.with_detail(TypeDetail::Type(
KnownClass::Tuple.to_class_literal(self.db),
))
.write_str("tuple")?;
f.with_type(KnownClass::Tuple.to_class_literal(self.db))
.write_str("tuple")?;
f.write_char('[')?;
}
tuple
Expand Down Expand Up @@ -1218,8 +1200,7 @@ impl<'db> FmtDetailed<'db> for DisplayGenericAlias<'db> {
Some(_) => "]",
};
if let Some((name, form)) = prefix_details {
f.with_detail(TypeDetail::Type(Type::SpecialForm(form)))
.write_str(name)?;
f.with_type(Type::SpecialForm(form)).write_str(name)?;
f.write_char('[')?;
}
self.origin
Expand Down Expand Up @@ -1890,10 +1871,8 @@ const LITERAL_POLICY: TruncationPolicy = TruncationPolicy {

impl<'db> FmtDetailed<'db> for DisplayLiteralGroup<'db> {
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
f.with_detail(TypeDetail::Type(Type::SpecialForm(
SpecialFormType::Literal,
)))
.write_str("Literal")?;
f.with_type(Type::SpecialForm(SpecialFormType::Literal))
.write_str("Literal")?;
f.write_char('[')?;

let total_entries = self.literals.len();
Expand Down
Loading