all: minor cleanup of generics (#9744)
parent
dcf4a6b008
commit
466dc4540b
|
@ -9,19 +9,19 @@ import v.util
|
|||
|
||||
pub struct Table {
|
||||
pub mut:
|
||||
type_symbols []TypeSymbol
|
||||
type_idxs map[string]int
|
||||
fns map[string]Fn
|
||||
dumps map[int]string // needed for efficiently generating all _v_dump_expr_TNAME() functions
|
||||
imports []string // List of all imports
|
||||
modules []string // Topologically sorted list of all modules registered by the application
|
||||
cflags []cflag.CFlag
|
||||
redefined_fns []string
|
||||
fn_gen_types map[string][][]Type // for generic functions
|
||||
cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.`
|
||||
is_fmt bool
|
||||
used_fns map[string]bool // filled in by the checker, when pref.skip_unused = true;
|
||||
used_consts map[string]bool // filled in by the checker, when pref.skip_unused = true;
|
||||
type_symbols []TypeSymbol
|
||||
type_idxs map[string]int
|
||||
fns map[string]Fn
|
||||
dumps map[int]string // needed for efficiently generating all _v_dump_expr_TNAME() functions
|
||||
imports []string // List of all imports
|
||||
modules []string // Topologically sorted list of all modules registered by the application
|
||||
cflags []cflag.CFlag
|
||||
redefined_fns []string
|
||||
fn_generic_types map[string][][]Type // for generic functions
|
||||
cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.`
|
||||
is_fmt bool
|
||||
used_fns map[string]bool // filled in by the checker, when pref.skip_unused = true;
|
||||
used_consts map[string]bool // filled in by the checker, when pref.skip_unused = true;
|
||||
}
|
||||
|
||||
pub struct Fn {
|
||||
|
@ -859,13 +859,13 @@ pub fn (t &Table) mktyp(typ Type) Type {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn (mut t Table) register_fn_gen_type(fn_name string, types []Type) {
|
||||
mut a := t.fn_gen_types[fn_name]
|
||||
pub fn (mut t Table) register_fn_generic_types(fn_name string, types []Type) {
|
||||
mut a := t.fn_generic_types[fn_name]
|
||||
if types in a {
|
||||
return
|
||||
}
|
||||
a << types
|
||||
t.fn_gen_types[fn_name] = a
|
||||
t.fn_generic_types[fn_name] = a
|
||||
}
|
||||
|
||||
// TODO: there is a bug when casting sumtype the other way if its pointer
|
||||
|
|
|
@ -475,7 +475,7 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Typ
|
|||
return ast.string_type
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) infer_fn_types(f ast.Fn, mut call_expr ast.CallExpr) {
|
||||
pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallExpr) {
|
||||
mut inferred_types := []ast.Type{}
|
||||
for gi, gt_name in f.generic_names {
|
||||
// skip known types
|
||||
|
@ -565,5 +565,5 @@ pub fn (mut c Checker) infer_fn_types(f ast.Fn, mut call_expr ast.CallExpr) {
|
|||
inferred_types << typ
|
||||
call_expr.generic_types << typ
|
||||
}
|
||||
c.table.register_fn_gen_type(f.name, inferred_types)
|
||||
c.table.register_fn_generic_types(f.name, inferred_types)
|
||||
}
|
||||
|
|
|
@ -1494,9 +1494,9 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type {
|
|||
if has_generic_generic {
|
||||
if c.mod != '' {
|
||||
// Need to prepend the module when adding a generic type to a function
|
||||
c.table.register_fn_gen_type(c.mod + '.' + call_expr.name, generic_types)
|
||||
c.table.register_fn_generic_types(c.mod + '.' + call_expr.name, generic_types)
|
||||
} else {
|
||||
c.table.register_fn_gen_type(call_expr.name, generic_types)
|
||||
c.table.register_fn_generic_types(call_expr.name, generic_types)
|
||||
}
|
||||
}
|
||||
// TODO: remove this for actual methods, use only for compiler magic
|
||||
|
@ -1715,7 +1715,7 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type {
|
|||
}
|
||||
if method.generic_names.len != call_expr.generic_types.len {
|
||||
// no type arguments given in call, attempt implicit instantiation
|
||||
c.infer_fn_types(method, mut call_expr)
|
||||
c.infer_fn_generic_types(method, mut call_expr)
|
||||
}
|
||||
if call_expr.generic_types.len > 0 && method.return_type != 0 {
|
||||
if typ := c.table.resolve_generic_by_names(method.return_type, method.generic_names,
|
||||
|
@ -1937,9 +1937,9 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
|
|||
if has_generic_generic {
|
||||
if c.mod != '' {
|
||||
// Need to prepend the module when adding a generic type to a function
|
||||
c.table.register_fn_gen_type(c.mod + '.' + fn_name, generic_types)
|
||||
c.table.register_fn_generic_types(c.mod + '.' + fn_name, generic_types)
|
||||
} else {
|
||||
c.table.register_fn_gen_type(fn_name, generic_types)
|
||||
c.table.register_fn_generic_types(fn_name, generic_types)
|
||||
}
|
||||
}
|
||||
if fn_name == 'json.encode' {
|
||||
|
@ -2026,7 +2026,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
|
|||
os_name := 'os.$fn_name'
|
||||
if f := c.table.find_fn(os_name) {
|
||||
if f.generic_names.len == call_expr.generic_types.len {
|
||||
c.table.fn_gen_types[os_name] = c.table.fn_gen_types['${call_expr.mod}.$call_expr.name']
|
||||
c.table.fn_generic_types[os_name] = c.table.fn_generic_types['${call_expr.mod}.$call_expr.name']
|
||||
}
|
||||
call_expr.name = os_name
|
||||
found = true
|
||||
|
@ -2220,7 +2220,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
|
|||
}
|
||||
if func.generic_names.len != call_expr.generic_types.len {
|
||||
// no type arguments given in call, attempt implicit instantiation
|
||||
c.infer_fn_types(func, mut call_expr)
|
||||
c.infer_fn_generic_types(func, mut call_expr)
|
||||
}
|
||||
if func.generic_names.len > 0 {
|
||||
for i, call_arg in call_expr.args {
|
||||
|
@ -6326,13 +6326,13 @@ fn (mut c Checker) post_process_generic_fns() {
|
|||
// Loop thru each generic function concrete type.
|
||||
// Check each specific fn instantiation.
|
||||
for i in 0 .. c.file.generic_fns.len {
|
||||
if c.table.fn_gen_types.len == 0 {
|
||||
if c.table.fn_generic_types.len == 0 {
|
||||
// no concrete types, so just skip:
|
||||
continue
|
||||
}
|
||||
mut node := c.file.generic_fns[i]
|
||||
c.mod = node.mod
|
||||
for gen_types in c.table.fn_gen_types[node.name] {
|
||||
for gen_types in c.table.fn_generic_types[node.name] {
|
||||
c.cur_generic_types = gen_types
|
||||
c.fn_decl(mut node)
|
||||
if node.name in ['vweb.run_app', 'vweb.run'] {
|
||||
|
@ -6350,7 +6350,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
|||
// It will be processed later in c.post_process_generic_fns,
|
||||
// after all other normal functions are processed.
|
||||
// This is done so that all generic function calls can
|
||||
// have a chance to populate c.table.fn_gen_types with
|
||||
// have a chance to populate c.table.fn_generic_types with
|
||||
// the correct concrete types.
|
||||
c.file.generic_fns << node
|
||||
return
|
||||
|
|
|
@ -129,7 +129,7 @@ fn (mut g Gen) gen_fn_decl(node ast.FnDecl, skip bool) {
|
|||
// }
|
||||
if node.generic_names.len > 0 && g.cur_generic_types.len == 0 { // need the cur_generic_type check to avoid inf. recursion
|
||||
// loop thru each generic type and generate a function
|
||||
for gen_types in g.table.fn_gen_types[node.name] {
|
||||
for gen_types in g.table.fn_generic_types[node.name] {
|
||||
if g.pref.is_verbose {
|
||||
syms := gen_types.map(g.table.get_type_symbol(it))
|
||||
the_type := syms.map(node.name).join(', ')
|
||||
|
|
|
@ -46,7 +46,7 @@ pub fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr
|
|||
has_generic_generic := generic_types.filter(it.has_flag(.generic)).len > 0
|
||||
if !has_generic_generic {
|
||||
// will be added in checker
|
||||
p.table.register_fn_gen_type(full_generic_fn_name, generic_types)
|
||||
p.table.register_fn_generic_types(full_generic_fn_name, generic_types)
|
||||
}
|
||||
}
|
||||
p.check(.lpar)
|
||||
|
|
|
@ -2248,7 +2248,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
|
|||
has_generic_generic := generic_types.filter(it.has_flag(.generic)).len > 0
|
||||
if !has_generic_generic {
|
||||
// will be added in checker
|
||||
p.table.register_fn_gen_type(field_name, generic_types)
|
||||
p.table.register_fn_generic_types(field_name, generic_types)
|
||||
}
|
||||
}
|
||||
if p.tok.kind == .lpar {
|
||||
|
|
Loading…
Reference in New Issue