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:
parent
d0702f3897
commit
b9352ce834
@ -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
|
||||
|
@ -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('(')
|
||||
|
24
vlib/v/fmt/tests/generics_fntype_keep.vv
Normal file
24
vlib/v/fmt/tests/generics_fntype_keep.vv
Normal 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
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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'
|
||||
}
|
||||
|
@ -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'
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user