ast, parser, fmt: fix alias array no cast init (#20898)

This commit is contained in:
yuyi 2024-02-24 17:56:01 +08:00 committed by GitHub
parent cf7dcfe287
commit 1733dab29b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 139 additions and 94 deletions

View File

@ -1492,6 +1492,7 @@ pub mut:
elem_type Type // element type
init_type Type // init: value type
typ Type // array type
alias_type Type // alias type
}
pub struct ArrayDecompose {

View File

@ -1710,7 +1710,11 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
if node.exprs.len == 0 && node.typ != 0 && node.typ != ast.void_type {
// `x := []string{}`
f.mark_types_import_as_used(node.typ)
if node.alias_type != ast.void_type {
f.write(f.table.type_to_str_using_aliases(node.alias_type, f.mod2alias))
} else {
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
}
f.write('{')
if node.has_len {
f.write('len: ')

View File

@ -6,10 +6,9 @@ module parser
import v.ast
import v.token
fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
fn (mut p Parser) array_init(is_option bool, alias_array_type ast.Type) ast.ArrayInit {
first_pos := p.tok.pos()
mut last_pos := p.tok.pos()
p.check(.lsbr)
mut array_type := ast.void_type
mut elem_type := ast.void_type
mut elem_type_pos := first_pos
@ -22,13 +21,16 @@ fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
mut has_init := false
mut has_index := false
mut init_expr := ast.empty_expr
if alias_array_type == ast.void_type {
p.check(.lsbr)
if p.tok.kind == .rsbr {
last_pos = p.tok.pos()
// []typ => `[]` and `typ` must be on the same line
line_nr := p.tok.line_nr
p.next()
// []string
if p.tok.kind in [.name, .amp, .lsbr, .question, .key_shared] && p.tok.line_nr == line_nr {
if p.tok.kind in [.name, .amp, .lsbr, .question, .key_shared]
&& p.tok.line_nr == line_nr {
elem_type_pos = p.tok.pos()
elem_type = p.parse_type()
// this is set here because it's a known type, others could be the
@ -108,7 +110,8 @@ fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
}
if p.tok.kind == .not && p.tok.line_nr == p.prev_tok.line_nr {
last_pos = p.tok.pos()
p.error_with_pos('use e.g. `[1, 2, 3]!` instead of `[1, 2, 3]!!`', last_pos)
p.error_with_pos('use e.g. `[1, 2, 3]!` instead of `[1, 2, 3]!!`',
last_pos)
p.next()
}
}
@ -120,6 +123,11 @@ fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
first_pos.extend(last_pos))
}
}
} else {
array_type = (p.table.sym(alias_array_type).info as ast.Alias).parent_type
elem_type = p.table.sym(array_type).array_info().elem_type
p.next()
}
mut has_len := false
mut has_cap := false
mut len_expr := ast.empty_expr
@ -170,6 +178,7 @@ fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
mod: p.mod
elem_type: elem_type
typ: array_type
alias_type: alias_array_type
exprs: exprs
ecmnts: ecmnts
pre_cmnts: pre_cmnts

View File

@ -216,10 +216,10 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr {
pos: pos
}
} else {
node = p.array_init(false)
node = p.array_init(false, ast.void_type)
}
} else {
node = p.array_init(false)
node = p.array_init(false, ast.void_type)
}
}
.key_none {

View File

@ -2543,6 +2543,19 @@ fn (mut p Parser) is_generic_cast() bool {
return false
}
fn (mut p Parser) alias_array_type() ast.Type {
full_name := p.prepend_mod(p.tok.lit)
if idx := p.table.type_idxs[full_name] {
sym := p.table.sym(idx)
if sym.info is ast.Alias {
if p.table.sym(sym.info.parent_type).kind == .array {
return idx
}
}
}
return ast.void_type
}
@[direct_array_access]
fn (mut p Parser) name_expr() ast.Expr {
prev_tok_kind := p.prev_tok.kind
@ -2840,7 +2853,13 @@ fn (mut p Parser) name_expr() ast.Expr {
&& (!p.inside_match || (p.inside_select && prev_tok_kind == .arrow && lit0_is_capital))
&& !p.inside_match_case && (!p.inside_if || p.inside_select)
&& (!p.inside_for || p.inside_select) {
return p.struct_init(p.mod + '.' + p.tok.lit, .normal, is_option) // short_syntax: false
alias_array_type := p.alias_array_type()
if alias_array_type != ast.void_type {
return p.array_init(is_option, alias_array_type)
} else {
// `if a == Foo{} {...}` or `match foo { Foo{} {...} }`
return p.struct_init(p.mod + '.' + p.tok.lit, .normal, is_option)
}
} else if p.peek_tok.kind == .lcbr
&& ((p.inside_if && lit0_is_capital && p.tok.lit.len > 1 && !known_var && language == .v)
|| (p.inside_match_case && p.tok.kind == .name && p.peek_tok.is_next_to(p.tok))) {
@ -2957,7 +2976,7 @@ fn (mut p Parser) name_expr() ast.Expr {
p.expr_mod = ''
return node
} else if is_option && p.tok.kind == .lsbr {
return p.array_init(is_option)
return p.array_init(is_option, ast.void_type)
} else if !known_var && language == .v && p.peek_tok.kind == .dot && !p.pref.is_fmt {
peek_tok2 := p.peek_token(2)
peek_tok3 := p.peek_token(3)

View File

@ -0,0 +1,12 @@
pub type Labels = [][]int
pub fn new_labels(width int, height int) Labels {
mut labels := Labels{len: height, init: []int{len: width}}
return labels
}
fn test_alias_array_no_cast_init() {
mut labels := new_labels(2, 2)
println(labels)
assert labels == [[0, 0], [0, 0]]
}