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 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
|
||||||
|
@ -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('(')
|
||||||
|
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
|
pos: decl_pos
|
||||||
type_pos: type_pos
|
type_pos: type_pos
|
||||||
comments: comments
|
comments: comments
|
||||||
|
generic_types: generic_types
|
||||||
attrs: attrs
|
attrs: attrs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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'
|
||||||
}
|
}
|
||||||
|
@ -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'
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user