Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fmt: cleanup fields alignment #22018

Merged
merged 2 commits into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 32 additions & 15 deletions vlib/v/fmt/align.v
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,55 @@ pub:
threshold int = 25
}

fn (mut infos []AlignInfo) add_new_info(len int, line int) {
infos << AlignInfo{
struct FieldAlign {
mut:
infos []AlignInfo
cur_idx int
}

fn (mut fa FieldAlign) add_new_info(len int, line int) {
fa.infos << AlignInfo{
line_nr: line
max_len: len
}
}

@[direct_array_access]
fn (mut infos []AlignInfo) add_info(len int, line int, cfg AddInfoConfig) {
if infos.len == 0 {
infos.add_new_info(len, line)
fn (mut fa FieldAlign) add_info(len int, line int, cfg AddInfoConfig) {
if fa.infos.len == 0 {
fa.add_new_info(len, line)
return
}
i := infos.len - 1
if line - infos[i].line_nr > 1 {
infos.add_new_info(len, line)
i := fa.infos.len - 1
if line - fa.infos[i].line_nr > 1 {
fa.add_new_info(len, line)
return
}
if cfg.use_threshold {
len_diff := if infos[i].max_len >= len {
infos[i].max_len - len
len_diff := if fa.infos[i].max_len >= len {
fa.infos[i].max_len - len
} else {
len - infos[i].max_len
len - fa.infos[i].max_len
}

if len_diff >= cfg.threshold {
infos.add_new_info(len, line)
fa.add_new_info(len, line)
return
}
}
infos[i].line_nr = line
if len > infos[i].max_len {
infos[i].max_len = len
fa.infos[i].line_nr = line
if len > fa.infos[i].max_len {
fa.infos[i].max_len = len
}
}

fn (mut fa FieldAlign) max_len(line_nr int) int {
if fa.cur_idx < fa.infos.len && fa.infos[fa.cur_idx].line_nr < line_nr {
fa.cur_idx++
}
if fa.cur_idx < fa.infos.len {
return fa.infos[fa.cur_idx].max_len
} else {
return 0
}
}
57 changes: 19 additions & 38 deletions vlib/v/fmt/fmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -1039,9 +1039,9 @@ pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) {
f.writeln('enum ${name} {')
f.comments(node.comments, same_line: true, level: .indent)

mut value_aligns := []AlignInfo{}
mut attr_aligns := []AlignInfo{}
mut comment_aligns := []AlignInfo{}
mut value_aligns := FieldAlign{}
mut attr_aligns := FieldAlign{}
mut comment_aligns := FieldAlign{}
for field in node.fields {
if field.has_expr {
value_aligns.add_info(field.name.len, field.pos.line_nr)
Expand All @@ -1065,46 +1065,34 @@ pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) {
}
}

mut value_align_i := 0
mut attr_align_i := 0
mut comment_align_i := 0
for i, field in node.fields {
if i > 0 && field.has_prev_newline {
f.writeln('')
}
f.write('\t${field.name}')
if field.has_expr {
if value_aligns[value_align_i].line_nr < field.pos.line_nr {
value_align_i++
}
f.write(strings.repeat(` `, value_aligns[value_align_i].max_len - field.name.len))
f.write(strings.repeat(` `, value_aligns.max_len(field.pos.line_nr) - field.name.len))
f.write(' = ')
f.expr(field.expr)
}
attrs_len := inline_attrs_len(field.attrs)
if field.attrs.len > 0 {
if attr_aligns[attr_align_i].line_nr < field.pos.line_nr {
attr_align_i++
}
if field.has_expr {
f.write(strings.repeat(` `, attr_aligns[attr_align_i].max_len - field.expr.str().len - 2))
f.write(strings.repeat(` `, attr_aligns.max_len(field.pos.line_nr) - field.expr.str().len - 2))
} else {
f.write(strings.repeat(` `, attr_aligns[attr_align_i].max_len - field.name.len))
f.write(strings.repeat(` `, attr_aligns.max_len(field.pos.line_nr) - field.name.len))
}
f.write(' ')
f.single_line_attrs(field.attrs, same_line: true)
}
// f.comments(field.comments, same_line: true, has_nl: false, level: .indent)
if field.comments.len > 0 {
if comment_aligns[comment_align_i].line_nr < field.pos.line_nr {
comment_align_i++
}
if field.attrs.len > 0 {
f.write(strings.repeat(` `, comment_aligns[comment_align_i].max_len - attrs_len))
f.write(strings.repeat(` `, comment_aligns.max_len(field.pos.line_nr) - attrs_len))
} else if field.has_expr {
f.write(strings.repeat(` `, comment_aligns[comment_align_i].max_len - field.expr.str().len - 2))
f.write(strings.repeat(` `, comment_aligns.max_len(field.pos.line_nr) - field.expr.str().len - 2))
} else {
f.write(strings.repeat(` `, comment_aligns[comment_align_i].max_len - field.name.len))
f.write(strings.repeat(` `, comment_aligns.max_len(field.pos.line_nr) - field.name.len))
}
f.write(' ')
f.comments(field.comments, same_line: true, has_nl: false)
Expand Down Expand Up @@ -1408,34 +1396,27 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) {
}
}

mut type_aligns := []AlignInfo{}
mut comment_aligns := []AlignInfo{}
mut default_expr_aligns := []AlignInfo{}
mut attr_aligns := []AlignInfo{}
mut type_aligns := FieldAlign{}
mut comment_aligns := FieldAlign{}
mut default_expr_aligns := FieldAlign{}
mut attr_aligns := FieldAlign{}
mut field_types := []string{cap: node.fields.len}

// Calculate the alignments first
f.calculate_alignment(node.fields, mut type_aligns, mut comment_aligns, mut default_expr_aligns, mut
attr_aligns, mut field_types)

mut type_align_i := 0
// TODO: alignment, comments, etc.
for field in immut_fields {
if type_aligns[type_align_i].line_nr < field.pos.line_nr {
type_align_i++
}
f.interface_field(field, type_aligns[type_align_i])
f.interface_field(field, type_aligns.max_len(field.pos.line_nr))
}
for method in immut_methods {
f.interface_method(method)
}
if mut_fields.len + mut_methods.len > 0 {
f.writeln('mut:')
for field in mut_fields {
if type_aligns[type_align_i].line_nr < field.pos.line_nr {
type_align_i++
}
f.interface_field(field, type_aligns[type_align_i])
f.interface_field(field, type_aligns.max_len(field.pos.line_nr))
}
for method in mut_methods {
f.interface_method(method)
Expand All @@ -1451,8 +1432,8 @@ enum AlignState {
has_everything
}

pub fn (mut f Fmt) calculate_alignment(fields []ast.StructField, mut type_aligns []AlignInfo, mut comment_aligns []AlignInfo,
mut default_expr_aligns []AlignInfo, mut attr_aligns []AlignInfo, mut field_types []string) {
pub fn (mut f Fmt) calculate_alignment(fields []ast.StructField, mut type_aligns FieldAlign, mut comment_aligns FieldAlign,
mut default_expr_aligns FieldAlign, mut attr_aligns FieldAlign, mut field_types []string) {
// Calculate the alignments first
mut prev_state := AlignState.plain
for field in fields {
Expand Down Expand Up @@ -1510,7 +1491,7 @@ pub fn (mut f Fmt) calculate_alignment(fields []ast.StructField, mut type_aligns
}
}

pub fn (mut f Fmt) interface_field(field ast.StructField, field_align AlignInfo) {
pub fn (mut f Fmt) interface_field(field ast.StructField, max_len int) {
ft := f.no_cur_mod(f.table.type_to_str_using_aliases(field.typ, f.mod2alias))
mut pre_cmts, mut end_cmts, mut next_line_cmts := []ast.Comment{}, []ast.Comment{}, []ast.Comment{}
for cmt in field.comments {
Expand Down Expand Up @@ -1538,7 +1519,7 @@ pub fn (mut f Fmt) interface_field(field ast.StructField, field_align AlignInfo)
f.write('\t${field.name} ')
}
if !(sym.info is ast.Struct && sym.info.is_anon) {
f.write(strings.repeat(` `, field_align.max_len - field.name.len - comments_len))
f.write(strings.repeat(` `, max_len - field.name.len - comments_len))
f.write(ft)
}
if end_cmts.len > 0 {
Expand Down
40 changes: 10 additions & 30 deletions vlib/v/fmt/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
f.writeln(' {}')
return
}
mut type_aligns := []AlignInfo{}
mut default_expr_aligns := []AlignInfo{}
mut attr_aligns := []AlignInfo{}
mut comment_aligns := []AlignInfo{}
mut type_aligns := FieldAlign{}
mut default_expr_aligns := FieldAlign{}
mut attr_aligns := FieldAlign{}
mut comment_aligns := FieldAlign{}
mut field_types := []string{cap: node.fields.len}
// Calculate the alignments first
f.calculate_alignment(node.fields, mut type_aligns, mut comment_aligns, mut default_expr_aligns, mut
Expand All @@ -55,10 +55,6 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
}
}
// Now handle each field
mut type_align_i := 0
mut comment_align_i := 0
mut default_expr_align_i := 0
mut attr_align_i := 0
mut inc_indent := false // for correct indents with multi line default exprs
for i, field in node.fields {
match true {
Expand Down Expand Up @@ -94,23 +90,15 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
f.comments_before_field(pre_cmts)
volatile_prefix := if field.is_volatile { 'volatile ' } else { '' }
f.write('\t${volatile_prefix}${field.name} ')
if type_aligns[type_align_i].line_nr < field.pos.line_nr {
type_align_i++
}
type_align := type_aligns[type_align_i]
f.write(strings.repeat(` `, type_align.max_len - field.name.len))
f.write(strings.repeat(` `, type_aligns.max_len(field.pos.line_nr) - field.name.len))
// Handle anon structs recursively
if !f.write_anon_struct_field_decl(field.typ, field.anon_struct_decl) {
f.write(field_types[i])
}
f.mark_types_import_as_used(field.typ)
attrs_len := inline_attrs_len(field.attrs)
if field.has_default_expr {
if default_expr_aligns[default_expr_align_i].line_nr < field.pos.line_nr {
default_expr_align_i++
}
align := default_expr_aligns[default_expr_align_i]
f.write(strings.repeat(` `, align.max_len - field_types[i].len))
f.write(strings.repeat(` `, default_expr_aligns.max_len(field.pos.line_nr) - field_types[i].len))
f.write(' = ')
if !expr_is_single_line(field.default_expr) {
f.indent++
Expand All @@ -123,25 +111,17 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
}
}
if field.attrs.len > 0 {
if attr_aligns[attr_align_i].line_nr < field.pos.line_nr {
attr_align_i++
}
align := attr_aligns[attr_align_i]
f.write(strings.repeat(` `, align.max_len - field_types[i].len))
f.write(strings.repeat(` `, attr_aligns.max_len(field.pos.line_nr) - field_types[i].len))
f.single_line_attrs(field.attrs, same_line: true)
}
// Handle comments at the end of the line
if end_cmts.len > 0 {
if comment_aligns[comment_align_i].line_nr < field.pos.line_nr {
comment_align_i++
}
align := comment_aligns[comment_align_i]
if field.has_default_expr {
f.write(strings.repeat(` `, align.max_len - field.default_expr.str().len - 2))
f.write(strings.repeat(` `, comment_aligns.max_len(field.pos.line_nr) - field.default_expr.str().len - 2))
} else if field.attrs.len > 0 {
f.write(strings.repeat(` `, align.max_len - attrs_len))
f.write(strings.repeat(` `, comment_aligns.max_len(field.pos.line_nr) - attrs_len))
} else {
f.write(strings.repeat(` `, align.max_len - field_types[i].len))
f.write(strings.repeat(` `, comment_aligns.max_len(field.pos.line_nr) - field_types[i].len))
}
f.write(' ')
f.comments(end_cmts, level: .indent)
Expand Down
Loading