mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
fmt: fix and simplify align of struct fields (#21995)
This commit is contained in:
parent
576a0abcc7
commit
ddb6685d8a
139 changed files with 553 additions and 519 deletions
|
@ -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' }}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue