Skip to content

Commit 97edd61

Browse files
authored
v: implement comptime regular func params traversing (support $if T is $function { $for param in T.params {) (#25322)
1 parent ace3eb2 commit 97edd61

6 files changed

Lines changed: 46 additions & 14 deletions

File tree

‎vlib/builtin/builtin.v‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ fn __print_assert_failure(i &VAssertMetaInfo) {
8888
}
8989
}
9090

91-
// MethodParam holds type information for function and/or method arguments.
92-
pub struct MethodParam {
91+
// FunctionParam holds type information for function and/or method arguments.
92+
pub struct FunctionParam {
9393
pub:
9494
typ int
9595
name string
@@ -100,7 +100,7 @@ pub struct FunctionData {
100100
pub:
101101
name string
102102
attrs []string
103-
args []MethodParam
103+
args []FunctionParam
104104
return_type int
105105
typ int
106106
}

‎vlib/v/checker/comptime.v‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,13 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
364364
node.typ_pos)
365365
return
366366
}
367-
method := c.comptime.comptime_for_method
367+
368+
func := if sym.info is ast.FnType { &sym.info.func } else { c.comptime.comptime_for_method }
369+
params := if func.is_method { func.params[1..] } else { func.params }
368370
// example: fn (mut d MyStruct) add(x int, y int) string
369371
// `d` is params[0], `x` is params[1], `y` is params[2]
370372
// so we at least has one param (`d`) for method
371-
for param in method.params[1..] {
373+
for param in params {
372374
c.push_new_comptime_info()
373375
c.comptime.inside_comptime_for = true
374376
c.comptime.comptime_for_method_param_var = node.val_var

‎vlib/v/gen/c/comptime.v‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -649,10 +649,10 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
649649
}
650650
if method.params.len < 2 {
651651
// 0 or 1 (the receiver) args
652-
g.writeln('\t${node.val_var}.args = builtin____new_array_with_default(0, 0, sizeof(MethodParam), 0);')
652+
g.writeln('\t${node.val_var}.args = builtin____new_array_with_default(0, 0, sizeof(FunctionParam), 0);')
653653
} else {
654654
len := method.params.len - 1
655-
g.write('\t${node.val_var}.args = builtin__new_array_from_c_array(${len}, ${len}, sizeof(MethodParam), _MOV((MethodParam[${len}]){')
655+
g.write('\t${node.val_var}.args = builtin__new_array_from_c_array(${len}, ${len}, sizeof(FunctionParam), _MOV((FunctionParam[${len}]){')
656656
// Skip receiver arg
657657
for j, arg in method.params[1..] {
658658
typ := arg.typ.idx()
@@ -841,12 +841,12 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
841841
}
842842
}
843843
} else if node.kind == .params {
844-
method := g.comptime.comptime_for_method
845-
846-
if method.params.len > 0 {
847-
g.writeln('\tMethodParam ${node.val_var} = {0};')
844+
func := if sym.info is ast.FnType { &sym.info.func } else { g.comptime.comptime_for_method }
845+
if func.params.len > 0 {
846+
g.writeln('\tFunctionParam ${node.val_var} = {0};')
848847
}
849-
for param in method.params[1..] {
848+
params := if func.is_method { func.params[1..] } else { func.params }
849+
for param in params {
850850
g.push_new_comptime_info()
851851
g.comptime.inside_comptime_for = true
852852
g.comptime.comptime_for_method_param_var = node.val_var

‎vlib/v/markused/walker.v‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ fn (mut w Walker) mark_resource_dependencies() {
13541354
w.mark_by_sym_name('FunctionData')
13551355
}
13561356
if w.uses_ct_params {
1357-
w.mark_by_sym_name('MethodParam')
1357+
w.mark_by_sym_name('FunctionParam')
13581358
}
13591359
if w.uses_ct_values {
13601360
w.mark_by_sym_name('EnumData')

‎vlib/v/parser/comptime.v‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ fn (mut p Parser) comptime_for() ast.ComptimeFor {
423423
'params' {
424424
p.scope.register(ast.Var{
425425
name: val_var
426-
typ: p.table.find_type('MethodParam')
426+
typ: p.table.find_type('FunctionParam')
427427
pos: var_pos
428428
})
429429
kind = .params
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
fn demo(a int, b string) {
2+
}
3+
4+
fn g[T](cb T) {
5+
mut params := []FunctionParam{}
6+
$if T is $function {
7+
$for param in T.params {
8+
params << param
9+
}
10+
}
11+
assert params.len == 2
12+
assert params[0].name == 'a'
13+
assert params[0].typ == 8
14+
assert params[1].name == 'b'
15+
assert params[1].typ == 21
16+
}
17+
18+
fn test_main() {
19+
g(demo)
20+
21+
mut params := []FunctionParam{}
22+
$for param in demo.params {
23+
params << param
24+
}
25+
assert params.len == 2
26+
assert params[0].name == 'a'
27+
assert params[0].typ == 8
28+
assert params[1].name == 'b'
29+
assert params[1].typ == 21
30+
}

0 commit comments

Comments
 (0)