DEV: A bunch of improvments

* move comments on the same line up to the previous line.
* All statements should have two new lines between them.
* Handle comments with indentation whitespace properly.
This commit is contained in:
Jeremy Wall 2019-05-24 14:45:46 -05:00
parent c9b2b9994f
commit 685917876b
2 changed files with 85 additions and 66 deletions

View File

@ -76,7 +76,7 @@ where
None => return false, None => return false,
}; };
for c in s.chars() { for c in s.chars() {
if !c.is_ascii_alphanumeric() { if !(c.is_ascii_alphabetic() || c == '_') {
return false; return false;
} }
} }
@ -89,7 +89,15 @@ where
let cg = map.get(&line).unwrap_or(&empty); let cg = map.get(&line).unwrap_or(&empty);
let indent = self.make_indent(); let indent = self.make_indent();
for c in cg.iter() { for c in cg.iter() {
write!(self.w, "{}// {}\n", indent, c.fragment.trim())?; let first_char = match c.fragment.chars().nth(0) {
Some(c) => c,
None => '\0',
};
if !first_char.is_whitespace() {
write!(self.w, "{}// {}\n", indent, c.fragment.trim_end())?;
} else {
write!(self.w, "{}//{}\n", indent, c.fragment.trim_end())?;
}
} }
self.comment_group_lines.pop(); self.comment_group_lines.pop();
} }
@ -100,7 +108,7 @@ where
loop { loop {
if let Some(next_comment_line) = self.comment_group_lines.last() { if let Some(next_comment_line) = self.comment_group_lines.last() {
let next_comment_line = *next_comment_line; let next_comment_line = *next_comment_line;
if next_comment_line < line { if next_comment_line <= line {
self.print_comment_group(next_comment_line)?; self.print_comment_group(next_comment_line)?;
} else { } else {
break; break;
@ -116,18 +124,14 @@ where
} }
fn render_comment_if_needed(&mut self, line: usize) -> std::io::Result<()> { fn render_comment_if_needed(&mut self, line: usize) -> std::io::Result<()> {
if line > self.last_line { self.render_missed_comments(line)?;
self.render_missed_comments(line)?; self.last_line = line;
self.last_line = line;
}
Ok(()) Ok(())
} }
fn has_comment(&self, line: usize) -> bool { fn has_comment(&self, line: usize) -> bool {
if line > self.last_line { if let Some(next_comment_line) = self.comment_group_lines.last() {
if let Some(next_comment_line) = self.comment_group_lines.last() { return *next_comment_line < line;
return *next_comment_line < line;
}
} }
false false
} }
@ -549,7 +553,7 @@ where
self.render_expr(&_expr)?; self.render_expr(&_expr)?;
} }
}; };
write!(self.w, ";\n")?; write!(self.w, ";\n\n")?;
self.last_line = line; self.last_line = line;
Ok(()) Ok(())
} }

View File

@ -33,67 +33,67 @@ fn print_to_buffer(input: &str) -> String {
#[test] #[test]
fn test_simple_value_printing() { fn test_simple_value_printing() {
let input = "1;"; let input = "1;";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_simple_selector_printing() { fn test_simple_selector_printing() {
let input = "foo.bar.quux;"; let input = "foo.bar.quux;";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_simple_quoted_printing() { fn test_simple_quoted_printing() {
let input = "\"foo\";"; let input = "\"foo\";";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_escaped_quoted_printing() { fn test_escaped_quoted_printing() {
let input = "\"f\\\\o\\\"o\";"; let input = "\"f\\\\o\\\"o\";";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_empty_tuple_printing() { fn test_empty_tuple_printing() {
let input = "{};"; let input = "{};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_empty_list_printing() { fn test_empty_list_printing() {
let input = "[];"; let input = "[];";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_non_empty_tuple_printing() { fn test_non_empty_tuple_printing() {
let input = "{\n foo = 1,\n};"; let input = "{\n foo = 1,\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_nested_empty_tuple_printing() { fn test_nested_empty_tuple_printing() {
let input = "{\n foo = {},\n};"; let input = "{\n foo = {},\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_list_nested_empty_tuple_printing() { fn test_list_nested_empty_tuple_printing() {
let input = "[\n {},\n];"; let input = "[\n {},\n];";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_nested_non_empty_tuple_printing() { fn test_nested_non_empty_tuple_printing() {
let input = "{\n foo = {\n bar = 1,\n },\n};"; let input = "{\n foo = {\n bar = 1,\n },\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_nested_non_empty_list_printing() { fn test_nested_non_empty_list_printing() {
let input = "[\n [\n 1,\n ],\n];"; let input = "[\n [\n 1,\n ],\n];";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
@ -101,80 +101,80 @@ fn test_simple_quoted_field_tuple_printing() {
let input = "{\n \"foo\" = {\n bar = 1,\n },\n};"; let input = "{\n \"foo\" = {\n bar = 1,\n },\n};";
assert_eq!( assert_eq!(
print_to_buffer(input), print_to_buffer(input),
format!("{}\n", "{\n foo = {\n bar = 1,\n },\n};") format!("{}\n\n", "{\n foo = {\n bar = 1,\n },\n};")
); );
} }
#[test] #[test]
fn test_special_quoted_field_tuple_printing() { fn test_special_quoted_field_tuple_printing() {
let input = "{\n \"foo bar\" = {\n bar = 1,\n },\n};"; let input = "{\n \"foo bar\" = {\n bar = 1,\n },\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_let_statement_printing() { fn test_let_statement_printing() {
let input = "let tpl = {\n \"foo bar\" = {\n bar = 1,\n },\n};"; let input = "let tpl = {\n \"foo bar\" = {\n bar = 1,\n },\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_call_expr_printing() { fn test_call_expr_printing() {
let input = "call(\n foo,\n bar,\n);"; let input = "call(\n foo,\n bar,\n);";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_call_expr_one_arg_printing() { fn test_call_expr_one_arg_printing() {
let input = "call(foo);"; let input = "call(foo);";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_copy_expr_printing() { fn test_copy_expr_printing() {
let input = "copy{\n foo = 1,\n bar = 2,\n};"; let input = "copy{\n foo = 1,\n bar = 2,\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_copy_expr_one_arg_printing() { fn test_copy_expr_one_arg_printing() {
let input = "copy{\n foo = 1,\n};"; let input = "copy{\n foo = 1,\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_out_expr_printing() { fn test_out_expr_printing() {
let input = "out json {\n foo = 1,\n};"; let input = "out json {\n foo = 1,\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_select_expr_no_default_printing() { fn test_select_expr_no_default_printing() {
let input = "select true, {\n true = 1,\n false = 2,\n};"; let input = "select true, {\n true = 1,\n false = 2,\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_select_expr_with_default_printing() { fn test_select_expr_with_default_printing() {
let input = "select true, 3, {\n true = 1,\n false = 2,\n};"; let input = "select true, 3, {\n true = 1,\n false = 2,\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_not_expr_printing() { fn test_not_expr_printing() {
let input = "not true;"; let input = "not true;";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_fail_expr_printing() { fn test_fail_expr_printing() {
let input = "fail \"AHHh\";"; let input = "fail \"AHHh\";";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_trace_expr_printing() { fn test_trace_expr_printing() {
let input = "TRACE \"AHHh\";"; let input = "TRACE \"AHHh\";";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
@ -186,11 +186,12 @@ fn test_module_no_out_expr_printing() {
} => { } => {
let config = { let config = {
hostname = mod.hostname, hostname = mod.hostname,
\"memory_size\" = mod.mem, memory_size = mod.mem,
\"cpu_count\" = mod.cpu, cpu_count = mod.cpu,
}; };
};"; };";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
@ -202,11 +203,12 @@ fn test_module_with_out_expr_printing() {
} => (config) { } => (config) {
let config = { let config = {
hostname = mod.hostname, hostname = mod.hostname,
\"memory_size\" = mod.mem, memory_size = mod.mem,
\"cpu_count\" = mod.cpu, cpu_count = mod.cpu,
}; };
};"; };";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
@ -215,7 +217,7 @@ fn test_func_expr_printing() {
foo = foo, foo = foo,
bar = bar, bar = bar,
};"; };";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
@ -223,7 +225,7 @@ fn test_func_expr_single_arg_printing() {
let input = "let f = func (foo) => { let input = "let f = func (foo) => {
foo = foo, foo = foo,
};"; };";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
@ -231,7 +233,7 @@ fn test_format_expr_single_arg_printing() {
let input = "\"what? @{item.foo}\" % { let input = "\"what? @{item.foo}\" % {
foo = 1, foo = 1,
};"; };";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
@ -239,37 +241,51 @@ fn test_format_expr_list_arg_printing() {
let input = "\"what? @ @\" % ( let input = "\"what? @ @\" % (
1, 1,
2);"; 2);";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_statement_with_comment_printing() { fn test_statement_with_comment_printing() {
let input = "// add 1 + 1\n1 + 1;"; let input = "// add 1 + 1\n1 + 1;";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_statement_with_comment_printing_groups() { fn test_statement_with_comment_printing_groups() {
let input = "// add 1\n// and 1\n1 + 1;"; let input = "// add 1\n// and 1\n1 + 1;";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_statement_with_comment_printing_multiple_groups() { fn test_statement_with_comment_printing_multiple_groups() {
let input = "\n// group 1\n// more group 1\n\n// group 2\n// more group 2\n1 + 1;"; let input = "\n// group 1\n// more group 1\n\n// group 2\n// more group 2\n1 + 1;";
assert_eq!(print_to_buffer(input), format!("{}\n", input.trim())); assert_eq!(print_to_buffer(input), format!("{}\n\n", input.trim()));
} }
#[test] #[test]
fn test_statement_with_comment_printing_comments_at_end() { fn test_statement_with_comment_printing_comments_at_end() {
let input = "// group 1\n1 + 1;\n// group 2\n\n"; let input = "// group 1\n1 + 1;\n\n// group 2\n\n";
assert_eq!(print_to_buffer(input), format!("{}\n", input.trim())); assert_eq!(print_to_buffer(input), format!("{}\n", input.trim()));
} }
#[test] #[test]
fn test_tuple_expression_with_embedded_comment() { fn test_tuple_expression_with_embedded_comment() {
let input = "{\n foo = bar,\n // a comment\n bar = foo,\n};"; let input = "{\n foo = bar,\n // a comment\n bar = foo,\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
}
#[test]
fn test_tuple_expression_with_embedded_comment_same_line() {
let input = "{
foo = bar, // a comment
bar = foo,
};";
let expected = "{
// a comment
foo = bar,
bar = foo,
};";
assert_eq!(print_to_buffer(input), format!("{}\n\n", expected));
} }
#[test] #[test]
@ -277,7 +293,7 @@ fn test_tuple_expression_with_embedded_comment_mid_field_expr() {
let input = "{\n foo = bar,\n bar =\n// a comment\n foo\n};"; let input = "{\n foo = bar,\n bar =\n// a comment\n foo\n};";
assert_eq!( assert_eq!(
print_to_buffer(input), print_to_buffer(input),
"{\n foo = bar,\n // a comment\n bar = foo,\n};\n" "{\n foo = bar,\n // a comment\n bar = foo,\n};\n\n"
); );
} }
@ -286,57 +302,57 @@ fn test_tuple_expression_with_embedded_comment_and_mid_field_expr() {
let input = "{\n foo = bar,\n// a comment\n bar =\n// another comment\n foo\n};"; let input = "{\n foo = bar,\n// a comment\n bar =\n// another comment\n foo\n};";
assert_eq!( assert_eq!(
print_to_buffer(input), print_to_buffer(input),
"{\n foo = bar,\n // a comment\n // another comment\n bar = foo,\n};\n" "{\n foo = bar,\n // a comment\n // another comment\n bar = foo,\n};\n\n"
); );
} }
#[test] #[test]
fn test_list_expression_with_embedded_comment() { fn test_list_expression_with_embedded_comment() {
let input = "[\n bar,\n // a comment\n foo,\n];"; let input = "[\n bar,\n // a comment\n foo,\n];";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_binary_expression_with_embedded_comment() { fn test_binary_expression_with_embedded_comment() {
let input = "true == \n// false is not true\nfalse;"; let input = "true == \n// false is not true\nfalse;";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_empty_call_expression_with_comment() { fn test_empty_call_expression_with_comment() {
let input = "// a comment\nmyfunc();"; let input = "// a comment\nmyfunc();";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_call_expression_with_embedded_comment_in_args() { fn test_call_expression_with_embedded_comment_in_args() {
let input = "// a comment\nmyfunc(\n arg1,\n // another comment\n arg2,\n);"; let input = "// a comment\nmyfunc(\n arg1,\n // another comment\n arg2,\n);";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_copy_expression_with_embedded_comment_in_args() { fn test_copy_expression_with_embedded_comment_in_args() {
let input = "// a comment\nmyfunc{\n foo = arg1,\n // another comment\n bar = arg2,\n};"; let input = "// a comment\nmyfunc{\n foo = arg1,\n // another comment\n bar = arg2,\n};";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_trace_expression_with_embedded_comment() { fn test_trace_expression_with_embedded_comment() {
let input = "// a comment\nTRACE \n// another comment\nfoo;"; let input = "// a comment\nTRACE \n// another comment\nfoo;";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_fail_expression_with_embedded_comment() { fn test_fail_expression_with_embedded_comment() {
let input = "// a comment\nfail \n// another comment\nfoo;"; let input = "// a comment\nfail \n// another comment\nfoo;";
assert_eq!(print_to_buffer(input), format!("{}\n", input)); assert_eq!(print_to_buffer(input), format!("{}\n\n", input));
} }
#[test] #[test]
fn test_format_expression_with_embedded_comment() { fn test_format_expression_with_embedded_comment() {
let input = "// a comment\n\"@(item.bar)\" % \n// another comment\nfoo;"; let input = "// a comment\n\"@(item.bar)\" % \n// another comment\nfoo;";
let output = print_to_buffer(input); let output = print_to_buffer(input);
assert_eq!(output, format!("{}\n", input.trim())); assert_eq!(output, format!("{}\n\n", input.trim()));
} }
#[test] #[test]
@ -344,12 +360,11 @@ fn test_filter_func_operator_expression_with_embedded_comment() {
//let input = "// a comment\nfilter(foo, bar);"; //let input = "// a comment\nfilter(foo, bar);";
let input = "// a comment\nfilter(\n // another comment\n foo,\n // one more\n bar);"; let input = "// a comment\nfilter(\n // another comment\n foo,\n // one more\n bar);";
let output = print_to_buffer(input); let output = print_to_buffer(input);
assert_eq!(output, format!("{}\n", input.trim())); assert_eq!(output, format!("{}\n\n", input.trim()));
} }
#[test] #[test]
fn test_reduce_func_operator_expression_with_embedded_comment() { fn test_reduce_func_operator_expression_with_embedded_comment() {
//let input = "// a comment\nfilter(foo, bar);";
let input = "// a comment\nreduce( let input = "// a comment\nreduce(
// another comment // another comment
myfunc, myfunc,
@ -358,7 +373,7 @@ fn test_reduce_func_operator_expression_with_embedded_comment() {
// and the last // and the last
target);"; target);";
let output = print_to_buffer(input); let output = print_to_buffer(input);
assert_eq!(output, format!("{}\n", input.trim())); assert_eq!(output, format!("{}\n\n", input.trim()));
} }
#[test] #[test]
@ -366,7 +381,7 @@ fn test_map_func_operator_expression_with_embedded_comment() {
//let input = "// a comment\nfilter(foo, bar);"; //let input = "// a comment\nfilter(foo, bar);";
let input = "// a comment\nmap(\n // another comment\n foo,\n // one more\n bar);"; let input = "// a comment\nmap(\n // another comment\n foo,\n // one more\n bar);";
let output = print_to_buffer(input); let output = print_to_buffer(input);
assert_eq!(output, format!("{}\n", input.trim())); assert_eq!(output, format!("{}\n\n", input.trim()));
} }
#[test] #[test]
@ -374,5 +389,5 @@ fn test_grouped_expression_with_embedded_comment() {
//let input = "// a comment\nfilter(foo, bar);"; //let input = "// a comment\nfilter(foo, bar);";
let input = "// a comment\n(\n // a comment\n foo\n);"; let input = "// a comment\n(\n // a comment\n foo\n);";
let output = print_to_buffer(input); let output = print_to_buffer(input);
assert_eq!(output, format!("{}\n", input.trim())); assert_eq!(output, format!("{}\n\n", input.trim()));
} }