diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs | 138 |
1 files changed, 84 insertions, 54 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs index 5a9b825a2..cd6df0e63 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs @@ -2,10 +2,14 @@ use std::fmt::{self, Write}; +use hir_expand::db::ExpandDatabase; use syntax::ast::HasName; use crate::{ - expr::{Array, BindingAnnotation, BindingId, ClosureKind, Literal, Movability, Statement}, + hir::{ + Array, BindingAnnotation, BindingId, CaptureBy, ClosureKind, Literal, LiteralOrConst, + Movability, Statement, + }, pretty::{print_generic_args, print_path, print_type_ref}, type_ref::TypeRef, }; @@ -13,47 +17,71 @@ use crate::{ use super::*; pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String { - let needs_semi; let header = match owner { DefWithBodyId::FunctionId(it) => { - needs_semi = false; let item_tree_id = it.lookup(db).id; - format!("fn {}(…) ", item_tree_id.item_tree(db)[item_tree_id.value].name) + format!( + "fn {}", + item_tree_id.item_tree(db)[item_tree_id.value].name.display(db.upcast()) + ) } DefWithBodyId::StaticId(it) => { - needs_semi = true; let item_tree_id = it.lookup(db).id; - format!("static {} = ", item_tree_id.item_tree(db)[item_tree_id.value].name) + format!( + "static {} = ", + item_tree_id.item_tree(db)[item_tree_id.value].name.display(db.upcast()) + ) } DefWithBodyId::ConstId(it) => { - needs_semi = true; let item_tree_id = it.lookup(db).id; let name = match &item_tree_id.item_tree(db)[item_tree_id.value].name { - Some(name) => name.to_string(), + Some(name) => name.display(db.upcast()).to_string(), None => "_".to_string(), }; format!("const {name} = ") } + DefWithBodyId::InTypeConstId(_) => format!("In type const = "), DefWithBodyId::VariantId(it) => { - needs_semi = false; let src = it.parent.child_source(db); let variant = &src.value[it.local_id]; - let name = match &variant.name() { + match &variant.name() { Some(name) => name.to_string(), None => "_".to_string(), - }; - format!("{name}") + } } }; - let mut p = Printer { body, buf: header, indent_level: 0, needs_indent: false }; + let mut p = + Printer { db: db.upcast(), body, buf: header, indent_level: 0, needs_indent: false }; + if let DefWithBodyId::FunctionId(it) = owner { + p.buf.push('('); + body.params.iter().zip(&db.function_data(it).params).for_each(|(¶m, ty)| { + p.print_pat(param); + p.buf.push(':'); + p.print_type_ref(ty); + }); + p.buf.push(')'); + p.buf.push(' '); + } p.print_expr(body.body_expr); - if needs_semi { + if matches!(owner, DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_)) { p.buf.push(';'); } p.buf } +pub(super) fn print_expr_hir( + db: &dyn DefDatabase, + body: &Body, + _owner: DefWithBodyId, + expr: ExprId, +) -> String { + let mut p = + Printer { db: db.upcast(), body, buf: String::new(), indent_level: 0, needs_indent: false }; + p.print_expr(expr); + p.buf +} + macro_rules! w { ($dst:expr, $($arg:tt)*) => { { let _ = write!($dst, $($arg)*); } @@ -70,6 +98,7 @@ macro_rules! wln { } struct Printer<'a> { + db: &'a dyn ExpandDatabase, body: &'a Body, buf: String, indent_level: usize, @@ -144,29 +173,19 @@ impl<'a> Printer<'a> { } Expr::Loop { body, label } => { if let Some(lbl) = label { - w!(self, "{}: ", self.body[*lbl].name); + w!(self, "{}: ", self.body[*lbl].name.display(self.db)); } w!(self, "loop "); self.print_expr(*body); } Expr::While { condition, body, label } => { if let Some(lbl) = label { - w!(self, "{}: ", self.body[*lbl].name); + w!(self, "{}: ", self.body[*lbl].name.display(self.db)); } w!(self, "while "); self.print_expr(*condition); self.print_expr(*body); } - Expr::For { iterable, pat, body, label } => { - if let Some(lbl) = label { - w!(self, "{}: ", self.body[*lbl].name); - } - w!(self, "for "); - self.print_pat(*pat); - w!(self, " in "); - self.print_expr(*iterable); - self.print_expr(*body); - } Expr::Call { callee, args, is_assignee_expr: _ } => { self.print_expr(*callee); w!(self, "("); @@ -182,10 +201,10 @@ impl<'a> Printer<'a> { } Expr::MethodCall { receiver, method_name, args, generic_args } => { self.print_expr(*receiver); - w!(self, ".{}", method_name); + w!(self, ".{}", method_name.display(self.db)); if let Some(args) = generic_args { w!(self, "::<"); - print_generic_args(args, self).unwrap(); + print_generic_args(self.db, args, self).unwrap(); w!(self, ">"); } w!(self, "("); @@ -219,14 +238,14 @@ impl<'a> Printer<'a> { } Expr::Continue { label } => { w!(self, "continue"); - if let Some(label) = label { - w!(self, " {}", label); + if let Some(lbl) = label { + w!(self, " {}", self.body[*lbl].name.display(self.db)); } } Expr::Break { expr, label } => { w!(self, "break"); - if let Some(label) = label { - w!(self, " {}", label); + if let Some(lbl) = label { + w!(self, " {}", self.body[*lbl].name.display(self.db)); } if let Some(expr) = expr { self.whitespace(); @@ -265,7 +284,7 @@ impl<'a> Printer<'a> { w!(self, "{{"); self.indented(|p| { for field in &**fields { - w!(p, "{}: ", field.name); + w!(p, "{}: ", field.name.display(self.db)); p.print_expr(field.expr); wln!(p, ","); } @@ -282,16 +301,12 @@ impl<'a> Printer<'a> { } Expr::Field { expr, name } => { self.print_expr(*expr); - w!(self, ".{}", name); + w!(self, ".{}", name.display(self.db)); } Expr::Await { expr } => { self.print_expr(*expr); w!(self, ".await"); } - Expr::Try { expr } => { - self.print_expr(*expr); - w!(self, "?"); - } Expr::Cast { expr, type_ref } => { self.print_expr(*expr); w!(self, " as "); @@ -359,7 +374,7 @@ impl<'a> Printer<'a> { self.print_expr(*index); w!(self, "]"); } - Expr::Closure { args, arg_types, ret_type, body, closure_kind } => { + Expr::Closure { args, arg_types, ret_type, body, closure_kind, capture_by } => { match closure_kind { ClosureKind::Generator(Movability::Static) => { w!(self, "static "); @@ -369,6 +384,12 @@ impl<'a> Printer<'a> { } _ => (), } + match capture_by { + CaptureBy::Value => { + w!(self, "move "); + } + CaptureBy::Ref => (), + } w!(self, "|"); for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() { if i != 0 { @@ -418,20 +439,17 @@ impl<'a> Printer<'a> { } Expr::Literal(lit) => self.print_literal(lit), Expr::Block { id: _, statements, tail, label } => { - let label = label.map(|lbl| format!("{}: ", self.body[lbl].name)); + let label = label.map(|lbl| format!("{}: ", self.body[lbl].name.display(self.db))); self.print_block(label.as_deref(), statements, tail); } Expr::Unsafe { id: _, statements, tail } => { self.print_block(Some("unsafe "), statements, tail); } - Expr::TryBlock { id: _, statements, tail } => { - self.print_block(Some("try "), statements, tail); - } Expr::Async { id: _, statements, tail } => { self.print_block(Some("async "), statements, tail); } - Expr::Const { id: _, statements, tail } => { - self.print_block(Some("const "), statements, tail); + Expr::Const(id) => { + w!(self, "const {{ /* {id:?} */ }}"); } } } @@ -439,7 +457,7 @@ impl<'a> Printer<'a> { fn print_block( &mut self, label: Option<&str>, - statements: &Box<[Statement]>, + statements: &[Statement], tail: &Option<la_arena::Idx<Expr>>, ) { self.whitespace(); @@ -449,7 +467,7 @@ impl<'a> Printer<'a> { w!(self, "{{"); if !statements.is_empty() || tail.is_some() { self.indented(|p| { - for stmt in &**statements { + for stmt in statements { p.print_stmt(stmt); } if let Some(tail) = tail { @@ -497,7 +515,7 @@ impl<'a> Printer<'a> { w!(self, " {{"); self.indented(|p| { for arg in args.iter() { - w!(p, "{}: ", arg.name); + w!(p, "{}: ", arg.name.display(self.db)); p.print_pat(arg.pat); wln!(p, ","); } @@ -508,9 +526,13 @@ impl<'a> Printer<'a> { w!(self, "}}"); } Pat::Range { start, end } => { - self.print_expr(*start); - w!(self, "..."); - self.print_expr(*end); + if let Some(start) = start { + self.print_literal_or_const(start); + } + w!(self, "..="); + if let Some(end) = end { + self.print_literal_or_const(end); + } } Pat::Slice { prefix, slice, suffix } => { w!(self, "["); @@ -601,10 +623,18 @@ impl<'a> Printer<'a> { } } + fn print_literal_or_const(&mut self, literal_or_const: &LiteralOrConst) { + match literal_or_const { + LiteralOrConst::Literal(l) => self.print_literal(l), + LiteralOrConst::Const(c) => self.print_path(c), + } + } + fn print_literal(&mut self, literal: &Literal) { match literal { Literal::String(it) => w!(self, "{:?}", it), Literal::ByteString(it) => w!(self, "\"{}\"", it.escape_ascii()), + Literal::CString(it) => w!(self, "\"{}\\0\"", it), Literal::Char(it) => w!(self, "'{}'", it.escape_debug()), Literal::Bool(it) => w!(self, "{}", it), Literal::Int(i, suffix) => { @@ -629,11 +659,11 @@ impl<'a> Printer<'a> { } fn print_type_ref(&mut self, ty: &TypeRef) { - print_type_ref(ty, self).unwrap(); + print_type_ref(self.db, ty, self).unwrap(); } fn print_path(&mut self, path: &Path) { - print_path(path, self).unwrap(); + print_path(self.db, path, self).unwrap(); } fn print_binding(&mut self, id: BindingId) { @@ -644,6 +674,6 @@ impl<'a> Printer<'a> { BindingAnnotation::Ref => "ref ", BindingAnnotation::RefMut => "ref mut ", }; - w!(self, "{}{}", mode, name); + w!(self, "{}{}", mode, name.display(self.db)); } } |