all: minor cleanup of generics (#9744)

pull/9745/head
yuyi 2021-04-15 16:00:23 +08:00 committed by GitHub
parent dcf4a6b008
commit 466dc4540b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 31 additions and 31 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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

View File

@ -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(', ')

View File

@ -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)

View File

@ -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 {