2021-01-18 13:20:06 +01:00
|
|
|
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
2019-12-22 02:34:37 +01:00
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
module fmt
|
|
|
|
|
2020-04-14 19:32:23 +02:00
|
|
|
import v.ast
|
|
|
|
import v.table
|
|
|
|
import strings
|
2020-07-01 00:53:53 +02:00
|
|
|
import v.util
|
2021-02-02 09:14:34 +01:00
|
|
|
import v.pref
|
2020-02-17 22:50:04 +01:00
|
|
|
|
|
|
|
const (
|
2021-01-13 06:05:27 +01:00
|
|
|
bs = '\\'
|
2020-05-28 05:50:57 +02:00
|
|
|
tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t',
|
2020-07-19 19:58:34 +02:00
|
|
|
'\t\t\t\t\t\t\t\t',
|
2020-05-28 05:50:57 +02:00
|
|
|
]
|
2020-06-19 19:54:26 +02:00
|
|
|
// when to break a line dependant on penalty
|
2021-01-23 09:33:22 +01:00
|
|
|
max_len = [0, 35, 60, 85, 93, 100]
|
2020-02-17 22:50:04 +01:00
|
|
|
)
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub struct Fmt {
|
|
|
|
pub mut:
|
2021-01-10 17:39:37 +01:00
|
|
|
table &table.Table
|
|
|
|
out_imports strings.Builder
|
|
|
|
out strings.Builder
|
|
|
|
indent int
|
|
|
|
empty_line bool
|
2021-02-16 09:22:39 +01:00
|
|
|
line_len int // the current line length, NB: it counts \t as 4 spaces, and starts at 0 after f.writeln
|
2021-01-23 09:33:22 +01:00
|
|
|
buffering bool // disables line wrapping for exprs that will be analyzed later
|
|
|
|
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
|
2021-01-10 17:39:37 +01:00
|
|
|
single_line_if bool
|
|
|
|
cur_mod string
|
2021-01-29 00:26:57 +01:00
|
|
|
cur_short_mod string // TODO clean this up
|
2021-01-10 17:39:37 +01:00
|
|
|
file ast.File
|
|
|
|
did_imports bool
|
|
|
|
is_assign bool
|
2021-02-14 19:22:24 +01:00
|
|
|
is_struct_init bool
|
2021-02-07 03:58:43 +01:00
|
|
|
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
|
|
|
|
import_syms_used map[string]bool // to remove unused import symbols.
|
2021-01-10 17:39:37 +01:00
|
|
|
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
|
2021-01-24 10:54:27 +01:00
|
|
|
inside_const bool
|
2021-01-10 17:39:37 +01:00
|
|
|
is_mbranch_expr bool // math a { x...y { } }
|
2021-02-02 09:14:34 +01:00
|
|
|
pref &pref.Preferences
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
|
2021-02-02 09:14:34 +01:00
|
|
|
pub fn fmt(file ast.File, table &table.Table, pref &pref.Preferences, is_debug bool) string {
|
2020-04-21 05:11:50 +02:00
|
|
|
mut f := Fmt{
|
2020-02-17 22:50:04 +01:00
|
|
|
out: strings.new_builder(1000)
|
2020-04-12 17:45:04 +02:00
|
|
|
out_imports: strings.new_builder(200)
|
2020-02-17 22:50:04 +01:00
|
|
|
table: table
|
2020-02-18 22:35:14 +01:00
|
|
|
indent: 0
|
2020-04-05 02:08:10 +02:00
|
|
|
file: file
|
2020-05-04 16:22:41 +02:00
|
|
|
is_debug: is_debug
|
2021-02-02 09:14:34 +01:00
|
|
|
pref: pref
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-06-15 17:28:00 +02:00
|
|
|
f.process_file_imports(file)
|
2020-07-11 15:09:12 +02:00
|
|
|
f.set_current_module_name('main')
|
2021-01-29 11:17:59 +01:00
|
|
|
// As these are toplevel stmts, the indent increase done in f.stmts() has to be compensated
|
|
|
|
f.indent--
|
|
|
|
f.stmts(file.stmts)
|
|
|
|
f.indent++
|
2020-04-05 18:15:12 +02:00
|
|
|
// for comment in file.comments { println('$comment.line_nr $comment.text') }
|
2020-04-17 20:53:39 +02:00
|
|
|
f.imports(f.file.imports) // now that we have all autoimports, handle them
|
2020-04-12 17:45:04 +02:00
|
|
|
res := f.out.str().trim_space() + '\n'
|
2021-01-10 20:19:31 +01:00
|
|
|
if res.len == 1 {
|
|
|
|
return f.out_imports.str().trim_space() + '\n'
|
|
|
|
}
|
2020-07-14 18:52:28 +02:00
|
|
|
bounded_import_pos := util.imin(res.len, f.import_pos)
|
2020-07-11 13:53:21 +02:00
|
|
|
return res[..bounded_import_pos] + f.out_imports.str() + res[bounded_import_pos..] // + '\n'
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
|
2020-06-15 17:28:00 +02:00
|
|
|
pub fn (mut f Fmt) process_file_imports(file &ast.File) {
|
|
|
|
for imp in file.imports {
|
2021-02-17 20:42:26 +01:00
|
|
|
mod := imp.mod.all_after_last('.')
|
|
|
|
f.mod2alias[mod] = imp.alias
|
2020-07-18 21:34:38 +02:00
|
|
|
for sym in imp.syms {
|
2020-11-27 09:40:56 +01:00
|
|
|
f.mod2alias['${imp.mod}.$sym.name'] = sym.name
|
2021-02-17 20:42:26 +01:00
|
|
|
f.mod2alias['${mod}.$sym.name'] = sym.name
|
2020-07-18 21:34:38 +02:00
|
|
|
f.mod2alias[sym.name] = sym.name
|
2021-02-07 03:58:43 +01:00
|
|
|
f.import_syms_used[sym.name] = false
|
2020-07-18 21:34:38 +02:00
|
|
|
}
|
2020-06-15 17:28:00 +02:00
|
|
|
}
|
2021-01-08 17:42:40 +01:00
|
|
|
f.auto_imports = file.auto_imports
|
2020-06-15 17:28:00 +02:00
|
|
|
}
|
|
|
|
|
2020-04-21 05:11:50 +02:00
|
|
|
pub fn (mut f Fmt) write(s string) {
|
2021-01-23 09:33:22 +01:00
|
|
|
if f.indent > 0 && f.empty_line {
|
|
|
|
f.write_indent()
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2021-02-22 12:18:11 +01:00
|
|
|
f.out.write_string(s)
|
2021-01-23 09:33:22 +01:00
|
|
|
f.line_len += s.len
|
|
|
|
f.empty_line = false
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
|
2020-04-21 05:11:50 +02:00
|
|
|
pub fn (mut f Fmt) writeln(s string) {
|
2021-02-20 15:05:05 +01:00
|
|
|
if f.indent > 0 && f.empty_line && s.len > 0 {
|
2020-10-03 11:19:43 +02:00
|
|
|
f.write_indent()
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2021-01-23 09:33:22 +01:00
|
|
|
f.out.writeln(s)
|
2020-02-17 22:50:04 +01:00
|
|
|
f.empty_line = true
|
2020-02-21 15:32:48 +01:00
|
|
|
f.line_len = 0
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
|
2020-10-03 11:19:43 +02:00
|
|
|
fn (mut f Fmt) write_indent() {
|
2021-01-24 10:01:10 +01:00
|
|
|
if f.indent < fmt.tabs.len {
|
2021-02-22 12:18:11 +01:00
|
|
|
f.out.write_string(fmt.tabs[f.indent])
|
2020-10-03 11:19:43 +02:00
|
|
|
} else {
|
|
|
|
// too many indents, do it the slow way:
|
|
|
|
for _ in 0 .. f.indent {
|
2021-02-22 12:18:11 +01:00
|
|
|
f.out.write_string('\t')
|
2020-10-03 11:19:43 +02:00
|
|
|
}
|
|
|
|
}
|
2021-01-18 06:02:29 +01:00
|
|
|
f.line_len += f.indent * 4
|
2020-10-03 11:19:43 +02:00
|
|
|
}
|
|
|
|
|
2021-01-29 22:15:26 +01:00
|
|
|
fn (mut f Fmt) write_language_prefix(lang table.Language) {
|
|
|
|
match lang {
|
|
|
|
.c { f.write('C.') }
|
|
|
|
.js { f.write('JS.') }
|
|
|
|
else {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
pub fn (mut f Fmt) wrap_long_line(penalty_idx int, add_indent bool) bool {
|
2021-01-23 09:33:22 +01:00
|
|
|
if f.buffering {
|
|
|
|
return false
|
|
|
|
}
|
2021-02-25 11:10:54 +01:00
|
|
|
if penalty_idx > 0 && f.line_len <= fmt.max_len[penalty_idx] {
|
2021-01-15 10:26:33 +01:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
if f.out.buf[f.out.buf.len - 1] == ` ` {
|
|
|
|
f.out.go_back(1)
|
|
|
|
}
|
|
|
|
f.write('\n')
|
2021-01-18 06:02:29 +01:00
|
|
|
f.line_len = 0
|
2021-01-15 10:26:33 +01:00
|
|
|
if add_indent {
|
|
|
|
f.indent++
|
|
|
|
}
|
|
|
|
f.write_indent()
|
|
|
|
if add_indent {
|
|
|
|
f.indent--
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2021-02-22 17:43:54 +01:00
|
|
|
pub struct RemoveNewLineConfig {
|
|
|
|
imports_buffer bool // Work on f.out_imports instead of f.out
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) remove_new_line(cfg RemoveNewLineConfig) {
|
|
|
|
mut buffer := if cfg.imports_buffer { &f.out_imports } else { &f.out }
|
2021-01-15 10:26:33 +01:00
|
|
|
mut i := 0
|
2021-02-22 17:43:54 +01:00
|
|
|
for i = buffer.len - 1; i >= 0; i-- {
|
|
|
|
if !buffer.buf[i].is_space() { // != `\n` {
|
2021-01-15 10:26:33 +01:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2021-02-22 17:43:54 +01:00
|
|
|
buffer.go_back(buffer.len - i - 1)
|
2021-01-15 10:26:33 +01:00
|
|
|
f.empty_line = false
|
|
|
|
}
|
|
|
|
|
2020-07-14 18:52:28 +02:00
|
|
|
pub fn (mut f Fmt) set_current_module_name(cmodname string) {
|
2020-07-11 15:09:12 +02:00
|
|
|
f.cur_mod = cmodname
|
|
|
|
f.table.cmod_prefix = cmodname + '.'
|
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
fn (f Fmt) get_modname_prefix(mname string) (string, string) {
|
|
|
|
// ./tests/proto_module_importing_vproto_keep.vv to know, why here is checked for ']' and '&'
|
|
|
|
if !mname.contains(']') && !mname.contains('&') {
|
|
|
|
return mname, ''
|
|
|
|
}
|
|
|
|
after_rbc := mname.all_after_last(']')
|
|
|
|
after_ref := mname.all_after_last('&')
|
|
|
|
modname := if after_rbc.len < after_ref.len { after_rbc } else { after_ref }
|
|
|
|
return modname, mname.trim_suffix(modname)
|
|
|
|
}
|
|
|
|
|
2021-01-29 22:15:26 +01:00
|
|
|
fn (mut f Fmt) is_external_name(name string) bool {
|
|
|
|
if name.len > 2 && name[0] == `C` && name[1] == `.` {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if name.len > 3 && name[0] == `J` && name[1] == `S` && name[2] == `.` {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
pub fn (mut f Fmt) no_cur_mod(typename string) string {
|
|
|
|
return util.no_cur_mod(typename, f.cur_mod)
|
|
|
|
}
|
|
|
|
|
|
|
|
// foo.bar.fn() => bar.fn()
|
|
|
|
pub fn (mut f Fmt) short_module(name string) string {
|
|
|
|
if !name.contains('.') {
|
|
|
|
return name
|
|
|
|
}
|
|
|
|
if name in f.mod2alias {
|
|
|
|
return f.mod2alias[name]
|
|
|
|
}
|
|
|
|
if name.ends_with('>') {
|
|
|
|
x := name.trim_suffix('>').split('<')
|
|
|
|
if x.len == 2 {
|
|
|
|
main := f.short_module(x[0])
|
|
|
|
genlist := x[1].split(',')
|
|
|
|
genshorts := genlist.map(f.short_module(it)).join(',')
|
|
|
|
return '$main<$genshorts>'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vals := name.split('.')
|
|
|
|
if vals.len < 2 {
|
|
|
|
return name
|
|
|
|
}
|
|
|
|
mname, tprefix := f.get_modname_prefix(vals[vals.len - 2])
|
|
|
|
symname := vals[vals.len - 1]
|
|
|
|
aname := f.mod2alias[mname]
|
|
|
|
if aname == '' {
|
|
|
|
return symname
|
|
|
|
}
|
|
|
|
return '$tprefix${aname}.$symname'
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) mod(mod ast.Module) {
|
2020-07-11 15:09:12 +02:00
|
|
|
f.set_current_module_name(mod.name)
|
2021-01-29 00:26:57 +01:00
|
|
|
f.cur_short_mod = mod.short_name
|
2020-04-10 22:32:52 +02:00
|
|
|
if mod.is_skipped {
|
|
|
|
return
|
|
|
|
}
|
2021-01-08 16:24:42 +01:00
|
|
|
f.attrs(mod.attrs)
|
2021-01-20 06:04:59 +01:00
|
|
|
f.writeln('module $mod.short_name\n')
|
2021-02-24 19:33:17 +01:00
|
|
|
if f.import_pos == 0 {
|
|
|
|
f.import_pos = f.out.len
|
|
|
|
}
|
2020-02-18 22:35:14 +01:00
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
pub fn (mut f Fmt) mark_types_import_as_used(typ table.Type) {
|
|
|
|
sym := f.table.get_type_symbol(typ)
|
|
|
|
f.mark_import_as_used(sym.name)
|
|
|
|
}
|
|
|
|
|
|
|
|
// `name` is a function (`foo.bar()`) or type (`foo.Bar{}`)
|
|
|
|
pub fn (mut f Fmt) mark_import_as_used(name string) {
|
2021-02-07 03:58:43 +01:00
|
|
|
parts := name.split('.')
|
|
|
|
last := parts.last()
|
|
|
|
if last in f.import_syms_used {
|
|
|
|
f.import_syms_used[last] = true
|
|
|
|
}
|
|
|
|
if parts.len == 1 {
|
2021-01-15 10:26:33 +01:00
|
|
|
return
|
|
|
|
}
|
2021-02-07 03:58:43 +01:00
|
|
|
mod := parts[0..parts.len - 1].join('.')
|
2021-01-15 10:26:33 +01:00
|
|
|
if mod in f.used_imports {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
f.used_imports << mod
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) imports(imports []ast.Import) {
|
2020-04-14 18:24:19 +02:00
|
|
|
if f.did_imports || imports.len == 0 {
|
2020-04-05 21:53:00 +02:00
|
|
|
return
|
|
|
|
}
|
2020-04-14 18:24:19 +02:00
|
|
|
f.did_imports = true
|
2021-01-08 17:42:40 +01:00
|
|
|
mut num_imports := 0
|
2021-01-30 10:04:36 +01:00
|
|
|
mut already_imported := map[string]bool{}
|
2021-02-20 12:22:09 +01:00
|
|
|
|
2020-04-14 18:24:19 +02:00
|
|
|
for imp in imports {
|
2020-04-26 06:39:23 +02:00
|
|
|
if imp.mod !in f.used_imports {
|
2020-04-14 18:24:19 +02:00
|
|
|
// TODO bring back once only unused imports are removed
|
|
|
|
// continue
|
|
|
|
}
|
2021-01-08 17:42:40 +01:00
|
|
|
if imp.mod in f.auto_imports && imp.mod !in f.used_imports {
|
|
|
|
continue
|
|
|
|
}
|
2021-01-30 10:04:36 +01:00
|
|
|
import_text := 'import ${f.imp_stmt_str(imp)}'
|
|
|
|
if already_imported[import_text] {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
already_imported[import_text] = true
|
|
|
|
f.out_imports.writeln(import_text)
|
2021-02-01 14:45:08 +01:00
|
|
|
f.import_comments(imp.comments, inline: true)
|
2021-02-08 18:48:48 +01:00
|
|
|
f.import_comments(imp.next_comments, {})
|
2021-01-08 17:42:40 +01:00
|
|
|
num_imports++
|
|
|
|
}
|
|
|
|
if num_imports > 0 {
|
|
|
|
f.out_imports.writeln('')
|
2020-02-18 22:35:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (f Fmt) imp_stmt_str(imp ast.Import) string {
|
2020-02-21 20:12:55 +01:00
|
|
|
is_diff := imp.alias != imp.mod && !imp.mod.ends_with('.' + imp.alias)
|
2020-07-18 21:34:38 +02:00
|
|
|
mut imp_alias_suffix := if is_diff { ' as $imp.alias' } else { '' }
|
2021-02-07 03:58:43 +01:00
|
|
|
|
2021-02-20 12:22:09 +01:00
|
|
|
mut syms := imp.syms.map(it.name).filter(f.import_syms_used[it])
|
|
|
|
syms.sort()
|
2021-02-07 03:58:43 +01:00
|
|
|
if syms.len > 0 {
|
2021-01-29 14:48:28 +01:00
|
|
|
imp_alias_suffix += if imp.syms[0].pos.line_nr == imp.pos.line_nr {
|
2021-02-07 03:58:43 +01:00
|
|
|
' { ' + syms.join(', ') + ' }'
|
2021-01-29 14:48:28 +01:00
|
|
|
} else {
|
2021-02-07 03:58:43 +01:00
|
|
|
' {\n\t' + syms.join(',\n\t') + ',\n}'
|
2021-01-29 14:48:28 +01:00
|
|
|
}
|
2020-07-18 21:34:38 +02:00
|
|
|
}
|
2020-06-18 20:07:48 +02:00
|
|
|
return '$imp.mod$imp_alias_suffix'
|
2020-02-18 22:35:14 +01:00
|
|
|
}
|
|
|
|
|
2021-02-25 01:30:04 +01:00
|
|
|
fn (f Fmt) should_insert_newline_before_stmt(stmt ast.Stmt, prev_stmt ast.Stmt) bool {
|
2021-01-29 11:17:59 +01:00
|
|
|
prev_line_nr := prev_stmt.position().last_line
|
2021-02-20 15:00:30 +01:00
|
|
|
// No need to insert a newline if there is already one
|
|
|
|
if f.out.last_n(2) == '\n\n' {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
// Force a newline after a block of HashStmts
|
2021-02-01 14:50:41 +01:00
|
|
|
if prev_stmt is ast.HashStmt && stmt !is ast.HashStmt && stmt !is ast.ExprStmt {
|
|
|
|
return true
|
|
|
|
}
|
2021-02-20 15:00:30 +01:00
|
|
|
// Force a newline after a block of function declarations
|
|
|
|
if prev_stmt is ast.FnDecl {
|
|
|
|
if prev_stmt.no_body && stmt !is ast.FnDecl {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// The stmt shouldn't have a newline before
|
|
|
|
if stmt.position().line_nr - prev_line_nr <= 1 {
|
2021-01-29 11:17:59 +01:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
// Imports are handled special hence they are ignored here
|
|
|
|
if stmt is ast.Import || prev_stmt is ast.Import {
|
|
|
|
return false
|
|
|
|
}
|
2021-02-20 15:00:30 +01:00
|
|
|
// Attributes are not respected in the stmts position, so this requires a manual check
|
2021-01-29 11:17:59 +01:00
|
|
|
if stmt is ast.StructDecl {
|
|
|
|
if stmt.attrs.len > 0 && stmt.attrs[0].pos.line_nr - prev_line_nr <= 1 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if stmt is ast.FnDecl {
|
|
|
|
if stmt.attrs.len > 0 && stmt.attrs[0].pos.line_nr - prev_line_nr <= 1 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) stmts(stmts []ast.Stmt) {
|
2021-01-29 11:17:59 +01:00
|
|
|
mut prev_stmt := if stmts.len > 0 { stmts[0] } else { ast.Stmt{} }
|
2020-02-17 22:50:04 +01:00
|
|
|
f.indent++
|
|
|
|
for stmt in stmts {
|
2021-02-02 09:14:34 +01:00
|
|
|
if !f.pref.building_v && f.should_insert_newline_before_stmt(stmt, prev_stmt) {
|
2021-01-19 14:49:40 +01:00
|
|
|
f.out.writeln('')
|
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
f.stmt(stmt)
|
2021-01-29 11:17:59 +01:00
|
|
|
prev_stmt = stmt
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
f.indent--
|
|
|
|
}
|
|
|
|
|
2020-12-04 12:25:23 +01:00
|
|
|
pub fn (mut f Fmt) stmt_str(node ast.Stmt) string {
|
|
|
|
was_empty_line := f.empty_line
|
|
|
|
prev_line_len := f.line_len
|
|
|
|
pos := f.out.len
|
|
|
|
f.stmt(node)
|
|
|
|
str := f.out.after(pos).trim_space()
|
|
|
|
f.out.go_back_to(pos)
|
|
|
|
f.empty_line = was_empty_line
|
|
|
|
f.line_len = prev_line_len
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
2020-05-04 16:22:41 +02:00
|
|
|
if f.is_debug {
|
2021-01-07 20:32:02 +01:00
|
|
|
eprintln('stmt: ${node.position():-42} | node: ${node.type_name():-20}')
|
2020-05-04 16:22:41 +02:00
|
|
|
}
|
2020-11-25 12:09:40 +01:00
|
|
|
match node {
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.AssignStmt {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.assign_stmt(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-04-07 18:51:39 +02:00
|
|
|
ast.AssertStmt {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.assert_stmt(node)
|
2020-04-07 18:51:39 +02:00
|
|
|
}
|
2020-04-05 23:00:17 +02:00
|
|
|
ast.Block {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.block(node)
|
2020-04-05 23:00:17 +02:00
|
|
|
}
|
2020-02-18 03:28:39 +01:00
|
|
|
ast.BranchStmt {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.writeln(node.str())
|
2020-04-05 18:03:36 +02:00
|
|
|
}
|
2020-07-25 00:02:44 +02:00
|
|
|
ast.CompFor {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.comp_for(node)
|
2020-07-25 00:02:44 +02:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.ConstDecl {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.const_decl(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-02-26 20:44:42 +01:00
|
|
|
ast.DeferStmt {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.defer_stmt(node)
|
2020-02-26 20:44:42 +01:00
|
|
|
}
|
2020-02-28 17:21:20 +01:00
|
|
|
ast.EnumDecl {
|
2020-12-22 23:43:48 +01:00
|
|
|
f.enum_decl(node)
|
2020-02-28 17:21:20 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.ExprStmt {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.expr_stmt(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
ast.FnDecl {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.fn_decl(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-04-07 15:48:13 +02:00
|
|
|
ast.ForCStmt {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.for_c_stmt(node)
|
2020-04-07 15:48:13 +02:00
|
|
|
}
|
2020-02-22 14:39:25 +01:00
|
|
|
ast.ForInStmt {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.for_in_stmt(node)
|
2020-02-22 14:39:25 +01:00
|
|
|
}
|
2020-02-18 03:28:39 +01:00
|
|
|
ast.ForStmt {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.for_stmt(node)
|
2020-02-18 03:28:39 +01:00
|
|
|
}
|
2020-04-07 18:51:39 +02:00
|
|
|
ast.GlobalDecl {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.global_decl(node)
|
2020-04-07 18:51:39 +02:00
|
|
|
}
|
2020-04-25 17:49:16 +02:00
|
|
|
ast.GoStmt {
|
2021-01-15 22:40:26 +01:00
|
|
|
f.go_stmt(node, false)
|
2020-04-25 17:49:16 +02:00
|
|
|
}
|
2020-03-02 17:41:32 +01:00
|
|
|
ast.GotoLabel {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.writeln('$node.name:')
|
2020-03-02 17:41:32 +01:00
|
|
|
}
|
|
|
|
ast.GotoStmt {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.writeln('goto $node.name')
|
2020-03-02 17:41:32 +01:00
|
|
|
}
|
2020-04-08 21:21:58 +02:00
|
|
|
ast.HashStmt {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.writeln('#$node.val')
|
2020-04-08 21:21:58 +02:00
|
|
|
}
|
2020-04-05 18:03:36 +02:00
|
|
|
ast.Import {
|
2020-04-12 17:45:04 +02:00
|
|
|
// Imports are handled after the file is formatted, to automatically add necessary modules
|
2021-01-29 11:17:59 +01:00
|
|
|
// Just remember the position of the imports for now
|
|
|
|
f.import_pos = f.out.len
|
2020-04-05 18:03:36 +02:00
|
|
|
}
|
2020-04-22 20:20:49 +02:00
|
|
|
ast.InterfaceDecl {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.interface_decl(node)
|
2020-04-22 20:20:49 +02:00
|
|
|
}
|
2020-04-05 18:03:36 +02:00
|
|
|
ast.Module {
|
2020-11-20 14:12:40 +01:00
|
|
|
f.mod(node)
|
2020-03-24 22:18:58 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.Return {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.return_stmt(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-06-28 12:36:08 +02:00
|
|
|
ast.SqlStmt {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.sql_stmt(node)
|
2020-06-28 12:36:08 +02:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.StructDecl {
|
2020-11-24 13:58:29 +01:00
|
|
|
f.struct_decl(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-03-07 17:37:55 +01:00
|
|
|
ast.TypeDecl {
|
2020-11-24 13:58:29 +01:00
|
|
|
f.type_decl(node)
|
2020-03-07 17:37:55 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
fn stmt_is_single_line(stmt ast.Stmt) bool {
|
2021-02-26 07:41:24 +01:00
|
|
|
return match stmt {
|
|
|
|
ast.ExprStmt, ast.AssertStmt { expr_is_single_line(stmt.expr) }
|
|
|
|
ast.Return, ast.AssignStmt, ast.BranchStmt { true }
|
|
|
|
else { false }
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
|
2020-11-20 10:51:50 +01:00
|
|
|
mut comments := []ast.Comment{}
|
2020-11-25 12:09:40 +01:00
|
|
|
match node {
|
2020-03-07 17:37:55 +01:00
|
|
|
ast.AliasTypeDecl {
|
2020-06-18 20:07:48 +02:00
|
|
|
if node.is_pub {
|
2020-03-07 17:37:55 +01:00
|
|
|
f.write('pub ')
|
|
|
|
}
|
2020-10-13 15:17:02 +02:00
|
|
|
ptype := f.table.type_to_str(node.parent_type)
|
2020-09-25 12:02:32 +02:00
|
|
|
f.write('type $node.name = $ptype')
|
2020-11-20 10:51:50 +01:00
|
|
|
comments << node.comments
|
2020-03-07 17:37:55 +01:00
|
|
|
}
|
2020-04-25 20:58:00 +02:00
|
|
|
ast.FnTypeDecl {
|
2020-06-18 20:07:48 +02:00
|
|
|
if node.is_pub {
|
2020-04-25 20:58:00 +02:00
|
|
|
f.write('pub ')
|
|
|
|
}
|
2020-06-18 20:07:48 +02:00
|
|
|
typ_sym := f.table.get_type_symbol(node.typ)
|
2020-04-25 20:58:00 +02:00
|
|
|
fn_typ_info := typ_sym.info as table.FnType
|
|
|
|
fn_info := fn_typ_info.func
|
2020-07-11 15:09:12 +02:00
|
|
|
fn_name := f.no_cur_mod(node.name)
|
2020-04-25 20:58:00 +02:00
|
|
|
f.write('type $fn_name = fn (')
|
2020-09-27 03:46:15 +02:00
|
|
|
for i, arg in fn_info.params {
|
2020-08-04 15:08:47 +02:00
|
|
|
if arg.is_mut {
|
|
|
|
f.write(arg.typ.share().str() + ' ')
|
|
|
|
}
|
2020-04-25 20:58:00 +02:00
|
|
|
f.write(arg.name)
|
2020-07-11 01:42:57 +02:00
|
|
|
mut s := f.no_cur_mod(f.table.type_to_str(arg.typ))
|
2020-04-25 20:58:00 +02:00
|
|
|
if arg.is_mut {
|
|
|
|
if s.starts_with('&') {
|
|
|
|
s = s[1..]
|
|
|
|
}
|
|
|
|
}
|
2020-09-27 03:46:15 +02:00
|
|
|
is_last_arg := i == fn_info.params.len - 1
|
2021-01-23 09:33:22 +01:00
|
|
|
should_add_type := true || is_last_arg
|
|
|
|
|| fn_info.params[i + 1].typ != arg.typ
|
|
|
|
|| (fn_info.is_variadic && i == fn_info.params.len - 2)
|
2020-04-25 20:58:00 +02:00
|
|
|
if should_add_type {
|
2020-11-20 15:00:40 +01:00
|
|
|
ns := if arg.name == '' { '' } else { ' ' }
|
2020-04-25 20:58:00 +02:00
|
|
|
if fn_info.is_variadic && is_last_arg {
|
2020-11-20 15:00:40 +01:00
|
|
|
f.write(ns + '...' + s)
|
2020-04-25 20:58:00 +02:00
|
|
|
} else {
|
2020-11-20 15:00:40 +01:00
|
|
|
f.write(ns + s)
|
2020-04-25 20:58:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if !is_last_arg {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.write(')')
|
|
|
|
if fn_info.return_type.idx() != table.void_type_idx {
|
2020-07-11 01:42:57 +02:00
|
|
|
ret_str := f.no_cur_mod(f.table.type_to_str(fn_info.return_type))
|
2020-08-03 18:28:48 +02:00
|
|
|
f.write(' $ret_str')
|
|
|
|
} else if fn_info.return_type.has_flag(.optional) {
|
|
|
|
f.write(' ?')
|
2020-04-25 20:58:00 +02:00
|
|
|
}
|
2020-11-20 10:51:50 +01:00
|
|
|
comments << node.comments
|
2020-04-25 20:58:00 +02:00
|
|
|
}
|
2020-11-25 12:09:40 +01:00
|
|
|
ast.SumTypeDecl {
|
2020-11-11 09:18:15 +01:00
|
|
|
if node.is_pub {
|
|
|
|
f.write('pub ')
|
|
|
|
}
|
2020-11-25 12:09:40 +01:00
|
|
|
f.write('type $node.name = ')
|
2020-11-11 09:18:15 +01:00
|
|
|
mut sum_type_names := []string{}
|
2020-11-28 22:40:40 +01:00
|
|
|
for t in node.variants {
|
|
|
|
sum_type_names << f.table.type_to_str(t.typ)
|
2020-11-11 09:18:15 +01:00
|
|
|
}
|
|
|
|
sum_type_names.sort()
|
|
|
|
for i, name in sum_type_names {
|
|
|
|
f.write(name)
|
|
|
|
if i < sum_type_names.len - 1 {
|
|
|
|
f.write(' | ')
|
|
|
|
}
|
2021-01-11 22:19:42 +01:00
|
|
|
if i < sum_type_names.len - 1 {
|
2021-01-23 09:33:22 +01:00
|
|
|
f.wrap_long_line(3, true)
|
2021-01-11 22:19:42 +01:00
|
|
|
}
|
2020-11-11 09:18:15 +01:00
|
|
|
}
|
2020-11-20 10:51:50 +01:00
|
|
|
comments << node.comments
|
2020-11-11 09:18:15 +01:00
|
|
|
}
|
2020-03-07 17:37:55 +01:00
|
|
|
}
|
2020-11-20 10:51:50 +01:00
|
|
|
if comments.len > 0 {
|
|
|
|
f.write(' ')
|
2020-12-04 10:22:26 +01:00
|
|
|
f.comments(comments, has_nl: false)
|
2020-11-20 10:51:50 +01:00
|
|
|
}
|
2020-03-07 17:37:55 +01:00
|
|
|
f.writeln('\n')
|
|
|
|
}
|
|
|
|
|
2021-01-12 04:38:43 +01:00
|
|
|
[inline]
|
|
|
|
fn abs(v int) int {
|
2021-02-08 00:28:46 +01:00
|
|
|
return if v >= 0 { v } else { -v }
|
2021-01-12 04:38:43 +01:00
|
|
|
}
|
|
|
|
|
2021-01-03 21:10:25 +01:00
|
|
|
const (
|
|
|
|
threshold_to_align_struct = 8
|
|
|
|
)
|
|
|
|
|
2021-01-12 04:38:43 +01:00
|
|
|
struct StructFieldAlignInfo {
|
|
|
|
mut:
|
|
|
|
first_line int
|
|
|
|
last_line int
|
|
|
|
max_type_len int
|
|
|
|
max_len int
|
|
|
|
}
|
|
|
|
|
|
|
|
fn (mut list []StructFieldAlignInfo) add_new_info(len int, type_len int, line int) {
|
|
|
|
list << StructFieldAlignInfo{
|
|
|
|
first_line: line
|
|
|
|
last_line: line
|
|
|
|
max_type_len: type_len
|
|
|
|
max_len: len
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[direct_array_access]
|
|
|
|
fn (mut list []StructFieldAlignInfo) add_info(len int, type_len int, line int) {
|
|
|
|
if list.len == 0 {
|
|
|
|
list.add_new_info(len, type_len, line)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
i := list.len - 1
|
|
|
|
if line - list[i].last_line > 1 {
|
|
|
|
list.add_new_info(len, type_len, line)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
list[i].last_line = line
|
|
|
|
if len > list[i].max_len {
|
|
|
|
list[i].max_len = len
|
|
|
|
}
|
|
|
|
if type_len > list[i].max_type_len {
|
|
|
|
list[i].max_type_len = type_len
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-03 21:10:25 +01:00
|
|
|
struct CommentAndExprAlignInfo {
|
|
|
|
mut:
|
|
|
|
max_attrs_len int
|
|
|
|
max_type_len int
|
|
|
|
first_line int
|
|
|
|
last_line int
|
|
|
|
}
|
|
|
|
|
|
|
|
fn (mut list []CommentAndExprAlignInfo) add_new_info(attrs_len int, type_len int, line int) {
|
|
|
|
list << CommentAndExprAlignInfo{
|
|
|
|
max_attrs_len: attrs_len
|
|
|
|
max_type_len: type_len
|
|
|
|
first_line: line
|
|
|
|
last_line: line
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn (mut list []CommentAndExprAlignInfo) add_info(attrs_len int, type_len int, line int) {
|
|
|
|
if list.len == 0 {
|
|
|
|
list.add_new_info(attrs_len, type_len, line)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
i := list.len - 1
|
|
|
|
if line - list[i].last_line > 1 {
|
|
|
|
list.add_new_info(attrs_len, type_len, line)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
d_len := abs(list[i].max_attrs_len - attrs_len) + abs(list[i].max_type_len - type_len)
|
2021-01-24 10:01:10 +01:00
|
|
|
if !(d_len < fmt.threshold_to_align_struct) {
|
2021-01-03 21:10:25 +01:00
|
|
|
list.add_new_info(attrs_len, type_len, line)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
list[i].last_line = line
|
|
|
|
if attrs_len > list[i].max_attrs_len {
|
|
|
|
list[i].max_attrs_len = attrs_len
|
|
|
|
}
|
|
|
|
if type_len > list[i].max_type_len {
|
|
|
|
list[i].max_type_len = type_len
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
2020-08-04 20:10:22 +02:00
|
|
|
f.attrs(node.attrs)
|
2020-02-29 17:51:35 +01:00
|
|
|
if node.is_pub {
|
|
|
|
f.write('pub ')
|
|
|
|
}
|
2020-11-02 23:35:03 +01:00
|
|
|
if node.is_union {
|
|
|
|
f.write('union ')
|
|
|
|
} else {
|
|
|
|
f.write('struct ')
|
|
|
|
}
|
2020-06-02 07:41:02 +02:00
|
|
|
f.write_language_prefix(node.language)
|
2020-04-05 02:08:10 +02:00
|
|
|
name := node.name.after('.')
|
2020-11-11 16:48:42 +01:00
|
|
|
f.write(name)
|
|
|
|
if node.gen_types.len > 0 {
|
|
|
|
f.write(' <')
|
|
|
|
gtypes := node.gen_types.map(f.table.type_to_str(it)).join(', ')
|
|
|
|
f.write(gtypes)
|
|
|
|
f.write('>')
|
|
|
|
}
|
2021-02-16 12:45:56 +01:00
|
|
|
if node.fields.len == 0 && node.embeds.len == 0 && node.pos.line_nr == node.pos.last_line {
|
2021-02-20 15:00:30 +01:00
|
|
|
f.writeln(' {}')
|
2020-12-22 23:43:48 +01:00
|
|
|
return
|
|
|
|
}
|
2020-11-11 16:48:42 +01:00
|
|
|
f.writeln(' {')
|
2021-01-12 04:38:43 +01:00
|
|
|
mut field_aligns := []StructFieldAlignInfo{}
|
2021-01-03 21:10:25 +01:00
|
|
|
mut comment_aligns := []CommentAndExprAlignInfo{}
|
|
|
|
mut default_expr_aligns := []CommentAndExprAlignInfo{}
|
2020-08-10 12:13:42 +02:00
|
|
|
mut field_types := []string{cap: node.fields.len}
|
2021-01-03 21:10:25 +01:00
|
|
|
for i, field in node.fields {
|
|
|
|
mut ft := f.no_cur_mod(f.table.type_to_str(field.typ))
|
2021-02-24 19:26:12 +01:00
|
|
|
if !ft.contains('C.') && !ft.contains('JS.') && !ft.contains('fn (') && !ft.contains('chan') {
|
2021-01-03 21:10:25 +01:00
|
|
|
ft = f.short_module(ft)
|
|
|
|
}
|
|
|
|
field_types << ft
|
|
|
|
attrs_len := inline_attrs_len(field.attrs)
|
2020-06-23 18:01:56 +02:00
|
|
|
end_pos := field.pos.pos + field.pos.len
|
|
|
|
mut comments_len := 0 // Length of comments between field name and type
|
|
|
|
for comment in field.comments {
|
2020-06-24 14:35:00 +02:00
|
|
|
if comment.pos.pos >= end_pos {
|
2021-01-03 21:10:25 +01:00
|
|
|
if comment.pos.line_nr == field.pos.line_nr {
|
|
|
|
comment_aligns.add_info(attrs_len, field_types[i].len, comment.pos.line_nr)
|
|
|
|
}
|
|
|
|
continue
|
2020-06-24 14:35:00 +02:00
|
|
|
}
|
2020-06-23 18:01:56 +02:00
|
|
|
if comment.pos.pos > field.pos.pos {
|
2021-01-13 03:30:24 +01:00
|
|
|
comments_len += '/* ${comment.text.trim_left('\x01')} */ '.len
|
2020-06-23 18:01:56 +02:00
|
|
|
}
|
|
|
|
}
|
2021-01-12 04:38:43 +01:00
|
|
|
field_aligns.add_info(comments_len + field.name.len, ft.len, field.pos.line_nr)
|
2021-01-03 21:10:25 +01:00
|
|
|
if field.has_default_expr {
|
|
|
|
default_expr_aligns.add_info(attrs_len, field_types[i].len, field.pos.line_nr)
|
2020-08-10 12:13:42 +02:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-12-23 19:12:49 +01:00
|
|
|
for embed in node.embeds {
|
2021-02-18 10:32:45 +01:00
|
|
|
f.mark_types_import_as_used(embed.typ)
|
2020-12-23 19:12:49 +01:00
|
|
|
styp := f.table.type_to_str(embed.typ)
|
|
|
|
f.writeln('\t$styp')
|
2020-10-30 07:09:26 +01:00
|
|
|
}
|
2021-01-12 04:38:43 +01:00
|
|
|
mut field_align_i := 0
|
2021-01-03 21:10:25 +01:00
|
|
|
mut comment_align_i := 0
|
|
|
|
mut default_expr_align_i := 0
|
2021-01-17 05:01:55 +01:00
|
|
|
mut inc_indent := false // for correct indents with multi line default exprs
|
2020-02-22 14:13:19 +01:00
|
|
|
for i, field in node.fields {
|
|
|
|
if i == node.mut_pos {
|
|
|
|
f.writeln('mut:')
|
2020-04-05 18:03:36 +02:00
|
|
|
} else if i == node.pub_pos {
|
2020-02-22 14:13:19 +01:00
|
|
|
f.writeln('pub:')
|
2020-04-05 18:03:36 +02:00
|
|
|
} else if i == node.pub_mut_pos {
|
2020-02-22 14:13:19 +01:00
|
|
|
f.writeln('pub mut:')
|
2021-02-05 16:46:43 +01:00
|
|
|
} else if i == node.global_pos {
|
|
|
|
f.writeln('__global:')
|
2021-01-17 05:39:44 +01:00
|
|
|
} else if i == node.module_pos {
|
|
|
|
f.writeln('module:')
|
2021-02-17 05:45:09 +01:00
|
|
|
} else if i > 0 {
|
|
|
|
// keep one empty line between fields (exclude one after mut:, pub:, ...)
|
|
|
|
mut before_last_line := node.fields[i - 1].pos.line_nr
|
|
|
|
if node.fields[i - 1].comments.len > 0 {
|
|
|
|
before_last_line = util.imax(before_last_line, node.fields[i - 1].comments.last().pos.last_line)
|
|
|
|
}
|
|
|
|
if node.fields[i - 1].has_default_expr {
|
|
|
|
before_last_line = util.imax(before_last_line, node.fields[i - 1].default_expr.position().last_line)
|
|
|
|
}
|
|
|
|
|
|
|
|
mut next_first_line := field.pos.line_nr
|
|
|
|
if field.comments.len > 0 {
|
|
|
|
next_first_line = util.imin(next_first_line, field.comments[0].pos.line_nr)
|
|
|
|
}
|
|
|
|
if next_first_line - before_last_line > 1 {
|
|
|
|
f.writeln('')
|
|
|
|
}
|
2020-02-22 14:13:19 +01:00
|
|
|
}
|
2020-06-23 18:01:56 +02:00
|
|
|
end_pos := field.pos.pos + field.pos.len
|
2021-01-19 10:43:48 +01:00
|
|
|
before_comments := field.comments.filter(it.pos.pos < field.pos.pos)
|
|
|
|
between_comments := field.comments[before_comments.len..].filter(it.pos.pos < end_pos)
|
|
|
|
after_type_comments := field.comments[(before_comments.len + between_comments.len)..]
|
|
|
|
// Handle comments before the field
|
|
|
|
f.comments_before_field(before_comments)
|
2020-02-17 22:50:04 +01:00
|
|
|
f.write('\t$field.name ')
|
2020-06-23 18:01:56 +02:00
|
|
|
// Handle comments between field name and type
|
2021-01-19 10:43:48 +01:00
|
|
|
before_len := f.line_len
|
|
|
|
f.comments(between_comments, iembed: true, has_nl: false)
|
|
|
|
comments_len := f.line_len - before_len
|
2021-01-12 04:38:43 +01:00
|
|
|
mut field_align := field_aligns[field_align_i]
|
|
|
|
if field_align.last_line < field.pos.line_nr {
|
|
|
|
field_align_i++
|
|
|
|
field_align = field_aligns[field_align_i]
|
|
|
|
}
|
|
|
|
f.write(strings.repeat(` `, field_align.max_len - field.name.len - comments_len))
|
2020-08-10 12:13:42 +02:00
|
|
|
f.write(field_types[i])
|
2021-02-18 10:32:45 +01:00
|
|
|
f.mark_types_import_as_used(field.typ)
|
2021-01-03 21:10:25 +01:00
|
|
|
attrs_len := inline_attrs_len(field.attrs)
|
|
|
|
has_attrs := field.attrs.len > 0
|
|
|
|
if has_attrs {
|
2021-01-12 04:38:43 +01:00
|
|
|
f.write(strings.repeat(` `, field_align.max_type_len - field_types[i].len))
|
2020-10-15 22:12:59 +02:00
|
|
|
f.inline_attrs(field.attrs)
|
|
|
|
}
|
2020-04-12 12:35:54 +02:00
|
|
|
if field.has_default_expr {
|
2021-01-03 21:10:25 +01:00
|
|
|
mut align := default_expr_aligns[default_expr_align_i]
|
|
|
|
if align.last_line < field.pos.line_nr {
|
|
|
|
default_expr_align_i++
|
|
|
|
align = default_expr_aligns[default_expr_align_i]
|
|
|
|
}
|
|
|
|
pad_len := align.max_attrs_len - attrs_len + align.max_type_len - field_types[i].len
|
|
|
|
f.write(strings.repeat(` `, pad_len))
|
2020-05-18 15:37:06 +02:00
|
|
|
f.write(' = ')
|
2021-01-17 05:01:55 +01:00
|
|
|
if !expr_is_single_line(field.default_expr) {
|
|
|
|
f.indent++
|
|
|
|
inc_indent = true
|
|
|
|
}
|
2020-07-02 14:06:29 +02:00
|
|
|
f.prefix_expr_cast_expr(field.default_expr)
|
2021-01-17 05:01:55 +01:00
|
|
|
if inc_indent {
|
|
|
|
f.indent--
|
|
|
|
inc_indent = false
|
|
|
|
}
|
2020-04-10 00:30:43 +02:00
|
|
|
}
|
2021-01-19 10:43:48 +01:00
|
|
|
// Handle comments after field type
|
|
|
|
if after_type_comments.len > 0 {
|
|
|
|
if after_type_comments[0].pos.line_nr > field.pos.line_nr {
|
2020-10-15 22:12:59 +02:00
|
|
|
f.writeln('')
|
|
|
|
} else {
|
2021-01-03 21:10:25 +01:00
|
|
|
if !field.has_default_expr {
|
|
|
|
mut align := comment_aligns[comment_align_i]
|
|
|
|
if align.last_line < field.pos.line_nr {
|
|
|
|
comment_align_i++
|
|
|
|
align = comment_aligns[comment_align_i]
|
|
|
|
}
|
2021-01-28 11:23:48 +01:00
|
|
|
pad_len := align.max_attrs_len - attrs_len + align.max_type_len - field_types[i].len
|
2021-01-03 21:10:25 +01:00
|
|
|
f.write(strings.repeat(` `, pad_len))
|
|
|
|
}
|
2020-10-15 22:12:59 +02:00
|
|
|
f.write(' ')
|
|
|
|
}
|
2021-01-19 10:43:48 +01:00
|
|
|
f.comments(after_type_comments, level: .indent)
|
2020-10-15 22:12:59 +02:00
|
|
|
} else {
|
|
|
|
f.writeln('')
|
2020-04-05 12:25:33 +02:00
|
|
|
}
|
2020-06-23 18:01:56 +02:00
|
|
|
}
|
2020-08-27 14:07:49 +02:00
|
|
|
f.comments_after_last_field(node.end_comments)
|
|
|
|
f.writeln('}\n')
|
|
|
|
}
|
|
|
|
|
2020-07-14 18:52:28 +02:00
|
|
|
pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) {
|
|
|
|
if node.is_pub {
|
|
|
|
f.write('pub ')
|
|
|
|
}
|
|
|
|
name := node.name.after('.')
|
2020-12-22 23:43:48 +01:00
|
|
|
f.write('interface $name {')
|
2021-01-23 07:57:17 +01:00
|
|
|
if node.fields.len > 0 || node.methods.len > 0 || node.pos.line_nr < node.pos.last_line {
|
2020-12-22 23:43:48 +01:00
|
|
|
f.writeln('')
|
|
|
|
}
|
2020-10-14 21:48:49 +02:00
|
|
|
f.comments_after_last_field(node.pre_comments)
|
2021-01-23 07:57:17 +01:00
|
|
|
for field in node.fields {
|
|
|
|
// TODO: alignment, comments, etc.
|
|
|
|
mut ft := f.no_cur_mod(f.table.type_to_str(field.typ))
|
|
|
|
if !ft.contains('C.') && !ft.contains('JS.') && !ft.contains('fn (') {
|
|
|
|
ft = f.short_module(ft)
|
|
|
|
}
|
|
|
|
f.writeln('\t$field.name $ft')
|
|
|
|
}
|
2020-07-14 18:52:28 +02:00
|
|
|
for method in node.methods {
|
|
|
|
f.write('\t')
|
2020-12-22 21:38:13 +01:00
|
|
|
f.write(method.stringify(f.table, f.cur_mod, f.mod2alias).after('fn '))
|
2020-12-04 10:22:26 +01:00
|
|
|
f.comments(method.comments, inline: true, has_nl: false, level: .indent)
|
2020-11-05 17:23:45 +01:00
|
|
|
f.writeln('')
|
2020-12-28 17:14:55 +01:00
|
|
|
f.comments(method.next_comments, inline: false, has_nl: true, level: .indent)
|
2020-07-14 18:52:28 +02:00
|
|
|
}
|
|
|
|
f.writeln('}\n')
|
|
|
|
}
|
|
|
|
|
2020-12-22 23:43:48 +01:00
|
|
|
pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) {
|
|
|
|
f.attrs(node.attrs)
|
|
|
|
if node.is_pub {
|
|
|
|
f.write('pub ')
|
|
|
|
}
|
|
|
|
name := node.name.after('.')
|
|
|
|
if node.fields.len == 0 && node.pos.line_nr == node.pos.last_line {
|
|
|
|
f.writeln('enum $name {}\n')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
f.writeln('enum $name {')
|
|
|
|
f.comments(node.comments, inline: true, level: .indent)
|
|
|
|
for field in node.fields {
|
|
|
|
f.write('\t$field.name')
|
|
|
|
if field.has_expr {
|
|
|
|
f.write(' = ')
|
|
|
|
f.expr(field.expr)
|
|
|
|
}
|
|
|
|
f.comments(field.comments, inline: true, has_nl: false, level: .indent)
|
|
|
|
f.writeln('')
|
2020-12-25 20:41:59 +01:00
|
|
|
f.comments(field.next_comments, inline: false, has_nl: true, level: .indent)
|
2020-12-22 23:43:48 +01:00
|
|
|
}
|
|
|
|
f.writeln('}\n')
|
|
|
|
}
|
|
|
|
|
2020-07-02 14:06:29 +02:00
|
|
|
pub fn (mut f Fmt) prefix_expr_cast_expr(fexpr ast.Expr) {
|
2020-05-30 21:29:59 +02:00
|
|
|
mut is_pe_amp_ce := false
|
|
|
|
if fexpr is ast.PrefixExpr {
|
2020-07-09 17:14:14 +02:00
|
|
|
if fexpr.right is ast.CastExpr && fexpr.op == .amp {
|
2021-01-04 17:22:04 +01:00
|
|
|
mut ce := fexpr.right as ast.CastExpr
|
2020-07-02 14:06:29 +02:00
|
|
|
ce.typname = f.table.get_type_symbol(ce.typ).name
|
2020-05-30 21:29:59 +02:00
|
|
|
is_pe_amp_ce = true
|
|
|
|
f.expr(ce)
|
|
|
|
}
|
2020-09-08 00:36:05 +02:00
|
|
|
} else if fexpr is ast.CastExpr {
|
|
|
|
last := f.out.cut_last(1)
|
|
|
|
if last != '&' {
|
2021-02-22 12:18:11 +01:00
|
|
|
f.out.write_string(last)
|
2020-09-08 00:36:05 +02:00
|
|
|
}
|
2020-05-30 21:29:59 +02:00
|
|
|
}
|
|
|
|
if !is_pe_amp_ce {
|
|
|
|
f.expr(fexpr)
|
2020-09-08 00:36:05 +02:00
|
|
|
if fexpr is ast.PrefixExpr {
|
|
|
|
f.or_expr(fexpr.or_block)
|
|
|
|
}
|
2020-05-30 21:29:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) expr(node ast.Expr) {
|
2020-05-04 16:22:41 +02:00
|
|
|
if f.is_debug {
|
2021-01-07 20:32:02 +01:00
|
|
|
eprintln('expr: ${node.position():-42} | node: ${node.type_name():-20} | $node.str()')
|
2020-05-04 16:22:41 +02:00
|
|
|
}
|
2020-11-25 12:09:40 +01:00
|
|
|
match mut node {
|
2020-10-21 21:58:40 +02:00
|
|
|
ast.CTempVar {
|
|
|
|
eprintln('ast.CTempVar of $node.orig.str() should be generated/used only in cgen')
|
|
|
|
}
|
2020-04-25 17:49:16 +02:00
|
|
|
ast.AnonFn {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.fn_decl(node.decl)
|
2020-04-25 17:49:16 +02:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.ArrayInit {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.array_init(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-03-06 22:12:15 +01:00
|
|
|
ast.AsCast {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.as_cast(node)
|
2020-03-06 22:12:15 +01:00
|
|
|
}
|
2020-02-22 14:39:25 +01:00
|
|
|
ast.Assoc {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.assoc(node)
|
2020-02-22 14:39:25 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.BoolLiteral {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.write(node.val.str())
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-02-27 18:02:40 +01:00
|
|
|
ast.CastExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.cast_expr(node)
|
2020-02-27 18:02:40 +01:00
|
|
|
}
|
2020-11-05 09:12:32 +01:00
|
|
|
ast.AtExpr {
|
|
|
|
f.at_expr(node)
|
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.CallExpr {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.call_expr(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-08-14 21:18:42 +02:00
|
|
|
ast.ChanInit {
|
2020-08-27 22:37:33 +02:00
|
|
|
f.chan_init(mut node)
|
2020-08-14 21:18:42 +02:00
|
|
|
}
|
2020-02-27 21:51:40 +01:00
|
|
|
ast.CharLiteral {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.write('`$node.val`')
|
2020-02-27 21:51:40 +01:00
|
|
|
}
|
2020-07-17 19:13:22 +02:00
|
|
|
ast.Comment {
|
2021-02-24 19:33:59 +01:00
|
|
|
f.comment(node, inline: true)
|
2020-07-17 19:13:22 +02:00
|
|
|
}
|
2020-06-11 20:26:46 +02:00
|
|
|
ast.ComptimeCall {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.comptime_call(node)
|
2020-06-11 20:26:46 +02:00
|
|
|
}
|
2021-01-05 15:11:43 +01:00
|
|
|
ast.ComptimeSelector {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.comptime_selector(node)
|
2021-01-05 15:11:43 +01:00
|
|
|
}
|
2020-04-25 17:49:16 +02:00
|
|
|
ast.ConcatExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.concat_expr(node)
|
2020-04-25 17:49:16 +02:00
|
|
|
}
|
2020-02-18 03:28:39 +01:00
|
|
|
ast.EnumVal {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.enum_val(node)
|
2020-02-18 03:28:39 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.FloatLiteral {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.write(node.val)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2021-01-15 13:45:26 +01:00
|
|
|
ast.GoExpr {
|
2021-01-15 22:40:26 +01:00
|
|
|
f.go_stmt(node.go_stmt, true)
|
2021-01-15 13:45:26 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.IfExpr {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.if_expr(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
ast.Ident {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.ident(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-04-25 17:49:16 +02:00
|
|
|
ast.IfGuardExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.if_guard_expr(node)
|
2020-04-25 17:49:16 +02:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.InfixExpr {
|
2020-07-19 19:58:34 +02:00
|
|
|
f.infix_expr(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
ast.IndexExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.index_expr(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
ast.IntegerLiteral {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.write(node.val)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-07-04 12:44:25 +02:00
|
|
|
ast.LockExpr {
|
2020-07-04 15:13:58 +02:00
|
|
|
f.lock_expr(node)
|
2020-07-04 12:44:25 +02:00
|
|
|
}
|
2020-02-22 14:13:19 +01:00
|
|
|
ast.MapInit {
|
2020-12-06 02:04:45 +01:00
|
|
|
f.map_init(node)
|
2020-02-22 14:13:19 +01:00
|
|
|
}
|
2020-02-29 20:43:15 +01:00
|
|
|
ast.MatchExpr {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.match_expr(node)
|
2020-02-29 20:43:15 +01:00
|
|
|
}
|
2020-02-21 17:52:20 +01:00
|
|
|
ast.None {
|
|
|
|
f.write('none')
|
|
|
|
}
|
2020-04-25 17:49:16 +02:00
|
|
|
ast.OrExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
// shouldn't happen, an or expression is always linked to a call expr
|
2020-07-31 02:31:01 +02:00
|
|
|
panic('fmt: OrExpr should be linked to CallExpr')
|
2020-02-27 18:02:40 +01:00
|
|
|
}
|
2020-02-28 15:36:41 +01:00
|
|
|
ast.ParExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.par_expr(node)
|
2020-02-28 15:36:41 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.PostfixExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.postfix_expr(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
ast.PrefixExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.prefix_expr(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-02-29 17:45:08 +01:00
|
|
|
ast.RangeExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.range_expr(node)
|
2020-02-29 17:45:08 +01:00
|
|
|
}
|
2020-09-16 15:34:57 +02:00
|
|
|
ast.SelectExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.select_expr(node)
|
2020-09-16 15:34:57 +02:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.SelectorExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.selector_expr(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-04-07 18:51:39 +02:00
|
|
|
ast.SizeOf {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.size_of(node)
|
2020-04-07 18:51:39 +02:00
|
|
|
}
|
2021-01-30 12:57:09 +01:00
|
|
|
ast.OffsetOf {
|
|
|
|
f.write('__offsetof(${f.table.type_to_str(node.struct_type)}, $node.field)')
|
|
|
|
}
|
2020-06-28 12:36:08 +02:00
|
|
|
ast.SqlExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.sql_expr(node)
|
2020-06-28 12:36:08 +02:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.StringLiteral {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.string_literal(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-03-24 22:18:58 +01:00
|
|
|
ast.StringInterLiteral {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.string_inter_literal(node)
|
2020-03-24 22:18:58 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
ast.StructInit {
|
2020-06-18 20:07:48 +02:00
|
|
|
f.struct_init(node)
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
2020-04-05 02:08:10 +02:00
|
|
|
ast.Type {
|
2020-10-13 15:17:02 +02:00
|
|
|
f.write(f.table.type_to_str(node.typ))
|
2020-04-05 02:08:10 +02:00
|
|
|
}
|
2020-04-03 11:59:53 +02:00
|
|
|
ast.TypeOf {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.type_of(node)
|
2020-04-03 11:59:53 +02:00
|
|
|
}
|
2020-06-09 16:36:18 +02:00
|
|
|
ast.Likely {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.likely(node)
|
2020-06-09 16:36:18 +02:00
|
|
|
}
|
2020-07-12 12:58:33 +02:00
|
|
|
ast.UnsafeExpr {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.unsafe_expr(node)
|
2020-07-12 12:58:33 +02:00
|
|
|
}
|
2020-12-29 16:14:08 +01:00
|
|
|
ast.ArrayDecompose {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.array_decompose(node)
|
2020-12-29 16:14:08 +01:00
|
|
|
}
|
2020-02-17 22:50:04 +01:00
|
|
|
}
|
|
|
|
}
|
2019-12-22 02:34:37 +01:00
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
fn expr_is_single_line(expr ast.Expr) bool {
|
|
|
|
match expr {
|
|
|
|
ast.AnonFn {
|
|
|
|
if !expr.decl.no_body {
|
|
|
|
return false
|
|
|
|
}
|
2020-03-02 17:09:45 +01:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
ast.IfExpr {
|
|
|
|
return false
|
2020-03-02 17:09:45 +01:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
ast.Comment {
|
|
|
|
return false
|
2020-03-02 17:09:45 +01:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
ast.MatchExpr {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
ast.StructInit {
|
|
|
|
if !expr.is_short && (expr.fields.len > 0 || expr.pre_comments.len > 0) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast.CallExpr {
|
|
|
|
if expr.or_block.stmts.len > 1 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
2021-01-17 05:01:55 +01:00
|
|
|
ast.ArrayInit {
|
|
|
|
if expr.exprs.len > 0 {
|
|
|
|
return expr_is_single_line(expr.exprs[0])
|
|
|
|
}
|
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
else {}
|
2020-03-02 17:09:45 +01:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
return true
|
2020-03-02 17:09:45 +01:00
|
|
|
}
|
|
|
|
|
2021-02-17 05:43:29 +01:00
|
|
|
pub fn (mut f Fmt) or_expr(node ast.OrExpr) {
|
|
|
|
match node.kind {
|
2020-05-23 08:51:15 +02:00
|
|
|
.absent {}
|
|
|
|
.block {
|
2021-02-17 05:43:29 +01:00
|
|
|
if node.stmts.len == 0 {
|
2020-07-04 13:11:34 +02:00
|
|
|
f.write(' or { }')
|
2021-02-17 05:43:29 +01:00
|
|
|
return
|
2021-02-26 07:41:24 +01:00
|
|
|
} else if node.stmts.len == 1 && stmt_is_single_line(node.stmts[0]) {
|
2020-12-04 12:25:23 +01:00
|
|
|
// the control stmts (return/break/continue...) print a newline inside them,
|
|
|
|
// so, since this'll all be on one line, trim any possible whitespace
|
2021-02-17 05:43:29 +01:00
|
|
|
str := f.stmt_str(node.stmts[0]).trim_space()
|
2020-12-04 12:25:23 +01:00
|
|
|
single_line := ' or { $str }'
|
2021-01-24 10:01:10 +01:00
|
|
|
if single_line.len + f.line_len <= fmt.max_len.last() {
|
2020-12-04 12:25:23 +01:00
|
|
|
f.write(single_line)
|
2021-02-17 05:43:29 +01:00
|
|
|
return
|
2020-12-04 12:25:23 +01:00
|
|
|
}
|
2020-07-04 13:11:34 +02:00
|
|
|
}
|
2021-02-17 05:43:29 +01:00
|
|
|
// Make it multiline if the blocks has at least two stmts
|
|
|
|
// or a single line would be too long
|
|
|
|
f.writeln(' or {')
|
|
|
|
f.stmts(node.stmts)
|
|
|
|
f.write('}')
|
2020-05-23 08:51:15 +02:00
|
|
|
}
|
|
|
|
.propagate {
|
2020-08-29 01:56:43 +02:00
|
|
|
f.write(' ?')
|
2020-05-23 08:51:15 +02:00
|
|
|
}
|
2020-03-02 17:09:45 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-05 02:08:10 +02:00
|
|
|
|
2020-08-04 20:10:22 +02:00
|
|
|
fn (mut f Fmt) attrs(attrs []table.Attr) {
|
|
|
|
for attr in attrs {
|
2020-08-10 02:00:14 +02:00
|
|
|
f.writeln('[$attr]')
|
2020-08-04 20:10:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn (mut f Fmt) inline_attrs(attrs []table.Attr) {
|
|
|
|
if attrs.len == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
f.write(' [')
|
|
|
|
for i, attr in attrs {
|
|
|
|
if i > 0 {
|
2020-08-10 12:13:42 +02:00
|
|
|
f.write('; ')
|
2020-08-04 20:10:22 +02:00
|
|
|
}
|
2020-08-10 02:00:14 +02:00
|
|
|
f.write('$attr')
|
2020-08-04 20:10:22 +02:00
|
|
|
}
|
|
|
|
f.write(']')
|
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
fn inline_attrs_len(attrs []table.Attr) int {
|
|
|
|
if attrs.len == 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
mut n := 2 // ' ['.len
|
|
|
|
for i, attr in attrs {
|
|
|
|
if i > 0 {
|
|
|
|
n += 2 // '; '.len
|
|
|
|
}
|
|
|
|
n += '$attr'.len
|
|
|
|
}
|
|
|
|
n++ // ']'.len
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) fn_decl(node ast.FnDecl) {
|
|
|
|
f.attrs(node.attrs)
|
|
|
|
f.write(node.stringify(f.table, f.cur_mod, f.mod2alias)) // `Expr` instead of `ast.Expr` in mod ast
|
|
|
|
if node.language == .v {
|
|
|
|
if !node.no_body {
|
|
|
|
f.write(' {')
|
|
|
|
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(node.stmts)
|
|
|
|
}
|
|
|
|
f.write('}')
|
|
|
|
}
|
|
|
|
if !node.is_anon {
|
2021-02-20 15:00:30 +01:00
|
|
|
f.writeln('')
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
} else {
|
2021-02-20 15:00:30 +01:00
|
|
|
f.writeln('')
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
// Mark all function's used type so that they are not removed from imports
|
|
|
|
for arg in node.params {
|
|
|
|
f.mark_types_import_as_used(arg.typ)
|
|
|
|
}
|
|
|
|
f.mark_types_import_as_used(node.return_type)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) as_cast(node ast.AsCast) {
|
|
|
|
type_str := f.table.type_to_str(node.typ)
|
|
|
|
f.expr(node.expr)
|
|
|
|
f.write(' as $type_str')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) cast_expr(node ast.CastExpr) {
|
|
|
|
f.write(f.table.type_to_str(node.typ) + '(')
|
|
|
|
f.expr(node.expr)
|
|
|
|
if node.has_arg {
|
|
|
|
f.write(', ')
|
|
|
|
f.expr(node.arg)
|
|
|
|
}
|
|
|
|
f.write(')')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) assoc(node ast.Assoc) {
|
|
|
|
f.writeln('{')
|
2021-02-20 09:54:55 +01:00
|
|
|
f.indent++
|
|
|
|
f.writeln('...$node.var_name')
|
2021-01-15 10:26:33 +01:00
|
|
|
for i, field in node.fields {
|
2021-02-20 09:54:55 +01:00
|
|
|
f.write('$field: ')
|
2021-01-15 10:26:33 +01:00
|
|
|
f.expr(node.exprs[i])
|
|
|
|
f.writeln('')
|
|
|
|
}
|
2021-02-20 09:54:55 +01:00
|
|
|
f.indent--
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) comptime_call(node ast.ComptimeCall) {
|
|
|
|
if node.is_vweb {
|
|
|
|
if node.method_name == 'html' {
|
|
|
|
f.write('\$vweb.html()')
|
|
|
|
} else {
|
|
|
|
f.write("\$tmpl('$node.args_var')")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if node.is_embed {
|
|
|
|
f.write("\$embed_file('$node.embed_file.rpath')")
|
2021-01-31 18:22:42 +01:00
|
|
|
} else if node.is_env {
|
|
|
|
f.write("\$env('$node.args_var')")
|
2021-01-15 10:26:33 +01:00
|
|
|
} else {
|
|
|
|
method_expr := if node.has_parens {
|
|
|
|
'(${node.method_name}($node.args_var))'
|
|
|
|
} else {
|
|
|
|
'${node.method_name}($node.args_var)'
|
|
|
|
}
|
|
|
|
f.write('${node.left}.$$method_expr')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) comptime_selector(node ast.ComptimeSelector) {
|
2021-01-30 12:56:10 +01:00
|
|
|
f.write('${node.left}.\$($node.field_expr)')
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) concat_expr(node ast.ConcatExpr) {
|
|
|
|
for i, val in node.vals {
|
|
|
|
if i != 0 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
f.expr(val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) enum_val(node ast.EnumVal) {
|
|
|
|
name := f.short_module(node.enum_name)
|
|
|
|
f.write(name + '.' + node.val)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) ident(node ast.Ident) {
|
|
|
|
if mut node.info is ast.IdentVar {
|
|
|
|
if node.info.is_mut {
|
|
|
|
f.write(node.info.share.str() + ' ')
|
|
|
|
}
|
2021-02-28 18:38:22 +01:00
|
|
|
var_info := node.var_info()
|
|
|
|
if var_info.is_static {
|
|
|
|
f.write('static ')
|
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
f.write_language_prefix(node.language)
|
|
|
|
if node.name == 'it' && f.it_name != '' && !f.inside_lambda { // allow `it` in lambdas
|
|
|
|
f.write(f.it_name)
|
|
|
|
} else if node.kind == .blank_ident {
|
|
|
|
f.write('_')
|
|
|
|
} else {
|
2021-01-24 10:01:10 +01:00
|
|
|
// Force usage of full path to const in the same module:
|
|
|
|
// `println(minute)` => `println(time.minute)`
|
2021-01-29 00:26:57 +01:00
|
|
|
// This makes it clear that a module const is being used
|
2021-01-24 10:01:10 +01:00
|
|
|
// (since V's conts are no longer ALL_CAP).
|
2021-01-25 12:08:43 +01:00
|
|
|
// ^^^ except for `main`, where consts are allowed to not have a `main.` prefix.
|
2021-01-24 10:54:27 +01:00
|
|
|
if !node.name.contains('.') && !f.inside_const {
|
2021-01-29 00:26:57 +01:00
|
|
|
mod := if f.cur_mod == '' { f.cur_short_mod } else { f.cur_mod } // TODO why is this needed?
|
|
|
|
full_name := mod + '.' + node.name
|
2021-01-24 10:01:10 +01:00
|
|
|
if obj := f.file.global_scope.find(full_name) {
|
|
|
|
if obj is ast.ConstField {
|
|
|
|
// "v.fmt.foo" => "fmt.foo"
|
|
|
|
vals := full_name.split('.')
|
2021-01-25 12:08:43 +01:00
|
|
|
mod_prefix := vals[vals.len - 2]
|
|
|
|
const_name := vals[vals.len - 1]
|
|
|
|
if mod_prefix == 'main' {
|
|
|
|
f.write(const_name)
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
short := mod_prefix + '.' + const_name
|
|
|
|
f.write(short)
|
2021-02-07 03:58:43 +01:00
|
|
|
f.mark_import_as_used(short)
|
2021-01-25 12:08:43 +01:00
|
|
|
return
|
|
|
|
}
|
2021-01-24 10:01:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
name := f.short_module(node.name)
|
|
|
|
f.write(name)
|
2021-02-07 03:58:43 +01:00
|
|
|
f.mark_import_as_used(name)
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) if_guard_expr(node ast.IfGuardExpr) {
|
|
|
|
f.write(node.var_name + ' := ')
|
|
|
|
f.expr(node.expr)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) index_expr(node ast.IndexExpr) {
|
|
|
|
f.expr(node.left)
|
|
|
|
f.write('[')
|
|
|
|
f.expr(node.index)
|
|
|
|
f.write(']')
|
2021-01-19 07:42:56 +01:00
|
|
|
if node.or_expr.kind != .absent {
|
|
|
|
f.or_expr(node.or_expr)
|
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) par_expr(node ast.ParExpr) {
|
|
|
|
f.write('(')
|
|
|
|
f.par_level++
|
|
|
|
f.expr(node.expr)
|
|
|
|
f.par_level--
|
|
|
|
f.write(')')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) postfix_expr(node ast.PostfixExpr) {
|
|
|
|
f.expr(node.expr)
|
|
|
|
// `$if foo ?`
|
|
|
|
if node.op == .question {
|
|
|
|
f.write(' ?')
|
|
|
|
} else {
|
|
|
|
f.write('$node.op')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) prefix_expr(node ast.PrefixExpr) {
|
|
|
|
f.write(node.op.str())
|
|
|
|
f.prefix_expr_cast_expr(node.right)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) range_expr(node ast.RangeExpr) {
|
|
|
|
f.expr(node.low)
|
|
|
|
if f.is_mbranch_expr {
|
|
|
|
f.write('...')
|
|
|
|
} else {
|
|
|
|
f.write('..')
|
|
|
|
}
|
|
|
|
f.expr(node.high)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) select_expr(node ast.SelectExpr) {
|
|
|
|
f.writeln('select {')
|
|
|
|
f.indent++
|
|
|
|
for branch in node.branches {
|
|
|
|
if branch.comment.text != '' {
|
|
|
|
f.comment(branch.comment, inline: true)
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
if branch.is_else {
|
|
|
|
f.write('else {')
|
|
|
|
} else {
|
|
|
|
if branch.is_timeout {
|
|
|
|
f.write('> ')
|
|
|
|
}
|
|
|
|
f.single_line_if = true
|
|
|
|
match branch.stmt {
|
|
|
|
ast.ExprStmt { f.expr(branch.stmt.expr) }
|
|
|
|
else { f.stmt(branch.stmt) }
|
|
|
|
}
|
|
|
|
f.single_line_if = false
|
|
|
|
f.write(' {')
|
|
|
|
}
|
|
|
|
if branch.stmts.len > 0 {
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(branch.stmts)
|
|
|
|
}
|
|
|
|
f.writeln('}')
|
|
|
|
if branch.post_comments.len > 0 {
|
|
|
|
f.comments(branch.post_comments, inline: true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.indent--
|
|
|
|
f.write('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) selector_expr(node ast.SelectorExpr) {
|
|
|
|
f.expr(node.expr)
|
|
|
|
f.write('.')
|
|
|
|
f.write(node.field_name)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) size_of(node ast.SizeOf) {
|
|
|
|
f.write('sizeof(')
|
|
|
|
if node.is_type {
|
|
|
|
sym := f.table.get_type_symbol(node.typ)
|
|
|
|
if sym.name != '' {
|
|
|
|
if f.is_external_name(sym.name) {
|
|
|
|
f.write(sym.name)
|
|
|
|
} else {
|
|
|
|
f.write(f.short_module(sym.name))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
f.write(f.table.type_to_str(node.typ))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
f.expr(node.expr)
|
|
|
|
}
|
|
|
|
f.write(')')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) sql_expr(node ast.SqlExpr) {
|
|
|
|
// sql app.db { select from Contributor where repo == id && user == 0 }
|
|
|
|
f.write('sql ')
|
|
|
|
f.expr(node.db_expr)
|
|
|
|
f.writeln(' {')
|
2021-01-26 10:36:46 +01:00
|
|
|
f.write('\tselect ')
|
|
|
|
table_name := util.strip_mod_name(f.table.get_type_symbol(node.table_expr.typ).name)
|
2021-01-15 10:26:33 +01:00
|
|
|
if node.is_count {
|
|
|
|
f.write('count ')
|
|
|
|
} else {
|
2021-01-26 10:36:46 +01:00
|
|
|
for i, fd in node.fields {
|
|
|
|
f.write(fd.name)
|
|
|
|
if i < node.fields.len - 1 {
|
|
|
|
f.write(', ')
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-22 23:28:26 +01:00
|
|
|
f.write('from $table_name')
|
2021-01-15 10:26:33 +01:00
|
|
|
if node.has_where {
|
|
|
|
f.write(' where ')
|
|
|
|
f.expr(node.where_expr)
|
|
|
|
}
|
|
|
|
if node.has_order {
|
|
|
|
f.write(' order by ')
|
|
|
|
f.expr(node.order_expr)
|
|
|
|
if node.has_desc {
|
|
|
|
f.write(' desc')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if node.has_limit {
|
|
|
|
f.write(' limit ')
|
|
|
|
f.expr(node.limit_expr)
|
|
|
|
}
|
|
|
|
if node.has_offset {
|
|
|
|
f.write(' offset ')
|
|
|
|
f.expr(node.offset_expr)
|
|
|
|
}
|
|
|
|
f.writeln('')
|
|
|
|
f.write('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) string_literal(node ast.StringLiteral) {
|
|
|
|
use_double_quote := node.val.contains("'") && !node.val.contains('"')
|
|
|
|
if node.is_raw {
|
|
|
|
f.write('r')
|
|
|
|
} else if node.language == table.Language.c {
|
|
|
|
f.write('c')
|
|
|
|
}
|
|
|
|
if node.is_raw {
|
|
|
|
if use_double_quote {
|
|
|
|
f.write('"$node.val"')
|
|
|
|
} else {
|
|
|
|
f.write("'$node.val'")
|
|
|
|
}
|
|
|
|
} else {
|
2021-01-24 10:01:10 +01:00
|
|
|
unescaped_val := node.val.replace('$fmt.bs$fmt.bs', '\x01').replace_each(["$fmt.bs'", "'",
|
|
|
|
'$fmt.bs"', '"'])
|
2021-01-15 10:26:33 +01:00
|
|
|
if use_double_quote {
|
2021-01-24 10:01:10 +01:00
|
|
|
s := unescaped_val.replace_each(['\x01', '$fmt.bs$fmt.bs', '"', '$fmt.bs"'])
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write('"$s"')
|
|
|
|
} else {
|
2021-01-24 10:01:10 +01:00
|
|
|
s := unescaped_val.replace_each(['\x01', '$fmt.bs$fmt.bs', "'", "$fmt.bs'"])
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write("'$s'")
|
2021-01-03 21:10:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
pub fn (mut f Fmt) string_inter_literal(node ast.StringInterLiteral) {
|
|
|
|
// TODO: this code is very similar to ast.Expr.str()
|
|
|
|
mut quote := "'"
|
|
|
|
for val in node.vals {
|
|
|
|
if val.contains("'") {
|
|
|
|
quote = '"'
|
|
|
|
}
|
|
|
|
if val.contains('"') {
|
|
|
|
quote = "'"
|
|
|
|
break
|
2020-04-25 17:49:16 +02:00
|
|
|
}
|
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write(quote)
|
|
|
|
for i, val in node.vals {
|
|
|
|
f.write(val)
|
|
|
|
if i >= node.exprs.len {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
f.write('$')
|
|
|
|
fspec_str, needs_braces := node.get_fspec_braces(i)
|
|
|
|
if needs_braces {
|
|
|
|
f.write('{')
|
|
|
|
f.expr(node.exprs[i])
|
|
|
|
f.write(fspec_str)
|
|
|
|
f.write('}')
|
|
|
|
} else {
|
|
|
|
f.expr(node.exprs[i])
|
|
|
|
}
|
2020-04-25 17:49:16 +02:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write(quote)
|
2020-04-25 17:49:16 +02:00
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
pub fn (mut f Fmt) type_of(node ast.TypeOf) {
|
|
|
|
f.write('typeof(')
|
|
|
|
f.expr(node.expr)
|
|
|
|
f.write(')')
|
2020-07-11 01:42:57 +02:00
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
pub fn (mut f Fmt) likely(node ast.Likely) {
|
|
|
|
if node.is_likely {
|
|
|
|
f.write('_likely_')
|
|
|
|
} else {
|
|
|
|
f.write('_unlikely_')
|
2020-11-11 20:40:56 +01:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write('(')
|
|
|
|
f.expr(node.expr)
|
|
|
|
f.write(')')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) unsafe_expr(node ast.UnsafeExpr) {
|
|
|
|
single_line := node.pos.line_nr >= node.pos.last_line
|
|
|
|
f.write('unsafe {')
|
|
|
|
if single_line {
|
|
|
|
f.write(' ')
|
|
|
|
} else {
|
|
|
|
f.writeln('')
|
|
|
|
f.indent++
|
|
|
|
f.empty_line = true
|
2020-04-05 03:37:38 +02:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
f.expr(node.expr)
|
|
|
|
if single_line {
|
|
|
|
f.write(' ')
|
|
|
|
} else {
|
|
|
|
f.writeln('')
|
|
|
|
f.indent--
|
2020-05-23 10:56:06 +02:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) array_decompose(node ast.ArrayDecompose) {
|
|
|
|
f.write('...')
|
|
|
|
f.expr(node.expr)
|
2020-04-05 18:03:36 +02:00
|
|
|
}
|
|
|
|
|
2020-07-04 12:44:25 +02:00
|
|
|
pub fn (mut f Fmt) lock_expr(lex ast.LockExpr) {
|
2021-02-03 15:16:52 +01:00
|
|
|
mut num_locked := 0
|
|
|
|
mut num_rlocked := 0
|
|
|
|
for is_rlock in lex.is_rlock {
|
|
|
|
if is_rlock {
|
|
|
|
num_rlocked++
|
|
|
|
} else {
|
|
|
|
num_locked++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if num_locked > 0 || num_rlocked == 0 {
|
|
|
|
f.write('lock ')
|
|
|
|
mut n := 0
|
|
|
|
for i, v in lex.lockeds {
|
|
|
|
if !lex.is_rlock[i] {
|
|
|
|
if n > 0 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
f.expr(v)
|
|
|
|
n++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if num_rlocked > 0 {
|
|
|
|
if num_locked > 0 {
|
|
|
|
f.write('; ')
|
|
|
|
}
|
|
|
|
f.write('rlock ')
|
|
|
|
mut n := 0
|
|
|
|
for i, v in lex.lockeds {
|
|
|
|
if lex.is_rlock[i] {
|
|
|
|
if n > 0 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
f.expr(v)
|
|
|
|
n++
|
|
|
|
}
|
2020-07-04 12:44:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
f.write(' {')
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(lex.stmts)
|
|
|
|
f.write('}')
|
|
|
|
}
|
|
|
|
|
2020-07-19 19:58:34 +02:00
|
|
|
pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
|
2020-10-15 22:12:59 +02:00
|
|
|
buffering_save := f.buffering
|
2021-01-28 11:23:48 +01:00
|
|
|
if !f.buffering && node.op in [.logical_or, .and, .plus] {
|
2020-07-19 19:58:34 +02:00
|
|
|
f.buffering = true
|
2020-10-15 22:12:59 +02:00
|
|
|
}
|
2021-02-01 20:08:42 +01:00
|
|
|
is_assign_save := f.is_assign
|
2021-01-24 08:02:35 +01:00
|
|
|
if node.op == .left_shift {
|
2021-02-01 20:08:42 +01:00
|
|
|
f.is_assign = true // To write ternary if on a single line
|
2021-01-24 08:02:35 +01:00
|
|
|
}
|
2021-02-07 23:10:39 +01:00
|
|
|
start_pos := f.out.len
|
2021-01-23 09:33:22 +01:00
|
|
|
start_len := f.line_len
|
2020-10-15 22:12:59 +02:00
|
|
|
f.expr(node.left)
|
2021-01-23 09:33:22 +01:00
|
|
|
is_one_val_array_init := node.op in [.key_in, .not_in] && node.right is ast.ArrayInit
|
|
|
|
&& (node.right as ast.ArrayInit).exprs.len == 1
|
2020-10-15 22:12:59 +02:00
|
|
|
if is_one_val_array_init {
|
|
|
|
// `var in [val]` => `var == val`
|
2021-01-23 09:33:22 +01:00
|
|
|
op := if node.op == .key_in { ' == ' } else { ' != ' }
|
|
|
|
f.write(op)
|
2020-10-15 22:12:59 +02:00
|
|
|
} else {
|
|
|
|
f.write(' $node.op.str() ')
|
|
|
|
}
|
|
|
|
if is_one_val_array_init {
|
|
|
|
// `var in [val]` => `var == val`
|
|
|
|
f.expr((node.right as ast.ArrayInit).exprs[0])
|
|
|
|
} else {
|
|
|
|
f.expr(node.right)
|
|
|
|
}
|
2021-01-23 09:33:22 +01:00
|
|
|
if !buffering_save && f.buffering {
|
2020-10-15 22:12:59 +02:00
|
|
|
f.buffering = false
|
2021-01-24 10:01:10 +01:00
|
|
|
if !f.single_line_if && f.line_len > fmt.max_len.last() {
|
2021-02-07 23:10:39 +01:00
|
|
|
f.wrap_infix(start_pos, start_len, false)
|
2020-10-15 22:12:59 +02:00
|
|
|
}
|
2020-07-19 19:58:34 +02:00
|
|
|
}
|
2021-02-01 20:08:42 +01:00
|
|
|
f.is_assign = is_assign_save
|
2021-01-08 21:39:21 +01:00
|
|
|
f.or_expr(node.or_block)
|
2020-07-19 19:58:34 +02:00
|
|
|
}
|
|
|
|
|
2021-02-07 23:10:39 +01:00
|
|
|
pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int, ignore_paren bool) {
|
2021-01-23 09:33:22 +01:00
|
|
|
cut_span := f.out.len - start_pos
|
|
|
|
condstr := f.out.cut_last(cut_span)
|
|
|
|
is_cond_infix := condstr.contains_any_substr(['&&', '||'])
|
|
|
|
if !is_cond_infix && !condstr.contains('+') {
|
|
|
|
f.write(condstr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
f.line_len = start_len
|
|
|
|
if start_len == 0 {
|
|
|
|
f.empty_line = true
|
|
|
|
}
|
|
|
|
or_pen := if condstr.contains('&&') { 3 } else { 5 }
|
|
|
|
cond_parts := condstr.split(' ')
|
|
|
|
mut grouped_cond := false
|
|
|
|
mut conditions := ['']
|
|
|
|
mut penalties := [5]
|
|
|
|
mut index := 0
|
|
|
|
for cp in cond_parts {
|
|
|
|
if is_cond_infix && cp in ['&&', '||'] {
|
|
|
|
if grouped_cond {
|
|
|
|
conditions[index] += '$cp '
|
|
|
|
} else {
|
|
|
|
p := if cp == '||' { or_pen } else { 5 }
|
|
|
|
penalties << p
|
|
|
|
conditions << '$cp '
|
|
|
|
index++
|
|
|
|
}
|
|
|
|
} else if !is_cond_infix && cp == '+' {
|
|
|
|
penalties << 5
|
|
|
|
conditions[index] += '$cp '
|
|
|
|
conditions << ''
|
|
|
|
index++
|
|
|
|
} else {
|
|
|
|
conditions[index] += '$cp '
|
2021-02-07 23:10:39 +01:00
|
|
|
if ignore_paren {
|
|
|
|
continue
|
|
|
|
}
|
2021-01-23 09:33:22 +01:00
|
|
|
if cp.starts_with('(') {
|
|
|
|
grouped_cond = true
|
|
|
|
} else if cp.ends_with(')') {
|
|
|
|
grouped_cond = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for i, c in conditions {
|
|
|
|
cnd := c.trim_space()
|
2021-01-24 10:01:10 +01:00
|
|
|
if f.line_len + cnd.len < fmt.max_len[penalties[i]] {
|
2021-02-07 23:10:39 +01:00
|
|
|
if (i > 0 && i < conditions.len) || (ignore_paren && i == 0 && cnd[3] == `(`) {
|
2021-01-23 09:33:22 +01:00
|
|
|
f.write(' ')
|
|
|
|
}
|
|
|
|
f.write(cnd)
|
|
|
|
} else {
|
2021-02-07 23:10:39 +01:00
|
|
|
prev_len := f.line_len
|
|
|
|
prev_pos := f.out.len
|
2021-01-23 09:33:22 +01:00
|
|
|
f.writeln('')
|
|
|
|
f.indent++
|
|
|
|
f.write(cnd)
|
|
|
|
f.indent--
|
2021-02-07 23:10:39 +01:00
|
|
|
if f.line_len > fmt.max_len.last() && (cnd[0] == `(` || cnd[3] == `(`)
|
|
|
|
&& cnd.ends_with(')') {
|
|
|
|
f.wrap_infix(prev_pos, prev_len, true)
|
|
|
|
}
|
2021-01-23 09:33:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-08 00:28:46 +01:00
|
|
|
pub fn (mut f Fmt) if_expr(node ast.IfExpr) {
|
|
|
|
dollar := if node.is_comptime { '$' } else { '' }
|
2021-02-20 15:05:05 +01:00
|
|
|
mut is_ternary := node.branches.len == 2 && node.has_else
|
2021-02-08 00:28:46 +01:00
|
|
|
&& branch_is_single_line(node.branches[0]) && branch_is_single_line(node.branches[1])
|
2021-02-14 19:22:24 +01:00
|
|
|
&& (node.is_expr || f.is_assign || f.is_struct_init || f.single_line_fields)
|
2021-02-20 15:05:05 +01:00
|
|
|
f.single_line_if = is_ternary
|
2021-02-16 09:13:48 +01:00
|
|
|
start_pos := f.out.len
|
|
|
|
start_len := f.line_len
|
2020-12-27 14:20:30 +01:00
|
|
|
for {
|
2021-02-08 00:28:46 +01:00
|
|
|
for i, branch in node.branches {
|
2020-12-27 14:20:30 +01:00
|
|
|
if i == 0 {
|
|
|
|
// first `if`
|
2020-07-20 16:48:33 +02:00
|
|
|
f.comments(branch.comments, {})
|
|
|
|
} else {
|
2020-12-27 14:20:30 +01:00
|
|
|
// `else`, close previous branch
|
|
|
|
if branch.comments.len > 0 {
|
|
|
|
f.writeln('}')
|
|
|
|
f.comments(branch.comments, {})
|
|
|
|
} else {
|
|
|
|
f.write('} ')
|
|
|
|
}
|
|
|
|
f.write('${dollar}else ')
|
|
|
|
}
|
2021-02-08 00:28:46 +01:00
|
|
|
if i < node.branches.len - 1 || !node.has_else {
|
2020-12-27 14:20:30 +01:00
|
|
|
f.write('${dollar}if ')
|
2021-01-26 11:19:32 +01:00
|
|
|
cur_pos := f.out.len
|
2020-12-27 14:20:30 +01:00
|
|
|
f.expr(branch.cond)
|
2021-01-26 11:19:32 +01:00
|
|
|
cond_len := f.out.len - cur_pos
|
|
|
|
is_cond_wrapped := cond_len > 0
|
|
|
|
&& (branch.cond is ast.IfGuardExpr || branch.cond is ast.CallExpr)
|
|
|
|
&& '\n' in f.out.last_n(cond_len)
|
|
|
|
if is_cond_wrapped {
|
|
|
|
f.writeln('')
|
|
|
|
} else {
|
|
|
|
f.write(' ')
|
|
|
|
}
|
2020-12-27 14:20:30 +01:00
|
|
|
}
|
|
|
|
f.write('{')
|
2021-02-20 15:05:05 +01:00
|
|
|
if is_ternary {
|
2020-12-27 14:20:30 +01:00
|
|
|
f.write(' ')
|
|
|
|
} else {
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
f.stmts(branch.stmts)
|
2021-02-20 15:05:05 +01:00
|
|
|
if is_ternary {
|
2020-12-27 14:20:30 +01:00
|
|
|
f.write(' ')
|
2020-07-20 16:48:33 +02:00
|
|
|
}
|
2020-04-05 19:35:10 +02:00
|
|
|
}
|
2021-01-28 11:23:48 +01:00
|
|
|
// When a single line if is really long, write it again as multiline,
|
|
|
|
// except it is part of an InfixExpr.
|
2021-02-20 15:05:05 +01:00
|
|
|
if is_ternary && f.line_len > fmt.max_len.last() && !f.buffering {
|
|
|
|
is_ternary = false
|
2020-12-27 14:20:30 +01:00
|
|
|
f.single_line_if = false
|
2021-02-16 09:13:48 +01:00
|
|
|
f.out.go_back_to(start_pos)
|
|
|
|
f.line_len = start_len
|
|
|
|
f.empty_line = start_len == 0
|
2020-12-27 14:20:30 +01:00
|
|
|
continue
|
2020-04-05 18:03:36 +02:00
|
|
|
}
|
2020-12-27 14:20:30 +01:00
|
|
|
break
|
2020-04-05 18:03:36 +02:00
|
|
|
}
|
|
|
|
f.write('}')
|
|
|
|
f.single_line_if = false
|
2021-02-08 00:28:46 +01:00
|
|
|
if node.post_comments.len > 0 {
|
2020-07-20 16:48:33 +02:00
|
|
|
f.writeln('')
|
2021-02-20 15:05:05 +01:00
|
|
|
f.comments(node.post_comments,
|
|
|
|
has_nl: false
|
|
|
|
prev_line: node.branches.last().body_pos.last_line
|
|
|
|
)
|
2020-07-20 16:48:33 +02:00
|
|
|
}
|
2020-04-05 03:37:38 +02:00
|
|
|
}
|
2020-04-12 17:45:04 +02:00
|
|
|
|
2020-12-27 12:59:28 +01:00
|
|
|
fn branch_is_single_line(b ast.IfBranch) bool {
|
|
|
|
if b.stmts.len == 1 && b.comments.len == 0 && stmt_is_single_line(b.stmts[0]) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-11-05 09:12:32 +01:00
|
|
|
pub fn (mut f Fmt) at_expr(node ast.AtExpr) {
|
|
|
|
f.write(node.name)
|
|
|
|
}
|
|
|
|
|
2021-01-05 01:29:58 +01:00
|
|
|
fn (mut f Fmt) write_generic_if_require(node ast.CallExpr) {
|
2021-01-22 13:49:56 +01:00
|
|
|
if node.generic_types.len > 0 {
|
2021-01-05 01:29:58 +01:00
|
|
|
f.write('<')
|
2021-01-22 13:49:56 +01:00
|
|
|
for i, generic_type in node.generic_types {
|
|
|
|
is_last := i == node.generic_types.len - 1
|
|
|
|
f.write(f.table.type_to_str(generic_type))
|
|
|
|
if !is_last {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
2021-01-05 01:29:58 +01:00
|
|
|
f.write('>')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
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() + ' ')
|
|
|
|
}
|
2021-02-06 21:46:52 +01:00
|
|
|
if i > 0 && !f.single_line_if {
|
2021-01-23 09:33:22 +01:00
|
|
|
f.wrap_long_line(3, true)
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
f.expr(arg.expr)
|
|
|
|
if i < args.len - 1 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.single_line_fields = false
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) call_expr(node ast.CallExpr) {
|
2020-12-04 10:22:26 +01:00
|
|
|
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 {
|
2021-01-10 17:39:37 +01:00
|
|
|
struct_expr := node.args.last().expr as ast.StructInit
|
|
|
|
if struct_expr.typ == table.void_type {
|
2020-12-04 10:22:26 +01:00
|
|
|
f.use_short_fn_args = true
|
|
|
|
}
|
2020-05-24 04:43:00 +02:00
|
|
|
}
|
2020-07-20 16:48:33 +02:00
|
|
|
for arg in node.args {
|
|
|
|
f.comments(arg.comments, {})
|
|
|
|
}
|
2020-04-12 17:45:04 +02:00
|
|
|
if node.is_method {
|
2020-10-30 07:35:44 +01:00
|
|
|
if node.name in ['map', 'filter'] {
|
|
|
|
f.inside_lambda = true
|
|
|
|
defer {
|
|
|
|
f.inside_lambda = false
|
|
|
|
}
|
|
|
|
}
|
2020-04-25 17:49:16 +02:00
|
|
|
if node.left is ast.Ident {
|
|
|
|
// `time.now()` without `time imported` is processed as a method call with `time` being
|
|
|
|
// a `node.left` expression. Import `time` automatically.
|
|
|
|
// TODO fetch all available modules
|
2020-11-21 00:05:57 +01:00
|
|
|
if node.left.name in ['time', 'os', 'strings', 'math', 'json', 'base64'] {
|
2021-01-08 17:42:40 +01:00
|
|
|
f.file.imports << ast.Import{
|
|
|
|
mod: node.left.name
|
|
|
|
alias: node.left.name
|
2020-04-12 17:45:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.expr(node.left)
|
2021-01-05 01:29:58 +01:00
|
|
|
f.write('.' + node.name)
|
2020-04-12 17:45:04 +02:00
|
|
|
} else {
|
2020-05-28 08:06:20 +02:00
|
|
|
f.write_language_prefix(node.language)
|
2020-11-21 00:05:57 +01:00
|
|
|
if node.left is ast.AnonFn {
|
|
|
|
f.fn_decl(node.left.decl)
|
2020-12-22 14:32:49 +01:00
|
|
|
} else if node.language != .v {
|
|
|
|
f.write('${node.name.after_char(`.`)}')
|
2020-08-13 20:05:59 +02:00
|
|
|
} else {
|
|
|
|
mut name := f.short_module(node.name)
|
2021-01-15 10:26:33 +01:00
|
|
|
f.mark_import_as_used(name)
|
2020-08-13 20:05:59 +02:00
|
|
|
if node.name in f.mod2alias {
|
|
|
|
name = f.mod2alias[node.name]
|
|
|
|
}
|
|
|
|
f.write('$name')
|
2020-07-18 21:34:38 +02:00
|
|
|
}
|
2020-04-12 17:45:04 +02:00
|
|
|
}
|
2021-02-12 20:10:54 +01:00
|
|
|
if node.mod == '' && node.name == '' {
|
|
|
|
f.write(node.left.str())
|
|
|
|
}
|
2021-02-06 21:46:52 +01:00
|
|
|
f.write_generic_if_require(node)
|
|
|
|
f.write('(')
|
|
|
|
f.call_args(node.args)
|
|
|
|
f.write(')')
|
|
|
|
f.or_expr(node.or_block)
|
2021-01-09 22:47:33 +01:00
|
|
|
f.comments(node.comments, has_nl: false)
|
2020-12-04 10:22:26 +01:00
|
|
|
f.use_short_fn_args = old_short_arg_state
|
2020-04-12 17:45:04 +02:00
|
|
|
}
|
2020-04-13 15:05:51 +02:00
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) match_expr(it ast.MatchExpr) {
|
2020-04-17 20:51:16 +02:00
|
|
|
f.write('match ')
|
|
|
|
f.expr(it.cond)
|
2020-06-18 20:07:48 +02:00
|
|
|
if it.cond is ast.Ident {
|
2020-11-21 00:05:57 +01:00
|
|
|
f.it_name = it.cond.name
|
2020-06-18 20:07:48 +02:00
|
|
|
}
|
2020-04-17 20:51:16 +02:00
|
|
|
f.writeln(' {')
|
|
|
|
f.indent++
|
2021-01-30 11:57:57 +01:00
|
|
|
f.comments(it.comments, {})
|
2020-04-21 05:11:50 +02:00
|
|
|
mut single_line := true
|
2020-04-28 15:04:37 +02:00
|
|
|
for branch in it.branches {
|
2021-01-30 11:57:57 +01:00
|
|
|
if branch.stmts.len > 1 || branch.pos.line_nr < branch.pos.last_line {
|
2021-01-31 10:05:49 +01:00
|
|
|
// println(branch)
|
2020-04-17 20:51:16 +02:00
|
|
|
single_line = false
|
|
|
|
break
|
|
|
|
}
|
2020-04-21 04:51:50 +02:00
|
|
|
if branch.stmts.len == 0 {
|
|
|
|
continue
|
|
|
|
}
|
2020-10-15 22:12:59 +02:00
|
|
|
if !stmt_is_single_line(branch.stmts[0]) {
|
|
|
|
single_line = false
|
|
|
|
break
|
2020-04-21 04:51:50 +02:00
|
|
|
}
|
2020-04-17 20:51:16 +02:00
|
|
|
}
|
2020-04-28 15:04:37 +02:00
|
|
|
for branch in it.branches {
|
2020-04-17 20:51:16 +02:00
|
|
|
if !branch.is_else {
|
|
|
|
// normal branch
|
2020-11-05 17:35:14 +01:00
|
|
|
f.is_mbranch_expr = true
|
2020-04-17 20:51:16 +02:00
|
|
|
for j, expr in branch.exprs {
|
|
|
|
f.expr(expr)
|
2020-11-11 21:53:21 +01:00
|
|
|
if j < branch.ecmnts.len && branch.ecmnts[j].len > 0 {
|
|
|
|
f.write(' ')
|
|
|
|
for cmnt in branch.ecmnts[j] {
|
2020-12-04 10:22:26 +01:00
|
|
|
f.comment(cmnt, iembed: true)
|
2020-11-11 21:53:21 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-17 20:51:16 +02:00
|
|
|
if j < branch.exprs.len - 1 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
2021-01-23 09:33:22 +01:00
|
|
|
f.wrap_long_line(4, false)
|
2020-04-17 20:51:16 +02:00
|
|
|
}
|
2020-11-05 17:35:14 +01:00
|
|
|
f.is_mbranch_expr = false
|
2020-04-17 20:51:16 +02:00
|
|
|
} else {
|
|
|
|
// else branch
|
|
|
|
f.write('else')
|
|
|
|
}
|
|
|
|
if branch.stmts.len == 0 {
|
|
|
|
f.writeln(' {}')
|
|
|
|
} else {
|
|
|
|
if single_line {
|
|
|
|
f.write(' { ')
|
|
|
|
} else {
|
|
|
|
f.writeln(' {')
|
|
|
|
}
|
|
|
|
f.stmts(branch.stmts)
|
|
|
|
if single_line {
|
2021-02-22 17:43:54 +01:00
|
|
|
f.remove_new_line({})
|
2020-04-17 20:51:16 +02:00
|
|
|
f.writeln(' }')
|
|
|
|
} else {
|
|
|
|
f.writeln('}')
|
|
|
|
}
|
|
|
|
}
|
2020-07-03 16:16:20 +02:00
|
|
|
if branch.post_comments.len > 0 {
|
2020-12-04 10:22:26 +01:00
|
|
|
f.comments(branch.post_comments, inline: true)
|
2020-07-03 16:16:20 +02:00
|
|
|
}
|
2020-04-17 20:51:16 +02:00
|
|
|
}
|
|
|
|
f.indent--
|
|
|
|
f.write('}')
|
2020-06-18 20:07:48 +02:00
|
|
|
f.it_name = ''
|
2020-04-17 20:51:16 +02:00
|
|
|
}
|
|
|
|
|
2020-08-27 22:37:33 +02:00
|
|
|
pub fn (mut f Fmt) chan_init(mut it ast.ChanInit) {
|
2020-09-08 00:36:05 +02:00
|
|
|
info := f.table.get_type_symbol(it.typ).chan_info()
|
2020-08-27 22:37:33 +02:00
|
|
|
if it.elem_type == 0 && it.typ > 0 {
|
|
|
|
it.elem_type = info.elem_type
|
|
|
|
}
|
2020-09-08 00:36:05 +02:00
|
|
|
is_mut := info.is_mut
|
2020-12-27 14:20:30 +01:00
|
|
|
el_typ := if is_mut {
|
|
|
|
it.elem_type.set_nr_muls(it.elem_type.nr_muls() - 1)
|
|
|
|
} else {
|
|
|
|
it.elem_type
|
|
|
|
}
|
2020-08-27 22:37:33 +02:00
|
|
|
f.write('chan ')
|
2020-09-08 00:36:05 +02:00
|
|
|
if is_mut {
|
|
|
|
f.write('mut ')
|
|
|
|
}
|
2020-10-13 15:17:02 +02:00
|
|
|
f.write(f.table.type_to_str(el_typ))
|
2020-08-27 22:37:33 +02:00
|
|
|
f.write('{')
|
|
|
|
if it.has_cap {
|
|
|
|
f.write('cap: ')
|
|
|
|
f.expr(it.cap_expr)
|
|
|
|
}
|
|
|
|
f.write('}')
|
|
|
|
}
|
|
|
|
|
2021-01-17 05:32:10 +01:00
|
|
|
fn should_decrease_arr_penalty(e ast.Expr) bool {
|
|
|
|
if e is ast.ArrayInit || e is ast.StructInit || e is ast.MapInit || e is ast.CallExpr {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-02-24 19:33:59 +01:00
|
|
|
pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
|
|
|
|
if node.exprs.len == 0 && node.typ != 0 && node.typ != table.void_type {
|
2021-01-17 05:32:10 +01:00
|
|
|
// `x := []string{}`
|
2021-02-24 19:33:59 +01:00
|
|
|
f.mark_types_import_as_used(node.typ)
|
|
|
|
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
|
2020-04-29 12:20:22 +02:00
|
|
|
f.write('{')
|
2021-02-24 19:33:59 +01:00
|
|
|
if node.has_len {
|
2020-05-13 16:11:52 +02:00
|
|
|
f.write('len: ')
|
2021-02-24 19:33:59 +01:00
|
|
|
f.expr(node.len_expr)
|
|
|
|
if node.has_cap || node.has_default {
|
2020-05-13 16:11:52 +02:00
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
2021-02-24 19:33:59 +01:00
|
|
|
if node.has_cap {
|
2020-04-29 12:20:22 +02:00
|
|
|
f.write('cap: ')
|
2021-02-24 19:33:59 +01:00
|
|
|
f.expr(node.cap_expr)
|
|
|
|
if node.has_default {
|
2020-05-13 16:11:52 +02:00
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
2021-02-24 19:33:59 +01:00
|
|
|
if node.has_default {
|
2020-05-13 22:00:24 +02:00
|
|
|
f.write('init: ')
|
2021-02-24 19:33:59 +01:00
|
|
|
f.expr(node.default_expr)
|
2020-04-29 12:20:22 +02:00
|
|
|
}
|
|
|
|
f.write('}')
|
2020-04-26 07:16:58 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
// `[1,2,3]`
|
|
|
|
f.write('[')
|
|
|
|
mut inc_indent := false
|
2021-02-24 19:33:59 +01:00
|
|
|
mut last_line_nr := node.pos.line_nr // to have the same newlines between array elements
|
2020-07-09 22:36:49 +02:00
|
|
|
f.array_init_depth++
|
2021-02-25 11:10:54 +01:00
|
|
|
if node.pre_cmnts.len > 0 {
|
|
|
|
if node.pre_cmnts[0].pos.line_nr > last_line_nr {
|
2021-02-21 19:18:19 +01:00
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
}
|
2021-02-25 11:10:54 +01:00
|
|
|
for i, c in node.pre_cmnts {
|
|
|
|
if i < node.pre_cmnts.len - 1 {
|
|
|
|
if c.pos.last_line < node.pre_cmnts[i + 1].pos.line_nr {
|
2021-02-26 08:01:03 +01:00
|
|
|
f.comment(c, level: .indent)
|
2021-02-25 11:10:54 +01:00
|
|
|
f.writeln('')
|
|
|
|
} else {
|
2021-02-26 08:01:03 +01:00
|
|
|
f.comment(c, level: .indent, iembed: true)
|
2021-02-25 11:10:54 +01:00
|
|
|
f.write(' ')
|
|
|
|
}
|
|
|
|
} else {
|
2021-02-26 08:01:03 +01:00
|
|
|
if c.pos.last_line < node.pos.last_line {
|
|
|
|
f.comment(c, level: .indent)
|
|
|
|
if node.exprs.len == 0 {
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
f.comment(c, level: .indent, iembed: true)
|
|
|
|
if node.exprs.len > 0 {
|
|
|
|
f.write(' ')
|
|
|
|
}
|
2021-02-25 11:10:54 +01:00
|
|
|
}
|
2021-02-22 16:53:55 +01:00
|
|
|
}
|
2021-02-25 11:10:54 +01:00
|
|
|
last_line_nr = c.pos.last_line
|
2021-02-21 19:18:19 +01:00
|
|
|
}
|
2021-02-24 19:33:59 +01:00
|
|
|
mut set_comma := false
|
|
|
|
for i, expr in node.exprs {
|
2021-02-25 11:10:54 +01:00
|
|
|
pos := expr.position()
|
2020-07-09 22:36:49 +02:00
|
|
|
if i == 0 {
|
|
|
|
if f.array_init_depth > f.array_init_break.len {
|
2021-02-25 11:10:54 +01:00
|
|
|
f.array_init_break << pos.line_nr > last_line_nr
|
2020-07-09 22:36:49 +02:00
|
|
|
}
|
2020-07-09 19:47:12 +02:00
|
|
|
}
|
2021-01-10 21:06:48 +01:00
|
|
|
line_break := f.array_init_break[f.array_init_depth - 1]
|
2021-02-25 11:10:54 +01:00
|
|
|
mut penalty := if line_break { 0 } else { 4 }
|
2020-07-09 19:47:12 +02:00
|
|
|
if penalty > 0 {
|
2021-02-24 19:33:59 +01:00
|
|
|
if i == 0 || should_decrease_arr_penalty(node.exprs[i - 1]) {
|
2020-07-09 19:47:12 +02:00
|
|
|
penalty--
|
|
|
|
}
|
2021-01-17 05:32:10 +01:00
|
|
|
if should_decrease_arr_penalty(expr) {
|
2020-07-09 19:47:12 +02:00
|
|
|
penalty--
|
|
|
|
}
|
2020-06-19 19:54:26 +02:00
|
|
|
}
|
|
|
|
is_new_line := f.wrap_long_line(penalty, !inc_indent)
|
|
|
|
if is_new_line && !inc_indent {
|
|
|
|
f.indent++
|
|
|
|
inc_indent = true
|
2020-04-26 07:16:58 +02:00
|
|
|
}
|
|
|
|
if !is_new_line && i > 0 {
|
|
|
|
f.write(' ')
|
|
|
|
}
|
|
|
|
f.expr(expr)
|
2021-02-24 19:33:59 +01:00
|
|
|
if i < node.ecmnts.len && node.ecmnts[i].len > 0 {
|
|
|
|
expr_pos := expr.position()
|
|
|
|
for cmt in node.ecmnts[i] {
|
|
|
|
if !set_comma && cmt.pos.pos > expr_pos.pos + expr_pos.len + 2 {
|
|
|
|
f.write(',')
|
|
|
|
set_comma = true
|
|
|
|
}
|
|
|
|
if cmt.pos.line_nr > expr_pos.last_line {
|
2021-01-29 19:19:14 +01:00
|
|
|
f.writeln('')
|
2021-02-26 08:01:03 +01:00
|
|
|
f.comment(cmt, {})
|
2021-02-24 19:33:59 +01:00
|
|
|
} else {
|
|
|
|
f.write(' ')
|
2021-02-26 08:01:03 +01:00
|
|
|
f.comment(cmt, iembed: true)
|
2021-01-29 19:19:14 +01:00
|
|
|
}
|
2020-11-11 21:53:21 +01:00
|
|
|
}
|
|
|
|
}
|
2021-02-24 19:33:59 +01:00
|
|
|
if i == node.exprs.len - 1 {
|
2020-04-26 07:16:58 +02:00
|
|
|
if is_new_line {
|
2021-02-25 11:10:54 +01:00
|
|
|
if !set_comma {
|
2020-07-17 19:13:22 +02:00
|
|
|
f.write(',')
|
|
|
|
}
|
2020-04-26 07:16:58 +02:00
|
|
|
f.writeln('')
|
|
|
|
}
|
2021-02-25 11:10:54 +01:00
|
|
|
} else if !set_comma {
|
2020-04-26 07:16:58 +02:00
|
|
|
f.write(',')
|
|
|
|
}
|
2021-02-25 11:10:54 +01:00
|
|
|
last_line_nr = pos.last_line
|
2021-02-24 19:33:59 +01:00
|
|
|
set_comma = false
|
2020-04-26 07:16:58 +02:00
|
|
|
}
|
2020-07-09 22:36:49 +02:00
|
|
|
f.array_init_depth--
|
|
|
|
if f.array_init_depth == 0 {
|
|
|
|
f.array_init_break = []
|
|
|
|
}
|
2020-04-26 07:16:58 +02:00
|
|
|
if inc_indent {
|
|
|
|
f.indent--
|
|
|
|
}
|
|
|
|
f.write(']')
|
2020-05-18 16:52:09 +02:00
|
|
|
// `[100]byte`
|
2021-02-24 19:33:59 +01:00
|
|
|
if node.is_fixed {
|
|
|
|
if node.has_val {
|
2021-01-13 08:32:17 +01:00
|
|
|
f.write('!')
|
2020-08-23 19:49:16 +02:00
|
|
|
return
|
|
|
|
}
|
2021-02-24 19:33:59 +01:00
|
|
|
f.write(f.table.type_to_str(node.elem_type))
|
|
|
|
if node.has_default {
|
2020-12-26 14:12:25 +01:00
|
|
|
f.write('{init: ')
|
2021-02-24 19:33:59 +01:00
|
|
|
f.expr(node.default_expr)
|
2020-12-26 14:12:25 +01:00
|
|
|
f.write('}')
|
2020-08-15 11:01:54 +02:00
|
|
|
} else {
|
|
|
|
f.write('{}')
|
|
|
|
}
|
2020-05-18 16:52:09 +02:00
|
|
|
}
|
2020-04-26 07:16:58 +02:00
|
|
|
}
|
2020-05-05 15:06:51 +02:00
|
|
|
|
2020-12-06 02:04:45 +01:00
|
|
|
pub fn (mut f Fmt) map_init(it ast.MapInit) {
|
|
|
|
if it.keys.len == 0 {
|
2021-02-08 15:57:42 +01:00
|
|
|
if it.typ > table.void_type {
|
|
|
|
f.mark_types_import_as_used(it.typ)
|
|
|
|
f.write(f.table.type_to_str(it.typ))
|
|
|
|
} else {
|
|
|
|
// m = map{}
|
|
|
|
f.write('map')
|
|
|
|
}
|
2020-12-06 02:04:45 +01:00
|
|
|
f.write('{}')
|
|
|
|
return
|
|
|
|
}
|
2021-02-08 15:57:42 +01:00
|
|
|
f.writeln('map{')
|
2020-12-06 02:04:45 +01:00
|
|
|
f.indent++
|
2021-02-22 12:04:48 +01:00
|
|
|
f.comments(it.pre_cmnts, {})
|
2020-12-06 02:04:45 +01:00
|
|
|
mut max_field_len := 0
|
|
|
|
for key in it.keys {
|
|
|
|
if key.str().len > max_field_len {
|
|
|
|
max_field_len = key.str().len
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for i, key in it.keys {
|
|
|
|
f.expr(key)
|
|
|
|
f.write(': ')
|
|
|
|
f.write(strings.repeat(` `, max_field_len - key.str().len))
|
|
|
|
f.expr(it.vals[i])
|
2021-02-22 12:04:48 +01:00
|
|
|
f.comments(it.comments[i], prev_line: it.vals[i].position().last_line, has_nl: false)
|
2020-12-06 02:04:45 +01:00
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
f.indent--
|
|
|
|
f.write('}')
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) struct_init(it ast.StructInit) {
|
2021-02-14 19:22:24 +01:00
|
|
|
struct_init_save := f.is_struct_init
|
|
|
|
f.is_struct_init = true
|
|
|
|
defer {
|
|
|
|
f.is_struct_init = struct_init_save
|
|
|
|
}
|
|
|
|
|
2020-05-05 15:06:51 +02:00
|
|
|
type_sym := f.table.get_type_symbol(it.typ)
|
|
|
|
// f.write('<old name: $type_sym.name>')
|
2020-07-02 14:06:29 +02:00
|
|
|
mut name := type_sym.name
|
|
|
|
if !name.starts_with('C.') {
|
2020-07-11 01:42:57 +02:00
|
|
|
name = f.no_cur_mod(f.short_module(type_sym.name)) // TODO f.type_to_str?
|
2020-07-02 14:06:29 +02:00
|
|
|
}
|
2020-05-05 15:06:51 +02:00
|
|
|
if name == 'void' {
|
|
|
|
name = ''
|
|
|
|
}
|
2021-01-04 19:19:03 +01:00
|
|
|
if it.fields.len == 0 && !it.has_update_expr {
|
2020-12-09 15:35:03 +01:00
|
|
|
// `Foo{}` on one line if there are no fields or comments
|
|
|
|
if it.pre_comments.len == 0 {
|
|
|
|
f.write('$name{}')
|
|
|
|
} else {
|
|
|
|
f.writeln('$name{')
|
|
|
|
f.comments(it.pre_comments, inline: true, has_nl: true, level: .indent)
|
|
|
|
f.write('}')
|
|
|
|
}
|
2021-02-07 03:58:43 +01:00
|
|
|
f.mark_import_as_used(name)
|
2020-05-18 15:37:06 +02:00
|
|
|
} else if it.is_short {
|
2020-05-05 15:06:51 +02:00
|
|
|
// `Foo{1,2,3}` (short syntax )
|
|
|
|
f.write('$name{')
|
2021-02-07 03:58:43 +01:00
|
|
|
f.mark_import_as_used(name)
|
2021-01-04 19:19:03 +01:00
|
|
|
if it.has_update_expr {
|
|
|
|
f.write('...')
|
|
|
|
f.expr(it.update_expr)
|
|
|
|
f.write(', ')
|
|
|
|
}
|
2020-05-05 15:06:51 +02:00
|
|
|
for i, field in it.fields {
|
2020-07-02 14:06:29 +02:00
|
|
|
f.prefix_expr_cast_expr(field.expr)
|
2020-05-05 15:06:51 +02:00
|
|
|
if i < it.fields.len - 1 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.write('}')
|
|
|
|
} else {
|
2020-12-04 10:22:26 +01:00
|
|
|
use_short_args := f.use_short_fn_args
|
|
|
|
f.use_short_fn_args = false
|
2021-01-10 17:39:37 +01:00
|
|
|
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
|
|
|
|
}
|
2020-12-04 10:22:26 +01:00
|
|
|
if !use_short_args {
|
2021-01-10 17:39:37 +01:00
|
|
|
f.write('$name{')
|
2021-02-07 03:58:43 +01:00
|
|
|
f.mark_import_as_used(name)
|
2021-01-10 17:39:37 +01:00
|
|
|
if single_line_fields {
|
|
|
|
f.write(' ')
|
2020-12-28 19:26:24 +01:00
|
|
|
}
|
2020-05-24 04:43:00 +02:00
|
|
|
}
|
2021-01-10 17:39:37 +01:00
|
|
|
fields_start := f.out.len
|
|
|
|
fields_loop: for {
|
|
|
|
if !single_line_fields {
|
|
|
|
f.writeln('')
|
|
|
|
f.indent++
|
|
|
|
}
|
2020-12-28 19:26:24 +01:00
|
|
|
f.comments(it.pre_comments, inline: true, has_nl: true, level: .keep)
|
2021-01-04 20:01:35 +01:00
|
|
|
if it.has_update_expr {
|
|
|
|
f.write('...')
|
|
|
|
f.expr(it.update_expr)
|
|
|
|
f.writeln('')
|
|
|
|
f.comments(it.update_expr_comments, inline: true, has_nl: true, level: .keep)
|
|
|
|
}
|
2020-12-28 17:14:08 +01:00
|
|
|
for i, field in it.fields {
|
|
|
|
f.write('$field.name: ')
|
|
|
|
f.prefix_expr_cast_expr(field.expr)
|
|
|
|
f.comments(field.comments, inline: true, has_nl: false, level: .indent)
|
2021-01-10 17:39:37 +01:00
|
|
|
if single_line_fields {
|
2020-12-28 17:14:08 +01:00
|
|
|
if i < it.fields.len - 1 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
f.writeln('')
|
2020-12-14 05:03:17 +01:00
|
|
|
}
|
2020-12-28 17:14:08 +01:00
|
|
|
f.comments(field.next_comments, inline: false, has_nl: true, level: .keep)
|
2021-02-07 23:10:39 +01:00
|
|
|
if single_line_fields && (field.comments.len > 0
|
|
|
|
|| field.next_comments.len > 0
|
|
|
|
|| !expr_is_single_line(field.expr)
|
2021-01-24 10:01:10 +01:00
|
|
|
|| f.line_len > fmt.max_len.last()) {
|
2021-01-10 17:39:37 +01:00
|
|
|
single_line_fields = false
|
|
|
|
f.out.go_back_to(fields_start)
|
|
|
|
f.line_len = fields_start
|
2021-02-22 17:43:54 +01:00
|
|
|
f.remove_new_line({})
|
2021-01-10 17:39:37 +01:00
|
|
|
continue fields_loop
|
2020-12-14 05:03:17 +01:00
|
|
|
}
|
|
|
|
}
|
2020-12-28 17:14:08 +01:00
|
|
|
break
|
2020-12-14 05:03:17 +01:00
|
|
|
}
|
2021-01-10 17:39:37 +01:00
|
|
|
if !single_line_fields {
|
|
|
|
f.indent--
|
|
|
|
}
|
2020-12-04 10:22:26 +01:00
|
|
|
if !use_short_args {
|
2021-01-10 17:39:37 +01:00
|
|
|
if single_line_fields {
|
|
|
|
f.write(' ')
|
|
|
|
}
|
2020-05-24 04:43:00 +02:00
|
|
|
f.write('}')
|
|
|
|
}
|
2020-05-05 15:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
2020-05-12 00:09:59 +02:00
|
|
|
|
2020-05-19 13:19:37 +02:00
|
|
|
pub fn (mut f Fmt) const_decl(it ast.ConstDecl) {
|
2020-05-12 00:09:59 +02:00
|
|
|
if it.is_pub {
|
|
|
|
f.write('pub ')
|
|
|
|
}
|
2020-12-22 23:43:48 +01:00
|
|
|
if it.fields.len == 0 && it.pos.line_nr == it.pos.last_line {
|
|
|
|
f.writeln('const ()\n')
|
|
|
|
return
|
|
|
|
}
|
2021-01-24 10:54:27 +01:00
|
|
|
f.inside_const = true
|
|
|
|
defer {
|
|
|
|
f.inside_const = false
|
|
|
|
}
|
2020-12-30 02:15:44 +01:00
|
|
|
f.write('const ')
|
|
|
|
if it.is_block {
|
2020-12-30 02:24:38 +01:00
|
|
|
f.writeln('(')
|
2020-12-30 02:15:44 +01:00
|
|
|
}
|
2020-05-12 00:09:59 +02:00
|
|
|
mut max := 0
|
|
|
|
for field in it.fields {
|
|
|
|
if field.name.len > max {
|
|
|
|
max = field.name.len
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.indent++
|
|
|
|
for field in it.fields {
|
2020-06-23 18:01:56 +02:00
|
|
|
comments := field.comments
|
|
|
|
mut j := 0
|
|
|
|
for j < comments.len && comments[j].pos.pos < field.pos.pos {
|
2020-12-04 10:22:26 +01:00
|
|
|
f.comment(comments[j], inline: true)
|
2020-07-17 19:13:22 +02:00
|
|
|
f.writeln('')
|
2020-06-23 18:01:56 +02:00
|
|
|
j++
|
2020-05-12 00:09:59 +02:00
|
|
|
}
|
|
|
|
name := field.name.after('.')
|
|
|
|
f.write('$name ')
|
|
|
|
f.write(strings.repeat(` `, max - field.name.len))
|
|
|
|
f.write('= ')
|
|
|
|
f.expr(field.expr)
|
|
|
|
f.writeln('')
|
|
|
|
}
|
2020-08-27 14:07:49 +02:00
|
|
|
f.comments_after_last_field(it.end_comments)
|
2020-05-12 00:09:59 +02:00
|
|
|
f.indent--
|
2020-12-30 02:15:44 +01:00
|
|
|
if it.is_block {
|
|
|
|
f.writeln(')\n')
|
|
|
|
} else {
|
|
|
|
f.writeln('')
|
|
|
|
}
|
2020-05-12 00:09:59 +02:00
|
|
|
}
|
2020-07-21 15:28:30 +02:00
|
|
|
|
2020-10-03 07:03:44 +02:00
|
|
|
fn (mut f Fmt) global_decl(it ast.GlobalDecl) {
|
|
|
|
single := it.fields.len == 1
|
|
|
|
if single {
|
|
|
|
f.write('__global ( ')
|
|
|
|
} else {
|
|
|
|
f.write('__global (')
|
|
|
|
f.writeln('')
|
|
|
|
f.indent++
|
|
|
|
}
|
|
|
|
mut max := 0
|
|
|
|
mut has_assign := false
|
|
|
|
for field in it.fields {
|
|
|
|
if field.name.len > max {
|
|
|
|
max = field.name.len
|
|
|
|
}
|
|
|
|
if field.has_expr {
|
|
|
|
has_assign = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for field in it.fields {
|
|
|
|
comments := field.comments
|
|
|
|
for comment in comments {
|
2020-12-04 10:22:26 +01:00
|
|
|
f.comment(comment, inline: true)
|
2020-10-03 07:03:44 +02:00
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
f.write('$field.name ')
|
|
|
|
f.write(strings.repeat(` `, max - field.name.len))
|
|
|
|
if field.has_expr {
|
|
|
|
f.write('= ')
|
2020-10-13 15:17:02 +02:00
|
|
|
f.write(f.table.type_to_str(field.typ))
|
2020-10-03 07:03:44 +02:00
|
|
|
f.write('(')
|
|
|
|
f.expr(field.expr)
|
|
|
|
f.write(')')
|
|
|
|
} else {
|
|
|
|
if !single && has_assign {
|
|
|
|
f.write(' ')
|
|
|
|
}
|
2020-10-13 15:17:02 +02:00
|
|
|
f.write('${f.table.type_to_str(field.typ)} ')
|
2020-10-03 07:03:44 +02:00
|
|
|
}
|
|
|
|
if !single {
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !single {
|
|
|
|
f.indent--
|
|
|
|
}
|
|
|
|
f.comments_after_last_field(it.end_comments)
|
|
|
|
f.writeln(')\n')
|
|
|
|
}
|
|
|
|
|
2021-01-15 10:26:33 +01:00
|
|
|
pub fn (mut f Fmt) assign_stmt(node ast.AssignStmt) {
|
|
|
|
f.comments(node.comments, {})
|
|
|
|
for i, left in node.left {
|
|
|
|
if left is ast.Ident {
|
|
|
|
f.expr(left)
|
|
|
|
} else {
|
|
|
|
f.expr(left)
|
|
|
|
}
|
|
|
|
if i < node.left.len - 1 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
2020-12-14 05:03:43 +01:00
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
f.is_assign = true
|
|
|
|
f.write(' $node.op.str() ')
|
|
|
|
for i, val in node.right {
|
|
|
|
f.prefix_expr_cast_expr(val)
|
|
|
|
if i < node.right.len - 1 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.comments(node.end_comments, has_nl: false, inline: true, level: .keep)
|
|
|
|
if !f.single_line_if {
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
f.is_assign = false
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) assert_stmt(node ast.AssertStmt) {
|
|
|
|
f.write('assert ')
|
2021-01-26 10:36:21 +01:00
|
|
|
if node.expr is ast.ParExpr {
|
|
|
|
if node.expr.expr is ast.InfixExpr {
|
|
|
|
infix := node.expr.expr
|
|
|
|
f.expr(infix)
|
|
|
|
f.writeln('')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
f.expr(node.expr)
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) block(node ast.Block) {
|
|
|
|
if node.is_unsafe {
|
|
|
|
f.write('unsafe ')
|
|
|
|
}
|
|
|
|
f.write('{')
|
|
|
|
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(node.stmts)
|
|
|
|
}
|
|
|
|
f.writeln('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) comp_for(node ast.CompFor) {
|
|
|
|
typ := f.no_cur_mod(f.table.type_to_str(node.typ))
|
|
|
|
f.write('\$for $node.val_var in ${typ}.$node.kind.str() {')
|
|
|
|
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(node.stmts)
|
|
|
|
}
|
|
|
|
f.writeln('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) defer_stmt(node ast.DeferStmt) {
|
|
|
|
f.write('defer {')
|
|
|
|
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(node.stmts)
|
|
|
|
}
|
|
|
|
f.writeln('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) expr_stmt(node ast.ExprStmt) {
|
|
|
|
f.comments(node.comments, {})
|
|
|
|
f.expr(node.expr)
|
|
|
|
if !f.single_line_if {
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) for_c_stmt(node ast.ForCStmt) {
|
|
|
|
if node.label.len > 0 {
|
|
|
|
f.write('$node.label: ')
|
|
|
|
}
|
|
|
|
f.write('for ')
|
|
|
|
if node.has_init {
|
|
|
|
f.single_line_if = true // to keep all for ;; exprs on the same line
|
|
|
|
f.stmt(node.init)
|
|
|
|
f.single_line_if = false
|
|
|
|
}
|
|
|
|
f.write('; ')
|
|
|
|
f.expr(node.cond)
|
|
|
|
f.write('; ')
|
|
|
|
f.stmt(node.inc)
|
2021-02-22 17:43:54 +01:00
|
|
|
f.remove_new_line({})
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write(' {')
|
|
|
|
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(node.stmts)
|
|
|
|
}
|
|
|
|
f.writeln('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) for_in_stmt(node ast.ForInStmt) {
|
|
|
|
if node.label.len > 0 {
|
|
|
|
f.write('$node.label: ')
|
|
|
|
}
|
|
|
|
f.write('for ')
|
|
|
|
if node.key_var != '' {
|
|
|
|
f.write(node.key_var)
|
|
|
|
}
|
|
|
|
if node.val_var != '' {
|
|
|
|
if node.key_var != '' {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
if node.val_is_mut {
|
|
|
|
f.write('mut ')
|
|
|
|
}
|
|
|
|
f.write(node.val_var)
|
|
|
|
}
|
|
|
|
f.write(' in ')
|
|
|
|
f.expr(node.cond)
|
|
|
|
if node.is_range {
|
|
|
|
f.write(' .. ')
|
|
|
|
f.expr(node.high)
|
|
|
|
}
|
|
|
|
f.write(' {')
|
|
|
|
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(node.stmts)
|
|
|
|
}
|
|
|
|
f.writeln('}')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) for_stmt(node ast.ForStmt) {
|
|
|
|
if node.label.len > 0 {
|
|
|
|
f.write('$node.label: ')
|
|
|
|
}
|
|
|
|
f.write('for ')
|
|
|
|
f.expr(node.cond)
|
2021-01-29 22:15:26 +01:00
|
|
|
if !node.is_inf {
|
|
|
|
f.write(' ')
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
2021-01-29 22:15:26 +01:00
|
|
|
f.write('{')
|
2021-01-15 10:26:33 +01:00
|
|
|
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
|
|
|
|
f.writeln('')
|
|
|
|
f.stmts(node.stmts)
|
|
|
|
}
|
|
|
|
f.writeln('}')
|
|
|
|
}
|
|
|
|
|
2021-01-15 22:40:26 +01:00
|
|
|
pub fn (mut f Fmt) go_stmt(node ast.GoStmt, is_expr bool) {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write('go ')
|
|
|
|
f.expr(node.call_expr)
|
2021-01-15 22:40:26 +01:00
|
|
|
if !is_expr {
|
|
|
|
f.writeln('')
|
|
|
|
}
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) return_stmt(node ast.Return) {
|
|
|
|
f.comments(node.comments, {})
|
|
|
|
f.write('return')
|
2021-01-25 23:22:14 +01:00
|
|
|
if node.exprs.len > 0 {
|
2021-01-15 10:26:33 +01:00
|
|
|
f.write(' ')
|
2021-01-25 23:22:14 +01:00
|
|
|
// Loop over all return values. In normal returns this will only run once.
|
2021-01-15 10:26:33 +01:00
|
|
|
for i, expr in node.exprs {
|
|
|
|
f.expr(expr)
|
|
|
|
if i < node.exprs.len - 1 {
|
|
|
|
f.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut f Fmt) sql_stmt(node ast.SqlStmt) {
|
|
|
|
f.write('sql ')
|
|
|
|
f.expr(node.db_expr)
|
|
|
|
f.writeln(' {')
|
2021-01-22 23:28:26 +01:00
|
|
|
table_name := util.strip_mod_name(f.table.get_type_symbol(node.table_expr.typ).name)
|
2021-01-26 10:36:46 +01:00
|
|
|
f.write('\t')
|
2021-01-15 10:26:33 +01:00
|
|
|
match node.kind {
|
|
|
|
.insert {
|
2021-01-26 10:36:46 +01:00
|
|
|
f.writeln('insert $node.object_var_name into $table_name')
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
.update {
|
2021-01-26 10:36:46 +01:00
|
|
|
f.write('update $table_name set ')
|
2021-01-15 10:26:33 +01:00
|
|
|
for i, col in node.updated_columns {
|
|
|
|
f.write('$col = ')
|
|
|
|
f.expr(node.update_exprs[i])
|
|
|
|
if i < node.updated_columns.len - 1 {
|
|
|
|
f.write(', ')
|
|
|
|
} else {
|
|
|
|
f.write(' ')
|
|
|
|
}
|
2021-01-23 09:33:22 +01:00
|
|
|
f.wrap_long_line(3, true)
|
2021-01-15 10:26:33 +01:00
|
|
|
}
|
|
|
|
f.write('where ')
|
|
|
|
f.expr(node.where_expr)
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
.delete {
|
2021-01-26 10:36:46 +01:00
|
|
|
f.write('delete from $table_name where ')
|
2021-01-15 10:26:33 +01:00
|
|
|
f.expr(node.where_expr)
|
|
|
|
f.writeln('')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.writeln('}')
|
2020-12-14 05:03:43 +01:00
|
|
|
}
|