mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
ab6e93394f
commit
f407d6de02
@ -966,11 +966,11 @@ fn (t Tree) comptime_call(node ast.ComptimeCall) &Node {
|
||||
obj.add_terse('is_vweb', t.bool_node(node.is_vweb))
|
||||
obj.add_terse('vweb_tmpl', t.string_node(node.vweb_tmpl.path))
|
||||
obj.add_terse('args_var', t.string_node(node.args_var))
|
||||
obj.add_terse('sym', t.string_node(node.sym.name))
|
||||
obj.add_terse('has_parens', t.bool_node(node.has_parens))
|
||||
obj.add_terse('is_embed', t.bool_node(node.is_embed))
|
||||
obj.add_terse('embed_file', t.embed_file(node.embed_file))
|
||||
obj.add('method_pos', t.position(node.method_pos))
|
||||
obj.add_terse('left_type', t.type_node(node.left_type))
|
||||
obj.add_terse('result_type', t.type_node(node.result_type))
|
||||
obj.add('scope', t.scope(node.scope))
|
||||
obj.add_terse('env_value', t.string_node(node.env_value))
|
||||
|
@ -1559,7 +1559,7 @@ pub:
|
||||
//
|
||||
is_pkgconfig bool
|
||||
pub mut:
|
||||
sym TypeSymbol
|
||||
left_type Type
|
||||
result_type Type
|
||||
env_value string
|
||||
args []CallArg
|
||||
|
@ -10,7 +10,7 @@ import v.pkgconfig
|
||||
|
||||
fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||
sym := c.table.get_type_symbol(c.unwrap_generic(c.expr(node.left)))
|
||||
node.sym = *sym
|
||||
node.left_type = c.expr(node.left)
|
||||
if node.is_env {
|
||||
env_value := util.resolve_env_value("\$env('$node.args_var')", false) or {
|
||||
c.error(err.msg, node.env_pos)
|
||||
@ -91,7 +91,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||
} else {
|
||||
c.error('todo: not a string literal', node.method_pos)
|
||||
}
|
||||
f := node.sym.find_method(method_name) or {
|
||||
f := sym.find_method(method_name) or {
|
||||
c.error('could not find method `$method_name`', node.method_pos)
|
||||
return ast.void_type
|
||||
}
|
||||
|
@ -76,10 +76,11 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
|
||||
}
|
||||
return
|
||||
}
|
||||
g.trace_autofree('// \$method call. sym="$node.sym.name"')
|
||||
sym := g.table.get_type_symbol(g.unwrap_generic(node.left_type))
|
||||
g.trace_autofree('// \$method call. sym="$sym.name"')
|
||||
if node.method_name == 'method' {
|
||||
// `app.$method()`
|
||||
m := node.sym.find_method(g.comptime_for_method) or { return }
|
||||
m := sym.find_method(g.comptime_for_method) or { return }
|
||||
/*
|
||||
vals := m.attrs[0].split('/')
|
||||
args := vals.filter(it.starts_with(':')).map(it[1..])
|
||||
@ -99,7 +100,7 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
|
||||
// check argument length and types
|
||||
if m.params.len - 1 != node.args.len && !expand_strs {
|
||||
// do not generate anything if the argument lengths don't match
|
||||
g.writeln('/* skipping ${node.sym.name}.$m.name due to mismatched arguments list */')
|
||||
g.writeln('/* skipping ${sym.name}.$m.name due to mismatched arguments list */')
|
||||
// g.writeln('println(_SLIT("skipping ${node.sym.name}.$m.name due to mismatched arguments list"));')
|
||||
// eprintln('info: skipping ${node.sym.name}.$m.name due to mismatched arguments list\n' +
|
||||
//'method.params: $m.params, args: $node.args\n\n')
|
||||
@ -107,7 +108,7 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
|
||||
return
|
||||
}
|
||||
// TODO: check argument types
|
||||
g.write('${util.no_dots(node.sym.name)}_${g.comptime_for_method}(')
|
||||
g.write('${util.no_dots(sym.name)}_${g.comptime_for_method}(')
|
||||
|
||||
// try to see if we need to pass a pointer
|
||||
if node.left is ast.Ident {
|
||||
@ -153,7 +154,7 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
|
||||
return
|
||||
}
|
||||
mut j := 0
|
||||
for method in node.sym.methods {
|
||||
for method in sym.methods {
|
||||
// if method.return_type != ast.void_type {
|
||||
if method.return_type != node.result_type {
|
||||
continue
|
||||
@ -172,7 +173,7 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
|
||||
}
|
||||
g.write('if (string__eq($node.method_name, _SLIT("$method.name"))) ')
|
||||
}
|
||||
g.write('${util.no_dots(node.sym.name)}_${method.name}($amp ')
|
||||
g.write('${util.no_dots(sym.name)}_${method.name}($amp ')
|
||||
g.expr(node.left)
|
||||
g.writeln(');')
|
||||
j++
|
||||
|
39
vlib/v/tests/generics_multi_type_comptime_call_test.v
Normal file
39
vlib/v/tests/generics_multi_type_comptime_call_test.v
Normal file
@ -0,0 +1,39 @@
|
||||
struct Foo {}
|
||||
|
||||
['/'; 'GET']
|
||||
fn (mut f Foo) hello() string {
|
||||
return @FN
|
||||
}
|
||||
|
||||
struct Bar {}
|
||||
|
||||
['/'; 'GET']
|
||||
fn (b &Bar) world() string {
|
||||
return @FN
|
||||
}
|
||||
|
||||
fn execute_methods<T>() string {
|
||||
tmp := T{}
|
||||
$for method in T.methods {
|
||||
if method.attrs.len >= 2 {
|
||||
fun_path := method.attrs[0]
|
||||
fun_method := method.attrs[1]
|
||||
|
||||
if fun_path == '/' && fun_method == 'GET' {
|
||||
ret := tmp.$method()
|
||||
return ret
|
||||
}
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
fn test_generics_multi_type_comptime_call() {
|
||||
ret1 := execute_methods<Foo>()
|
||||
println(ret1)
|
||||
assert ret1 == 'hello'
|
||||
|
||||
ret2 := execute_methods<Bar>()
|
||||
println(ret2)
|
||||
assert ret2 == 'world'
|
||||
}
|
Loading…
Reference in New Issue
Block a user