Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Dec 28, 2024
1 parent 2ea6115 commit 300506b
Show file tree
Hide file tree
Showing 25 changed files with 694 additions and 675 deletions.
11 changes: 6 additions & 5 deletions vlib/v/checker/assign.v
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
&& right.or_expr.kind == .absent {
right_obj_var := right.obj as ast.Var
if right_obj_var.ct_type_var != .no_comptime {
ctyp := c.comptime.get_type(right)
ctyp := c.type_resolver.get_type(right)
if ctyp != ast.void_type {
left.obj.ct_type_var = right_obj_var.ct_type_var
left.obj.typ = ctyp
Expand All @@ -407,7 +407,8 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
if left.obj.ct_type_var in [.generic_var, .no_comptime]
&& c.table.cur_fn != unsafe { nil }
&& c.table.cur_fn.generic_names.len != 0
&& !right.comptime_ret_val && c.is_generic_expr(right) {
&& !right.comptime_ret_val
&& c.type_resolver.is_generic_expr(right) {
// mark variable as generic var because its type changes according to fn return generic resolution type
left.obj.ct_type_var = .generic_var
if right.return_type_generic.has_flag(.generic) {
Expand All @@ -419,7 +420,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
} else {
fn_ret_type.clear_option_and_result()
}
c.comptime.type_map['g.${left.name}.${left.obj.pos.pos}'] = var_type
c.type_resolver.type_map['g.${left.name}.${left.obj.pos.pos}'] = var_type
}
} else if right.is_static_method
&& right.left_type.has_flag(.generic) {
Expand All @@ -429,7 +430,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
} else {
fn_ret_type.clear_option_and_result()
}
c.comptime.type_map['g.${left.name}.${left.obj.pos.pos}'] = var_type
c.type_resolver.type_map['g.${left.name}.${left.obj.pos.pos}'] = var_type
}
}
}
Expand Down Expand Up @@ -505,7 +506,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
if (left.is_map || left.is_farray) && left.is_setter {
left.recursive_mapset_is_setter(true)
}
right_type = c.comptime.get_type_or_default(right, right_type)
right_type = c.type_resolver.get_type_or_default(right, right_type)
}
if mut left is ast.InfixExpr {
c.error('cannot use infix expression on the left side of `${node.op}`',
Expand Down
6 changes: 4 additions & 2 deletions vlib/v/checker/check_types.v
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,8 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) {
typ = ast.new_type(idx).derive(arg.typ)
} else if c.comptime.comptime_for_field_var != '' && sym.kind in [.struct, .any]
&& arg.expr is ast.ComptimeSelector {
comptime_typ := c.comptime.get_comptime_selector_type(arg.expr, ast.void_type)
comptime_typ := c.type_resolver.get_comptime_selector_type(arg.expr,
ast.void_type)
if comptime_typ != ast.void_type {
typ = comptime_typ
if func.return_type.has_flag(.generic)
Expand Down Expand Up @@ -1121,7 +1122,8 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) {
}
// resolve lambda with generic return type
if arg.expr is ast.LambdaExpr && typ.has_flag(.generic) {
typ = c.comptime.unwrap_generic_expr(arg.expr.expr, typ)
typ = c.type_resolver.unwrap_generic_expr(arg.expr.expr,
typ)
if typ.has_flag(.generic) {
lambda_ret_gt_name := c.table.type_to_str(typ)
idx := func.generic_names.index(lambda_ret_gt_name)
Expand Down
28 changes: 13 additions & 15 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import v.util.version
import v.errors
import v.pkgconfig
import v.transformer
import v.comptime
import v.type_resolver

// prevent stack overflows by restricting too deep recursion:
const expr_level_cutoff_limit = 40
Expand Down Expand Up @@ -116,9 +116,9 @@ mut:
loop_labels []string // filled, when inside labelled for loops: `a_label: for x in 0..10 {`
vweb_gen_types []ast.Type // vweb route checks
timers &util.Timers = util.get_timers()
comptime_info_stack []comptime.ComptimeInfo // stores the values from the above on each $for loop, to make nesting them easier
comptime comptime.ComptimeInfo
fn_scope &ast.Scope = unsafe { nil }
type_resolver type_resolver.TypeResolver
comptime &type_resolver.ResolverInfo = unsafe { nil }
fn_scope &ast.Scope = unsafe { nil }
main_fn_decl_node ast.FnDecl
match_exhaustive_cutoff_limit int = 10
is_last_stmt bool
Expand Down Expand Up @@ -164,10 +164,8 @@ pub fn new_checker(table &ast.Table, pref_ &pref.Preferences) &Checker {
v_current_commit_hash: if pref_.building_v { version.githash(pref_.vroot) or {
@VCURRENTHASH} } else { @VCURRENTHASH }
}
checker.comptime = &comptime.ComptimeInfo{
resolver: checker
table: table
}
checker.type_resolver = type_resolver.TypeResolver.new(table, checker)
checker.comptime = &checker.type_resolver.info
return checker
}

Expand Down Expand Up @@ -1674,7 +1672,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
} else if c.comptime.inside_comptime_for && typ == c.enum_data_type
&& node.field_name == 'value' {
// for comp-time enum.values
node.expr_type = c.comptime.type_map['${c.comptime.comptime_for_enum_var}.typ']
node.expr_type = c.type_resolver.type_map['${c.comptime.comptime_for_enum_var}.typ']
node.typ = typ
return node.expr_type
}
Expand Down Expand Up @@ -3056,9 +3054,9 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
}
if c.comptime.inside_comptime_for && mut node.expr is ast.Ident {
if node.expr.ct_expr {
node.expr_type = c.comptime.get_type(node.expr as ast.Ident)
} else if (node.expr as ast.Ident).name in c.comptime.type_map {
node.expr_type = c.comptime.type_map[(node.expr as ast.Ident).name]
node.expr_type = c.type_resolver.get_type(node.expr as ast.Ident)
} else if (node.expr as ast.Ident).name in c.type_resolver.type_map {
node.expr_type = c.type_resolver.type_map[(node.expr as ast.Ident).name]
}
}
c.check_expr_option_or_result_call(node.expr, node.expr_type)
Expand Down Expand Up @@ -3348,9 +3346,9 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
c.inside_integer_literal_cast = old_inside_integer_literal_cast

if mut node.expr is ast.ComptimeSelector {
node.expr_type = c.comptime.get_comptime_selector_type(node.expr, node.expr_type)
node.expr_type = c.type_resolver.get_comptime_selector_type(node.expr, node.expr_type)
} else if node.expr is ast.Ident && c.comptime.is_comptime_variant_var(node.expr) {
node.expr_type = c.comptime.type_map['${c.comptime.comptime_for_variant_var}.typ']
node.expr_type = c.type_resolver.type_map['${c.comptime.comptime_for_variant_var}.typ']
}
mut from_type := c.unwrap_generic(node.expr_type)
from_sym := c.table.sym(from_type)
Expand Down Expand Up @@ -3960,7 +3958,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
// second use
if node.kind in [.constant, .global, .variable] {
info := node.info as ast.IdentVar
typ := c.comptime.get_type_or_default(node, info.typ)
typ := c.type_resolver.get_type_or_default(node, info.typ)
// Got a var with type T, return current generic type
if node.or_expr.kind != .absent {
if !typ.has_flag(.option) {
Expand Down
50 changes: 24 additions & 26 deletions vlib/v/checker/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import v.pref
import v.token
import v.util
import v.pkgconfig
import v.comptime
import v.type_resolver

fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
if node.left !is ast.EmptyExpr {
Expand Down Expand Up @@ -160,7 +160,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
}
}
c.stmts_ending_with_expression(mut node.or_block.stmts, c.expected_or_type)
return c.comptime.get_type(node)
return c.type_resolver.get_type(node)
}
if node.method_name == 'res' {
if !c.inside_defer {
Expand Down Expand Up @@ -240,17 +240,17 @@ fn (mut c Checker) comptime_selector(mut node ast.ComptimeSelector) ast.Type {
}
if mut node.field_expr is ast.SelectorExpr {
left_pos := node.field_expr.expr.pos()
if c.comptime.type_map.len == 0 {
if c.type_resolver.type_map.len == 0 {
c.error('compile time field access can only be used when iterating over `T.fields`',
left_pos)
}
expr_type = c.comptime.get_comptime_selector_type(node, ast.void_type)
expr_type = c.type_resolver.get_comptime_selector_type(node, ast.void_type)
if expr_type != ast.void_type {
return expr_type
}
expr_name := node.field_expr.expr.str()
if expr_name in c.comptime.type_map {
return c.comptime.type_map[expr_name]
if expr_name in c.type_resolver.type_map {
return c.type_resolver.type_map[expr_name]
}
c.error('unknown `\$for` variable `${expr_name}`', left_pos)
} else {
Expand Down Expand Up @@ -300,8 +300,8 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
}
c.comptime.comptime_for_field_value = field
c.comptime.comptime_for_field_var = node.val_var
c.comptime.type_map[node.val_var] = c.field_data_type
c.comptime.type_map['${node.val_var}.typ'] = node.typ
c.type_resolver.type_map[node.val_var] = c.field_data_type
c.type_resolver.type_map['${node.val_var}.typ'] = node.typ
c.comptime.comptime_for_field_type = field.typ
c.stmts(mut node.stmts)

Expand Down Expand Up @@ -345,8 +345,8 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
c.enum_data_type = c.table.find_type('EnumData')
}
c.comptime.comptime_for_enum_var = node.val_var
c.comptime.type_map[node.val_var] = c.enum_data_type
c.comptime.type_map['${node.val_var}.typ'] = node.typ
c.type_resolver.type_map[node.val_var] = c.enum_data_type
c.type_resolver.type_map['${node.val_var}.typ'] = node.typ
c.stmts(mut node.stmts)
c.pop_comptime_info()
c.table.used_features.comptime_for = true
Expand All @@ -363,7 +363,7 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
c.comptime.comptime_for_method = unsafe { &method }
c.comptime.comptime_for_method_var = node.val_var
c.comptime.comptime_for_method_ret_type = method.return_type
c.comptime.type_map['${node.val_var}.return_type'] = method.return_type
c.type_resolver.type_map['${node.val_var}.return_type'] = method.return_type
c.stmts(mut node.stmts)
c.pop_comptime_info()
}
Expand Down Expand Up @@ -398,8 +398,8 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
c.push_new_comptime_info()
c.comptime.inside_comptime_for = true
c.comptime.comptime_for_variant_var = node.val_var
c.comptime.type_map[node.val_var] = c.variant_data_type
c.comptime.type_map['${node.val_var}.typ'] = variant
c.type_resolver.type_map[node.val_var] = c.variant_data_type
c.type_resolver.type_map['${node.val_var}.typ'] = variant
c.stmts(mut node.stmts)
c.pop_comptime_info()
}
Expand Down Expand Up @@ -833,7 +833,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, pos token.Pos) ComptimeBr
} else if cond.left is ast.TypeNode && mut cond.right is ast.ComptimeType {
left := cond.left as ast.TypeNode
checked_type := c.unwrap_generic(left.typ)
return if c.comptime.is_comptime_type(checked_type, cond.right) {
return if c.type_resolver.is_comptime_type(checked_type, cond.right) {
.eval
} else {
.skip
Expand All @@ -844,8 +844,10 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, pos token.Pos) ComptimeBr
if mut cond.left is ast.SelectorExpr && cond.right is ast.ComptimeType {
comptime_type := cond.right as ast.ComptimeType
if c.comptime.is_comptime_selector_type(cond.left) {
checked_type := c.comptime.get_type(cond.left)
return if c.comptime.is_comptime_type(checked_type, comptime_type) {
checked_type := c.type_resolver.get_type(cond.left)
return if c.type_resolver.is_comptime_type(checked_type,
comptime_type)
{
.eval
} else {
.skip
Expand All @@ -854,7 +856,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, pos token.Pos) ComptimeBr
&& cond.left.name_type != 0 {
// T.unaliased_typ
checked_type := c.unwrap_generic(cond.left.name_type)
return if c.comptime.is_comptime_type(c.table.unaliased_type(checked_type),
return if c.type_resolver.is_comptime_type(c.table.unaliased_type(checked_type),
comptime_type)
{
.eval
Expand Down Expand Up @@ -1085,7 +1087,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, pos token.Pos) ComptimeBr
ast.SelectorExpr {
if c.comptime.check_comptime_is_field_selector(cond) {
if c.comptime.check_comptime_is_field_selector_bool(cond) {
ret_bool := c.comptime.get_comptime_selector_bool_field(cond.field_name)
ret_bool := c.type_resolver.get_comptime_selector_bool_field(cond.field_name)
return if ret_bool { .eval } else { .skip }
}
c.error('unknown field `${cond.field_name}` from ${c.comptime.comptime_for_field_var}',
Expand All @@ -1102,10 +1104,8 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, pos token.Pos) ComptimeBr

// push_new_comptime_info saves the current comptime information
fn (mut c Checker) push_new_comptime_info() {
c.comptime_info_stack << comptime.ComptimeInfo{
resolver: c.comptime.resolver
table: c.comptime.table
type_map: c.comptime.type_map.clone()
c.type_resolver.info_stack << type_resolver.ResolverInfo{
saved_type_map: c.type_resolver.type_map.clone()
inside_comptime_for: c.comptime.inside_comptime_for
comptime_for_variant_var: c.comptime.comptime_for_variant_var
comptime_for_field_var: c.comptime.comptime_for_field_var
Expand All @@ -1120,10 +1120,8 @@ fn (mut c Checker) push_new_comptime_info() {

// pop_comptime_info pops the current comptime information frame
fn (mut c Checker) pop_comptime_info() {
old := c.comptime_info_stack.pop()
c.comptime.resolver = old.resolver
c.comptime.table = old.table
c.comptime.type_map = old.type_map.clone()
old := c.type_resolver.info_stack.pop()
c.type_resolver.type_map = old.saved_type_map.clone()
c.comptime.inside_comptime_for = old.inside_comptime_for
c.comptime.comptime_for_variant_var = old.comptime_for_variant_var
c.comptime.comptime_for_field_var = old.comptime_for_field_var
Expand Down
46 changes: 7 additions & 39 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -1805,7 +1805,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
continue
}
c.check_expected_call_arg(utyp, unwrap_typ, node.language, call_arg) or {
if c.comptime.type_map.len > 0 {
if c.type_resolver.type_map.len > 0 {
continue
}
if mut call_arg.expr is ast.LambdaExpr {
Expand Down Expand Up @@ -1885,38 +1885,6 @@ fn (mut c Checker) register_trace_call(node &ast.CallExpr, func &ast.Fn) {
}
}

// is_generic_expr checks if the expr relies on fn generic argument
fn (mut c Checker) is_generic_expr(node ast.Expr) bool {
return match node {
ast.Ident {
// variable declared as generic type
c.comptime.is_generic_param_var(node)
}
ast.IndexExpr {
// generic_var[N]
c.comptime.is_generic_param_var(node.left)
}
ast.CallExpr {
// fn which has any generic dependent expr
if node.args.any(c.comptime.is_generic_param_var(it.expr)) {
return true
}
if node.is_static_method && node.left_type.has_flag(.generic) {
return true
}
// fn[T]() or generic_var.fn[T]()
node.concrete_types.any(it.has_flag(.generic))
}
ast.SelectorExpr {
// generic_var.property
c.comptime.is_generic_param_var(node.expr)
}
else {
false
}
}
}

fn (mut c Checker) resolve_comptime_args(func &ast.Fn, node_ ast.CallExpr, concrete_types []ast.Type) map[int]ast.Type {
mut comptime_args := map[int]ast.Type{}
has_dynamic_vars := (c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len > 0)
Expand All @@ -1938,7 +1906,7 @@ fn (mut c Checker) resolve_comptime_args(func &ast.Fn, node_ ast.CallExpr, concr
if call_arg.expr is ast.Ident {
if call_arg.expr.obj is ast.Var {
if call_arg.expr.obj.ct_type_var !in [.generic_var, .generic_param, .no_comptime] {
mut ctyp := c.comptime.get_type(call_arg.expr)
mut ctyp := c.type_resolver.get_type(call_arg.expr)
if ctyp != ast.void_type {
arg_sym := c.table.sym(ctyp)
param_sym := c.table.final_sym(param_typ)
Expand All @@ -1961,7 +1929,7 @@ fn (mut c Checker) resolve_comptime_args(func &ast.Fn, node_ ast.CallExpr, concr
comptime_args[k] = ctyp
}
} else if call_arg.expr.obj.ct_type_var == .generic_param {
mut ctyp := c.comptime.get_type(call_arg.expr)
mut ctyp := c.type_resolver.get_type(call_arg.expr)
if ctyp != ast.void_type {
arg_sym := c.table.final_sym(call_arg.typ)
param_typ_sym := c.table.sym(param_typ)
Expand Down Expand Up @@ -2024,7 +1992,7 @@ fn (mut c Checker) resolve_comptime_args(func &ast.Fn, node_ ast.CallExpr, concr
}
}
} else if call_arg.expr.obj.ct_type_var == .generic_var {
mut ctyp := c.comptime.get_type(call_arg.expr)
mut ctyp := c.type_resolver.get_type(call_arg.expr)
if node_.args[i].expr.is_auto_deref_var() {
ctyp = ctyp.deref()
}
Expand All @@ -2036,14 +2004,14 @@ fn (mut c Checker) resolve_comptime_args(func &ast.Fn, node_ ast.CallExpr, concr
}
} else if call_arg.expr is ast.PrefixExpr {
if call_arg.expr.right is ast.ComptimeSelector {
comptime_args[k] = c.comptime.get_type(call_arg.expr.right)
comptime_args[k] = c.type_resolver.get_type(call_arg.expr.right)
comptime_args[k] = comptime_args[k].deref()
if comptime_args[k].nr_muls() > 0 && param_typ.nr_muls() > 0 {
comptime_args[k] = comptime_args[k].set_nr_muls(0)
}
}
} else if call_arg.expr is ast.ComptimeSelector {
ct_value := c.comptime.get_type(call_arg.expr)
ct_value := c.type_resolver.get_type(call_arg.expr)
param_typ_sym := c.table.sym(param_typ)
if ct_value != ast.void_type {
arg_sym := c.table.final_sym(call_arg.typ)
Expand All @@ -2068,7 +2036,7 @@ fn (mut c Checker) resolve_comptime_args(func &ast.Fn, node_ ast.CallExpr, concr
}
}
} else if call_arg.expr is ast.ComptimeCall {
comptime_args[k] = c.comptime.get_type(call_arg.expr)
comptime_args[k] = c.type_resolver.get_type(call_arg.expr)
}
}
}
Expand Down
Loading

0 comments on commit 300506b

Please sign in to comment.