Skip to content

Commit f5e6cad

Browse files
author
Lukas Neubert
authored
fmt: proper infix operator detection in wrapping logic (#9824)
1 parent 254d247 commit f5e6cad

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

vlib/v/fmt/fmt.v

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,14 +1888,15 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
18881888
if !buffering_save && f.buffering {
18891889
f.buffering = false
18901890
if !f.single_line_if && f.line_len > fmt.max_len.last() {
1891-
f.wrap_infix(start_pos, start_len)
1891+
is_cond := node.op in [.and, .logical_or]
1892+
f.wrap_infix(start_pos, start_len, is_cond)
18921893
}
18931894
}
18941895
f.is_assign = is_assign_save
18951896
f.or_expr(node.or_block)
18961897
}
18971898

1898-
pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int) {
1899+
pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int, is_cond bool) {
18991900
cut_span := f.out.len - start_pos
19001901
infix_str := f.out.cut_last(cut_span)
19011902
if !infix_str.contains_any_substr(['&&', '||', '+']) {
@@ -1906,14 +1907,13 @@ pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int) {
19061907
if start_len == 0 {
19071908
f.empty_line = true
19081909
}
1909-
conditions, penalties := split_up_infix(infix_str, false)
1910-
f.write_splitted_infix(conditions, penalties, false)
1910+
conditions, penalties := split_up_infix(infix_str, false, is_cond)
1911+
f.write_splitted_infix(conditions, penalties, false, is_cond)
19111912
}
19121913

1913-
fn split_up_infix(infix_str string, ignore_paren bool) ([]string, []int) {
1914+
fn split_up_infix(infix_str string, ignore_paren bool, is_cond_infix bool) ([]string, []int) {
19141915
mut conditions := ['']
19151916
mut penalties := [5]
1916-
is_cond_infix := infix_str.contains_any_substr(['&&', '||'])
19171917
or_pen := if infix_str.contains('&&') { 3 } else { 5 }
19181918
parts := infix_str.split(' ')
19191919
mut inside_paren := false
@@ -1948,12 +1948,9 @@ fn split_up_infix(infix_str string, ignore_paren bool) ([]string, []int) {
19481948
return conditions, penalties
19491949
}
19501950

1951-
fn (mut f Fmt) write_splitted_infix(conditions []string, penalties []int, ignore_paren bool) {
1951+
fn (mut f Fmt) write_splitted_infix(conditions []string, penalties []int, ignore_paren bool, is_cond bool) {
19521952
for i, cnd in conditions {
19531953
c := cnd.trim_space()
1954-
if c.len == 0 {
1955-
continue
1956-
}
19571954
if f.line_len + c.len < fmt.max_len[penalties[i]] {
19581955
if (i > 0 && i < conditions.len) || (ignore_paren && i == 0 && c.len > 5 && c[3] == `(`) {
19591956
f.write(' ')
@@ -1963,8 +1960,8 @@ fn (mut f Fmt) write_splitted_infix(conditions []string, penalties []int, ignore
19631960
is_paren_expr := (c[0] == `(` || (c.len > 5 && c[3] == `(`)) && c.ends_with(')')
19641961
final_len := ((f.indent + 1) * 4) + c.len
19651962
if final_len > fmt.max_len.last() && is_paren_expr {
1966-
conds, pens := split_up_infix(c, true)
1967-
f.write_splitted_infix(conds, pens, true)
1963+
conds, pens := split_up_infix(c, true, is_cond)
1964+
f.write_splitted_infix(conds, pens, true, is_cond)
19681965
continue
19691966
}
19701967
if i == 0 {

vlib/v/fmt/tests/infix_expr_keep.vv

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,14 @@ fn infix_in_multi_assign() {
22
child_width, child_height = child.adj_width + child.margin(.left) + child.margin(.right),
33
child.adj_height + child.margin(.top) + child.margin(.bottom)
44
}
5+
6+
fn impostor_infix() {
7+
/*
8+
String concatiation is an InfixExpr. The second part is so long
9+
that it overflows a single line. Therefore the wrapping logic is run.
10+
The problem was that `&&` and `||` inside the string were detected as infix operators.
11+
Thus causing a totally wrong wrapping and sometimes runtime panics.
12+
*/
13+
x := 'foo' +
14+
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || (eeeeeeeeeeeeeeeeee && ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) && bbbbbbbbbbbbbbbbbbbbbbbbbbbb'
15+
}

0 commit comments

Comments
 (0)