Skip to content

Commit

Permalink
fmt: fix enum/struct_decl/struct_init fields with empty newlines
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Aug 15, 2024
1 parent f879368 commit cb7881d
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 50 deletions.
3 changes: 2 additions & 1 deletion vlib/sync/channels.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ pub struct Channel {
ringbuf &u8 = unsafe { nil } // queue for buffered channels
statusbuf &u8 = unsafe { nil } // flags to synchronize write/read in ringbuf
objsize u32
mut: // atomic
mut:
// atomic
writesem Semaphore // to wake thread that wanted to write, but buffer was full
readsem Semaphore // to wake thread that wanted to read, but buffer was empty
writesem_im Semaphore
Expand Down
6 changes: 5 additions & 1 deletion vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,9 @@ pub:
pos token.Pos
type_pos token.Pos
option_pos token.Pos
pre_comments []Comment
comments []Comment
next_comments []Comment
i int
has_default_expr bool
has_prev_newline bool
Expand Down Expand Up @@ -457,7 +459,8 @@ pub struct StructInitField {
pub:
pos token.Pos
name_pos token.Pos
comments []Comment
pre_comments []Comment
end_comments []Comment
next_comments []Comment
has_prev_newline bool
pub mut:
Expand Down Expand Up @@ -1366,6 +1369,7 @@ pub:
name string // just `lock`, or `abc`, etc, no matter if the name is a keyword or not.
source_name string // The name in the source, for example `@lock`, and `abc`. Note that `lock` is a keyword in V.
pos token.Pos
pre_comments []Comment // comment before Enumfield
comments []Comment // comment after Enumfield in the same line
next_comments []Comment // comments between current EnumField and next EnumField
has_expr bool // true, when .expr has a value
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/fmt/fmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,9 @@ pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) {
if i > 0 && field.has_prev_newline {
f.writeln('')
}
if field.pre_comments.len > 0 {
f.comments(field.pre_comments, has_nl: true, level: .indent)
}
f.write('\t${field.name}')
if field.has_expr {
f.write(strings.repeat(` `, value_align.max_len(field.pos.line_nr) - field.name.len))
Expand Down
31 changes: 14 additions & 17 deletions vlib/v/fmt/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,10 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
}
else {}
}
mut pre_cmts, mut end_cmts, mut next_line_cmts := []ast.Comment{}, []ast.Comment{}, []ast.Comment{}
for cmt in field.comments {
match true {
cmt.pos.pos < field.pos.pos { pre_cmts << cmt }
cmt.pos.line_nr > field.pos.last_line { next_line_cmts << cmt }
else { end_cmts << cmt }
}
}
// Handle comments before the field
f.comments_before_field(pre_cmts)
if field.pre_comments.len > 0 {
f.comments(field.pre_comments, level: .indent)
}
volatile_prefix := if field.is_volatile { 'volatile ' } else { '' }
f.write('\t${volatile_prefix}${field.name} ')
f.write(strings.repeat(` `, type_align.max_len(field.pos.line_nr) - field.name.len))
Expand Down Expand Up @@ -115,7 +109,7 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
f.single_line_attrs(field.attrs, same_line: true)
}
// Handle comments at the end of the line
if end_cmts.len > 0 {
if field.comments.len > 0 {
if field.has_default_expr {
f.write(strings.repeat(` `, comment_align.max_len(field.pos.line_nr) - field.default_expr.str().len - 2))
} else if field.attrs.len > 0 {
Expand All @@ -124,13 +118,13 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
f.write(strings.repeat(` `, comment_align.max_len(field.pos.line_nr) - field_types[i].len))
}
f.write(' ')
f.comments(end_cmts, level: .indent)
f.comments(field.comments, level: .indent)
} else {
f.writeln('')
}
// Handle comments on the next lines
if next_line_cmts.len > 0 {
f.comments(next_line_cmts, level: .indent)
if field.next_comments.len > 0 {
f.comments(field.next_comments, level: .indent)
}
}
if is_anon || node.end_comments.len > 0 {
Expand Down Expand Up @@ -279,23 +273,26 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) {
mut comment_align := new_field_align(use_threshold: true)
for init_field in node.init_fields {
value_align.add_info(init_field.name.len, init_field.pos.line_nr)
if init_field.comments.len > 0 {
if init_field.end_comments.len > 0 {
comment_align.add_info(init_field.expr.str().len, init_field.pos.line_nr)
}
}
for i, init_field in node.init_fields {
if i > 0 && init_field.has_prev_newline {
f.writeln('')
}
if init_field.pre_comments.len > 0 {
f.comments(init_field.pre_comments, has_nl: true, level: .keep)
}
f.write('${init_field.name}: ')
if !single_line_fields {
f.write(strings.repeat(` `, value_align.max_len(init_field.pos.line_nr) - init_field.name.len))
}
f.expr(init_field.expr)
if init_field.comments.len > 0 {
if init_field.end_comments.len > 0 {
f.write(strings.repeat(` `, comment_align.max_len(init_field.pos.line_nr) - init_field.expr.str().len))
f.write(' ')
f.comments(init_field.comments, has_nl: false, level: .indent)
f.comments(init_field.end_comments, has_nl: false, level: .indent)
}
if single_line_fields {
if i < node.init_fields.len - 1 {
Expand All @@ -305,7 +302,7 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) {
f.writeln('')
}
f.comments(init_field.next_comments, has_nl: true, level: .keep)
if single_line_fields && (init_field.comments.len > 0
if single_line_fields && (init_field.end_comments.len > 0
|| init_field.next_comments.len > 0
|| !expr_is_single_line(init_field.expr) || f.line_len > max_len) {
single_line_fields = false
Expand Down
1 change: 1 addition & 0 deletions vlib/v/fmt/tests/comments_input.vv
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import time // foo

/*
block
comment
Expand Down
19 changes: 19 additions & 0 deletions vlib/v/fmt/tests/enum_fields_with_empty_line_2_keep.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
enum Info {
aa = 1 // aa
bbb // bbb

cccc = 5 /* cccc
--- cccc
*/
ddddd = 10 // ddddd

// before
ee = 20
fff = 30

// before comment1
// before comment2
gg
}

fn main() {}
17 changes: 17 additions & 0 deletions vlib/v/fmt/tests/struct_decl_with_newline_and_comments_keep.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module main

fn main() {
}

pub struct OperateInfo { // implements IperateInfo
pub mut:
title string // title

// msg, id
msg string // msg
id string // id

// other1
// other2
other string
} // operate info
25 changes: 25 additions & 0 deletions vlib/v/fmt/tests/struct_init_with_newline_and_comments_2_keep.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module abcde

pub struct Builder {
pub mut:
// inline before field
buf []u8
str_calls int
len int
initial_size int = 1
}

pub fn new_builder(initial_size int) Builder {
return Builder{
// buf: make(0, initial_size)
buf: []u8{cap: initial_size}

// before comment
str_calls: 0 // after str_calls
len: 0 // after len

// before comment1
// before comment2
initial_size: initial_size // final
}
}
10 changes: 6 additions & 4 deletions vlib/v/parser/parser.v
Original file line number Diff line number Diff line change
Expand Up @@ -904,16 +904,16 @@ pub:
}

fn (mut p Parser) eat_comments(cfg EatCommentsConfig) []ast.Comment {
mut line := p.prev_tok.line_nr
mut line := p.prev_tok.line_nr + p.prev_tok.lit.count('\n')
mut comments := []ast.Comment{}
for {
if p.tok.kind != .comment || (cfg.same_line && p.tok.line_nr > line)
|| (cfg.follow_up && (p.tok.line_nr > line + 1 || p.tok.lit.contains('\n'))) {
|| (cfg.follow_up && p.tok.line_nr > line + 1) {
break
}
comments << p.comment()
if cfg.follow_up {
line = p.prev_tok.line_nr
line = p.prev_tok.line_nr + p.prev_tok.lit.count('\n')
}
}
return comments
Expand Down Expand Up @@ -4122,6 +4122,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
mut uses_exprs := false
mut enum_attrs := map[string][]ast.Attr{}
for p.tok.kind != .eof && p.tok.kind != .rcbr {
pre_comments := p.eat_comments()
pos := p.tok.pos()
has_prev_newline := p.has_prev_newline()
val := p.check_name()
Expand All @@ -4143,14 +4144,15 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
p.attrs = []
}
comments := p.eat_comments(same_line: true)
next_comments := p.eat_comments()
next_comments := p.eat_comments(follow_up: true)
fields << ast.EnumField{
name: val
source_name: source_name(val)
pos: pos
expr: expr
has_expr: has_expr
has_prev_newline: has_prev_newline
pre_comments: pre_comments
comments: comments
next_comments: next_comments
attrs: attrs
Expand Down
46 changes: 19 additions & 27 deletions vlib/v/parser/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,6 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
mut i := 0
for p.tok.kind != .rcbr {
mut comments := []ast.Comment{}
for p.tok.kind == .comment {
comments << p.comment()
if p.tok.kind == .rcbr {
break
}
}
if p.tok.kind == .rcbr {
end_comments = p.eat_comments(same_line: true)
break
Expand Down Expand Up @@ -168,12 +162,8 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
is_field_mut = false
is_field_global = false
}
for p.tok.kind == .comment {
comments << p.comment()
if p.tok.kind == .rcbr {
break
}
}
pre_field_comments := p.eat_comments()
mut next_field_comments := []ast.Comment{}
field_start_pos := p.tok.pos()
mut is_field_volatile := false
mut is_field_deprecated := false
Expand Down Expand Up @@ -227,12 +217,6 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
} else {
// struct field
field_name = p.check_name()
for p.tok.kind == .comment {
comments << p.comment()
if p.tok.kind == .rcbr {
break
}
}
p.inside_struct_field_decl = true
if p.tok.kind == .key_struct {
// Anon structs
Expand Down Expand Up @@ -269,7 +253,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
}
p.inside_struct_attr_decl = false
}
comments << p.eat_comments()
comments << p.eat_comments(same_line: true)
mut default_expr := ast.empty_expr
mut has_default_expr := false
if !is_embed {
Expand All @@ -283,7 +267,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
else {}
}
has_default_expr = true
comments << p.eat_comments()
comments << p.eat_comments(same_line: true)
}
if p.tok.kind == .at {
p.inside_struct_attr_decl = true
Expand All @@ -295,15 +279,18 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
}
}
p.inside_struct_attr_decl = false
comments << p.eat_comments()
comments << p.eat_comments(same_line: true)
}
next_field_comments = p.eat_comments(follow_up: true)
ast_fields << ast.StructField{
name: field_name
typ: typ
pos: field_pos
type_pos: type_pos
option_pos: option_pos
pre_comments: pre_field_comments
comments: comments
next_comments: next_field_comments
i: i
default_expr: default_expr
has_default_expr: has_default_expr
Expand All @@ -324,7 +311,9 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
pos: field_pos
type_pos: type_pos
option_pos: option_pos
pre_comments: pre_field_comments
comments: comments
next_comments: next_field_comments
i: i
default_expr: default_expr
has_default_expr: has_default_expr
Expand Down Expand Up @@ -429,15 +418,16 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
mut expr := ast.empty_expr
mut field_pos := token.Pos{}
mut first_field_pos := token.Pos{}
mut comments := []ast.Comment{}
mut prev_comments := []ast.Comment{}
mut end_comments := []ast.Comment{}
mut nline_comments := []ast.Comment{}
is_update_expr := init_fields.len == 0 && p.tok.kind == .ellipsis
if no_keys {
// name will be set later in checker
expr = p.expr(0)
field_pos = expr.pos()
first_field_pos = field_pos
comments = p.eat_comments(same_line: true)
end_comments = p.eat_comments(same_line: true)
} else if is_update_expr {
// struct updating syntax; f2 := Foo{ ...f, name: 'f2' }
update_expr_pos = p.tok.pos()
Expand All @@ -446,12 +436,13 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
update_expr_comments << p.eat_comments(same_line: true)
has_update_expr = true
} else {
prev_comments = p.eat_comments()
first_field_pos = p.tok.pos()
has_prev_newline = p.has_prev_newline()
field_name = p.check_name()
p.check(.colon)
expr = p.expr(0)
comments = p.eat_comments(same_line: true)
end_comments = p.eat_comments(same_line: true)
last_field_pos := expr.pos()
field_len := if last_field_pos.len > 0 {
last_field_pos.pos - first_field_pos.pos + last_field_pos.len
Expand All @@ -469,15 +460,16 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
if p.tok.kind == .comma {
p.next()
}
comments << p.eat_comments(same_line: true)
nline_comments << p.eat_comments()
end_comments << p.eat_comments(same_line: true)
nline_comments << p.eat_comments(follow_up: true)
if !is_update_expr {
init_fields << ast.StructInitField{
name: field_name
expr: expr
pos: field_pos
name_pos: first_field_pos
comments: comments
pre_comments: prev_comments
end_comments: end_comments
next_comments: nline_comments
parent_type: typ
has_prev_newline: has_prev_newline
Expand Down

0 comments on commit cb7881d

Please sign in to comment.