summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
diff options
context:
space:
mode:
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.rs138
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(|(&param, 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));
}
}