mirror of https://github.com/astral-sh/ruff
[ty] More low-hanging fruit for inlay hint goto-definition (#21548)
This commit is contained in:
parent
eb7c098d6b
commit
06941c1987
|
|
@ -588,6 +588,8 @@ mod tests {
|
|||
y = x
|
||||
z = i(1)
|
||||
w = z
|
||||
aa = b'foo'
|
||||
bb = aa
|
||||
",
|
||||
);
|
||||
|
||||
|
|
@ -599,6 +601,8 @@ mod tests {
|
|||
y[: Literal[1]] = x
|
||||
z[: int] = i(1)
|
||||
w[: int] = z
|
||||
aa = b'foo'
|
||||
bb[: Literal[b"foo"]] = aa
|
||||
|
||||
---------------------------------------------
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
|
|
@ -620,6 +624,25 @@ mod tests {
|
|||
8 | w[: int] = z
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:6:13
|
||||
|
|
||||
5 | x = 1
|
||||
6 | y[: Literal[1]] = x
|
||||
| ^
|
||||
7 | z[: int] = i(1)
|
||||
8 | w[: int] = z
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
|
|
@ -637,6 +660,7 @@ mod tests {
|
|||
7 | z[: int] = i(1)
|
||||
| ^^^
|
||||
8 | w[: int] = z
|
||||
9 | aa = b'foo'
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
|
|
@ -655,6 +679,44 @@ mod tests {
|
|||
7 | z[: int] = i(1)
|
||||
8 | w[: int] = z
|
||||
| ^^^
|
||||
9 | aa = b'foo'
|
||||
10 | bb[: Literal[b"foo"]] = aa
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/typing.pyi:351:1
|
||||
|
|
||||
349 | Final: _SpecialForm
|
||||
350 |
|
||||
351 | Literal: _SpecialForm
|
||||
| ^^^^^^^
|
||||
352 | TypedDict: _SpecialForm
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:10:6
|
||||
|
|
||||
8 | w[: int] = z
|
||||
9 | aa = b'foo'
|
||||
10 | bb[: Literal[b"foo"]] = aa
|
||||
| ^^^^^^^
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:1448:7
|
||||
|
|
||||
1447 | @disjoint_base
|
||||
1448 | class bytes(Sequence[int]):
|
||||
| ^^^^^
|
||||
1449 | """bytes(iterable_of_ints) -> bytes
|
||||
1450 | bytes(string, encoding[, errors]) -> bytes
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:10:14
|
||||
|
|
||||
8 | w[: int] = z
|
||||
9 | aa = b'foo'
|
||||
10 | bb[: Literal[b"foo"]] = aa
|
||||
| ^^^^^^
|
||||
|
|
||||
"#);
|
||||
}
|
||||
|
|
@ -706,6 +768,25 @@ mod tests {
|
|||
10 | x4[: int], y4[: str] = (x3, y3)
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:14
|
||||
|
|
||||
7 | x1, y1 = (1, 'abc')
|
||||
8 | x2[: Literal[1]], y2[: Literal["abc"]] = (x1, y1)
|
||||
| ^
|
||||
9 | x3[: int], y3[: str] = (i(1), s('abc'))
|
||||
10 | x4[: int], y4[: str] = (x3, y3)
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/typing.pyi:351:1
|
||||
|
|
||||
|
|
@ -725,6 +806,25 @@ mod tests {
|
|||
10 | x4[: int], y4[: str] = (x3, y3)
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:915:7
|
||||
|
|
||||
914 | @disjoint_base
|
||||
915 | class str(Sequence[str]):
|
||||
| ^^^
|
||||
916 | """str(object='') -> str
|
||||
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:32
|
||||
|
|
||||
7 | x1, y1 = (1, 'abc')
|
||||
8 | x2[: Literal[1]], y2[: Literal["abc"]] = (x1, y1)
|
||||
| ^^^^^
|
||||
9 | x3[: int], y3[: str] = (i(1), s('abc'))
|
||||
10 | x4[: int], y4[: str] = (x3, y3)
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
|
|
@ -848,6 +948,25 @@ mod tests {
|
|||
10 | x4[: int], y4[: str] = x3, y3
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:14
|
||||
|
|
||||
7 | x1, y1 = 1, 'abc'
|
||||
8 | x2[: Literal[1]], y2[: Literal["abc"]] = x1, y1
|
||||
| ^
|
||||
9 | x3[: int], y3[: str] = i(1), s('abc')
|
||||
10 | x4[: int], y4[: str] = x3, y3
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/typing.pyi:351:1
|
||||
|
|
||||
|
|
@ -867,6 +986,25 @@ mod tests {
|
|||
10 | x4[: int], y4[: str] = x3, y3
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:915:7
|
||||
|
|
||||
914 | @disjoint_base
|
||||
915 | class str(Sequence[str]):
|
||||
| ^^^
|
||||
916 | """str(object='') -> str
|
||||
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:32
|
||||
|
|
||||
7 | x1, y1 = 1, 'abc'
|
||||
8 | x2[: Literal[1]], y2[: Literal["abc"]] = x1, y1
|
||||
| ^^^^^
|
||||
9 | x3[: int], y3[: str] = i(1), s('abc')
|
||||
10 | x4[: int], y4[: str] = x3, y3
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
|
|
@ -1008,6 +1146,25 @@ mod tests {
|
|||
10 | w[: tuple[int, str]] = z
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:19
|
||||
|
|
||||
7 | x = (1, 'abc')
|
||||
8 | y[: tuple[Literal[1], Literal["abc"]]] = x
|
||||
| ^
|
||||
9 | z[: tuple[int, str]] = (i(1), s('abc'))
|
||||
10 | w[: tuple[int, str]] = z
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/typing.pyi:351:1
|
||||
|
|
||||
|
|
@ -1027,6 +1184,25 @@ mod tests {
|
|||
10 | w[: tuple[int, str]] = z
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:915:7
|
||||
|
|
||||
914 | @disjoint_base
|
||||
915 | class str(Sequence[str]):
|
||||
| ^^^
|
||||
916 | """str(object='') -> str
|
||||
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:31
|
||||
|
|
||||
7 | x = (1, 'abc')
|
||||
8 | y[: tuple[Literal[1], Literal["abc"]]] = x
|
||||
| ^^^^^
|
||||
9 | z[: tuple[int, str]] = (i(1), s('abc'))
|
||||
10 | w[: tuple[int, str]] = z
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:2695:7
|
||||
|
|
||||
|
|
@ -1183,6 +1359,25 @@ mod tests {
|
|||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:14
|
||||
|
|
||||
7 | x1, (y1, z1) = (1, ('abc', 2))
|
||||
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
|
||||
| ^
|
||||
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
|
||||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/typing.pyi:351:1
|
||||
|
|
||||
|
|
@ -1202,6 +1397,25 @@ mod tests {
|
|||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:915:7
|
||||
|
|
||||
914 | @disjoint_base
|
||||
915 | class str(Sequence[str]):
|
||||
| ^^^
|
||||
916 | """str(object='') -> str
|
||||
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:33
|
||||
|
|
||||
7 | x1, (y1, z1) = (1, ('abc', 2))
|
||||
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
|
||||
| ^^^^^
|
||||
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
|
||||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/typing.pyi:351:1
|
||||
|
|
||||
|
|
@ -1221,6 +1435,25 @@ mod tests {
|
|||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:8:55
|
||||
|
|
||||
7 | x1, (y1, z1) = (1, ('abc', 2))
|
||||
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
|
||||
| ^
|
||||
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
|
||||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
|
|
@ -1375,6 +1608,25 @@ mod tests {
|
|||
8 | w[: int] = z
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:6:13
|
||||
|
|
||||
5 | x: int = 1
|
||||
6 | y[: Literal[1]] = x
|
||||
| ^
|
||||
7 | z: int = i(1)
|
||||
8 | w[: int] = z
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
|
|
@ -4988,6 +5240,78 @@ mod tests {
|
|||
| ^^^^^^^
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:13:17
|
||||
|
|
||||
11 | else:
|
||||
12 | x = None
|
||||
13 | y[: Literal[1, 2, 3, "hello"] | None] = x
|
||||
| ^
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:13:20
|
||||
|
|
||||
11 | else:
|
||||
12 | x = None
|
||||
13 | y[: Literal[1, 2, 3, "hello"] | None] = x
|
||||
| ^
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:348:7
|
||||
|
|
||||
347 | @disjoint_base
|
||||
348 | class int:
|
||||
| ^^^
|
||||
349 | """int([x]) -> integer
|
||||
350 | int(x, base=10) -> integer
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:13:23
|
||||
|
|
||||
11 | else:
|
||||
12 | x = None
|
||||
13 | y[: Literal[1, 2, 3, "hello"] | None] = x
|
||||
| ^
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/builtins.pyi:915:7
|
||||
|
|
||||
914 | @disjoint_base
|
||||
915 | class str(Sequence[str]):
|
||||
| ^^^
|
||||
916 | """str(object='') -> str
|
||||
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:13:26
|
||||
|
|
||||
11 | else:
|
||||
12 | x = None
|
||||
13 | y[: Literal[1, 2, 3, "hello"] | None] = x
|
||||
| ^^^^^^^
|
||||
|
|
||||
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> stdlib/types.pyi:950:11
|
||||
|
|
||||
|
|
@ -5123,6 +5447,45 @@ mod tests {
|
|||
"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_property_literal_type() {
|
||||
let mut test = inlay_hint_test(
|
||||
r"
|
||||
class F:
|
||||
@property
|
||||
def whatever(self): ...
|
||||
|
||||
ab = F.whatever",
|
||||
);
|
||||
|
||||
assert_snapshot!(test.inlay_hints(), @r"
|
||||
class F:
|
||||
@property
|
||||
def whatever(self): ...
|
||||
|
||||
ab[: property] = F.whatever
|
||||
---------------------------------------------
|
||||
info[inlay-hint-location]: Inlay Hint Target
|
||||
--> main.py:4:9
|
||||
|
|
||||
2 | class F:
|
||||
3 | @property
|
||||
4 | def whatever(self): ...
|
||||
| ^^^^^^^^
|
||||
5 |
|
||||
6 | ab = F.whatever
|
||||
|
|
||||
info: Source
|
||||
--> main2.py:6:6
|
||||
|
|
||||
4 | def whatever(self): ...
|
||||
5 |
|
||||
6 | ab[: property] = F.whatever
|
||||
| ^^^^^^^^
|
||||
|
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complex_parameter_combinations() {
|
||||
let mut test = inlay_hint_test(
|
||||
|
|
|
|||
|
|
@ -7601,6 +7601,11 @@ impl<'db> Type<'db> {
|
|||
Self::TypeAlias(alias) => alias.value_type(db).definition(db),
|
||||
Self::NewTypeInstance(newtype) => Some(TypeDefinition::NewType(newtype.definition(db))),
|
||||
|
||||
Self::PropertyInstance(property) => property
|
||||
.getter(db)
|
||||
.and_then(|getter|getter.definition(db))
|
||||
.or_else(||property.setter(db).and_then(|setter|setter.definition(db))),
|
||||
|
||||
Self::StringLiteral(_)
|
||||
| Self::BooleanLiteral(_)
|
||||
| Self::LiteralString
|
||||
|
|
@ -7612,7 +7617,6 @@ impl<'db> Type<'db> {
|
|||
| Self::WrapperDescriptor(_)
|
||||
| Self::DataclassDecorator(_)
|
||||
| Self::DataclassTransformer(_)
|
||||
| Self::PropertyInstance(_)
|
||||
| Self::BoundSuper(_) => self.to_meta_type(db).definition(db),
|
||||
|
||||
Self::TypeVar(bound_typevar) => Some(TypeDefinition::TypeVar(bound_typevar.typevar(db).definition(db)?)),
|
||||
|
|
@ -7622,20 +7626,22 @@ impl<'db> Type<'db> {
|
|||
Protocol::Synthesized(_) => None,
|
||||
},
|
||||
|
||||
Type::TypedDict(typed_dict) => {
|
||||
Self::TypedDict(typed_dict) => {
|
||||
Some(TypeDefinition::Class(typed_dict.defining_class().definition(db)))
|
||||
}
|
||||
|
||||
Self::Union(_) | Self::Intersection(_) => None,
|
||||
|
||||
Self::SpecialForm(special_form) => special_form.definition(db),
|
||||
Self::Never => Type::SpecialForm(SpecialFormType::Never).definition(db),
|
||||
Self::Dynamic(DynamicType::Any) => Type::SpecialForm(SpecialFormType::Any).definition(db),
|
||||
Self::Dynamic(DynamicType::Unknown) => Type::SpecialForm(SpecialFormType::Unknown).definition(db),
|
||||
Self::AlwaysTruthy => Type::SpecialForm(SpecialFormType::AlwaysTruthy).definition(db),
|
||||
Self::AlwaysFalsy => Type::SpecialForm(SpecialFormType::AlwaysFalsy).definition(db),
|
||||
|
||||
// These types have no definition
|
||||
Self::Dynamic(_)
|
||||
| Self::Never
|
||||
Self::Dynamic(DynamicType::Divergent(_) | DynamicType::Todo(_) | DynamicType::TodoTypeAlias | DynamicType::TodoUnpack)
|
||||
| Self::Callable(_)
|
||||
| Self::AlwaysTruthy
|
||||
| Self::AlwaysFalsy
|
||||
| Self::TypeIs(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ use crate::types::signatures::{CallableSignature, Parameter, Parameters, Signatu
|
|||
use crate::types::tuple::TupleSpec;
|
||||
use crate::types::visitor::TypeVisitor;
|
||||
use crate::types::{
|
||||
BoundTypeVarIdentity, CallableType, DynamicType, IntersectionType, KnownBoundMethodType,
|
||||
KnownClass, MaterializationKind, Protocol, ProtocolInstanceType, SpecialFormType,
|
||||
StringLiteralType, SubclassOfInner, Type, UnionType, WrapperDescriptorKind, visitor,
|
||||
BoundTypeVarIdentity, CallableType, IntersectionType, KnownBoundMethodType, KnownClass,
|
||||
MaterializationKind, Protocol, ProtocolInstanceType, SpecialFormType, StringLiteralType,
|
||||
SubclassOfInner, Type, UnionType, WrapperDescriptorKind, visitor,
|
||||
};
|
||||
use ruff_db::parsed::parsed_module;
|
||||
|
||||
|
|
@ -611,9 +611,7 @@ 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) => dynamic
|
||||
.display_with(self.db, self.settings.clone())
|
||||
.fmt_detailed(f),
|
||||
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::NominalInstance(instance) => {
|
||||
let class = instance.class(self.db);
|
||||
|
|
@ -662,7 +660,9 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
|||
f.write_char('>')
|
||||
}
|
||||
},
|
||||
Type::PropertyInstance(_) => f.write_str("property"),
|
||||
Type::PropertyInstance(_) => f
|
||||
.with_detail(TypeDetail::Type(self.ty))
|
||||
.write_str("property"),
|
||||
Type::ModuleLiteral(module) => {
|
||||
write!(
|
||||
f.with_detail(TypeDetail::Type(self.ty)),
|
||||
|
|
@ -709,9 +709,10 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
|||
f.with_detail(TypeDetail::Type(KnownClass::Type.to_class_literal(self.db)))
|
||||
.write_str("type")?;
|
||||
f.write_char('[')?;
|
||||
dynamic
|
||||
.display_with(self.db, self.settings.clone())
|
||||
.fmt_detailed(f)?;
|
||||
write!(
|
||||
f.with_detail(TypeDetail::Type(Type::Dynamic(dynamic))),
|
||||
"{dynamic}"
|
||||
)?;
|
||||
f.write_char(']')
|
||||
}
|
||||
},
|
||||
|
|
@ -847,18 +848,33 @@ 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, "{n}"),
|
||||
Type::BooleanLiteral(boolean) => f.write_str(if boolean { "True" } else { "False" }),
|
||||
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::StringLiteral(string) => {
|
||||
write!(f, "{}", string.display_with(self.db, self.settings.clone()))
|
||||
write!(
|
||||
f.with_detail(TypeDetail::Type(self.ty)),
|
||||
"{}",
|
||||
string.display_with(self.db, self.settings.clone())
|
||||
)
|
||||
}
|
||||
// an alternative would be to use `Type::SpecialForm(SpecialFormType::LiteralString)` here,
|
||||
// which would mean users would be able to jump to the definition of `LiteralString` from the
|
||||
// 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::BytesLiteral(bytes) => {
|
||||
let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db), Quote::Double);
|
||||
|
||||
escape.bytes_repr(TripleQuotes::No).write(f)
|
||||
write!(
|
||||
f.with_detail(TypeDetail::Type(self.ty)),
|
||||
"{}",
|
||||
escape.bytes_repr(TripleQuotes::No)
|
||||
)
|
||||
}
|
||||
Type::EnumLiteral(enum_literal) => {
|
||||
enum_literal
|
||||
|
|
@ -1162,48 +1178,6 @@ impl Display for DisplayFunctionType<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'db> DynamicType<'db> {
|
||||
fn display_with<'a>(
|
||||
&'a self,
|
||||
db: &'db dyn Db,
|
||||
settings: DisplaySettings<'db>,
|
||||
) -> DisplayDynamicType<'a, 'db> {
|
||||
DisplayDynamicType {
|
||||
dynamic_type: self,
|
||||
db,
|
||||
settings,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DisplayDynamicType<'a, 'db> {
|
||||
dynamic_type: &'a DynamicType<'db>,
|
||||
#[allow(dead_code)]
|
||||
db: &'db dyn Db,
|
||||
#[allow(dead_code)]
|
||||
settings: DisplaySettings<'db>,
|
||||
}
|
||||
|
||||
impl<'db> FmtDetailed<'db> for DisplayDynamicType<'_, 'db> {
|
||||
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
||||
match self.dynamic_type {
|
||||
DynamicType::Any => write!(
|
||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(SpecialFormType::Any))),
|
||||
"{}",
|
||||
self.dynamic_type,
|
||||
),
|
||||
DynamicType::Unknown => write!(
|
||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(
|
||||
SpecialFormType::Unknown
|
||||
))),
|
||||
"{}",
|
||||
self.dynamic_type,
|
||||
),
|
||||
_ => write!(f, "{}", self.dynamic_type),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'db> GenericAlias<'db> {
|
||||
pub(crate) fn display(self, db: &'db dyn Db) -> DisplayGenericAlias<'db> {
|
||||
self.display_with(db, DisplaySettings::default())
|
||||
|
|
@ -1237,16 +1211,20 @@ impl<'db> FmtDetailed<'db> for DisplayGenericAlias<'db> {
|
|||
.display_with(self.db, self.settings.clone())
|
||||
.fmt_detailed(f)
|
||||
} else {
|
||||
let prefix = match self.specialization.materialization_kind(self.db) {
|
||||
None => "",
|
||||
Some(MaterializationKind::Top) => "Top[",
|
||||
Some(MaterializationKind::Bottom) => "Bottom[",
|
||||
let prefix_details = match self.specialization.materialization_kind(self.db) {
|
||||
None => None,
|
||||
Some(MaterializationKind::Top) => Some(("Top", SpecialFormType::Top)),
|
||||
Some(MaterializationKind::Bottom) => Some(("Bottom", SpecialFormType::Bottom)),
|
||||
};
|
||||
let suffix = match self.specialization.materialization_kind(self.db) {
|
||||
None => "",
|
||||
Some(_) => "]",
|
||||
};
|
||||
f.write_str(prefix)?;
|
||||
if let Some((name, form)) = prefix_details {
|
||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(form)))
|
||||
.write_str(name)?;
|
||||
f.write_char('[')?;
|
||||
}
|
||||
self.origin
|
||||
.display_with(self.db, self.settings.clone())
|
||||
.fmt_detailed(f)?;
|
||||
|
|
|
|||
Loading…
Reference in New Issue