diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 7b142948a9..eb4a7d6b17 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -571,6 +571,107 @@ pub mut: pos token.Pos // function declaration position } +pub fn (f &FnDecl) new_method_with_receiver_type(new_type Type) FnDecl { + unsafe { + mut new_method := f + new_method.params = f.params.clone() + for i in 1 .. new_method.params.len { + if new_method.params[i].typ == new_method.params[0].typ { + new_method.params[i].typ = new_type + } + } + new_method.params[0].typ = new_type + return *new_method + } +} + +[minify] +pub struct Fn { +pub: + is_variadic bool + language Language + is_pub bool + is_ctor_new bool // `[use_new] fn JS.Array.prototype.constructor()` + is_deprecated bool // `[deprecated] fn abc(){}` + is_noreturn bool // `[noreturn] fn abc(){}` + is_unsafe bool // `[unsafe] fn abc(){}` + is_placeholder bool + is_main bool // `fn main(){}` + is_test bool // `fn test_abc(){}` + is_keep_alive bool // passed memory must not be freed (by GC) before function returns + is_method bool // true for `fn (x T) name()`, and for interface declarations (which are also for methods) + no_body bool // a pure declaration like `fn abc(x int)`; used in .vh files, C./JS. fns. + is_file_translated bool // true, when the file it resides in is `[translated]` + mod string + file string + file_mode Language + pos token.Pos + return_type_pos token.Pos +pub mut: + return_type Type + receiver_type Type // != 0, when .is_method == true + name string + params []Param + source_fn voidptr // set in the checker, while processing fn declarations // TODO get rid of voidptr + usages int + generic_names []string + dep_names []string // globals or consts dependent names + attrs []Attr // all fn attributes + is_conditional bool // true for `[if abc]fn(){}` + ctdefine_idx int // the index of the attribute, containing the compile time define [if mytag] +} + +fn (f &Fn) method_equals(o &Fn) bool { + return f.params[1..].equals(o.params[1..]) && f.return_type == o.return_type + && f.is_variadic == o.is_variadic && f.language == o.language + && f.generic_names == o.generic_names && f.is_pub == o.is_pub && f.mod == o.mod + && f.name == o.name +} + +[minify] +pub struct Param { +pub: + pos token.Pos + name string + is_mut bool + is_auto_rec bool + type_pos token.Pos + is_hidden bool // interface first arg +pub mut: + typ Type +} + +pub fn (f &Fn) new_method_with_receiver_type(new_type Type) Fn { + unsafe { + mut new_method := f + new_method.params = f.params.clone() + for i in 1 .. new_method.params.len { + if new_method.params[i].typ == new_method.params[0].typ { + new_method.params[i].typ = new_type + } + } + new_method.params[0].typ = new_type + + return *new_method + } +} + +fn (p &Param) equals(o &Param) bool { + return p.name == o.name && p.is_mut == o.is_mut && p.typ == o.typ && p.is_hidden == o.is_hidden +} + +fn (p []Param) equals(o []Param) bool { + if p.len != o.len { + return false + } + for i in 0 .. p.len { + if !p[i].equals(o[i]) { + return false + } + } + return true +} + // break, continue [minify] pub struct BranchStmt { diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index e2673559dd..5d91a130e4 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -5,7 +5,6 @@ module ast import v.cflag -import v.token import v.util [heap; minify] @@ -90,107 +89,6 @@ pub fn (t &Table) panic(message string) { t.panic_handler(t, message) } -[minify] -pub struct Fn { -pub: - is_variadic bool - language Language - is_pub bool - is_ctor_new bool // `[use_new] fn JS.Array.prototype.constructor()` - is_deprecated bool // `[deprecated] fn abc(){}` - is_noreturn bool // `[noreturn] fn abc(){}` - is_unsafe bool // `[unsafe] fn abc(){}` - is_placeholder bool - is_main bool // `fn main(){}` - is_test bool // `fn test_abc(){}` - is_keep_alive bool // passed memory must not be freed (by GC) before function returns - is_method bool // true for `fn (x T) name()`, and for interface declarations (which are also for methods) - no_body bool // a pure declaration like `fn abc(x int)`; used in .vh files, C./JS. fns. - is_file_translated bool // true, when the file it resides in is `[translated]` - mod string - file string - file_mode Language - pos token.Pos - return_type_pos token.Pos -pub mut: - return_type Type - receiver_type Type // != 0, when .is_method == true - name string - params []Param - source_fn voidptr // set in the checker, while processing fn declarations // TODO get rid of voidptr - usages int - generic_names []string - dep_names []string // globals or consts dependent names - attrs []Attr // all fn attributes - is_conditional bool // true for `[if abc]fn(){}` - ctdefine_idx int // the index of the attribute, containing the compile time define [if mytag] -} - -fn (f &Fn) method_equals(o &Fn) bool { - return f.params[1..].equals(o.params[1..]) && f.return_type == o.return_type - && f.is_variadic == o.is_variadic && f.language == o.language - && f.generic_names == o.generic_names && f.is_pub == o.is_pub && f.mod == o.mod - && f.name == o.name -} - -[minify] -pub struct Param { -pub: - pos token.Pos - name string - is_mut bool - is_auto_rec bool - type_pos token.Pos - is_hidden bool // interface first arg -pub mut: - typ Type -} - -pub fn (f &Fn) new_method_with_receiver_type(new_type Type) Fn { - unsafe { - mut new_method := f - new_method.params = f.params.clone() - for i in 1 .. new_method.params.len { - if new_method.params[i].typ == new_method.params[0].typ { - new_method.params[i].typ = new_type - } - } - new_method.params[0].typ = new_type - - return *new_method - } -} - -pub fn (f &FnDecl) new_method_with_receiver_type(new_type Type) FnDecl { - unsafe { - mut new_method := f - new_method.params = f.params.clone() - for i in 1 .. new_method.params.len { - if new_method.params[i].typ == new_method.params[0].typ { - new_method.params[i].typ = new_type - } - } - new_method.params[0].typ = new_type - return *new_method - } -} - -fn (p &Param) equals(o &Param) bool { - return p.name == o.name && p.is_mut == o.is_mut && p.typ == o.typ && p.is_hidden == o.is_hidden -} - -fn (p []Param) equals(o []Param) bool { - if p.len != o.len { - return false - } - for i in 0 .. p.len { - if !p[i].equals(o[i]) { - return false - } - } - return true -} - pub fn new_table() &Table { mut t := &Table{ global_scope: &Scope{ diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index fd926a134d..51ecdd505d 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -133,6 +133,131 @@ pub fn (t ShareType) str() string { } } +pub struct MultiReturn { +pub mut: + types []Type +} + +pub struct FnType { +pub mut: + is_anon bool + has_decl bool + func Fn +} + +[minify] +pub struct Struct { +pub: + attrs []Attr +pub mut: + embeds []Type + fields []StructField + is_typedef bool // C. [typedef] + is_union bool + is_heap bool + is_minify bool + is_anon bool + is_generic bool + generic_types []Type + concrete_types []Type + parent_type Type +} + +// instantiation of a generic struct +pub struct GenericInst { +pub mut: + parent_idx int // idx of the base generic struct + concrete_types []Type // concrete types, e.g. [int, string] +} + +[minify] +pub struct Interface { +pub mut: + types []Type // all types that implement this interface + fields []StructField + methods []Fn + embeds []Type + // `I1 is I2` conversions + conversions map[int][]Type + // generic interface support + is_generic bool + generic_types []Type + concrete_types []Type + parent_type Type +} + +pub struct Enum { +pub: + vals []string + is_flag bool + is_multi_allowed bool + uses_exprs bool + typ Type +} + +[minify] +pub struct Alias { +pub: + parent_type Type + language Language + is_import bool +} + +pub struct Aggregate { +mut: + fields []StructField // used for faster lookup inside the module +pub: + sum_type Type + types []Type +} + +pub struct Array { +pub: + nr_dims int +pub mut: + elem_type Type +} + +[minify] +pub struct ArrayFixed { +pub: + size int + size_expr Expr // used by fmt for e.g. ´[my_const]u8´ +pub mut: + elem_type Type +} + +pub struct Chan { +pub mut: + elem_type Type + is_mut bool +} + +pub struct Thread { +pub mut: + return_type Type +} + +pub struct Map { +pub mut: + key_type Type + value_type Type +} + +[minify] +pub struct SumType { +pub mut: + fields []StructField + found_fields bool + is_anon bool + // generic sumtype support + is_generic bool + variants []Type + generic_types []Type + concrete_types []Type + parent_type Type +} + // defines special typenames pub fn (t Type) atomic_typename() string { idx := t.idx() @@ -557,18 +682,6 @@ pub fn mktyp(typ Type) Type { } } -pub struct MultiReturn { -pub mut: - types []Type -} - -pub struct FnType { -pub mut: - is_anon bool - has_decl bool - func Fn -} - // returns TypeSymbol kind only if there are no type modifiers pub fn (t &Table) type_kind(typ Type) Kind { if typ.nr_muls() > 0 || typ.has_flag(.option) || typ.has_flag(.result) { @@ -1031,119 +1144,6 @@ pub fn (kinds []Kind) str() string { return kinds_str } -[minify] -pub struct Struct { -pub: - attrs []Attr -pub mut: - embeds []Type - fields []StructField - is_typedef bool // C. [typedef] - is_union bool - is_heap bool - is_minify bool - is_anon bool - is_generic bool - generic_types []Type - concrete_types []Type - parent_type Type -} - -// instantiation of a generic struct -pub struct GenericInst { -pub mut: - parent_idx int // idx of the base generic struct - concrete_types []Type // concrete types, e.g. [int, string] -} - -[minify] -pub struct Interface { -pub mut: - types []Type // all types that implement this interface - fields []StructField - methods []Fn - embeds []Type - // `I1 is I2` conversions - conversions map[int][]Type - // generic interface support - is_generic bool - generic_types []Type - concrete_types []Type - parent_type Type -} - -pub struct Enum { -pub: - vals []string - is_flag bool - is_multi_allowed bool - uses_exprs bool - typ Type -} - -[minify] -pub struct Alias { -pub: - parent_type Type - language Language - is_import bool -} - -pub struct Aggregate { -mut: - fields []StructField // used for faster lookup inside the module -pub: - sum_type Type - types []Type -} - -pub struct Array { -pub: - nr_dims int -pub mut: - elem_type Type -} - -[minify] -pub struct ArrayFixed { -pub: - size int - size_expr Expr // used by fmt for e.g. ´[my_const]u8´ -pub mut: - elem_type Type -} - -pub struct Chan { -pub mut: - elem_type Type - is_mut bool -} - -pub struct Thread { -pub mut: - return_type Type -} - -pub struct Map { -pub mut: - key_type Type - value_type Type -} - -[minify] -pub struct SumType { -pub mut: - fields []StructField - found_fields bool - is_anon bool - // generic sumtype support - is_generic bool - variants []Type - generic_types []Type - concrete_types []Type - parent_type Type -} - // human readable type name, also used by vfmt pub fn (t &Table) type_to_str(typ Type) string { return t.type_to_str_using_aliases(typ, map[string]string{})