fmt: fix and simplify align of struct fields (#21995)

This commit is contained in:
yuyi 2024-08-06 01:23:39 +08:00 committed by GitHub
parent 576a0abcc7
commit ddb6685d8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
139 changed files with 553 additions and 519 deletions

View file

@ -155,18 +155,18 @@ jobs:
echo "Build v-analyzer release" echo "Build v-analyzer release"
v build.vsh release v build.vsh release
- name: Format vlang/v-analyzer # - name: Format vlang/v-analyzer
if: ${{ !cancelled() && steps.build.outcome == 'success' }} # if: ${{ !cancelled() && steps.build.outcome == 'success' }}
run: | # run: |
cd /tmp/v-analyzer # cd /tmp/v-analyzer
set +e # set +e
v fmt -c . # v fmt -c .
exit_code=$? # exit_code=$?
if [[ $exit_code -ne 0 && $exit_code -ne 5 ]]; then # if [[ $exit_code -ne 0 && $exit_code -ne 5 ]]; then
# Don't fail if there are only internal errors (exit code 5). # # Don't fail if there are only internal errors (exit code 5).
v fmt -diff . # v fmt -diff .
exit 1 # exit 1
fi # fi
- name: Build vlang/go2v - name: Build vlang/go2v
if: ${{ !cancelled() && steps.build.outcome == 'success' && matrix.os != 'macos-14' }} if: ${{ !cancelled() && steps.build.outcome == 'success' && matrix.os != 'macos-14' }}

View file

@ -3,47 +3,46 @@
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module fmt module fmt
import v.mathutil
struct AlignInfo { struct AlignInfo {
mut: mut:
line_nr int line_nr int
max_len int max_len int
max_type_len int
} }
@[params] @[params]
struct AddInfoConfig { struct AddInfoConfig {
pub: pub:
use_threshold bool use_threshold bool
threshold int = 8 threshold int = 25
} }
fn (mut infos []AlignInfo) add_new_info(len int, type_len int, line int) { fn (mut infos []AlignInfo) add_new_info(len int, line int) {
infos << AlignInfo{ infos << AlignInfo{
line_nr: line line_nr: line
max_len: len max_len: len
max_type_len: type_len
} }
} }
@[direct_array_access] @[direct_array_access]
fn (mut infos []AlignInfo) add_info(len int, type_len int, line int, cfg AddInfoConfig) { fn (mut infos []AlignInfo) add_info(len int, line int, cfg AddInfoConfig) {
if infos.len == 0 { if infos.len == 0 {
infos.add_new_info(len, type_len, line) infos.add_new_info(len, line)
return return
} }
i := infos.len - 1 i := infos.len - 1
if line - infos[i].line_nr > 1 { if line - infos[i].line_nr > 1 {
infos.add_new_info(len, type_len, line) infos.add_new_info(len, line)
return return
} }
if cfg.use_threshold { if cfg.use_threshold {
len_diff := mathutil.abs(infos[i].max_len - len) + len_diff := if infos[i].max_len >= len {
mathutil.abs(infos[i].max_type_len - type_len) infos[i].max_len - len
} else {
len - infos[i].max_len
}
if len_diff >= cfg.threshold { if len_diff >= cfg.threshold {
infos.add_new_info(len, type_len, line) infos.add_new_info(len, line)
return return
} }
} }
@ -51,7 +50,4 @@ fn (mut infos []AlignInfo) add_info(len int, type_len int, line int, cfg AddInfo
if len > infos[i].max_len { if len > infos[i].max_len {
infos[i].max_len = len infos[i].max_len = len
} }
if type_len > infos[i].max_type_len {
infos[i].max_type_len = type_len
}
} }

View file

@ -1374,22 +1374,23 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) {
} }
} }
mut field_aligns := []AlignInfo{} mut type_aligns := []AlignInfo{}
mut comment_aligns := []AlignInfo{} mut comment_aligns := []AlignInfo{}
mut default_expr_aligns := []AlignInfo{} mut default_expr_aligns := []AlignInfo{}
mut attr_aligns := []AlignInfo{}
mut field_types := []string{cap: node.fields.len} mut field_types := []string{cap: node.fields.len}
// Calculate the alignments first // Calculate the alignments first
f.calculate_alignment(node.fields, mut field_aligns, mut comment_aligns, mut default_expr_aligns, mut f.calculate_alignment(node.fields, mut type_aligns, mut comment_aligns, mut default_expr_aligns, mut
field_types) attr_aligns, mut field_types)
mut field_align_i := 0 mut type_align_i := 0
// TODO: alignment, comments, etc. // TODO: alignment, comments, etc.
for field in immut_fields { for field in immut_fields {
if field_aligns[field_align_i].line_nr < field.pos.line_nr { if type_aligns[type_align_i].line_nr < field.pos.line_nr {
field_align_i++ type_align_i++
} }
f.interface_field(field, field_aligns[field_align_i]) f.interface_field(field, type_aligns[type_align_i])
} }
for method in immut_methods { for method in immut_methods {
f.interface_method(method) f.interface_method(method)
@ -1397,10 +1398,10 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) {
if mut_fields.len + mut_methods.len > 0 { if mut_fields.len + mut_methods.len > 0 {
f.writeln('mut:') f.writeln('mut:')
for field in mut_fields { for field in mut_fields {
if field_aligns[field_align_i].line_nr < field.pos.line_nr { if type_aligns[type_align_i].line_nr < field.pos.line_nr {
field_align_i++ type_align_i++
} }
f.interface_field(field, field_aligns[field_align_i]) f.interface_field(field, type_aligns[type_align_i])
} }
for method in mut_methods { for method in mut_methods {
f.interface_method(method) f.interface_method(method)
@ -1409,31 +1410,69 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) {
f.writeln('}\n') f.writeln('}\n')
} }
pub fn (mut f Fmt) calculate_alignment(fields []ast.StructField, mut field_aligns []AlignInfo, mut comment_aligns []AlignInfo, enum AlignState {
mut default_expr_aligns []AlignInfo, mut field_types []string) { plain
has_attributes
has_default_expression
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) {
// Calculate the alignments first // Calculate the alignments first
for i, field in fields { mut prev_state := AlignState.plain
for field in fields {
ft := f.no_cur_mod(f.table.type_to_str_using_aliases(field.typ, f.mod2alias)) ft := f.no_cur_mod(f.table.type_to_str_using_aliases(field.typ, f.mod2alias))
// Handle anon structs recursively // Handle anon structs recursively
field_types << ft field_types << ft
attrs_len := inline_attrs_len(field.attrs) attrs_len := inline_attrs_len(field.attrs)
end_pos := field.pos.pos + field.pos.len end_pos := field.pos.pos + field.pos.len
type_aligns.add_info(field.name.len, field.pos.line_nr)
if field.has_default_expr {
default_expr_aligns.add_info(ft.len, field.pos.line_nr,
use_threshold: true
)
}
if field.attrs.len > 0 {
attr_aligns.add_info(ft.len, field.pos.line_nr, use_threshold: true)
}
for comment in field.comments { for comment in field.comments {
if comment.pos.pos >= end_pos { if comment.pos.pos >= end_pos {
if comment.pos.line_nr == field.pos.line_nr { if comment.pos.line_nr == field.pos.line_nr {
comment_aligns.add_info(attrs_len, field_types[i].len, comment.pos.line_nr, if field.attrs.len > 0 {
if prev_state != AlignState.has_attributes {
comment_aligns.add_new_info(attrs_len, comment.pos.line_nr)
} else {
comment_aligns.add_info(attrs_len, comment.pos.line_nr,
use_threshold: true use_threshold: true
) )
} }
prev_state = AlignState.has_attributes
} else if field.has_default_expr {
if prev_state != AlignState.has_default_expression {
comment_aligns.add_new_info(field.default_expr.str().len + 2,
comment.pos.line_nr)
} else {
comment_aligns.add_info(field.default_expr.str().len + 2,
comment.pos.line_nr,
use_threshold: true
)
}
prev_state = AlignState.has_default_expression
} else {
if prev_state != AlignState.has_everything {
comment_aligns.add_new_info(ft.len, comment.pos.line_nr)
} else {
comment_aligns.add_info(ft.len, comment.pos.line_nr,
use_threshold: true
)
}
prev_state = AlignState.has_everything
}
}
continue continue
} }
} }
field_aligns.add_info(field.name.len, ft.len, field.pos.line_nr)
if field.has_default_expr {
default_expr_aligns.add_info(attrs_len, field_types[i].len, field.pos.line_nr,
use_threshold: true
)
}
} }
} }

View file

@ -27,13 +27,14 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
f.writeln(' {}') f.writeln(' {}')
return return
} }
mut field_aligns := []AlignInfo{} mut type_aligns := []AlignInfo{}
mut comment_aligns := []AlignInfo{}
mut default_expr_aligns := []AlignInfo{} mut default_expr_aligns := []AlignInfo{}
mut attr_aligns := []AlignInfo{}
mut comment_aligns := []AlignInfo{}
mut field_types := []string{cap: node.fields.len} mut field_types := []string{cap: node.fields.len}
// Calculate the alignments first // Calculate the alignments first
f.calculate_alignment(node.fields, mut field_aligns, mut comment_aligns, mut default_expr_aligns, mut f.calculate_alignment(node.fields, mut type_aligns, mut comment_aligns, mut default_expr_aligns, mut
field_types) attr_aligns, mut field_types)
f.writeln(' {') f.writeln(' {')
if node.pre_comments.len > 0 { if node.pre_comments.len > 0 {
f.comments_before_field(node.pre_comments) f.comments_before_field(node.pre_comments)
@ -54,9 +55,10 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
} }
} }
// Now handle each field // Now handle each field
mut field_align_i := 0 mut type_align_i := 0
mut comment_align_i := 0 mut comment_align_i := 0
mut default_expr_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 mut inc_indent := false // for correct indents with multi line default exprs
for i, field in node.fields { for i, field in node.fields {
match true { match true {
@ -112,32 +114,23 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
f.comments_before_field(pre_cmts) f.comments_before_field(pre_cmts)
volatile_prefix := if field.is_volatile { 'volatile ' } else { '' } volatile_prefix := if field.is_volatile { 'volatile ' } else { '' }
f.write('\t${volatile_prefix}${field.name} ') f.write('\t${volatile_prefix}${field.name} ')
if field_aligns[field_align_i].line_nr < field.pos.line_nr { if type_aligns[type_align_i].line_nr < field.pos.line_nr {
field_align_i++ type_align_i++
} }
field_align := field_aligns[field_align_i] type_align := type_aligns[type_align_i]
f.write(strings.repeat(` `, field_align.max_len - field.name.len)) f.write(strings.repeat(` `, type_align.max_len - field.name.len))
// Handle anon structs recursively // Handle anon structs recursively
if !f.write_anon_struct_field_decl(field.typ, field.anon_struct_decl) { if !f.write_anon_struct_field_decl(field.typ, field.anon_struct_decl) {
f.write(field_types[i]) f.write(field_types[i])
} }
f.mark_types_import_as_used(field.typ) f.mark_types_import_as_used(field.typ)
attrs_len := inline_attrs_len(field.attrs) attrs_len := inline_attrs_len(field.attrs)
has_attrs := field.attrs.len > 0
// has_at := if has_attrs { field.attrs[0].has_at } else { false }
has_at := true
// TODO: this will get removed in next stage
if has_attrs && !has_at {
f.write(strings.repeat(` `, field_align.max_type_len - field_types[i].len))
f.single_line_attrs(field.attrs, same_line: true)
}
if field.has_default_expr { if field.has_default_expr {
if default_expr_aligns[default_expr_align_i].line_nr < field.pos.line_nr { if default_expr_aligns[default_expr_align_i].line_nr < field.pos.line_nr {
default_expr_align_i++ default_expr_align_i++
} }
align := default_expr_aligns[default_expr_align_i] align := default_expr_aligns[default_expr_align_i]
pad_len := align.max_len - attrs_len + align.max_type_len - field_types[i].len f.write(strings.repeat(` `, align.max_len - field_types[i].len))
f.write(strings.repeat(` `, pad_len))
f.write(' = ') f.write(' = ')
if !expr_is_single_line(field.default_expr) { if !expr_is_single_line(field.default_expr) {
f.indent++ f.indent++
@ -149,19 +142,26 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
inc_indent = false inc_indent = false
} }
} }
if has_attrs && has_at { if field.attrs.len > 0 {
f.write(strings.repeat(` `, field_align.max_type_len - field_types[i].len)) 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.single_line_attrs(field.attrs, same_line: true) f.single_line_attrs(field.attrs, same_line: true)
} }
// Handle comments at the end of the line // Handle comments at the end of the line
if end_cmts.len > 0 { if end_cmts.len > 0 {
if !field.has_default_expr {
if comment_aligns[comment_align_i].line_nr < field.pos.line_nr { if comment_aligns[comment_align_i].line_nr < field.pos.line_nr {
comment_align_i++ comment_align_i++
} }
align := comment_aligns[comment_align_i] align := comment_aligns[comment_align_i]
pad_len := align.max_len - attrs_len + align.max_type_len - field_types[i].len if field.has_default_expr {
f.write(strings.repeat(` `, pad_len)) f.write(strings.repeat(` `, align.max_len - field.default_expr.str().len - 2))
} else if field.attrs.len > 0 {
f.write(strings.repeat(` `, align.max_len - attrs_len))
} else {
f.write(strings.repeat(` `, align.max_len - field_types[i].len))
} }
f.write(' ') f.write(' ')
f.comments(end_cmts, level: .indent) f.comments(end_cmts, level: .indent)

View file

@ -98,4 +98,3 @@ algorithm and multiple iterations.
See also: See also:
- [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) - [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html)