fmt: split infix wrapping into smaller functions and fix a trailing space bug (#9806)

* change recursive fn calls to reduce write operations

* format files and test

* Update vtest-cleancode.v

* fix test
pull/9810/head
Lukas Neubert 2021-04-19 20:56:39 +02:00 committed by GitHub
parent c174bfa52f
commit 4a1f75c964
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 45 deletions

View File

@ -5,9 +5,7 @@ import testing
import v.util import v.util
const ( const (
vet_known_failing_exceptions = [ vet_known_failing_exceptions = []string{}
'vlib/v/gen/js/js.v' /* trailing space */,
]
vet_folders = [ vet_folders = [
'vlib/sqlite', 'vlib/sqlite',
'vlib/v', 'vlib/v',

View File

@ -1888,81 +1888,89 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
if !buffering_save && f.buffering { if !buffering_save && f.buffering {
f.buffering = false f.buffering = false
if !f.single_line_if && f.line_len > fmt.max_len.last() { if !f.single_line_if && f.line_len > fmt.max_len.last() {
f.wrap_infix(start_pos, start_len, false) f.wrap_infix(start_pos, start_len)
} }
} }
f.is_assign = is_assign_save f.is_assign = is_assign_save
f.or_expr(node.or_block) f.or_expr(node.or_block)
} }
pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int, ignore_paren bool) { pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int) {
cut_span := f.out.len - start_pos cut_span := f.out.len - start_pos
condstr := f.out.cut_last(cut_span) infix_str := f.out.cut_last(cut_span)
is_cond_infix := condstr.contains_any_substr(['&&', '||']) if !infix_str.contains_any_substr(['&&', '||', '+']) {
if !is_cond_infix && !condstr.contains('+') { f.write(infix_str)
f.write(condstr)
return return
} }
f.line_len = start_len f.line_len = start_len
if start_len == 0 { if start_len == 0 {
f.empty_line = true f.empty_line = true
} }
or_pen := if condstr.contains('&&') { 3 } else { 5 } conditions, penalties := split_up_infix(infix_str, false)
cond_parts := condstr.split(' ') f.write_splitted_infix(conditions, penalties, false)
mut grouped_cond := false }
fn split_up_infix(infix_str string, ignore_paren bool) ([]string, []int) {
mut conditions := [''] mut conditions := ['']
mut penalties := [5] mut penalties := [5]
mut index := 0 is_cond_infix := infix_str.contains_any_substr(['&&', '||'])
for cp in cond_parts { or_pen := if infix_str.contains('&&') { 3 } else { 5 }
if is_cond_infix && cp in ['&&', '||'] { parts := infix_str.split(' ')
if grouped_cond { mut inside_paren := false
conditions[index] += '$cp ' mut ind := 0
for p in parts {
if is_cond_infix && p in ['&&', '||'] {
if inside_paren {
conditions[ind] += '$p '
} else { } else {
p := if cp == '||' { or_pen } else { 5 } pen := if p == '||' { or_pen } else { 5 }
penalties << p penalties << pen
conditions << '$cp ' conditions << '$p '
index++ ind++
} }
} else if !is_cond_infix && cp == '+' { } else if !is_cond_infix && p == '+' {
penalties << 5 penalties << 5
conditions[index] += '$cp ' conditions[ind] += '$p '
conditions << '' conditions << ''
index++ ind++
} else { } else {
conditions[index] += '$cp ' conditions[ind] += '$p '
if ignore_paren { if ignore_paren {
continue continue
} }
if cp.starts_with('(') { if p.starts_with('(') {
grouped_cond = true inside_paren = true
} else if cp.ends_with(')') { } else if p.ends_with(')') {
grouped_cond = false inside_paren = false
} }
} }
} }
for i, c in conditions { return conditions, penalties
cnd := c.trim_space() }
if f.line_len + cnd.len < fmt.max_len[penalties[i]] {
if (i > 0 && i < conditions.len) fn (mut f Fmt) write_splitted_infix(conditions []string, penalties []int, ignore_paren bool) {
|| (ignore_paren && i == 0 && cnd.len > 5 && cnd[3] == `(`) { for i, cnd in conditions {
c := cnd.trim_space()
if f.line_len + c.len < fmt.max_len[penalties[i]] {
if (i > 0 && i < conditions.len) || (ignore_paren && i == 0 && c.len > 5 && c[3] == `(`) {
f.write(' ') f.write(' ')
} }
f.write(cnd) f.write(c)
} else { } else {
is_paren_expr := (cnd[0] == `(` || (cnd.len > 5 && cnd[3] == `(`)) && cnd.ends_with(')') is_paren_expr := (c[0] == `(` || (c.len > 5 && c[3] == `(`)) && c.ends_with(')')
final_len := ((f.indent + 1) * 4) + cnd.len final_len := ((f.indent + 1) * 4) + c.len
prev_len := f.line_len if final_len > fmt.max_len.last() && is_paren_expr {
prev_pos := f.out.len conds, pens := split_up_infix(c, true)
if i == 0 && !is_paren_expr { f.write_splitted_infix(conds, pens, true)
continue
}
if i == 0 {
f.remove_new_line({}) f.remove_new_line({})
} }
f.writeln('') f.writeln('')
f.indent++ f.indent++
f.write(cnd) f.write(c)
f.indent-- f.indent--
if final_len > fmt.max_len.last() && is_paren_expr {
f.wrap_infix(prev_pos, prev_len, true)
}
} }
} }
} }

View File

@ -19,4 +19,15 @@ fn main() {
clean_struct_v_type_name = clean_struct_v_type_name =
clean_struct_v_type_name.replace('_Array', '_array').replace('_T_', '<').replace('_', ', ') + clean_struct_v_type_name.replace('_Array', '_array').replace('_T_', '<').replace('_', ', ') +
'>' '>'
{
{
{
// Indent this much to force a break after the assign (`:=`).
// Check that the trailing space is removed
should_cast :=
(g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables)
&& (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last())
}
}
}
} }

View File

@ -12,4 +12,13 @@ fn unwrap_grouped_conds() {
fn main() { fn main() {
clean_struct_v_type_name = clean_struct_v_type_name.replace('_Array', '_array').replace('_T_', '<').replace('_', ', ') + '>' clean_struct_v_type_name = clean_struct_v_type_name.replace('_Array', '_array').replace('_T_', '<').replace('_', ', ') + '>'
{
{
{
// Indent this much to force a break after the assign (`:=`).
// Check that the trailing space is removed
should_cast := (g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables) && (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last())
}
}
}
} }

View File

@ -695,7 +695,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) {
} else { } else {
g.write(' $op ') g.write(' $op ')
// TODO: Multiple types?? // TODO: Multiple types??
should_cast := should_cast :=
(g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables) (g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables)
&& (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last()) && (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last())