mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
generic: replace generic <>
with []
part 1 - allow for both (#16532)
This commit is contained in:
parent
a9b41d2980
commit
b19b97e7b1
@ -35,7 +35,7 @@ pub fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr
|
||||
|
||||
mut concrete_types := []ast.Type{}
|
||||
mut concrete_list_pos := p.tok.pos()
|
||||
if p.tok.kind == .lt {
|
||||
if p.tok.kind in [.lt, .lsbr] {
|
||||
// `foo<int>(10)`
|
||||
p.expr_mod = ''
|
||||
concrete_types = p.parse_concrete_types()
|
||||
|
@ -629,7 +629,8 @@ pub fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_d
|
||||
if name.len == 1 && name[0].is_capital() {
|
||||
return p.parse_generic_type(name)
|
||||
}
|
||||
if p.tok.kind == .lt {
|
||||
if p.tok.kind in [.lt, .lsbr]
|
||||
&& p.tok.pos - p.prev_tok.pos == p.prev_tok.len {
|
||||
return p.parse_generic_inst_type(name)
|
||||
}
|
||||
return p.find_type_or_add_placeholder(name, language)
|
||||
@ -707,7 +708,7 @@ pub fn (mut p Parser) parse_generic_inst_type(name string) ast.Type {
|
||||
p.struct_init_generic_types = concrete_types
|
||||
}
|
||||
concrete_types_pos := start_pos.extend(p.tok.pos())
|
||||
p.check(.gt)
|
||||
p.next()
|
||||
p.inside_generic_params = false
|
||||
bs_name += '>'
|
||||
// fmt operates on a per-file basis, so is_instance might be not set correctly. Thus it's ignored.
|
||||
|
@ -2159,6 +2159,32 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
||||
}
|
||||
}
|
||||
|
||||
fn (p &Parser) is_generic_struct_init() bool {
|
||||
lit0_is_capital := p.tok.kind != .eof && p.tok.lit.len > 0 && p.tok.lit[0].is_capital()
|
||||
if !lit0_is_capital || p.peek_tok.kind !in [.lt, .lsbr] {
|
||||
return false
|
||||
}
|
||||
if p.peek_tok.kind == .lt {
|
||||
return true
|
||||
} else {
|
||||
mut i := 2
|
||||
for {
|
||||
cur_tok := p.peek_token(i)
|
||||
if cur_tok.kind == .eof || cur_tok.kind !in [.amp, .dot, .comma, .name, .lsbr, .rsbr] {
|
||||
break
|
||||
}
|
||||
if cur_tok.kind == .rsbr {
|
||||
if p.peek_token(i + 1).kind == .lcbr {
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fn (p &Parser) is_typename(t token.Token) bool {
|
||||
return t.kind == .name && (t.lit[0].is_capital() || p.table.known_type(t.lit))
|
||||
}
|
||||
@ -2177,7 +2203,7 @@ fn (p &Parser) is_typename(t token.Token) bool {
|
||||
// see also test_generic_detection in vlib/v/tests/generics_test.v
|
||||
fn (p &Parser) is_generic_call() bool {
|
||||
lit0_is_capital := p.tok.kind != .eof && p.tok.lit.len > 0 && p.tok.lit[0].is_capital()
|
||||
if lit0_is_capital || p.peek_tok.kind != .lt {
|
||||
if lit0_is_capital || p.peek_tok.kind !in [.lt, .lsbr] {
|
||||
return false
|
||||
}
|
||||
mut tok2 := p.peek_token(2)
|
||||
@ -2206,13 +2232,31 @@ fn (p &Parser) is_generic_call() bool {
|
||||
// case 2
|
||||
return true
|
||||
}
|
||||
return match kind3 {
|
||||
.gt { true } // case 3
|
||||
.lt { !(tok4.lit.len == 1 && tok4.lit[0].is_capital()) } // case 4
|
||||
.comma { p.is_typename(tok2) } // case 5
|
||||
// case 6 and 7
|
||||
.dot { kind4 == .name && (kind5 == .gt || (kind5 == .comma && p.is_typename(tok4))) }
|
||||
else { false }
|
||||
if p.peek_tok.kind == .lt {
|
||||
return match kind3 {
|
||||
.gt { true } // case 3
|
||||
.lt { !(tok4.lit.len == 1 && tok4.lit[0].is_capital()) } // case 4
|
||||
.comma { p.is_typename(tok2) } // case 5
|
||||
// case 6 and 7
|
||||
.dot { kind4 == .name && (kind5 == .gt || (kind5 == .comma && p.is_typename(tok4))) }
|
||||
else { false }
|
||||
}
|
||||
} else if p.peek_tok.kind == .lsbr {
|
||||
mut i := 3
|
||||
for {
|
||||
cur_tok := p.peek_token(i)
|
||||
if cur_tok.kind == .eof
|
||||
|| cur_tok.kind !in [.amp, .dot, .comma, .name, .lsbr, .rsbr] {
|
||||
break
|
||||
}
|
||||
if cur_tok.kind == .rsbr {
|
||||
if p.peek_token(i + 1).kind == .lpar {
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
@ -2231,10 +2275,10 @@ fn (mut p Parser) is_generic_cast() bool {
|
||||
i++
|
||||
tok := p.peek_token(i)
|
||||
|
||||
if tok.kind == .lt {
|
||||
if tok.kind in [.lt, .lsbr] {
|
||||
lt_count++
|
||||
level++
|
||||
} else if tok.kind == .gt {
|
||||
} else if tok.kind in [.gt, .rsbr] {
|
||||
level--
|
||||
}
|
||||
if lt_count > 0 && level == 0 {
|
||||
@ -2414,6 +2458,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||
is_optional := p.tok.kind == .question
|
||||
is_generic_call := p.is_generic_call()
|
||||
is_generic_cast := p.is_generic_cast()
|
||||
is_generic_struct_init := p.is_generic_struct_init()
|
||||
// p.warn('name expr $p.tok.lit $p.peek_tok.str()')
|
||||
same_line := p.tok.line_nr == p.peek_tok.line_nr
|
||||
// `(` must be on same line as name token otherwise it's a ParExpr
|
||||
@ -2494,7 +2539,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (p.peek_tok.kind == .lcbr || (p.peek_tok.kind == .lt && lit0_is_capital))
|
||||
} else if (p.peek_tok.kind == .lcbr || is_generic_struct_init)
|
||||
&& (!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) && !known_var {
|
||||
@ -2975,13 +3020,14 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
|
||||
fn (mut p Parser) parse_generic_types() ([]ast.Type, []string) {
|
||||
mut types := []ast.Type{}
|
||||
mut param_names := []string{}
|
||||
if p.tok.kind != .lt {
|
||||
if p.tok.kind !in [.lt, .lsbr] {
|
||||
return types, param_names
|
||||
}
|
||||
p.check(.lt)
|
||||
end_kind := if p.tok.kind == .lt { token.Kind.gt } else { token.Kind.rsbr }
|
||||
p.next()
|
||||
mut first_done := false
|
||||
mut count := 0
|
||||
for p.tok.kind !in [.gt, .eof] {
|
||||
for p.tok.kind !in [end_kind, .eof] {
|
||||
if first_done {
|
||||
p.check(.comma)
|
||||
}
|
||||
@ -3018,25 +3064,26 @@ fn (mut p Parser) parse_generic_types() ([]ast.Type, []string) {
|
||||
first_done = true
|
||||
count++
|
||||
}
|
||||
p.check(.gt)
|
||||
p.check(end_kind)
|
||||
return types, param_names
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_concrete_types() []ast.Type {
|
||||
mut types := []ast.Type{}
|
||||
if p.tok.kind != .lt {
|
||||
if p.tok.kind !in [.lt, .lsbr] {
|
||||
return types
|
||||
}
|
||||
end_kind := if p.tok.kind == .lt { token.Kind.gt } else { token.Kind.rsbr }
|
||||
p.next() // `<`
|
||||
mut first_done := false
|
||||
for p.tok.kind !in [.eof, .gt] {
|
||||
for p.tok.kind !in [.eof, end_kind] {
|
||||
if first_done {
|
||||
p.check(.comma)
|
||||
}
|
||||
types << p.parse_type()
|
||||
first_done = true
|
||||
}
|
||||
p.check(.gt) // `>`
|
||||
p.check(end_kind) // `>`
|
||||
return types
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user