diff --git a/src/fmt.rs b/src/fmt.rs new file mode 100644 index 0000000000..4946b0c10e --- /dev/null +++ b/src/fmt.rs @@ -0,0 +1,75 @@ +use parse::ast::CommentOrNewline::Newline; +use parse::ast::{AssignedField, Expr, Pattern}; + +pub fn is_multiline_expr<'a>(expr: &'a Expr<'a>) -> bool { + use parse::ast::Expr::*; + // TODO cache these answers using a Map, so + // we don't have to traverse subexpressions repeatedly + + match expr { + // Return whether these spaces contain any Newlines + SpaceBefore(_, spaces) | SpaceAfter(_, spaces) => { + spaces.iter().any(|space| space == &Newline) + } + + // These expressions never have newlines + Float(_) + | Int(_) + | HexInt(_) + | OctalInt(_) + | BinaryInt(_) + | Str(_) + | Field(_, _) + | QualifiedField(_, _) + | AccessorFunction(_) + | Var(_, _) + | MalformedIdent(_) + | MalformedClosure + | Variant(_, _) => false, + + // These expressions always have newlines + Defs(_, _) | Case(_, _) => true, + + List(elems) => elems + .iter() + .any(|loc_expr| is_multiline_expr(&loc_expr.value)), + + BlockStr(lines) => lines.len() > 1, + Apply(loc_expr, args, _) => { + is_multiline_expr(&loc_expr.value) + || args.iter().any(|loc_arg| is_multiline_expr(&loc_arg.value)) + } + + If((loc_cond, loc_if_true, loc_if_false)) => { + is_multiline_expr(&loc_cond.value) + || is_multiline_expr(&loc_if_true.value) + || is_multiline_expr(&loc_if_false.value) + } + + Operator((loc_left, _, loc_right)) => { + is_multiline_expr(&loc_left.value) || is_multiline_expr(&loc_right.value) + } + + PrecedenceConflict(_, _, loc_expr) => is_multiline_expr(&loc_expr.value), + + Closure(loc_patterns, loc_body) => { + // check the body first because it's more likely to be multiline + is_multiline_expr(&loc_body.value) + || loc_patterns + .iter() + .any(|loc_pattern| is_multiline_pattern(&loc_pattern.value)) + } + + Record(loc_fields) => loc_fields + .iter() + .any(|loc_field| is_multiline_field(&loc_field.value)), + } +} + +pub fn is_multiline_field<'a, Val>(_field: &'a AssignedField<'a, Val>) -> bool { + panic!("TODO return iff there are any newlines") +} + +pub fn is_multiline_pattern<'a>(_pattern: &'a Pattern<'a>) -> bool { + panic!("TODO return iff there are any newlines") +} diff --git a/src/lib.rs b/src/lib.rs index fbdef85776..60e3527b6c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ pub mod string; pub mod constrain; pub mod ena; +pub mod fmt; pub mod infer; pub mod pretty_print_types; pub mod solve;