fmt: proper infix operator detection in wrapping logic (#9824)
parent
254d247e80
commit
f5e6cadf63
|
@ -1888,14 +1888,15 @@ 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)
|
is_cond := node.op in [.and, .logical_or]
|
||||||
|
f.wrap_infix(start_pos, start_len, is_cond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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) {
|
pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int, is_cond bool) {
|
||||||
cut_span := f.out.len - start_pos
|
cut_span := f.out.len - start_pos
|
||||||
infix_str := f.out.cut_last(cut_span)
|
infix_str := f.out.cut_last(cut_span)
|
||||||
if !infix_str.contains_any_substr(['&&', '||', '+']) {
|
if !infix_str.contains_any_substr(['&&', '||', '+']) {
|
||||||
|
@ -1906,14 +1907,13 @@ pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int) {
|
||||||
if start_len == 0 {
|
if start_len == 0 {
|
||||||
f.empty_line = true
|
f.empty_line = true
|
||||||
}
|
}
|
||||||
conditions, penalties := split_up_infix(infix_str, false)
|
conditions, penalties := split_up_infix(infix_str, false, is_cond)
|
||||||
f.write_splitted_infix(conditions, penalties, false)
|
f.write_splitted_infix(conditions, penalties, false, is_cond)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_up_infix(infix_str string, ignore_paren bool) ([]string, []int) {
|
fn split_up_infix(infix_str string, ignore_paren bool, is_cond_infix bool) ([]string, []int) {
|
||||||
mut conditions := ['']
|
mut conditions := ['']
|
||||||
mut penalties := [5]
|
mut penalties := [5]
|
||||||
is_cond_infix := infix_str.contains_any_substr(['&&', '||'])
|
|
||||||
or_pen := if infix_str.contains('&&') { 3 } else { 5 }
|
or_pen := if infix_str.contains('&&') { 3 } else { 5 }
|
||||||
parts := infix_str.split(' ')
|
parts := infix_str.split(' ')
|
||||||
mut inside_paren := false
|
mut inside_paren := false
|
||||||
|
@ -1948,12 +1948,9 @@ fn split_up_infix(infix_str string, ignore_paren bool) ([]string, []int) {
|
||||||
return conditions, penalties
|
return conditions, penalties
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut f Fmt) write_splitted_infix(conditions []string, penalties []int, ignore_paren bool) {
|
fn (mut f Fmt) write_splitted_infix(conditions []string, penalties []int, ignore_paren bool, is_cond bool) {
|
||||||
for i, cnd in conditions {
|
for i, cnd in conditions {
|
||||||
c := cnd.trim_space()
|
c := cnd.trim_space()
|
||||||
if c.len == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if f.line_len + c.len < fmt.max_len[penalties[i]] {
|
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] == `(`) {
|
if (i > 0 && i < conditions.len) || (ignore_paren && i == 0 && c.len > 5 && c[3] == `(`) {
|
||||||
f.write(' ')
|
f.write(' ')
|
||||||
|
@ -1963,8 +1960,8 @@ fn (mut f Fmt) write_splitted_infix(conditions []string, penalties []int, ignore
|
||||||
is_paren_expr := (c[0] == `(` || (c.len > 5 && c[3] == `(`)) && c.ends_with(')')
|
is_paren_expr := (c[0] == `(` || (c.len > 5 && c[3] == `(`)) && c.ends_with(')')
|
||||||
final_len := ((f.indent + 1) * 4) + c.len
|
final_len := ((f.indent + 1) * 4) + c.len
|
||||||
if final_len > fmt.max_len.last() && is_paren_expr {
|
if final_len > fmt.max_len.last() && is_paren_expr {
|
||||||
conds, pens := split_up_infix(c, true)
|
conds, pens := split_up_infix(c, true, is_cond)
|
||||||
f.write_splitted_infix(conds, pens, true)
|
f.write_splitted_infix(conds, pens, true, is_cond)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
|
|
|
@ -2,3 +2,14 @@ fn infix_in_multi_assign() {
|
||||||
child_width, child_height = child.adj_width + child.margin(.left) + child.margin(.right),
|
child_width, child_height = child.adj_width + child.margin(.left) + child.margin(.right),
|
||||||
child.adj_height + child.margin(.top) + child.margin(.bottom)
|
child.adj_height + child.margin(.top) + child.margin(.bottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn impostor_infix() {
|
||||||
|
/*
|
||||||
|
String concatiation is an InfixExpr. The second part is so long
|
||||||
|
that it overflows a single line. Therefore the wrapping logic is run.
|
||||||
|
The problem was that `&&` and `||` inside the string were detected as infix operators.
|
||||||
|
Thus causing a totally wrong wrapping and sometimes runtime panics.
|
||||||
|
*/
|
||||||
|
x := 'foo' +
|
||||||
|
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || (eeeeeeeeeeeeeeeeee && ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) && bbbbbbbbbbbbbbbbbbbbbbbbbbbb'
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue