mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
register methods (wip)
This commit is contained in:
parent
3425934c39
commit
3c0fca9258
@ -166,6 +166,7 @@ pub fn (a array) last() voidptr {
|
||||
return a.data + (a.len - 1) * a.element_size
|
||||
}
|
||||
|
||||
/*
|
||||
// array.left returns a new array using the same buffer as the given array
|
||||
// with the first `n` elements of the given array.
|
||||
fn (a array) left(n int) array {
|
||||
@ -191,12 +192,7 @@ fn (a array) right(n int) array {
|
||||
}
|
||||
return a.slice(n, a.len)
|
||||
}
|
||||
|
||||
// used internally for [2..4]
|
||||
fn (a array) slice2(start, _end int, end_max bool) array {
|
||||
end := if end_max { a.len } else { _end }
|
||||
return a.slice(start, end)
|
||||
}
|
||||
*/
|
||||
|
||||
// array.slice returns an array using the same buffer as original array
|
||||
// but starting from the `start` element and ending with the element before
|
||||
@ -223,6 +219,29 @@ fn (a array) slice(start, _end int) array {
|
||||
return res
|
||||
}
|
||||
|
||||
// used internally for [2..4]
|
||||
fn (a array) slice2(start, _end int, end_max bool) array {
|
||||
end := if end_max { a.len } else { _end }
|
||||
return a.slice(start, end)
|
||||
}
|
||||
|
||||
// array.clone returns an independent copy of a given array
|
||||
pub fn (a array) clone() array {
|
||||
mut size := a.cap * a.element_size
|
||||
if size == 0 {
|
||||
size++
|
||||
}
|
||||
arr := array{
|
||||
len: a.len
|
||||
cap: a.cap
|
||||
element_size: a.element_size
|
||||
data: calloc(size)
|
||||
}
|
||||
C.memcpy(arr.data, a.data, a.cap * a.element_size)
|
||||
return arr
|
||||
}
|
||||
|
||||
|
||||
fn (a array) slice_clone(start, _end int) array {
|
||||
mut end := _end
|
||||
if start > end {
|
||||
@ -282,21 +301,6 @@ pub fn (a array) reverse() array {
|
||||
return arr
|
||||
}
|
||||
|
||||
// array.clone returns an independent copy of a given array
|
||||
pub fn (a array) clone() array {
|
||||
mut size := a.cap * a.element_size
|
||||
if size == 0 {
|
||||
size++
|
||||
}
|
||||
arr := array{
|
||||
len: a.len
|
||||
cap: a.cap
|
||||
element_size: a.element_size
|
||||
data: calloc(size)
|
||||
}
|
||||
C.memcpy(arr.data, a.data, a.cap * a.element_size)
|
||||
return arr
|
||||
}
|
||||
|
||||
// pub fn (a []int) free() {
|
||||
[unsafe_fn]
|
||||
@ -364,7 +368,7 @@ pub fn (b []byte) hex() string {
|
||||
pub fn copy(dst, src []byte) int {
|
||||
if dst.len > 0 && src.len > 0 {
|
||||
min := if dst.len < src.len { dst.len } else { src.len }
|
||||
C.memcpy(dst.data, src.left(min).data, dst.element_size * min)
|
||||
C.memcpy(dst.data, src[min..].data, dst.element_size * min)
|
||||
return min
|
||||
}
|
||||
return 0
|
||||
|
@ -222,11 +222,8 @@ fn test_repeat() {
|
||||
|
||||
fn test_right() {
|
||||
a := [1, 2, 3, 4]
|
||||
b := a.right(1)
|
||||
c := a[1..a.len]
|
||||
d := a[1..]
|
||||
assert b[0] == 2
|
||||
assert b[1] == 3
|
||||
assert c[0] == 2
|
||||
assert c[1] == 3
|
||||
assert d[0] == 2
|
||||
@ -252,18 +249,13 @@ fn test_right_with_n_bigger_than_array_size() {
|
||||
|
||||
fn test_left() {
|
||||
a := [1, 2, 3]
|
||||
b := a.left(2)
|
||||
c := a[0..2]
|
||||
d := a[..2]
|
||||
e := a.left(4)
|
||||
assert b[0] == 1
|
||||
assert b[1] == 2
|
||||
assert c[0] == 1
|
||||
assert c[1] == 2
|
||||
assert d[0] == 1
|
||||
assert d[1] == 2
|
||||
assert e[0] == 1
|
||||
assert e[2] == 3
|
||||
assert e.len == 3
|
||||
}
|
||||
|
||||
|
@ -149,6 +149,7 @@ $c_common_macros
|
||||
byte g_str_buf[1024];
|
||||
int load_so(byteptr);
|
||||
void reload_so();
|
||||
|
||||
'
|
||||
js_headers = '
|
||||
|
||||
|
@ -77,6 +77,18 @@ fn (p mut Parser) bool_expression() string {
|
||||
}
|
||||
p.cgen.set_placeholder(start_ph, '*($cast_typ*)')
|
||||
p.gen('.obj')
|
||||
// Make sure the sum type can be cast, otherwise throw a runtime error
|
||||
/*
|
||||
sum_type:= p.cgen.cur_line.all_after('*) (').replace('.obj', '.typ')
|
||||
|
||||
n := cast_typ.all_after('__')
|
||||
p.cgen.insert_before('if (($sum_type != SumType_$n) {
|
||||
puts("runtime error: $p.file_name:$p.scanner.line_nr cannot cast sum type `$typ` to `$n`");
|
||||
exit(1);
|
||||
}
|
||||
')
|
||||
*/
|
||||
|
||||
} else {
|
||||
p.cgen.set_placeholder(start_ph, '($cast_typ)(')
|
||||
p.gen(')')
|
||||
|
@ -137,7 +137,17 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||
ti = p.parse_ti()
|
||||
p.return_ti = ti
|
||||
}
|
||||
if !is_method {
|
||||
if is_method {
|
||||
ok := p.table.register_method(rec_ti, table.Fn{
|
||||
name: name
|
||||
args: args
|
||||
return_ti: ti
|
||||
})
|
||||
if !ok {
|
||||
p.error('expected Struct')
|
||||
}
|
||||
}
|
||||
else {
|
||||
p.table.register_fn(table.Fn{
|
||||
name: name
|
||||
args: args
|
||||
|
@ -423,19 +423,12 @@ fn (p mut Parser) index_expr(left ast.Expr) (ast.Expr,types.TypeIdent) {
|
||||
fn (p mut Parser) dot_expr(left ast.Expr, ti types.TypeIdent) (ast.Expr,types.TypeIdent) {
|
||||
p.next()
|
||||
field_name := p.check_name()
|
||||
typ := p.table.types[ti.idx] as types.Struct
|
||||
mut ok := false
|
||||
for field in typ.fields {
|
||||
if field.name == field_name {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
p.error('type `$typ.name` has no field or method `$field_name`')
|
||||
}
|
||||
struc := p.table.types[ti.idx] as types.Struct
|
||||
// Method call
|
||||
if p.tok.kind == .lpar {
|
||||
if !p.table.struct_has_method(struc, field_name) {
|
||||
p.error('type `$struc.name` has no method `$field_name`')
|
||||
}
|
||||
p.next()
|
||||
args := p.call_args()
|
||||
println('method call $field_name')
|
||||
@ -447,6 +440,9 @@ fn (p mut Parser) dot_expr(left ast.Expr, ti types.TypeIdent) (ast.Expr,types.Ty
|
||||
}
|
||||
return node,types.int_ti
|
||||
}
|
||||
if !p.table.struct_has_field(struc, field_name) {
|
||||
p.error('type `$struc.name` has no field `$field_name`')
|
||||
}
|
||||
/*
|
||||
// p.next()
|
||||
field := p.check_name()
|
||||
@ -660,7 +656,7 @@ fn (p mut Parser) array_init() (ast.Expr,types.TypeIdent) {
|
||||
p.check(.comma)
|
||||
}
|
||||
}
|
||||
type_idx, type_name := p.table.find_or_register_array(val_ti, 1)
|
||||
type_idx,type_name := p.table.find_or_register_array(val_ti, 1)
|
||||
array_ti := types.new_ti(.array, type_name, type_idx, 0)
|
||||
mut node := ast.Expr{}
|
||||
node = ast.ArrayInit{
|
||||
|
@ -28,9 +28,9 @@ pub:
|
||||
|
||||
pub struct Fn {
|
||||
pub:
|
||||
name string
|
||||
args []Var
|
||||
return_ti types.TypeIdent
|
||||
name string
|
||||
args []Var
|
||||
return_ti types.TypeIdent
|
||||
}
|
||||
|
||||
pub fn new_table() &Table {
|
||||
@ -116,8 +116,234 @@ pub fn (t mut Table) register_fn(new_fn Fn) {
|
||||
t.fns[new_fn.name] = new_fn
|
||||
}
|
||||
|
||||
pub fn (t mut Table) register_method(ti types.TypeIdent, new_fn Fn) bool {
|
||||
println('register method `$new_fn.name` tiname=$ti.name ')
|
||||
match t.types[ti.idx] {
|
||||
types.Struct {
|
||||
println('got struct')
|
||||
}
|
||||
else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
mut struc := t.types[ti.idx] as types.Struct
|
||||
if struc.methods.len == 0 {
|
||||
struc.methods = make(0, 0, sizeof(types.Field))
|
||||
}
|
||||
println('register method `$new_fn.name` struct=$struc.name ')
|
||||
struc.methods << types.Field{
|
||||
name: new_fn.name
|
||||
}
|
||||
t.types[ti.idx] = struc
|
||||
return true
|
||||
}
|
||||
|
||||
pub fn (t mut Table) new_tmp_var() string {
|
||||
t.tmp_cnt++
|
||||
return 'tmp$t.tmp_cnt'
|
||||
}
|
||||
|
||||
pub fn (t &Table) struct_has_field(s &types.Struct, name string) bool {
|
||||
println('struct_has_field($s.name, $name) s.idx=$s.idx types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
||||
// for typ in t.types {
|
||||
// println('$typ.idx $typ.name')
|
||||
// }
|
||||
for field in s.fields {
|
||||
if field.name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if s.parent_idx != 0 {
|
||||
parent := t.types[s.parent_idx] as types.Struct
|
||||
println('got parent $parent.name')
|
||||
for field in parent.fields {
|
||||
if field.name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn (t &Table) struct_has_method(s &types.Struct, name string) bool {
|
||||
for field in s.methods {
|
||||
if field.name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &Table) find_type_idx(name string) int {
|
||||
return t.type_idxs[name]
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &Table) find_type(name string) ?types.Type {
|
||||
idx := t.type_idxs[name]
|
||||
if idx > 0 {
|
||||
return t.types[idx]
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
pub fn (t mut Table) register_struct(typ types.Struct) int {
|
||||
println('register_struct($typ.name)')
|
||||
// existing
|
||||
existing_idx := t.type_idxs[typ.name]
|
||||
if existing_idx > 0 {
|
||||
ex_type := t.types[existing_idx]
|
||||
match ex_type {
|
||||
types.Placeholder {
|
||||
// override placeholder
|
||||
println('overriding type placeholder `$it.name` with struct')
|
||||
mut struct_type := types.Type{}
|
||||
struct_type = {
|
||||
typ |
|
||||
idx:existing_idx
|
||||
}
|
||||
t.types[existing_idx] = struct_type
|
||||
return existing_idx
|
||||
}
|
||||
types.Struct {
|
||||
return existing_idx
|
||||
}
|
||||
else {
|
||||
panic('cannot register type `$typ.name`, another type with this name exists')
|
||||
}
|
||||
}
|
||||
}
|
||||
// register
|
||||
println('registering: $typ.name')
|
||||
idx := t.types.len
|
||||
t.type_idxs[typ.name] = idx
|
||||
mut struct_type := types.Type{}
|
||||
struct_type = {
|
||||
typ |
|
||||
idx:idx,
|
||||
parent_idx:0,
|
||||
}
|
||||
t.types << struct_type
|
||||
return idx
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_map(key_ti &types.TypeIdent, value_ti &types.TypeIdent) (int,string) {
|
||||
name := 'map_${key_ti.name}_${value_ti.name}'
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut map_type := types.Type{}
|
||||
map_type = types.Map{
|
||||
name: name
|
||||
key_type_idx: key_ti.idx
|
||||
value_type_idx: value_ti.idx
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << map_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_array(elem_ti &types.TypeIdent, nr_dims int) (int,string) {
|
||||
name := 'array_${elem_ti.name}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut array_type := types.Type{}
|
||||
array_type = types.Array{
|
||||
idx: idx
|
||||
name: name
|
||||
elem_type_idx: elem_ti.idx
|
||||
elem_is_ptr: elem_ti.is_ptr()
|
||||
nr_dims: nr_dims
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << array_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_array_fixed(elem_ti &types.TypeIdent, size int, nr_dims int) (int,string) {
|
||||
name := 'array_fixed_${elem_ti.name}_${size}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut array_fixed_type := types.Type{}
|
||||
array_fixed_type = types.ArrayFixed{
|
||||
idx: idx
|
||||
name: name
|
||||
elem_type_idx: elem_ti.idx
|
||||
elem_is_ptr: elem_ti.is_ptr()
|
||||
size: size
|
||||
nr_dims: nr_dims
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << array_fixed_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_multi_return(mr_tis []types.TypeIdent) (int,string) {
|
||||
mut name := 'multi_return'
|
||||
for mr_ti in mr_tis {
|
||||
name += '_$mr_ti.name'
|
||||
}
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut mr_type := types.Type{}
|
||||
mr_type = types.MultiReturn{
|
||||
idx: idx
|
||||
name: name
|
||||
tis: mr_tis
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << mr_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_variadic(variadic_ti &types.TypeIdent) (int,string) {
|
||||
name := 'variadic_$variadic_ti.name'
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut variadic_type := types.Type{}
|
||||
variadic_type = types.Variadic{
|
||||
idx: idx
|
||||
ti: variadic_ti
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << variadic_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) add_placeholder_type(name string) int {
|
||||
idx := t.types.len
|
||||
t.type_idxs[name] = t.types.len
|
||||
mut pt := types.Type{}
|
||||
pt = types.Placeholder{
|
||||
idx: idx
|
||||
name: name
|
||||
}
|
||||
println('added placeholder: $name - $idx ')
|
||||
t.types << pt
|
||||
return idx
|
||||
}
|
||||
|
@ -1,178 +0,0 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
module table
|
||||
|
||||
import v.types
|
||||
|
||||
[inline]
|
||||
pub fn (t &Table) find_type_idx(name string) int {
|
||||
return t.type_idxs[name]
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &Table) find_type(name string) ?types.Type {
|
||||
idx := t.type_idxs[name]
|
||||
if idx > 0 {
|
||||
return t.types[idx]
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
pub fn (t mut Table) register_struct(typ types.Struct) int {
|
||||
// existing
|
||||
existing_idx := t.type_idxs[typ.name]
|
||||
if existing_idx > 0 {
|
||||
ex_type := t.types[existing_idx]
|
||||
match ex_type {
|
||||
types.Placeholder {
|
||||
// override placeholder
|
||||
println('overriding type placeholder `$it.name` with struct')
|
||||
mut struct_type := types.Type{}
|
||||
struct_type = {
|
||||
typ |
|
||||
idx:existing_idx
|
||||
}
|
||||
t.types[existing_idx] = struct_type
|
||||
return existing_idx
|
||||
}
|
||||
types.Struct {
|
||||
return existing_idx
|
||||
}
|
||||
else {
|
||||
panic('cannot register type `$typ.name`, another type with this name exists')
|
||||
}
|
||||
}
|
||||
}
|
||||
// register
|
||||
println('registering: $typ.name')
|
||||
idx := t.types.len
|
||||
t.type_idxs[typ.name] = idx
|
||||
mut struct_type := types.Type{}
|
||||
struct_type = {
|
||||
typ |
|
||||
idx:idx
|
||||
}
|
||||
t.types << struct_type
|
||||
return idx
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_map(key_ti &types.TypeIdent, value_ti &types.TypeIdent) (int,string) {
|
||||
name := 'map_${key_ti.name}_${value_ti.name}'
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut map_type := types.Type{}
|
||||
map_type = types.Map{
|
||||
name: name
|
||||
key_type_idx: key_ti.idx
|
||||
value_type_idx: value_ti.idx
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << map_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_array(elem_ti &types.TypeIdent, nr_dims int) (int,string) {
|
||||
name := 'array_${elem_ti.name}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut array_type := types.Type{}
|
||||
array_type = types.Array{
|
||||
idx: idx
|
||||
name: name
|
||||
elem_type_idx: elem_ti.idx
|
||||
elem_is_ptr: elem_ti.is_ptr()
|
||||
nr_dims: nr_dims
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << array_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_array_fixed(elem_ti &types.TypeIdent, size int, nr_dims int) (int,string) {
|
||||
name := 'array_fixed_${elem_ti.name}_${size}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut array_fixed_type := types.Type{}
|
||||
array_fixed_type = types.ArrayFixed{
|
||||
idx: idx
|
||||
name: name
|
||||
elem_type_idx: elem_ti.idx
|
||||
elem_is_ptr: elem_ti.is_ptr()
|
||||
size: size
|
||||
nr_dims: nr_dims
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << array_fixed_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_multi_return(mr_tis []types.TypeIdent) (int,string) {
|
||||
mut name := 'multi_return'
|
||||
for mr_ti in mr_tis {
|
||||
name += '_$mr_ti.name'
|
||||
}
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut mr_type := types.Type{}
|
||||
mr_type = types.MultiReturn{
|
||||
idx: idx
|
||||
name: name
|
||||
tis: mr_tis
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << mr_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) find_or_register_variadic(variadic_ti &types.TypeIdent) (int,string) {
|
||||
name := 'variadic_$variadic_ti.name'
|
||||
// existing
|
||||
existing_idx := t.type_idxs[name]
|
||||
if existing_idx > 0 {
|
||||
return existing_idx,name
|
||||
}
|
||||
// register
|
||||
idx := t.types.len
|
||||
mut variadic_type := types.Type{}
|
||||
variadic_type = types.Variadic{
|
||||
idx: idx
|
||||
ti: variadic_ti
|
||||
}
|
||||
t.type_idxs[name] = idx
|
||||
t.types << variadic_type
|
||||
return idx,name
|
||||
}
|
||||
|
||||
pub fn (t mut Table) add_placeholder_type(name string) int {
|
||||
idx := t.types.len
|
||||
t.type_idxs[name] = t.types.len
|
||||
mut pt := types.Type{}
|
||||
pt = types.Placeholder{
|
||||
idx: idx
|
||||
name: name
|
||||
}
|
||||
println('added placeholder: $name - $idx ')
|
||||
t.types << pt
|
||||
return idx
|
||||
}
|
@ -56,7 +56,7 @@ pub fn new_ti(kind Kind, name string, idx int, nr_muls int) TypeIdent {
|
||||
[inline]
|
||||
pub fn new_builtin_ti(kind Kind, nr_muls int) TypeIdent {
|
||||
return TypeIdent{
|
||||
idx: -int(kind)-1
|
||||
idx: -int(kind) - 1
|
||||
kind: kind
|
||||
name: kind.str()
|
||||
nr_muls: nr_muls
|
||||
@ -224,10 +224,12 @@ pub:
|
||||
|
||||
pub struct Struct {
|
||||
pub:
|
||||
idx int
|
||||
name string
|
||||
fields []Field
|
||||
// methods
|
||||
idx int
|
||||
parent_idx int
|
||||
name string
|
||||
pub mut:
|
||||
fields []Field
|
||||
methods []Field // TODO Method
|
||||
}
|
||||
|
||||
pub struct Field {
|
||||
|
Loading…
Reference in New Issue
Block a user