all: move cur_concrete_types to Table (#10269)
parent
9fc5b9dc54
commit
cb19079d53
|
@ -10,26 +10,27 @@ import v.util
|
||||||
[heap]
|
[heap]
|
||||||
pub struct Table {
|
pub struct Table {
|
||||||
pub mut:
|
pub mut:
|
||||||
type_symbols []TypeSymbol
|
type_symbols []TypeSymbol
|
||||||
type_idxs map[string]int
|
type_idxs map[string]int
|
||||||
fns map[string]Fn
|
fns map[string]Fn
|
||||||
dumps map[int]string // needed for efficiently generating all _v_dump_expr_TNAME() functions
|
dumps map[int]string // needed for efficiently generating all _v_dump_expr_TNAME() functions
|
||||||
imports []string // List of all imports
|
imports []string // List of all imports
|
||||||
modules []string // Topologically sorted list of all modules registered by the application
|
modules []string // Topologically sorted list of all modules registered by the application
|
||||||
cflags []cflag.CFlag
|
cflags []cflag.CFlag
|
||||||
redefined_fns []string
|
redefined_fns []string
|
||||||
fn_generic_types map[string][][]Type // for generic functions
|
fn_generic_types map[string][][]Type // for generic functions
|
||||||
interfaces map[int]InterfaceDecl
|
interfaces map[int]InterfaceDecl
|
||||||
cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.`
|
cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.`
|
||||||
is_fmt bool
|
is_fmt bool
|
||||||
used_fns map[string]bool // filled in by the checker, when pref.skip_unused = true;
|
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_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;
|
used_vweb_types []Type // vweb context types, filled in by checker, when pref.skip_unused = true;
|
||||||
panic_handler FnPanicHandler = default_table_panic_handler
|
panic_handler FnPanicHandler = default_table_panic_handler
|
||||||
panic_userdata voidptr = voidptr(0) // can be used to pass arbitrary data to panic_handler;
|
panic_userdata voidptr = voidptr(0) // can be used to pass arbitrary data to panic_handler;
|
||||||
panic_npanics int
|
panic_npanics int
|
||||||
cur_fn &FnDecl = 0 // previously stored in Checker.cur_fn and Gen.cur_fn
|
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.
|
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 {`
|
// 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
|
info := sym.info as ast.Struct
|
||||||
if c.table.cur_fn.generic_names.len > 0 { // in generic fn
|
if c.table.cur_fn.generic_names.len > 0 { // in generic fn
|
||||||
if gt_name in c.table.cur_fn.generic_names
|
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)
|
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
|
} else { // in non-generic fn
|
||||||
receiver_generic_names := info.generic_types.map(c.table.get_type_symbol(it).name)
|
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
|
error_lines []int // to avoid printing multiple errors for the same line
|
||||||
expected_type ast.Type
|
expected_type ast.Type
|
||||||
expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block 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_decl string
|
const_deps []string
|
||||||
const_deps []string
|
const_names []string
|
||||||
const_names []string
|
global_names []string
|
||||||
global_names []string
|
locked_names []string // vars that are currently locked
|
||||||
locked_names []string // vars that are currently locked
|
rlocked_names []string // vars that are currently read-locked
|
||||||
rlocked_names []string // vars that are currently read-locked
|
in_for_count int // if checker is currently in a for loop
|
||||||
in_for_count int // if checker is currently in a for loop
|
|
||||||
// checked_ident string // to avoid infinite checker loops
|
// checked_ident string // to avoid infinite checker loops
|
||||||
returns bool
|
returns bool
|
||||||
scope_returns bool
|
scope_returns bool
|
||||||
|
@ -82,7 +81,6 @@ mut:
|
||||||
timers &util.Timers = util.new_timers(false)
|
timers &util.Timers = util.new_timers(false)
|
||||||
comptime_fields_type map[string]ast.Type
|
comptime_fields_type map[string]ast.Type
|
||||||
fn_scope &ast.Scope = voidptr(0)
|
fn_scope &ast.Scope = voidptr(0)
|
||||||
cur_concrete_types []ast.Type // current concrete types, e.g. <int, string>
|
|
||||||
main_fn_decl_node ast.FnDecl
|
main_fn_decl_node ast.FnDecl
|
||||||
match_exhaustive_cutoff_limit int = 10
|
match_exhaustive_cutoff_limit int = 10
|
||||||
// TODO: these are here temporarily and used for deprecations; remove soon
|
// 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)
|
struct_sym := c.table.get_type_symbol(struct_init.typ)
|
||||||
if struct_sym.info is ast.Struct {
|
if struct_sym.info is ast.Struct {
|
||||||
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
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>',
|
c.error('generic struct init must specify type parameter, e.g. Foo<int>',
|
||||||
struct_init.pos)
|
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
|
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 {}
|
c.ensure_type_exists(utyp, struct_init.pos) or {}
|
||||||
type_sym := c.table.get_type_symbol(utyp)
|
type_sym := c.table.get_type_symbol(utyp)
|
||||||
if !c.inside_unsafe && type_sym.kind == .sum_type {
|
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{}`,
|
// Make sure the first letter is capital, do not allow e.g. `x := string{}`,
|
||||||
// but `x := T{}` is ok.
|
// but `x := T{}` is ok.
|
||||||
if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v
|
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 }
|
pos := type_sym.name.last_index('.') or { -1 }
|
||||||
first_letter := type_sym.name[pos + 1]
|
first_letter := type_sym.name[pos + 1]
|
||||||
if !first_letter.is_capital() {
|
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
|
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',
|
c.error('generic fn using generic types cannot be called outside of generic fn',
|
||||||
call_expr.pos)
|
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)
|
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 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,
|
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
|
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]
|
mut expected_types := [expected_type]
|
||||||
if expected_type_sym.info is ast.MultiReturn {
|
if expected_type_sym.info is ast.MultiReturn {
|
||||||
expected_types = expected_type_sym.info.types
|
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))
|
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 {
|
pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
|
||||||
if typ.has_flag(.generic) {
|
if typ.has_flag(.generic) {
|
||||||
if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names,
|
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
|
return t_typ
|
||||||
}
|
}
|
||||||
|
@ -7063,7 +7061,7 @@ fn (mut c Checker) post_process_generic_fns() {
|
||||||
mut node := c.file.generic_fns[i]
|
mut node := c.file.generic_fns[i]
|
||||||
c.mod = node.mod
|
c.mod = node.mod
|
||||||
for concrete_types in c.table.fn_generic_types[node.name] {
|
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)
|
c.fn_decl(mut node)
|
||||||
if node.name == 'vweb.run' {
|
if node.name == 'vweb.run' {
|
||||||
for ct in concrete_types {
|
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) {
|
fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
c.returns = false
|
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.
|
// Just remember the generic function for now.
|
||||||
// It will be processed later in c.post_process_generic_fns,
|
// It will be processed later in c.post_process_generic_fns,
|
||||||
// after all other normal functions are processed.
|
// after all other normal functions are processed.
|
||||||
|
|
|
@ -124,22 +124,20 @@ mut:
|
||||||
is_builtin_mod bool
|
is_builtin_mod bool
|
||||||
hotcode_fn_names []string
|
hotcode_fn_names []string
|
||||||
embedded_files []ast.EmbeddedFile
|
embedded_files []ast.EmbeddedFile
|
||||||
// cur_fn ast.FnDecl
|
sql_i int
|
||||||
cur_concrete_types []ast.Type // current concrete types, e.g. <int, string>
|
sql_stmt_name string
|
||||||
sql_i int
|
sql_bind_name string
|
||||||
sql_stmt_name string
|
sql_idents []string
|
||||||
sql_bind_name string
|
sql_idents_types []ast.Type
|
||||||
sql_idents []string
|
sql_left_type ast.Type
|
||||||
sql_idents_types []ast.Type
|
sql_table_name string
|
||||||
sql_left_type ast.Type
|
sql_fkey string
|
||||||
sql_table_name string
|
sql_parent_id string
|
||||||
sql_fkey string
|
sql_side SqlExprSide // left or right, to distinguish idents in `name == name`
|
||||||
sql_parent_id string
|
inside_vweb_tmpl bool
|
||||||
sql_side SqlExprSide // left or right, to distinguish idents in `name == name`
|
inside_return bool
|
||||||
inside_vweb_tmpl bool
|
inside_or_block bool
|
||||||
inside_return bool
|
strs_to_free0 []string // strings.Builder
|
||||||
inside_or_block bool
|
|
||||||
strs_to_free0 []string // strings.Builder
|
|
||||||
// strs_to_free []string // strings.Builder
|
// strs_to_free []string // strings.Builder
|
||||||
inside_call bool
|
inside_call bool
|
||||||
has_main 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') {
|
// if g.fileis('vweb.v') {
|
||||||
// println('\ngen_fn_decl() $node.name $node.is_generic $g.cur_generic_type')
|
// 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
|
// loop thru each generic type and generate a function
|
||||||
for concrete_types in g.table.fn_generic_types[node.name] {
|
for concrete_types in g.table.fn_generic_types[node.name] {
|
||||||
if g.pref.is_verbose {
|
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(', ')
|
the_type := syms.map(node.name).join(', ')
|
||||||
println('gen fn `$node.name` for type `$the_type`')
|
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.gen_fn_decl(node, skip)
|
||||||
}
|
}
|
||||||
g.cur_concrete_types = []
|
g.table.cur_concrete_types = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cur_fn_save := g.table.cur_fn
|
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)
|
name = c_name(name)
|
||||||
}
|
}
|
||||||
mut type_name := g.typ(node.return_type)
|
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
|
// foo<T>() => foo_T_int(), foo_T_string() etc
|
||||||
// Using _T_ to differentiate between get<string> and get_string
|
// Using _T_ to differentiate between get<string> and get_string
|
||||||
name += '_T'
|
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)
|
gen_name := g.typ(concrete_type)
|
||||||
name += '_' + gen_name
|
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 {
|
pub fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
||||||
if typ.has_flag(.generic) {
|
if typ.has_flag(.generic) {
|
||||||
if t_typ := g.table.resolve_generic_to_concrete(typ, g.table.cur_fn.generic_names,
|
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
|
return t_typ
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue