fmt: align struct field comments (#7632)
parent
095857d59b
commit
dd516858d4
123
vlib/v/fmt/fmt.v
123
vlib/v/fmt/fmt.v
|
@ -580,6 +580,60 @@ pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
|
||||||
f.writeln('\n')
|
f.writeln('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
threshold_to_align_struct = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
fn abs(v int) int {
|
||||||
|
return if v >= 0 {
|
||||||
|
v
|
||||||
|
} else {
|
||||||
|
-v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
if !(d_len < threshold_to_align_struct) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||||
f.attrs(node.attrs)
|
f.attrs(node.attrs)
|
||||||
if node.is_pub {
|
if node.is_pub {
|
||||||
|
@ -605,14 +659,28 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||||
}
|
}
|
||||||
f.writeln(' {')
|
f.writeln(' {')
|
||||||
mut max := 0
|
mut max := 0
|
||||||
mut max_type := 0
|
mut max_type_len := 0
|
||||||
|
mut comment_aligns := []CommentAndExprAlignInfo{}
|
||||||
|
mut default_expr_aligns := []CommentAndExprAlignInfo{}
|
||||||
mut field_types := []string{cap: node.fields.len}
|
mut field_types := []string{cap: node.fields.len}
|
||||||
for field in node.fields {
|
for i, field in node.fields {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
field_types << ft
|
||||||
|
if ft.len > max_type_len {
|
||||||
|
max_type_len = ft.len
|
||||||
|
}
|
||||||
|
attrs_len := inline_attrs_len(field.attrs)
|
||||||
end_pos := field.pos.pos + field.pos.len
|
end_pos := field.pos.pos + field.pos.len
|
||||||
mut comments_len := 0 // Length of comments between field name and type
|
mut comments_len := 0 // Length of comments between field name and type
|
||||||
for comment in field.comments {
|
for comment in field.comments {
|
||||||
if comment.pos.pos >= end_pos {
|
if comment.pos.pos >= end_pos {
|
||||||
break
|
if comment.pos.line_nr == field.pos.line_nr {
|
||||||
|
comment_aligns.add_info(attrs_len, field_types[i].len, comment.pos.line_nr)
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if comment.pos.pos > field.pos.pos {
|
if comment.pos.pos > field.pos.pos {
|
||||||
comments_len += '/* $comment.text */ '.len
|
comments_len += '/* $comment.text */ '.len
|
||||||
|
@ -621,19 +689,16 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||||
if comments_len + field.name.len > max {
|
if comments_len + field.name.len > max {
|
||||||
max = comments_len + field.name.len
|
max = comments_len + field.name.len
|
||||||
}
|
}
|
||||||
mut ft := f.no_cur_mod(f.table.type_to_str(field.typ))
|
if field.has_default_expr {
|
||||||
if !ft.contains('C.') && !ft.contains('JS.') && !ft.contains('fn (') {
|
default_expr_aligns.add_info(attrs_len, field_types[i].len, field.pos.line_nr)
|
||||||
ft = f.short_module(ft)
|
|
||||||
}
|
|
||||||
field_types << ft
|
|
||||||
if ft.len > max_type {
|
|
||||||
max_type = ft.len
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for embed in node.embeds {
|
for embed in node.embeds {
|
||||||
styp := f.table.type_to_str(embed.typ)
|
styp := f.table.type_to_str(embed.typ)
|
||||||
f.writeln('\t$styp')
|
f.writeln('\t$styp')
|
||||||
}
|
}
|
||||||
|
mut comment_align_i := 0
|
||||||
|
mut default_expr_align_i := 0
|
||||||
for i, field in node.fields {
|
for i, field in node.fields {
|
||||||
if i == node.mut_pos {
|
if i == node.mut_pos {
|
||||||
f.writeln('mut:')
|
f.writeln('mut:')
|
||||||
|
@ -665,11 +730,21 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||||
}
|
}
|
||||||
f.write(strings.repeat(` `, max - field.name.len - comments_len))
|
f.write(strings.repeat(` `, max - field.name.len - comments_len))
|
||||||
f.write(field_types[i])
|
f.write(field_types[i])
|
||||||
if field.attrs.len > 0 {
|
after_type_pad_len := max_type_len - field_types[i].len
|
||||||
f.write(strings.repeat(` `, max_type - field_types[i].len))
|
attrs_len := inline_attrs_len(field.attrs)
|
||||||
|
has_attrs := field.attrs.len > 0
|
||||||
|
if has_attrs {
|
||||||
|
f.write(strings.repeat(` `, after_type_pad_len))
|
||||||
f.inline_attrs(field.attrs)
|
f.inline_attrs(field.attrs)
|
||||||
}
|
}
|
||||||
if field.has_default_expr {
|
if field.has_default_expr {
|
||||||
|
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))
|
||||||
f.write(' = ')
|
f.write(' = ')
|
||||||
f.prefix_expr_cast_expr(field.default_expr)
|
f.prefix_expr_cast_expr(field.default_expr)
|
||||||
}
|
}
|
||||||
|
@ -678,6 +753,15 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||||
if comments[comm_idx].pos.line_nr > field.pos.line_nr {
|
if comments[comm_idx].pos.line_nr > field.pos.line_nr {
|
||||||
f.writeln('')
|
f.writeln('')
|
||||||
} else {
|
} else {
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
pad_len := align.max_attrs_len - attrs_len + align.max_type_len - field_types[i].len
|
||||||
|
f.write(strings.repeat(` `, pad_len))
|
||||||
|
}
|
||||||
f.write(' ')
|
f.write(' ')
|
||||||
}
|
}
|
||||||
f.comments(comments[comm_idx..], level: .indent)
|
f.comments(comments[comm_idx..], level: .indent)
|
||||||
|
@ -1230,6 +1314,21 @@ fn (mut f Fmt) inline_attrs(attrs []table.Attr) {
|
||||||
f.write(']')
|
f.write(']')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
enum CommentsLevel {
|
enum CommentsLevel {
|
||||||
keep
|
keep
|
||||||
indent
|
indent
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
struct User {
|
struct User {
|
||||||
name string
|
name string // name
|
||||||
|
name2 ustring // name2
|
||||||
very_long_field bool
|
very_long_field bool
|
||||||
age int
|
age int // age
|
||||||
|
very_long_type_field1 very_looooog_type // long
|
||||||
|
very_long_type_field2 very_loooooooong_type // long
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
field1 int
|
field1 int // f1
|
||||||
field2 string
|
field2 string // f2
|
||||||
pub:
|
pub:
|
||||||
public_field1 int
|
public_field1 int // f1
|
||||||
public_field2 f64
|
public_field2 f64 // f2
|
||||||
mut:
|
mut:
|
||||||
mut_field string
|
mut_field string
|
||||||
pub mut:
|
pub mut:
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
struct User {
|
struct User {
|
||||||
name string
|
name string // name
|
||||||
|
name2 ustring // name2
|
||||||
very_long_field bool
|
very_long_field bool
|
||||||
age int
|
age int // age
|
||||||
|
very_long_type_field1 very_looooog_type // long
|
||||||
|
very_long_type_field2 very_loooooooong_type // long
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
field1 int
|
field1 int // f1
|
||||||
field2 string
|
field2 string // f2
|
||||||
pub:
|
pub:
|
||||||
public_field1 int
|
public_field1 int // f1
|
||||||
public_field2 f64
|
public_field2 f64 // f2
|
||||||
mut:
|
mut:
|
||||||
mut_field string
|
mut_field string
|
||||||
pub mut:
|
pub mut:
|
||||||
|
|
Loading…
Reference in New Issue