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:
name string
is_pub bool
typ Type
pos token.Pos
type_pos token.Pos
comments []Comment
attrs []Attr // attributes of type declaration
name string
is_pub bool
typ Type
pos token.Pos
type_pos token.Pos
comments []Comment
generic_types []Type
attrs []Attr // attributes of type declaration
}
// 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_info := fn_typ_info.func
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 {
if arg.is_mut {
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 == '' {
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('(')

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
type_pos: type_pos
comments: comments
generic_types: generic_types
attrs: attrs
}
}

View File

@ -29,16 +29,16 @@ fn f5(s string) fn (string) !string {
}
fn test_call_nested_anon() {
println(main.f1('V')('Lang')!)
s1 := main.f1('V')('Lang')!
println(f1('V')('Lang')!)
s1 := f1('V')('Lang')!
println(s1)
s2 := main.f1('V')('Lang') or { 'ErrLang' }
s2 := f1('V')('Lang') or { 'ErrLang' }
println(s2)
s3 := main.f2('V')('Lang')?
s3 := f2('V')('Lang')?
println(s3)
s4 := main.f2('V')('Lang') or { 'NoneLang' }
s4 := f2('V')('Lang') or { 'NoneLang' }
println(s4)
s := main.f3('V')('Lang')
s := f3('V')('Lang')
println(s)
assert s == 'VLang'
assert s1 == 'VLang'
@ -46,10 +46,10 @@ fn test_call_nested_anon() {
assert s3 == 'VLang'
assert s4 == 'VLang'
s5 := main.f4('V')('Lang') or { 'Lang++' }
s5 := f4('V')('Lang') or { 'Lang++' }
println(s5)
assert s5 == 'Lang++'
s6 := main.f5('V')('Lang') or { '${err}' }
s6 := f5('V')('Lang') or { '${err}' }
println(s6)
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 pg2 = main.fn_generator()()
const pg2 = fn_generator()()
fn fn_generator() 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() {
assert main.fn_generator()() == 'ok'
assert fn_generator()() == 'ok'
x := fn_generator()
assert x() == 'ok'

View File

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

View File

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

View File

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

View File

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