1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast, parser, fmt: implement inline comments (#19012)

This commit is contained in:
yuyi 2023-08-01 02:22:51 +08:00 committed by GitHub
parent 0f861db9b0
commit 8861538c66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 294 additions and 113 deletions

View File

@ -532,10 +532,11 @@ pub:
method_idx int method_idx int
rec_mut bool // is receiver mutable rec_mut bool // is receiver mutable
rec_share ShareType rec_share ShareType
language Language // V, C, JS language Language // V, C, JS
file_mode Language // whether *the file*, where a function was a '.c.v', '.js.v' etc. file_mode Language // whether *the file*, where a function was a '.c.v', '.js.v' etc.
no_body bool // just a definition `fn C.malloc()` no_body bool // just a definition `fn C.malloc()`
is_builtin bool // this function is defined in builtin/strconv is_builtin bool // this function is defined in builtin/strconv
name_pos token.Pos
body_pos token.Pos // function bodys position body_pos token.Pos // function bodys position
file string file string
generic_names []string generic_names []string
@ -634,7 +635,8 @@ pub:
type_pos token.Pos type_pos token.Pos
is_hidden bool // interface first arg is_hidden bool // interface first arg
pub mut: pub mut:
typ Type typ Type
comments []Comment
} }
pub fn (p &Param) specifier() string { pub fn (p &Param) specifier() string {
@ -1195,6 +1197,7 @@ pub:
val_var string val_var string
is_range bool is_range bool
pos token.Pos pos token.Pos
kv_pos token.Pos
comments []Comment comments []Comment
val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array
// and the array cannot be indexed inside the loop // and the array cannot be indexed inside the loop

View File

@ -218,7 +218,7 @@ struct StringifyModReplacement {
weight int weight int
} }
fn shorten_full_name_based_on_aliases(input string, m2a map[string]string) string { pub fn shorten_full_name_based_on_aliases(input string, m2a map[string]string) string {
if m2a.len == 0 || -1 == input.index_u8(`.`) { if m2a.len == 0 || -1 == input.index_u8(`.`) {
// a simple typename, like `string` or `[]bool`; no module aliasings apply, // a simple typename, like `string` or `[]bool`; no module aliasings apply,
// (or there just are not any mappings) // (or there just are not any mappings)

View File

@ -14,14 +14,12 @@ pub enum CommentsLevel {
// - has_nl: adds an newline at the end of a list of comments // - has_nl: adds an newline at the end of a list of comments
// - inline: line comments will be on the same line as the last statement // - inline: line comments will be on the same line as the last statement
// - level: either .keep (don't indent), or .indent (increment indentation) // - level: either .keep (don't indent), or .indent (increment indentation)
// - iembed: a /* ... */ block comment used inside expressions; // comments the whole line
// - prev_line: the line number of the previous token to save linebreaks // - prev_line: the line number of the previous token to save linebreaks
[minify; params] [minify; params]
pub struct CommentsOptions { pub struct CommentsOptions {
has_nl bool = true has_nl bool = true
inline bool inline bool
level CommentsLevel level CommentsLevel
iembed bool
prev_line int = -1 prev_line int = -1
} }
@ -44,7 +42,7 @@ pub fn (mut f Fmt) comment(node ast.Comment, options CommentsOptions) {
if options.level == .indent { if options.level == .indent {
f.indent++ f.indent++
} }
if options.iembed { if node.is_inline && !node.is_multi {
x := node.text.trim_left('\x01').trim_space() x := node.text.trim_left('\x01').trim_space()
if x.contains('\n') { if x.contains('\n') {
f.writeln('/*') f.writeln('/*')
@ -105,7 +103,9 @@ pub fn (mut f Fmt) comments(comments []ast.Comment, options CommentsOptions) {
f.write(' ') f.write(' ')
} }
f.comment(c, options) f.comment(c, options)
if !options.iembed && (i < comments.len - 1 || options.has_nl) { if c.is_inline && i < comments.len - 1 && !c.is_multi {
f.write(' ')
} else if (!c.is_inline || c.is_multi) && (i < comments.len - 1 || options.has_nl) {
f.writeln('') f.writeln('')
} }
prev_line = c.pos.last_line prev_line = c.pos.last_line

View File

@ -813,8 +813,14 @@ pub fn (mut f Fmt) assert_stmt(node ast.AssertStmt) {
} }
pub fn (mut f Fmt) assign_stmt(node ast.AssignStmt) { pub fn (mut f Fmt) assign_stmt(node ast.AssignStmt) {
f.comments(node.comments) mut sum_len := 0
for i, left in node.left { for i, left in node.left {
pre_comments := node.comments[sum_len..].filter(it.pos.pos < left.pos().pos)
sum_len += pre_comments.len
if pre_comments.len > 0 {
f.comments(pre_comments)
f.write(' ')
}
f.expr(left) f.expr(left)
if i < node.left.len - 1 { if i < node.left.len - 1 {
f.write(', ') f.write(', ')
@ -823,6 +829,12 @@ pub fn (mut f Fmt) assign_stmt(node ast.AssignStmt) {
f.is_assign = true f.is_assign = true
f.write(' ${node.op.str()} ') f.write(' ${node.op.str()} ')
for i, val in node.right { for i, val in node.right {
pre_comments := node.comments[sum_len..].filter(it.pos.pos < val.pos().pos)
sum_len += pre_comments.len
if pre_comments.len > 0 {
f.comments(pre_comments)
f.write(' ')
}
f.expr(val) f.expr(val)
if i < node.right.len - 1 { if i < node.right.len - 1 {
f.write(', ') f.write(', ')
@ -1007,7 +1019,7 @@ pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) {
pub fn (mut f Fmt) fn_decl(node ast.FnDecl) { pub fn (mut f Fmt) fn_decl(node ast.FnDecl) {
f.attrs(node.attrs) f.attrs(node.attrs)
f.write(node.stringify_fn_decl(f.table, f.cur_mod, f.mod2alias)) // `Expr` instead of `ast.Expr` in mod ast f.fn_header(node)
// Handle trailing comments after fn header declarations // Handle trailing comments after fn header declarations
if node.no_body && node.end_comments.len > 0 { if node.no_body && node.end_comments.len > 0 {
first_comment := node.end_comments[0] first_comment := node.end_comments[0]
@ -1031,6 +1043,136 @@ pub fn (mut f Fmt) fn_decl(node ast.FnDecl) {
f.fn_body(node) f.fn_body(node)
} }
pub fn (mut f Fmt) fn_header(node ast.FnDecl) {
if node.is_pub {
f.write('pub ')
}
f.write('fn ')
pre_comments := node.comments.filter(it.pos.pos < node.name_pos.pos)
if pre_comments.len > 0 {
f.comments(pre_comments)
f.write(' ')
}
if node.is_method {
f.write('(')
mut styp := util.no_cur_mod(f.table.type_to_code(node.receiver.typ.clear_flag(.shared_f)),
f.cur_mod)
if node.rec_mut {
f.write(node.receiver.typ.share().str() + ' ')
styp = styp[1..] // remove &
}
f.write(node.receiver.name + ' ')
styp = util.no_cur_mod(styp, f.cur_mod)
if node.params[0].is_auto_rec {
styp = styp.trim('&')
}
f.write(styp + ') ')
} else if node.is_static_type_method {
mut styp := util.no_cur_mod(f.table.type_to_code(node.receiver.typ.clear_flag(.shared_f)),
f.cur_mod)
f.write(styp + '.')
}
mut name := if !node.is_method && node.language == .v {
node.name.all_after_last('.')
} else {
node.name
}
if node.is_static_type_method {
name = name.after('__static__')
}
f.write(name)
if name in ['+', '-', '*', '/', '%', '<', '>', '==', '!=', '>=', '<='] {
f.write(' ')
}
mut add_para_types := true
if node.generic_names.len > 0 {
if node.is_method {
sym := f.table.sym(node.params[0].typ)
if sym.info is ast.Struct {
generic_names := sym.info.generic_types.map(f.table.sym(it).name)
if generic_names == node.generic_names {
add_para_types = false
}
}
}
if add_para_types {
f.write('[')
for i, gname in node.generic_names {
is_last := i == node.generic_names.len - 1
f.write(gname)
if !is_last {
f.write(', ')
}
}
f.write(']')
}
}
f.write('(')
for i, arg in node.params {
before_comments := arg.comments.filter(it.pos.pos < arg.pos.pos)
if before_comments.len > 0 {
f.comments(before_comments, level: .indent)
}
// skip receiver
if node.is_method && i == 0 {
continue
}
if arg.is_hidden {
continue
}
is_last_arg := i == node.params.len - 1
is_type_only := arg.name == ''
should_add_type := true
if arg.is_mut {
f.write(arg.typ.share().str() + ' ')
}
f.write(arg.name)
arg_sym := f.table.sym(arg.typ)
if arg_sym.kind == .struct_ && (arg_sym.info as ast.Struct).is_anon {
f.write(' struct {')
struct_ := arg_sym.info as ast.Struct
for field in struct_.fields {
f.write(' ${field.name} ${f.table.type_to_str(field.typ)}')
if field.has_default_expr {
f.write(' = ${field.default_expr}')
}
}
if struct_.fields.len > 0 {
f.write(' ')
}
f.write('}')
} else {
mut s := f.table.type_to_str(arg.typ.clear_flag(.shared_f))
if arg.is_mut {
if s.starts_with('&') && ((!arg_sym.is_number() && arg_sym.kind != .bool)
|| node.language != .v) {
s = s[1..]
}
}
s = util.no_cur_mod(s, f.cur_mod)
s = ast.shorten_full_name_based_on_aliases(s, f.mod2alias)
if should_add_type {
if !is_type_only {
f.write(' ')
}
if node.is_variadic && is_last_arg {
f.write('...')
}
f.write(s)
}
}
if !is_last_arg {
f.write(', ')
}
}
f.write(')')
if node.return_type != ast.void_type {
sreturn_type := util.no_cur_mod(f.table.type_to_str(node.return_type), f.cur_mod)
short_sreturn_type := ast.shorten_full_name_based_on_aliases(sreturn_type, f.mod2alias)
f.write(' ${short_sreturn_type}')
}
}
pub fn (mut f Fmt) anon_fn(node ast.AnonFn) { pub fn (mut f Fmt) anon_fn(node ast.AnonFn) {
f.write(node.stringify_anon_decl(f.table, f.cur_mod, f.mod2alias)) // `Expr` instead of `ast.Expr` in mod ast f.write(node.stringify_anon_decl(f.table, f.cur_mod, f.mod2alias)) // `Expr` instead of `ast.Expr` in mod ast
f.fn_body(node.decl) f.fn_body(node.decl)
@ -1045,9 +1187,11 @@ fn (mut f Fmt) fn_body(node ast.FnDecl) {
if node.language == .v { if node.language == .v {
if !node.no_body { if !node.no_body {
f.write(' {') f.write(' {')
f.comments(node.comments, inline: true) pre_comments := node.comments.filter(it.pos.pos < node.name_pos.pos)
body_comments := node.comments[pre_comments.len..]
f.comments(body_comments, inline: true)
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
if node.comments.len == 0 { if body_comments.len == 0 {
f.writeln('') f.writeln('')
} }
f.stmts(node.stmts) f.stmts(node.stmts)
@ -1090,21 +1234,40 @@ pub fn (mut f Fmt) for_c_stmt(node ast.ForCStmt) {
if node.label.len > 0 { if node.label.len > 0 {
f.write('${node.label}: ') f.write('${node.label}: ')
} }
if node.comments.len > 0 { init_comments := node.comments.filter(it.pos.pos < node.init.pos.pos)
f.comments(node.comments) cond_comments := node.comments[init_comments.len..].filter(it.pos.pos < node.cond.pos().pos)
} inc_comments := node.comments[(init_comments.len + cond_comments.len)..].filter(it.pos.pos < node.inc.pos.pos)
after_inc_comments := node.comments[(init_comments.len + cond_comments.len + inc_comments.len)..]
f.write('for ') f.write('for ')
if node.has_init { if node.has_init {
if init_comments.len > 0 {
f.comments(init_comments)
f.write(' ')
}
f.single_line_if = true // to keep all for ;; exprs on the same line f.single_line_if = true // to keep all for ;; exprs on the same line
f.stmt(node.init) f.stmt(node.init)
f.single_line_if = false f.single_line_if = false
} }
f.write('; ') f.write('; ')
if cond_comments.len > 0 {
f.comments(cond_comments)
f.write(' ')
}
f.expr(node.cond) f.expr(node.cond)
f.write('; ') f.write('; ')
if inc_comments.len > 0 {
f.comments(inc_comments)
f.write(' ')
}
f.stmt(node.inc) f.stmt(node.inc)
f.remove_new_line() f.remove_new_line()
f.write(' {') if after_inc_comments.len > 0 {
f.comments(after_inc_comments)
}
if f.out.len > 1 && !f.out.last_n(1)[0].is_space() {
f.write(' ')
}
f.write('{')
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
f.writeln('') f.writeln('')
f.stmts(node.stmts) f.stmts(node.stmts)
@ -1116,10 +1279,14 @@ pub fn (mut f Fmt) for_in_stmt(node ast.ForInStmt) {
if node.label.len > 0 { if node.label.len > 0 {
f.write('${node.label}: ') f.write('${node.label}: ')
} }
if node.comments.len > 0 { kv_comments := node.comments.filter(it.pos.pos < node.kv_pos.pos)
f.comments(node.comments) cond_comments := node.comments[kv_comments.len..].filter(it.pos.pos < node.cond.pos().pos)
} after_comments := node.comments[(kv_comments.len + cond_comments.len)..]
f.write('for ') f.write('for ')
if kv_comments.len > 0 {
f.comments(kv_comments)
f.write(' ')
}
if node.key_var != '' { if node.key_var != '' {
f.write(node.key_var) f.write(node.key_var)
} }
@ -1133,12 +1300,22 @@ pub fn (mut f Fmt) for_in_stmt(node ast.ForInStmt) {
f.write(node.val_var) f.write(node.val_var)
} }
f.write(' in ') f.write(' in ')
if cond_comments.len > 0 {
f.comments(cond_comments)
f.write(' ')
}
f.expr(node.cond) f.expr(node.cond)
if node.is_range { if node.is_range {
f.write(' .. ') f.write(' .. ')
f.expr(node.high) f.expr(node.high)
} }
f.write(' {') if after_comments.len > 0 {
f.comments(after_comments)
}
if f.out.len > 1 && !f.out.last_n(1)[0].is_space() {
f.write(' ')
}
f.write('{')
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {
f.writeln('') f.writeln('')
f.stmts(node.stmts) f.stmts(node.stmts)
@ -1150,12 +1327,12 @@ pub fn (mut f Fmt) for_stmt(node ast.ForStmt) {
if node.label.len > 0 { if node.label.len > 0 {
f.write('${node.label}: ') f.write('${node.label}: ')
} }
f.write('for ')
if node.comments.len > 0 { if node.comments.len > 0 {
f.comments(node.comments) f.comments(node.comments)
} }
f.write('for ')
f.expr(node.cond) f.expr(node.cond)
if !node.is_inf { if f.out.len > 1 && !f.out.last_n(1)[0].is_space() {
f.write(' ') f.write(' ')
} }
f.write('{') f.write('{')
@ -1334,12 +1511,18 @@ pub fn (mut f Fmt) module_stmt(mod ast.Module) {
} }
pub fn (mut f Fmt) return_stmt(node ast.Return) { pub fn (mut f Fmt) return_stmt(node ast.Return) {
f.comments(node.comments)
f.write('return') f.write('return')
if node.exprs.len > 0 { if node.exprs.len > 0 {
f.write(' ') f.write(' ')
mut sum_len := 0
// Loop over all return values. In normal returns this will only run once. // Loop over all return values. In normal returns this will only run once.
for i, expr in node.exprs { for i, expr in node.exprs {
pre_comments := node.comments[sum_len..].filter(it.pos.pos < expr.pos().pos)
sum_len += pre_comments.len
if pre_comments.len > 0 {
f.comments(pre_comments)
f.write(' ')
}
if expr is ast.ParExpr { if expr is ast.ParExpr {
f.expr(expr.expr) f.expr(expr.expr)
} else { } else {
@ -1591,7 +1774,7 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
f.comment(c, level: .indent) f.comment(c, level: .indent)
f.writeln('') f.writeln('')
} else { } else {
f.comment(c, level: .indent, iembed: true) f.comment(c, level: .indent)
f.write(' ') f.write(' ')
} }
} else { } else {
@ -1606,7 +1789,7 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
f.writeln('') f.writeln('')
} }
} else { } else {
f.comment(c, level: .indent, iembed: true) f.comment(c, level: .indent)
if node.exprs.len > 0 { if node.exprs.len > 0 {
f.write(' ') f.write(' ')
} }
@ -1688,18 +1871,13 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
set_comma = true set_comma = true
} }
} }
mut next_pos := expr_pos
if i + 1 < node.exprs.len {
next_pos = node.exprs[i + 1].pos()
}
if cmt.pos.line_nr > expr_pos.last_line { if cmt.pos.line_nr > expr_pos.last_line {
embed := i + 1 < node.exprs.len && next_pos.line_nr == cmt.pos.last_line
f.writeln('') f.writeln('')
f.comment(cmt, iembed: embed) f.comment(cmt)
} else { } else {
if cmt.is_inline { if cmt.is_inline {
f.write(' ') f.write(' ')
f.comment(cmt, iembed: true) f.comment(cmt)
if !set_comma && cmt.pos.line_nr == expr_pos.last_line if !set_comma && cmt.pos.line_nr == expr_pos.last_line
&& cmt.pos.pos < expr_pos.pos { && cmt.pos.pos < expr_pos.pos {
f.write(',') f.write(',')
@ -1717,7 +1895,7 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
set_comma = true set_comma = true
} }
f.write(' ') f.write(' ')
f.comment(cmt, iembed: false) f.comment(cmt)
} }
} }
last_comment_was_inline = cmt.is_inline last_comment_was_inline = cmt.is_inline
@ -1793,10 +1971,6 @@ pub fn (mut f Fmt) at_expr(node ast.AtExpr) {
} }
pub fn (mut f Fmt) call_expr(node ast.CallExpr) { pub fn (mut f Fmt) call_expr(node ast.CallExpr) {
for arg in node.args {
f.comments(arg.comments)
}
mut is_method_newline := false mut is_method_newline := false
if node.is_method { if node.is_method {
if node.name in ['map', 'filter', 'all', 'any'] { if node.name in ['map', 'filter', 'all', 'any'] {
@ -1893,6 +2067,12 @@ pub fn (mut f Fmt) call_args(args []ast.CallArg) {
f.use_short_fn_args = old_short_arg_state f.use_short_fn_args = old_short_arg_state
} }
for i, arg in args { for i, arg in args {
pre_comments := arg.comments.filter(it.pos.pos < arg.expr.pos().pos)
post_comments := arg.comments[pre_comments.len..]
if pre_comments.len > 0 {
f.comments(pre_comments)
f.write(' ')
}
if i == args.len - 1 && arg.expr is ast.StructInit { if i == args.len - 1 && arg.expr is ast.StructInit {
if arg.expr.typ == ast.void_type { if arg.expr.typ == ast.void_type {
f.use_short_fn_args = true f.use_short_fn_args = true
@ -1905,6 +2085,10 @@ pub fn (mut f Fmt) call_args(args []ast.CallArg) {
f.wrap_long_line(3, true) f.wrap_long_line(3, true)
} }
f.expr(arg.expr) f.expr(arg.expr)
if post_comments.len > 0 {
f.comments(post_comments)
f.write(' ')
}
if i < args.len - 1 { if i < args.len - 1 {
f.write(', ') f.write(', ')
} }
@ -2133,14 +2317,16 @@ pub fn (mut f Fmt) if_expr(node ast.IfExpr) {
start_len := f.line_len start_len := f.line_len
for { for {
for i, branch in node.branches { for i, branch in node.branches {
if i == 0 { mut sum_len := 0
// first `if` if i > 0 {
f.comments(branch.comments)
} else {
// `else`, close previous branch // `else`, close previous branch
if branch.comments.len > 0 { if branch.comments.len > 0 {
f.writeln('}') f.writeln('}')
f.comments(branch.comments) pre_comments := branch.comments.filter(it.pos.pos < branch.pos.pos)
sum_len += pre_comments.len
if pre_comments.len > 0 {
f.comments(pre_comments)
}
} else { } else {
f.write('} ') f.write('} ')
} }
@ -2149,7 +2335,18 @@ pub fn (mut f Fmt) if_expr(node ast.IfExpr) {
if i < node.branches.len - 1 || !node.has_else { if i < node.branches.len - 1 || !node.has_else {
f.write('${dollar}if ') f.write('${dollar}if ')
cur_pos := f.out.len cur_pos := f.out.len
pre_comments := branch.comments[sum_len..].filter(it.pos.pos < branch.cond.pos().pos)
sum_len += pre_comments.len
post_comments := branch.comments[sum_len..]
if pre_comments.len > 0 {
f.comments(pre_comments)
f.write(' ')
}
f.expr(branch.cond) f.expr(branch.cond)
if post_comments.len > 0 {
f.comments(post_comments)
f.write(' ')
}
cond_len := f.out.len - cur_pos cond_len := f.out.len - cur_pos
is_cond_wrapped := cond_len > 0 && branch.cond in [ast.IfGuardExpr, ast.CallExpr] is_cond_wrapped := cond_len > 0 && branch.cond in [ast.IfGuardExpr, ast.CallExpr]
&& f.out.last_n(cond_len).contains('\n') && f.out.last_n(cond_len).contains('\n')
@ -2255,7 +2452,7 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
f.expr(node.left) f.expr(node.left)
} }
if node.before_op_comments.len > 0 { if node.before_op_comments.len > 0 {
f.comments(node.before_op_comments, iembed: node.before_op_comments[0].is_inline) f.comments(node.before_op_comments)
} }
is_one_val_array_init := node.op in [.key_in, .not_in] && node.right is ast.ArrayInit is_one_val_array_init := node.op in [.key_in, .not_in] && node.right is ast.ArrayInit
&& node.right.exprs.len == 1 && node.right.exprs.len == 1
@ -2270,7 +2467,7 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
f.write(' ${node.op.str()} ') f.write(' ${node.op.str()} ')
} }
if node.after_op_comments.len > 0 { if node.after_op_comments.len > 0 {
f.comments(node.after_op_comments, iembed: node.after_op_comments[0].is_inline) f.comments(node.after_op_comments)
f.write(' ') f.write(' ')
} }
if is_one_val_array_init && !f.inside_comptime_if { if is_one_val_array_init && !f.inside_comptime_if {
@ -2515,7 +2712,7 @@ fn (mut f Fmt) match_branch(branch ast.MatchBranch, single_line bool) {
f.write(estr) f.write(estr)
if j < branch.ecmnts.len && branch.ecmnts[j].len > 0 { if j < branch.ecmnts.len && branch.ecmnts[j].len > 0 {
f.write(' ') f.write(' ')
f.comments(branch.ecmnts[j], iembed: true) f.comments(branch.ecmnts[j])
} }
if j < branch.exprs.len - 1 { if j < branch.exprs.len - 1 {
f.write(', ') f.write(', ')

View File

@ -135,7 +135,7 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
f.write('\t${volatile_prefix}${field.name} ') f.write('\t${volatile_prefix}${field.name} ')
// Handle comments between field name and type // Handle comments between field name and type
before_len := f.line_len before_len := f.line_len
f.comments(between_comments, iembed: true, has_nl: false) f.comments(between_comments, has_nl: false)
comments_len := f.line_len - before_len comments_len := f.line_len - before_len
if field_aligns[field_align_i].line_nr < field.pos.line_nr { if field_aligns[field_align_i].line_nr < field.pos.line_nr {
field_align_i++ field_align_i++

View File

@ -5,5 +5,5 @@ v := [
// 2-3 // 2-3
3, // 3 3, // 3
// 4 // 4
// 5 /* 5 */
] ]

View File

@ -6,26 +6,23 @@ comment
*/ */
fn fun() int { fn fun() int {
// comment zero return /* comment zero */ 0 // another comment
return 0 // another comment
} }
fn mr_fun() (int, int) { fn mr_fun() (int, int) {
// one comment return /* one comment */ 1, /* another comment */ 2
// another comment
return 1, 2
} }
fn single_line_blocks() { fn single_line_blocks() {
// 1 /* 1 */
println('') println('')
// 2 /* 2 */
println('') println('')
// 3 /* 3 */
// 4 /* 4 */
println('') println('')
// 5 // 5
// 6 /* 6 */
} }
fn main() { fn main() {
@ -38,38 +35,28 @@ fn main() {
/* /*
block3 block3
*/ */
// this is a comment a := /* this is a comment */ 1
a := 1 b, c := /* and another comment */ a, /* just to make it worse */ 2
// and another comment
// just to make it worse
b, c := a, 2
d := c // and an extra one d := c // and an extra one
e := c e := c
// more comments = more good // more comments = more good
arr := [ arr := [
// block foo bar /* block foo bar */
// inline foo bar // inline foo bar
0, 0,
] ]
// before arg comment println( /* before arg comment */ 'this is a test' /* after arg comment */ )
// after arg comment if /* before if expr */ true /* after if expr */ {
println('this is a test')
// before if expr
// after if expr
if true {
println('if') println('if')
} }
// before else if // before else if
// between else if else if /* between else if */ false {
else if false {
println('else if') println('else if')
} }
// before else // before else
// after else
else { else {
println('else') println('else')
} }
// empty return
return return
} }
@ -104,47 +91,37 @@ fn between_if_branches() {
} }
} }
// comments for // comments
for { {
break break
} }
// comments for /* comments */ {
for {
break break
} }
// comments for i := 0; i < 1; i++ // comments
for i := 0; i < 1; i++ { {
break break
} }
// comments for i := 0; i < 1; i++ /* comments */ {
for i := 0; i < 1; i++ {
break break
} }
// comments1 for /* comments1 */ i := 0; /* comments2 */ i < 1; /* comments3 */ i++ /* comments4 */ {
// comments2
// comments3
// comments4
for i := 0; i < 1; i++ {
break break
} }
// comments for _ in [1, 2] /* comments */ {
for _ in [1, 2] {
break break
} }
// comments for _ in [1, 2] // comments
for _ in [1, 2] { {
break break
} }
// comments1 for /* comments1 */ _ in /* comments2 */ [1, 2] /* comments3 */ {
// comments2
// comments3
for _ in [1, 2] {
break break
} }

View File

@ -1,3 +1,2 @@
// comments if true /* comments */ {
if true {
} }

View File

@ -9,7 +9,7 @@ const two = 2
move move
*/ */
const three = 3 // rewrite and leave const three = 3 /* rewrite and leave */
// leave // leave
const four = 4 // leave const four = 4 // leave

View File

@ -1,12 +1,12 @@
fn C.Mix_LoadMUS1(file byteptr) voidptr // *Mix_Music fn C.Mix_LoadMUS1(file byteptr) voidptr // *Mix_Music
fn C.Mix_LoadMUS2(file byteptr) voidptr //*Mix_Music fn C.Mix_LoadMUS2(file byteptr) voidptr /* *Mix_Music */
fn C.Mix_LoadMUS3(file byteptr) voidptr // 1 fn C.Mix_LoadMUS3(file byteptr) voidptr /* 1 */
// 2 /* 2 */
// 3 /* 3 */
// Loads music // Loads music
fn C.Mix_LoadMUS4(file byteptr) voidptr fn C.Mix_LoadMUS4(file byteptr) voidptr

View File

@ -1,7 +1,8 @@
fn main() { // main fn /* main */ main() {
return return
} }
fn print_hi() { // hi fn // hi
print_hi() {
println('hi') println('hi')
} }

View File

@ -1,13 +1,12 @@
fn main() { fn main() {
a, b := true, true a, b := true, true
// a if a || b // a
if a || b { {
println('hi') println('hi')
} }
// a if a || b /* a */ {
if a || b {
println('hi') println('hi')
} }
} }

View File

@ -41,10 +41,7 @@ struct SomeStruct {
mut: mut:
// 2 // 2
// 3 // 3
somefield /* 4 */ /* 5 */ int // 6 somefield /* 4 */ /* 5 */ int /* 6 */ /* 7 */ /* 8 */ /*
// 7
// 8
/*
9 9
10 10
*/ */

View File

@ -620,6 +620,7 @@ run them via `v file.v` instead',
language: language language: language
no_body: no_body no_body: no_body
pos: start_pos.extend_with_last_line(end_pos, p.prev_tok.line_nr) pos: start_pos.extend_with_last_line(end_pos, p.prev_tok.line_nr)
name_pos: name_pos
body_pos: body_start_pos body_pos: body_start_pos
file: p.file_name file: p.file_name
is_builtin: p.builtin_mod || p.mod in util.builtin_module_parts is_builtin: p.builtin_mod || p.mod in util.builtin_module_parts
@ -867,6 +868,7 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
if types_only { if types_only {
mut arg_no := 1 mut arg_no := 1
for p.tok.kind != .rpar { for p.tok.kind != .rpar {
mut comments := p.eat_comments()
if p.tok.kind == .eof { if p.tok.kind == .eof {
p.error_with_pos('expecting `)`', p.tok.pos()) p.error_with_pos('expecting `)`', p.tok.pos())
return []ast.Param{}, false, false return []ast.Param{}, false, false
@ -926,6 +928,7 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
p.error_with_pos('expecting `)`', p.prev_tok.pos()) p.error_with_pos('expecting `)`', p.prev_tok.pos())
return []ast.Param{}, false, false return []ast.Param{}, false, false
} }
comments << p.eat_comments()
if p.tok.kind == .comma { if p.tok.kind == .comma {
if is_variadic { if is_variadic {
@ -954,6 +957,7 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
} }
} else { } else {
for p.tok.kind != .rpar { for p.tok.kind != .rpar {
mut comments := p.eat_comments()
if p.tok.kind == .eof { if p.tok.kind == .eof {
p.error_with_pos('expecting `)`', p.tok.pos()) p.error_with_pos('expecting `)`', p.tok.pos())
return []ast.Param{}, false, false return []ast.Param{}, false, false
@ -966,6 +970,7 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
} }
mut arg_pos := [p.tok.pos()] mut arg_pos := [p.tok.pos()]
name := p.check_name() name := p.check_name()
comments << p.eat_comments()
mut arg_names := [name] mut arg_names := [name]
if name.len > 0 && p.fn_language == .v && name[0].is_capital() { if name.len > 0 && p.fn_language == .v && name[0].is_capital() {
p.error_with_pos('parameter name must not begin with upper case letter (`${arg_names[0]}`)', p.error_with_pos('parameter name must not begin with upper case letter (`${arg_names[0]}`)',
@ -1031,6 +1036,7 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
// derive flags, however nr_muls only needs to be set on the array elem type, so clear it on the arg type // derive flags, however nr_muls only needs to be set on the array elem type, so clear it on the arg type
typ = ast.new_type(p.table.find_or_register_array(typ)).derive(typ).set_nr_muls(0).set_flag(.variadic) typ = ast.new_type(p.table.find_or_register_array(typ)).derive(typ).set_nr_muls(0).set_flag(.variadic)
} }
comments << p.eat_comments()
for i, arg_name in arg_names { for i, arg_name in arg_names {
alanguage := p.table.sym(typ).language alanguage := p.table.sym(typ).language
if alanguage != .v { if alanguage != .v {
@ -1044,6 +1050,7 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
is_shared: is_shared is_shared: is_shared
typ: typ typ: typ
type_pos: type_pos[i] type_pos: type_pos[i]
comments: comments
} }
// if typ.typ.kind == .variadic && p.tok.kind == .comma { // if typ.typ.kind == .variadic && p.tok.kind == .comma {
if is_variadic && p.tok.kind == .comma && p.peek_tok.kind != .rpar { if is_variadic && p.tok.kind == .comma && p.peek_tok.kind != .rpar {

View File

@ -198,6 +198,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
high: high_expr high: high_expr
is_range: is_range is_range: is_range
pos: pos pos: pos
kv_pos: key_var_pos
comments: comments comments: comments
val_is_mut: val_is_mut val_is_mut: val_is_mut
scope: p.scope scope: p.scope