mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 22:31:43 +00:00
ItemTree: pretty-print all paths
This commit is contained in:
parent
bc1ba1549d
commit
c22ccd07fe
2 changed files with 119 additions and 9 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
|
||||||
use crate::{attr::RawAttrs, visibility::RawVisibility};
|
use crate::{attr::RawAttrs, path::GenericArg, visibility::RawVisibility};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -466,7 +466,7 @@ impl<'a> Printer<'a> {
|
||||||
TypeRef::Macro(_ast_id) => {
|
TypeRef::Macro(_ast_id) => {
|
||||||
w!(self, "<macro>");
|
w!(self, "<macro>");
|
||||||
}
|
}
|
||||||
TypeRef::Error => drop(write!(self, "{{unknown}}")),
|
TypeRef::Error => w!(self, "{{unknown}}"),
|
||||||
TypeRef::ImplTrait(bounds) => {
|
TypeRef::ImplTrait(bounds) => {
|
||||||
w!(self, "impl ");
|
w!(self, "impl ");
|
||||||
self.print_type_bounds(bounds);
|
self.print_type_bounds(bounds);
|
||||||
|
@ -493,13 +493,77 @@ impl<'a> Printer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_path(&mut self, path: &Path) {
|
fn print_path(&mut self, path: &Path) {
|
||||||
if path.type_anchor().is_none()
|
match path.type_anchor() {
|
||||||
&& path.segments().iter().all(|seg| seg.args_and_bindings.is_none())
|
Some(anchor) => {
|
||||||
{
|
w!(self, "<");
|
||||||
w!(self, "{}", path.mod_path());
|
self.print_type_ref(anchor);
|
||||||
} else {
|
w!(self, ">::");
|
||||||
// too complicated, just use `Debug`
|
}
|
||||||
w!(self, "{:?}", path);
|
None => match path.kind() {
|
||||||
|
PathKind::Plain => {}
|
||||||
|
PathKind::Super(0) => w!(self, "self::"),
|
||||||
|
PathKind::Super(n) => {
|
||||||
|
for _ in 0..*n {
|
||||||
|
w!(self, "super::");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PathKind::Crate => w!(self, "crate::"),
|
||||||
|
PathKind::Abs => w!(self, "::"),
|
||||||
|
PathKind::DollarCrate(_) => w!(self, "$crate::"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, segment) in path.segments().iter().enumerate() {
|
||||||
|
if i != 0 {
|
||||||
|
w!(self, "::");
|
||||||
|
}
|
||||||
|
|
||||||
|
w!(self, "{}", segment.name);
|
||||||
|
if let Some(generics) = segment.args_and_bindings {
|
||||||
|
// NB: these are all in type position, so `::<` turbofish syntax is not necessary
|
||||||
|
w!(self, "<");
|
||||||
|
let mut first = true;
|
||||||
|
let args = if generics.has_self_type {
|
||||||
|
let (self_ty, args) = generics.args.split_first().unwrap();
|
||||||
|
w!(self, "Self=");
|
||||||
|
self.print_generic_arg(self_ty);
|
||||||
|
first = false;
|
||||||
|
args
|
||||||
|
} else {
|
||||||
|
&generics.args
|
||||||
|
};
|
||||||
|
for arg in args {
|
||||||
|
if !first {
|
||||||
|
w!(self, ", ");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
self.print_generic_arg(arg);
|
||||||
|
}
|
||||||
|
for binding in &generics.bindings {
|
||||||
|
if !first {
|
||||||
|
w!(self, ", ");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
w!(self, "{}", binding.name);
|
||||||
|
if !binding.bounds.is_empty() {
|
||||||
|
w!(self, ": ");
|
||||||
|
self.print_type_bounds(&binding.bounds);
|
||||||
|
}
|
||||||
|
if let Some(ty) = &binding.type_ref {
|
||||||
|
w!(self, " = ");
|
||||||
|
self.print_type_ref(ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w!(self, ">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_generic_arg(&mut self, arg: &GenericArg) {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Type(ty) => self.print_type_ref(ty),
|
||||||
|
GenericArg::Lifetime(lt) => w!(self, "{}", lt.name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,3 +242,49 @@ m!();
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mod_paths() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct S {
|
||||||
|
a: self::Ty,
|
||||||
|
b: super::SuperTy,
|
||||||
|
c: super::super::SuperSuperTy,
|
||||||
|
d: ::abs::Path,
|
||||||
|
e: crate::Crate,
|
||||||
|
f: plain::path::Ty,
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
pub(self) struct S {
|
||||||
|
pub(self) a: self::Ty,
|
||||||
|
pub(self) b: super::SuperTy,
|
||||||
|
pub(self) c: super::super::SuperSuperTy,
|
||||||
|
pub(self) d: ::abs::Path,
|
||||||
|
pub(self) e: crate::Crate,
|
||||||
|
pub(self) f: plain::path::Ty,
|
||||||
|
}
|
||||||
|
"#]],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn types() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct S {
|
||||||
|
a: Mixed<'a, T, Item=(), OtherItem=u8>,
|
||||||
|
b: <Fully as Qualified>::Syntax,
|
||||||
|
c: <TypeAnchored>::Path::<'a>,
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
pub(self) struct S {
|
||||||
|
pub(self) a: Mixed<'a, T, Item = (), OtherItem = u8>,
|
||||||
|
pub(self) b: Qualified<Self=Fully>::Syntax,
|
||||||
|
pub(self) c: <TypeAnchored>::Path<'a>,
|
||||||
|
}
|
||||||
|
"#]],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue