diff options
Diffstat (limited to 'src/stmt.rs')
-rw-r--r-- | src/stmt.rs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/stmt.rs b/src/stmt.rs new file mode 100644 index 0000000..a127b57 --- /dev/null +++ b/src/stmt.rs @@ -0,0 +1,85 @@ +use crate::algorithm::Printer; +use syn::{Expr, Stmt}; + +impl Printer { + pub fn stmt(&mut self, stmt: &Stmt) { + match stmt { + Stmt::Local(local) => { + self.outer_attrs(&local.attrs); + self.ibox(0); + self.word("let "); + self.pat(&local.pat); + if let Some((_eq, init)) = &local.init { + self.word(" = "); + self.neverbreak(); + self.expr(init); + } + self.word(";"); + self.end(); + self.hardbreak(); + } + Stmt::Item(item) => self.item(item), + Stmt::Expr(expr) => { + if break_after(expr) { + self.ibox(0); + self.expr_beginning_of_line(expr, true); + if add_semi(expr) { + self.word(";"); + } + self.end(); + self.hardbreak(); + } else { + self.expr_beginning_of_line(expr, true); + } + } + Stmt::Semi(expr, _semi) => { + if let Expr::Verbatim(tokens) = expr { + if tokens.is_empty() { + return; + } + } + self.ibox(0); + self.expr_beginning_of_line(expr, true); + if !remove_semi(expr) { + self.word(";"); + } + self.end(); + self.hardbreak(); + } + } + } +} + +pub fn add_semi(expr: &Expr) -> bool { + match expr { + Expr::Assign(_) + | Expr::AssignOp(_) + | Expr::Break(_) + | Expr::Continue(_) + | Expr::Return(_) + | Expr::Yield(_) => true, + Expr::Group(group) => add_semi(&group.expr), + _ => false, + } +} + +pub fn break_after(expr: &Expr) -> bool { + if let Expr::Group(group) = expr { + if let Expr::Verbatim(verbatim) = group.expr.as_ref() { + return !verbatim.is_empty(); + } + } + true +} + +fn remove_semi(expr: &Expr) -> bool { + match expr { + Expr::ForLoop(_) | Expr::While(_) => true, + Expr::Group(group) => remove_semi(&group.expr), + Expr::If(expr) => match &expr.else_branch { + Some((_else_token, else_branch)) => remove_semi(else_branch), + None => true, + }, + _ => false, + } +} |