parser: fixed parsing prototype function with recursive type (#13922)
parent
0cba579a7b
commit
359f16fdfd
|
@ -11,6 +11,8 @@ import v.util
|
|||
|
||||
[heap]
|
||||
pub struct Table {
|
||||
mut:
|
||||
parsing_type string // name of the type to enable recursive type parsing
|
||||
pub mut:
|
||||
type_symbols []&TypeSymbol
|
||||
type_idxs map[string]int
|
||||
|
@ -830,7 +832,17 @@ pub fn (mut t Table) register_enum_decl(enum_decl EnumDecl) {
|
|||
}
|
||||
|
||||
pub fn (t &Table) known_type(name string) bool {
|
||||
return t.find_type_idx(name) != 0
|
||||
return t.find_type_idx(name) != 0 || t.parsing_type == name
|
||||
}
|
||||
|
||||
// start_parsing_type open the scope during the parsing of a type
|
||||
// where the type name must include the module prefix
|
||||
pub fn (mut t Table) start_parsing_type(type_name string) {
|
||||
t.parsing_type = type_name
|
||||
}
|
||||
|
||||
pub fn (mut t Table) reset_parsing_type() {
|
||||
t.parsing_type = ''
|
||||
}
|
||||
|
||||
pub fn (t &Table) known_type_idx(typ Type) bool {
|
||||
|
|
|
@ -738,13 +738,14 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
|
|||
} else {
|
||||
p.tok.lit
|
||||
}
|
||||
|
||||
types_only := p.tok.kind in [.amp, .ellipsis, .key_fn, .lsbr]
|
||||
|| (p.peek_tok.kind == .comma && p.table.known_type(argname))
|
||||
|| p.peek_tok.kind == .dot || p.peek_tok.kind == .rpar
|
||||
|| (p.tok.kind == .key_mut && (p.peek_token(2).kind == .comma
|
||||
|| p.peek_token(2).kind == .rpar || (p.peek_tok.kind == .name
|
||||
&& p.peek_token(2).kind == .dot)))
|
||||
// TODO copy pasta, merge 2 branches
|
||||
// TODO copy paste, merge 2 branches
|
||||
if types_only {
|
||||
mut arg_no := 1
|
||||
for p.tok.kind != .rpar {
|
||||
|
@ -800,6 +801,7 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
|
|||
p.error_with_pos('expecting `)`', p.prev_tok.pos())
|
||||
return []ast.Param{}, false, false
|
||||
}
|
||||
|
||||
if p.tok.kind == .comma {
|
||||
if is_variadic {
|
||||
p.error_with_pos('cannot use ...(variadic) with non-final parameter no $arg_no',
|
||||
|
|
|
@ -51,6 +51,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
|
|||
p.error_with_pos('cannot register struct `IError`, it is builtin interface type',
|
||||
name_pos)
|
||||
}
|
||||
// append module name before any type of parsing to enable recursion parsing
|
||||
p.table.start_parsing_type(p.prepend_mod(name))
|
||||
defer {
|
||||
p.table.reset_parsing_type()
|
||||
}
|
||||
generic_types, _ := p.parse_generic_types()
|
||||
no_body := p.tok.kind != .lcbr
|
||||
if language == .v && no_body {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
module main
|
||||
|
||||
struct Ok {
|
||||
alibaba fn (Ok, )
|
||||
}
|
||||
|
||||
struct OkInt {
|
||||
a fn (int, )
|
||||
}
|
Loading…
Reference in New Issue