all: move cur_concrete_types to Table (#10269)
parent
9fc5b9dc54
commit
cb19079d53
|
@ -10,26 +10,27 @@ import v.util
|
|||
[heap]
|
||||
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_generic_types map[string][][]Type // for generic functions
|
||||
interfaces map[int]InterfaceDecl
|
||||
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;
|
||||
used_vweb_types []Type // vweb context types, filled in by checker, when pref.skip_unused = true;
|
||||
panic_handler FnPanicHandler = default_table_panic_handler
|
||||
panic_userdata voidptr = voidptr(0) // can be used to pass arbitrary data to panic_handler;
|
||||
panic_npanics int
|
||||
cur_fn &FnDecl = 0 // previously stored in Checker.cur_fn and Gen.cur_fn
|
||||
gostmts int // how many `go` statements there were in the parsed files.
|
||||
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
|
||||
interfaces map[int]InterfaceDecl
|
||||
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;
|
||||
used_vweb_types []Type // vweb context types, filled in by checker, when pref.skip_unused = true;
|
||||
panic_handler FnPanicHandler = default_table_panic_handler
|
||||
panic_userdata voidptr = voidptr(0) // can be used to pass arbitrary data to panic_handler;
|
||||
panic_npanics int
|
||||
cur_fn &FnDecl = 0 // previously stored in Checker.cur_fn and Gen.cur_fn
|
||||
cur_concrete_types []Type // current concrete types, e.g. <int, string>
|
||||
gostmts int // how many `go` statements there were in the parsed files.
|
||||
// When table.gostmts > 0, __VTHREADS__ is defined, which can be checked with `$if threads {`
|
||||
}
|
||||
|
||||
|
|
|
@ -508,9 +508,9 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
|
|||
info := sym.info as ast.Struct
|
||||
if c.table.cur_fn.generic_names.len > 0 { // in generic fn
|
||||
if gt_name in c.table.cur_fn.generic_names
|
||||
&& c.table.cur_fn.generic_names.len == c.cur_concrete_types.len {
|
||||
&& c.table.cur_fn.generic_names.len == c.table.cur_concrete_types.len {
|
||||
idx := c.table.cur_fn.generic_names.index(gt_name)
|
||||
typ = c.cur_concrete_types[idx]
|
||||
typ = c.table.cur_concrete_types[idx]
|
||||
}
|
||||
} else { // in non-generic fn
|
||||
receiver_generic_names := info.generic_types.map(c.table.get_type_symbol(it).name)
|
||||
|
|
|
@ -49,14 +49,13 @@ pub mut:
|
|||
error_lines []int // to avoid printing multiple errors for the same line
|
||||
expected_type ast.Type
|
||||
expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type
|
||||
// cur_fn &ast.FnDecl // current function
|
||||
const_decl string
|
||||
const_deps []string
|
||||
const_names []string
|
||||
global_names []string
|
||||
locked_names []string // vars that are currently locked
|
||||
rlocked_names []string // vars that are currently read-locked
|
||||
in_for_count int // if checker is currently in a for loop
|
||||
const_decl string
|
||||
const_deps []string
|
||||
const_names []string
|
||||
global_names []string
|
||||
locked_names []string // vars that are currently locked
|
||||
rlocked_names []string // vars that are currently read-locked
|
||||
in_for_count int // if checker is currently in a for loop
|
||||
// checked_ident string // to avoid infinite checker loops
|
||||
returns bool
|
||||
scope_returns bool
|
||||
|
@ -82,7 +81,6 @@ mut:
|
|||
timers &util.Timers = util.new_timers(false)
|
||||
comptime_fields_type map[string]ast.Type
|
||||
fn_scope &ast.Scope = voidptr(0)
|
||||
cur_concrete_types []ast.Type // current concrete types, e.g. <int, string>
|
||||
main_fn_decl_node ast.FnDecl
|
||||
match_exhaustive_cutoff_limit int = 10
|
||||
// TODO: these are here temporarily and used for deprecations; remove soon
|
||||
|
@ -689,7 +687,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
|
|||
struct_sym := c.table.get_type_symbol(struct_init.typ)
|
||||
if struct_sym.info is ast.Struct {
|
||||
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
||||
&& c.cur_concrete_types.len == 0 {
|
||||
&& c.table.cur_concrete_types.len == 0 {
|
||||
c.error('generic struct init must specify type parameter, e.g. Foo<int>',
|
||||
struct_init.pos)
|
||||
}
|
||||
|
@ -704,7 +702,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
|
|||
return ast.void_type
|
||||
}
|
||||
}
|
||||
utyp := c.unwrap_generic_struct(struct_init.typ, c.table.cur_fn.generic_names, c.cur_concrete_types)
|
||||
utyp := c.unwrap_generic_struct(struct_init.typ, c.table.cur_fn.generic_names, c.table.cur_concrete_types)
|
||||
c.ensure_type_exists(utyp, struct_init.pos) or {}
|
||||
type_sym := c.table.get_type_symbol(utyp)
|
||||
if !c.inside_unsafe && type_sym.kind == .sum_type {
|
||||
|
@ -713,7 +711,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
|
|||
// Make sure the first letter is capital, do not allow e.g. `x := string{}`,
|
||||
// but `x := T{}` is ok.
|
||||
if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v
|
||||
&& c.cur_concrete_types.len == 0 {
|
||||
&& c.table.cur_concrete_types.len == 0 {
|
||||
pos := type_sym.name.last_index('.') or { -1 }
|
||||
first_letter := type_sym.name[pos + 1]
|
||||
if !first_letter.is_capital() {
|
||||
|
@ -2220,7 +2218,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
|
|||
concrete_types << concrete_type
|
||||
}
|
||||
}
|
||||
if !isnil(c.table.cur_fn) && c.cur_concrete_types.len == 0 && has_generic {
|
||||
if !isnil(c.table.cur_fn) && c.table.cur_concrete_types.len == 0 && has_generic {
|
||||
c.error('generic fn using generic types cannot be called outside of generic fn',
|
||||
call_expr.pos)
|
||||
}
|
||||
|
@ -2981,7 +2979,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
|||
mut expected_type := c.unwrap_generic(c.expected_type)
|
||||
if expected_type.has_flag(.generic) && c.table.get_type_symbol(expected_type).kind == .struct_ {
|
||||
if t_typ := c.table.resolve_generic_to_concrete(expected_type, c.table.cur_fn.generic_names,
|
||||
c.cur_concrete_types, true)
|
||||
c.table.cur_concrete_types, true)
|
||||
{
|
||||
expected_type = t_typ
|
||||
}
|
||||
|
@ -3004,7 +3002,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
|||
mut expected_types := [expected_type]
|
||||
if expected_type_sym.info is ast.MultiReturn {
|
||||
expected_types = expected_type_sym.info.types
|
||||
if c.cur_concrete_types.len > 0 {
|
||||
if c.table.cur_concrete_types.len > 0 {
|
||||
expected_types = expected_types.map(c.unwrap_generic(it))
|
||||
}
|
||||
}
|
||||
|
@ -4561,7 +4559,7 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) {
|
|||
pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
|
||||
if typ.has_flag(.generic) {
|
||||
if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names,
|
||||
c.cur_concrete_types, false)
|
||||
c.table.cur_concrete_types, false)
|
||||
{
|
||||
return t_typ
|
||||
}
|
||||
|
@ -7063,7 +7061,7 @@ fn (mut c Checker) post_process_generic_fns() {
|
|||
mut node := c.file.generic_fns[i]
|
||||
c.mod = node.mod
|
||||
for concrete_types in c.table.fn_generic_types[node.name] {
|
||||
c.cur_concrete_types = concrete_types
|
||||
c.table.cur_concrete_types = concrete_types
|
||||
c.fn_decl(mut node)
|
||||
if node.name == 'vweb.run' {
|
||||
for ct in concrete_types {
|
||||
|
@ -7073,13 +7071,13 @@ fn (mut c Checker) post_process_generic_fns() {
|
|||
}
|
||||
}
|
||||
}
|
||||
c.cur_concrete_types = []
|
||||
c.table.cur_concrete_types = []
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||
c.returns = false
|
||||
if node.generic_names.len > 0 && c.cur_concrete_types.len == 0 {
|
||||
if node.generic_names.len > 0 && c.table.cur_concrete_types.len == 0 {
|
||||
// Just remember the generic function for now.
|
||||
// It will be processed later in c.post_process_generic_fns,
|
||||
// after all other normal functions are processed.
|
||||
|
|
|
@ -124,22 +124,20 @@ mut:
|
|||
is_builtin_mod bool
|
||||
hotcode_fn_names []string
|
||||
embedded_files []ast.EmbeddedFile
|
||||
// cur_fn ast.FnDecl
|
||||
cur_concrete_types []ast.Type // current concrete types, e.g. <int, string>
|
||||
sql_i int
|
||||
sql_stmt_name string
|
||||
sql_bind_name string
|
||||
sql_idents []string
|
||||
sql_idents_types []ast.Type
|
||||
sql_left_type ast.Type
|
||||
sql_table_name string
|
||||
sql_fkey string
|
||||
sql_parent_id string
|
||||
sql_side SqlExprSide // left or right, to distinguish idents in `name == name`
|
||||
inside_vweb_tmpl bool
|
||||
inside_return bool
|
||||
inside_or_block bool
|
||||
strs_to_free0 []string // strings.Builder
|
||||
sql_i int
|
||||
sql_stmt_name string
|
||||
sql_bind_name string
|
||||
sql_idents []string
|
||||
sql_idents_types []ast.Type
|
||||
sql_left_type ast.Type
|
||||
sql_table_name string
|
||||
sql_fkey string
|
||||
sql_parent_id string
|
||||
sql_side SqlExprSide // left or right, to distinguish idents in `name == name`
|
||||
inside_vweb_tmpl bool
|
||||
inside_return bool
|
||||
inside_or_block bool
|
||||
strs_to_free0 []string // strings.Builder
|
||||
// strs_to_free []string // strings.Builder
|
||||
inside_call bool
|
||||
has_main bool
|
||||
|
|
|
@ -141,7 +141,7 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
|||
// if g.fileis('vweb.v') {
|
||||
// println('\ngen_fn_decl() $node.name $node.is_generic $g.cur_generic_type')
|
||||
// }
|
||||
if node.generic_names.len > 0 && g.cur_concrete_types.len == 0 { // need the cur_concrete_type check to avoid inf. recursion
|
||||
if node.generic_names.len > 0 && g.table.cur_concrete_types.len == 0 { // need the cur_concrete_type check to avoid inf. recursion
|
||||
// loop thru each generic type and generate a function
|
||||
for concrete_types in g.table.fn_generic_types[node.name] {
|
||||
if g.pref.is_verbose {
|
||||
|
@ -149,10 +149,10 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
|||
the_type := syms.map(node.name).join(', ')
|
||||
println('gen fn `$node.name` for type `$the_type`')
|
||||
}
|
||||
g.cur_concrete_types = concrete_types
|
||||
g.table.cur_concrete_types = concrete_types
|
||||
g.gen_fn_decl(node, skip)
|
||||
}
|
||||
g.cur_concrete_types = []
|
||||
g.table.cur_concrete_types = []
|
||||
return
|
||||
}
|
||||
cur_fn_save := g.table.cur_fn
|
||||
|
@ -190,11 +190,11 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
|||
name = c_name(name)
|
||||
}
|
||||
mut type_name := g.typ(node.return_type)
|
||||
if g.cur_concrete_types.len > 0 {
|
||||
if g.table.cur_concrete_types.len > 0 {
|
||||
// foo<T>() => foo_T_int(), foo_T_string() etc
|
||||
// Using _T_ to differentiate between get<string> and get_string
|
||||
name += '_T'
|
||||
for concrete_type in g.cur_concrete_types {
|
||||
for concrete_type in g.table.cur_concrete_types {
|
||||
gen_name := g.typ(concrete_type)
|
||||
name += '_' + gen_name
|
||||
}
|
||||
|
@ -504,7 +504,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||
pub fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
||||
if typ.has_flag(.generic) {
|
||||
if t_typ := g.table.resolve_generic_to_concrete(typ, g.table.cur_fn.generic_names,
|
||||
g.cur_concrete_types, false)
|
||||
g.table.cur_concrete_types, false)
|
||||
{
|
||||
return t_typ
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue