Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Dec 2, 2023
1 parent c943d9a commit a5e9582
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 0 deletions.
2 changes: 2 additions & 0 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ mut:
comptime_fields_type map[string]ast.Type
comptime_for_field_value ast.StructField // value of the field variable
comptime_enum_field_value string // current enum value name
comptime_for_method string // $for method in T.methods {}
comptime_for_method_var string // $for method in T.methods {}; the variable name
fn_scope &ast.Scope = unsafe { nil }
main_fn_decl_node ast.FnDecl
match_exhaustive_cutoff_limit int = 10
Expand Down
19 changes: 19 additions & 0 deletions vlib/v/checker/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ fn (mut c Checker) get_comptime_var_type(node ast.Expr) ast.Type {
} else if node is ast.SelectorExpr && c.is_comptime_selector_type(node) {
// field_var.typ from $for field
return c.comptime_fields_default_type
} else if node is ast.ComptimeCall {
method_name := c.comptime_for_method
left_sym := c.table.sym(c.unwrap_generic(node.left_type))
f := left_sym.find_method(method_name) or {
c.error('could not find method `${method_name}` on compile-time resolution',
node.method_pos)
return ast.void_type
}
return f.return_type
}
return ast.void_type
}
Expand Down Expand Up @@ -323,6 +332,16 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
node.typ_pos)
return
}
} else if node.kind == .methods {
mut methods := sym.methods.filter(it.attrs.len == 0) // methods without attrs first
methods_with_attrs := sym.methods.filter(it.attrs.len > 0) // methods with attrs second
methods << methods_with_attrs

for method in methods {
c.comptime_for_method = method.name
c.comptime_for_method_var = node.val_var
c.stmts(mut node.stmts)
}
} else {
c.stmts(mut node.stmts)
}
Expand Down
2 changes: 2 additions & 0 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,8 @@ fn (mut c Checker) get_comptime_args(func ast.Fn, node_ ast.CallExpr, concrete_t
} else if call_arg.expr is ast.ComptimeSelector
&& c.table.is_comptime_var(call_arg.expr) {
comptime_args[i] = c.get_comptime_var_type(call_arg.expr)
} else if call_arg.expr is ast.ComptimeCall {
comptime_args[i] = c.get_comptime_var_type(call_arg.expr)
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions vlib/v/gen/c/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,14 @@ fn (mut g Gen) change_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concret
if param_typ.nr_muls() > 0 && comptime_args[i].nr_muls() > 0 {
comptime_args[i] = comptime_args[i].set_nr_muls(0)
}
} else if mut call_arg.expr is ast.ComptimeCall {
if call_arg.expr.method_name == 'method' {
sym := g.table.sym(g.unwrap_generic(call_arg.expr.left_type))
// `app.$method()`
if m := sym.find_method(g.comptime_for_method) {
comptime_args[i] = m.return_type
}
}
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions vlib/v/tests/method_call_resolve_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
struct Human {
name string
}

enum Animal {
dog
cat
}

type Entity = Animal | Human

@[sumtype_to: Animal]
fn (ent Entity) json_cast_to_animal() Animal {
return ent as Animal
}

@[sumtype_to: Human]
fn (ent Entity) json_cast_to_human() Human {
return ent as Human
}

fn encode[T](val T) {
$if T is $sumtype {
$for method in T.methods {
if method.attrs.len >= 1 {
if method.attrs[0].contains('sumtype_to') {
if val.type_name() == method.attrs[0].all_after('sumtype_to:').trim_space() {
// println(val.$method())
encode(val.$method()) // Problem here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!1!!!!11!
}
}
}
}
} $else $if T is $struct {
assert val == Human{
name: 'Monke'
}
} $else $if T is $enum {
assert val == Animal.cat
}
}

fn test_main() {
encode(Entity(Human{'Monke'}))
encode(Entity(Animal.cat))
}

0 comments on commit a5e9582

Please sign in to comment.