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('is_vweb', t.bool_node(node.is_vweb))
|
||||||
obj.add_terse('vweb_tmpl', t.string_node(node.vweb_tmpl.path))
|
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('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('has_parens', t.bool_node(node.has_parens))
|
||||||
obj.add_terse('is_embed', t.bool_node(node.is_embed))
|
obj.add_terse('is_embed', t.bool_node(node.is_embed))
|
||||||
obj.add_terse('embed_file', t.embed_file(node.embed_file))
|
obj.add_terse('embed_file', t.embed_file(node.embed_file))
|
||||||
obj.add('method_pos', t.position(node.method_pos))
|
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_terse('result_type', t.type_node(node.result_type))
|
||||||
obj.add('scope', t.scope(node.scope))
|
obj.add('scope', t.scope(node.scope))
|
||||||
obj.add_terse('env_value', t.string_node(node.env_value))
|
obj.add_terse('env_value', t.string_node(node.env_value))
|
||||||
|
@ -1559,7 +1559,7 @@ pub:
|
|||||||
//
|
//
|
||||||
is_pkgconfig bool
|
is_pkgconfig bool
|
||||||
pub mut:
|
pub mut:
|
||||||
sym TypeSymbol
|
left_type Type
|
||||||
result_type Type
|
result_type Type
|
||||||
env_value string
|
env_value string
|
||||||
args []CallArg
|
args []CallArg
|
||||||
|
@ -10,7 +10,7 @@ import v.pkgconfig
|
|||||||
|
|
||||||
fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
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)))
|
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 {
|
if node.is_env {
|
||||||
env_value := util.resolve_env_value("\$env('$node.args_var')", false) or {
|
env_value := util.resolve_env_value("\$env('$node.args_var')", false) or {
|
||||||
c.error(err.msg, node.env_pos)
|
c.error(err.msg, node.env_pos)
|
||||||
@ -91,7 +91,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
|||||||
} else {
|
} else {
|
||||||
c.error('todo: not a string literal', node.method_pos)
|
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)
|
c.error('could not find method `$method_name`', node.method_pos)
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
|
@ -76,10 +76,11 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
|
|||||||
}
|
}
|
||||||
return
|
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' {
|
if node.method_name == 'method' {
|
||||||
// `app.$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('/')
|
vals := m.attrs[0].split('/')
|
||||||
args := vals.filter(it.starts_with(':')).map(it[1..])
|
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
|
// check argument length and types
|
||||||
if m.params.len - 1 != node.args.len && !expand_strs {
|
if m.params.len - 1 != node.args.len && !expand_strs {
|
||||||
// do not generate anything if the argument lengths don't match
|
// 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"));')
|
// 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' +
|
// eprintln('info: skipping ${node.sym.name}.$m.name due to mismatched arguments list\n' +
|
||||||
//'method.params: $m.params, args: $node.args\n\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
|
return
|
||||||
}
|
}
|
||||||
// TODO: check argument types
|
// 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
|
// try to see if we need to pass a pointer
|
||||||
if node.left is ast.Ident {
|
if node.left is ast.Ident {
|
||||||
@ -153,7 +154,7 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
mut j := 0
|
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 != ast.void_type {
|
||||||
if method.return_type != node.result_type {
|
if method.return_type != node.result_type {
|
||||||
continue
|
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('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.expr(node.left)
|
||||||
g.writeln(');')
|
g.writeln(');')
|
||||||
j++
|
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