1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast, parser, fmt: fix fmt error of generic fntype (#17814)

This commit is contained in:
yuyi 2023-03-30 19:30:10 +08:00 committed by GitHub
parent d0702f3897
commit b9352ce834
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 63 additions and 28 deletions

View File

@ -1225,13 +1225,14 @@ pub mut:
pub struct FnTypeDecl { pub struct FnTypeDecl {
pub: pub:
name string name string
is_pub bool is_pub bool
typ Type typ Type
pos token.Pos pos token.Pos
type_pos token.Pos type_pos token.Pos
comments []Comment comments []Comment
attrs []Attr // attributes of type declaration generic_types []Type
attrs []Attr // attributes of type declaration
} }
// TODO: handle this differently // TODO: handle this differently

View File

@ -1396,7 +1396,12 @@ pub fn (mut f Fmt) fn_type_decl(node ast.FnTypeDecl) {
fn_typ_info := typ_sym.info as ast.FnType fn_typ_info := typ_sym.info as ast.FnType
fn_info := fn_typ_info.func fn_info := fn_typ_info.func
fn_name := f.no_cur_mod(node.name) fn_name := f.no_cur_mod(node.name)
f.write('type ${fn_name} = fn (') mut generic_types_str := ''
if node.generic_types.len > 0 {
generic_names := node.generic_types.map(f.table.sym(it).name)
generic_types_str = '[${generic_names.join(', ')}]'
}
f.write('type ${fn_name}${generic_types_str} = fn (')
for i, arg in fn_info.params { for i, arg in fn_info.params {
if arg.is_mut { if arg.is_mut {
f.write(arg.typ.share().str() + ' ') f.write(arg.typ.share().str() + ' ')
@ -1775,7 +1780,11 @@ pub fn (mut f Fmt) call_expr(node ast.CallExpr) {
} }
} }
if node.mod == '' && node.name == '' { if node.mod == '' && node.name == '' {
f.write(node.left.str()) if node.left is ast.CallExpr {
f.expr(node.left)
} else {
f.write(node.left.str())
}
} }
f.write_generic_call_if_require(node) f.write_generic_call_if_require(node)
f.write('(') f.write('(')

View File

@ -0,0 +1,24 @@
type Fn[T] = fn (T)
type FnReturn[T, R] = fn (T) R
fn func_fn_concrete() Fn[string] {
return fn (_s string) {}
}
fn func_fn_dynamic[T]() Fn[T] {
return fn [T](_t T) {}
}
fn func_fn_return_dynamic[T, R]() FnReturn[T, R] {
return fn [T, R](t T) R {
return t.int()
}
}
fn main() {
func_fn_concrete()('V')
func_fn_dynamic[string]()('V')
assert func_fn_return_dynamic[string, int]()('100') == 100
}

View File

@ -4016,6 +4016,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
pos: decl_pos pos: decl_pos
type_pos: type_pos type_pos: type_pos
comments: comments comments: comments
generic_types: generic_types
attrs: attrs attrs: attrs
} }
} }

View File

@ -29,16 +29,16 @@ fn f5(s string) fn (string) !string {
} }
fn test_call_nested_anon() { fn test_call_nested_anon() {
println(main.f1('V')('Lang')!) println(f1('V')('Lang')!)
s1 := main.f1('V')('Lang')! s1 := f1('V')('Lang')!
println(s1) println(s1)
s2 := main.f1('V')('Lang') or { 'ErrLang' } s2 := f1('V')('Lang') or { 'ErrLang' }
println(s2) println(s2)
s3 := main.f2('V')('Lang')? s3 := f2('V')('Lang')?
println(s3) println(s3)
s4 := main.f2('V')('Lang') or { 'NoneLang' } s4 := f2('V')('Lang') or { 'NoneLang' }
println(s4) println(s4)
s := main.f3('V')('Lang') s := f3('V')('Lang')
println(s) println(s)
assert s == 'VLang' assert s == 'VLang'
assert s1 == 'VLang' assert s1 == 'VLang'
@ -46,10 +46,10 @@ fn test_call_nested_anon() {
assert s3 == 'VLang' assert s3 == 'VLang'
assert s4 == 'VLang' assert s4 == 'VLang'
s5 := main.f4('V')('Lang') or { 'Lang++' } s5 := f4('V')('Lang') or { 'Lang++' }
println(s5) println(s5)
assert s5 == 'Lang++' assert s5 == 'Lang++'
s6 := main.f5('V')('Lang') or { '${err}' } s6 := f5('V')('Lang') or { '${err}' }
println(s6) println(s6)
assert s6 == 'test' assert s6 == 'test'
} }

View File

@ -39,7 +39,7 @@ fn test_a_const_that_is_alias_to_fn_from_module() {
const pg = fn_generator() const pg = fn_generator()
const pg2 = main.fn_generator()() const pg2 = fn_generator()()
fn fn_generator() fn () string { fn fn_generator() fn () string {
return fn () string { return fn () string {
@ -49,7 +49,7 @@ fn fn_generator() fn () string {
} }
fn test_a_const_can_be_assigned_a_fn_produced_by_a_fn_generator_and_the_const_can_be_used() { fn test_a_const_can_be_assigned_a_fn_produced_by_a_fn_generator_and_the_const_can_be_used() {
assert main.fn_generator()() == 'ok' assert fn_generator()() == 'ok'
x := fn_generator() x := fn_generator()
assert x() == 'ok' assert x() == 'ok'

View File

@ -11,9 +11,9 @@ fn foofun2(op string) fn () int {
} }
fn test_fn_call_using_anon_fn_call_arg() { fn test_fn_call_using_anon_fn_call_arg() {
println(main.foofun1('1')()) println(foofun1('1')())
assert main.foofun1('1')() == 'x passed' assert foofun1('1')() == 'x passed'
println(main.foofun2('1')()) println(foofun2('1')())
assert main.foofun2('1')() == 22 assert foofun2('1')() == 22
} }

View File

@ -77,13 +77,13 @@ fn err5(f fn ()) fn () {
} }
fn test_main() { fn test_main() {
var := main.err()() var := err()()
assert var == 'b' assert var == 'b'
var2 := main.err2()() var2 := err2()()
assert var2 == 'a' assert var2 == 'a'
var3 := main.err3()() var3 := err3()()
assert var3 == 'c' assert var3 == 'c'
var4 := err4() var4 := err4()

View File

@ -30,7 +30,7 @@ fn run(mmff Maybefnfact) string {
} }
fn test_sumtype_with_alias_fntype_fn_call() { fn test_sumtype_with_alias_fntype_fn_call() {
r1 := main.myfnfact()(1) r1 := myfnfact()(1)
println(r1) println(r1)
assert r1 == 1 assert r1 == 1

View File

@ -23,7 +23,7 @@ fn test_sumtype_with_alias_fntype() {
myfnfact := fn () Myfn { myfnfact := fn () Myfn {
return abc return abc
} }
r1 := main.myfnfact()(1) r1 := myfnfact()(1)
println(r1) println(r1)
assert r1 == 1 assert r1 == 1