fmt: intelligent newlines for trailing arg syntax (#7748)

pull/8016/head
Lukas Neubert 2021-01-10 17:39:37 +01:00 committed by GitHub
parent 7b41ef358c
commit d96a1b8a5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 58 deletions

View File

@ -19,34 +19,35 @@ const (
pub struct Fmt {
pub mut:
table &table.Table
out_imports strings.Builder
out strings.Builder
out_save strings.Builder
indent int
empty_line bool
line_len int
buffering bool // expressions will be analyzed later by adjust_complete_line() before finally written
expr_bufs []string // and stored here in the meantime (expr_bufs.len-1 = penalties.len = precedences.len)
penalties []int // how hard should it be to break line after each expression
precedences []int // operator/parenthese precedences for operator at end of each expression
par_level int // how many parentheses are put around the current expression
array_init_break []bool // line breaks after elements in hierarchy level of multi dimensional array
array_init_depth int // current level of hierarchie in array init
single_line_if bool
cur_mod string
file ast.File
did_imports bool
is_assign bool
auto_imports []string // automatically inserted imports that the user does not need to specify
import_pos int // position of the imports in the resulting string for later autoimports insertion
used_imports []string // to remove unused imports
is_debug bool
mod2alias map[string]string // for `import time as t`, will contain: 'time'=>'t'
use_short_fn_args bool
it_name string // the name to replace `it` with
inside_lambda bool
is_mbranch_expr bool // math a { x...y { } }
table &table.Table
out_imports strings.Builder
out strings.Builder
out_save strings.Builder
indent int
empty_line bool
line_len int
buffering bool // expressions will be analyzed later by adjust_complete_line() before finally written
expr_bufs []string // and stored here in the meantime (expr_bufs.len-1 = penalties.len = precedences.len)
penalties []int // how hard should it be to break line after each expression
precedences []int // operator/parenthese precedences for operator at end of each expression
par_level int // how many parentheses are put around the current expression
array_init_break []bool // line breaks after elements in hierarchy level of multi dimensional array
array_init_depth int // current level of hierarchie in array init
single_line_if bool
cur_mod string
file ast.File
did_imports bool
is_assign bool
auto_imports []string // automatically inserted imports that the user forgot to specify
import_pos int // position of the imports in the resulting string for later autoimports insertion
used_imports []string // to remove unused imports
is_debug bool
mod2alias map[string]string // for `import time as t`, will contain: 'time'=>'t'
use_short_fn_args bool
single_line_fields bool // should struct fields be on a single line
it_name string // the name to replace `it` with
inside_lambda bool
is_mbranch_expr bool // math a { x...y { } }
}
pub fn fmt(file ast.File, table &table.Table, is_debug bool) string {
@ -1263,6 +1264,7 @@ pub fn (mut f Fmt) wrap_long_line(penalty_idx int, add_indent bool) bool {
}
pub fn (mut f Fmt) call_args(args []ast.CallArg) {
f.single_line_fields = true
for i, arg in args {
if arg.is_mut {
f.write(arg.share.str() + ' ')
@ -1275,6 +1277,7 @@ pub fn (mut f Fmt) call_args(args []ast.CallArg) {
f.write(', ')
}
}
f.single_line_fields = false
}
pub fn (mut f Fmt) or_expr(or_block ast.OrExpr) {
@ -1646,8 +1649,8 @@ pub fn (mut f Fmt) call_expr(node ast.CallExpr) {
old_short_arg_state := f.use_short_fn_args
f.use_short_fn_args = false
if node.args.len > 0 && node.args.last().expr is ast.StructInit {
struct_typ := (node.args.last().expr as ast.StructInit).typ
if struct_typ == table.void_type {
struct_expr := node.args.last().expr as ast.StructInit
if struct_expr.typ == table.void_type {
f.use_short_fn_args = true
}
}
@ -2068,17 +2071,23 @@ pub fn (mut f Fmt) struct_init(it ast.StructInit) {
} else {
use_short_args := f.use_short_fn_args
f.use_short_fn_args = false
mut multiline_short_args := it.pre_comments.len > 0
mut single_line_fields := f.single_line_fields
f.single_line_fields = false
if it.pos.line_nr < it.pos.last_line || it.pre_comments.len > 0 {
single_line_fields = false
}
if !use_short_args {
f.writeln('$name{')
} else {
if multiline_short_args {
f.writeln('')
f.write('$name{')
if single_line_fields {
f.write(' ')
}
}
init_start := f.out.len
f.indent++
short_args_loop: for {
fields_start := f.out.len
fields_loop: for {
if !single_line_fields {
f.writeln('')
f.indent++
}
f.comments(it.pre_comments, inline: true, has_nl: true, level: .keep)
if it.has_update_expr {
f.write('...')
@ -2090,7 +2099,7 @@ pub fn (mut f Fmt) struct_init(it ast.StructInit) {
f.write('$field.name: ')
f.prefix_expr_cast_expr(field.expr)
f.comments(field.comments, inline: true, has_nl: false, level: .indent)
if use_short_args && !multiline_short_args {
if single_line_fields {
if i < it.fields.len - 1 {
f.write(', ')
}
@ -2098,21 +2107,25 @@ pub fn (mut f Fmt) struct_init(it ast.StructInit) {
f.writeln('')
}
f.comments(field.next_comments, inline: false, has_nl: true, level: .keep)
if use_short_args && !multiline_short_args &&
if single_line_fields &&
(field.comments.len > 0 ||
field.next_comments.len > 0 || !expr_is_single_line(field.expr) || f.line_len > max_len.last()) {
multiline_short_args = true
f.out.go_back_to(init_start)
f.line_len = init_start
single_line_fields = false
f.out.go_back_to(fields_start)
f.line_len = fields_start
f.remove_new_line()
f.writeln('')
continue short_args_loop
continue fields_loop
}
}
break
}
f.indent--
if !single_line_fields {
f.indent--
}
if !use_short_args {
if single_line_fields {
f.write(' ')
}
f.write('}')
}
}

View File

@ -13,10 +13,14 @@ struct Baz {
fn main() {
bar_func(x: 'bar', y: 13, z: 42)
bar_func(
x: 'bar'
y: 13
z: 42
)
foo_func(Baz{
x: 'Baz as Foo sumtype'
})
bar_func(x: 'bar', y: 2, z: 3, a: 4)
func_from_other_file(val: 'something')
bar_func(
// pre comment
@ -43,8 +47,6 @@ fn main() {
)
}
fn bar_func(bar Bar) {
}
fn bar_func(bar Bar) {}
fn foo_func(f Foo) {
}
fn foo_func(f Foo) {}

View File

@ -408,11 +408,7 @@ fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit {
update_expr: update_expr
update_expr_comments: update_expr_comments
has_update_expr: has_update_expr
pos: token.Position{
line_nr: first_pos.line_nr
pos: first_pos.pos
len: last_pos.pos - first_pos.pos + last_pos.len
}
pos: first_pos.extend_with_last_line(last_pos, p.tok.line_nr)
is_short: no_keys
pre_comments: pre_comments
}

View File

@ -197,9 +197,12 @@ fn test_http_client_shutdown_does_not_work_without_a_cookie() {
fn testsuite_end() {
// This test is guaranteed to be called last.
// It sends a request to the server to shutdown.
x := http.fetch('http://127.0.0.1:$sport/shutdown', method: .get, cookies: {
x := http.fetch('http://127.0.0.1:$sport/shutdown',
method: .get
cookies: {
'skey': 'superman'
}) or {
}
) or {
assert err == ''
return
}