ast: cleanup struct embeds related methods (#12719)
parent
0cb4557a8d
commit
0f50ac3260
|
@ -332,13 +332,13 @@ pub fn (t &Table) register_aggregate_method(mut sym TypeSymbol, name string) ?Fn
|
|||
return new_fn
|
||||
}
|
||||
|
||||
pub fn (t &Table) type_has_method(s &TypeSymbol, name string) bool {
|
||||
t.type_find_method(s, name) or { return false }
|
||||
pub fn (t &Table) has_method(s &TypeSymbol, name string) bool {
|
||||
t.find_method(s, name) or { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
// type_find_method searches from current type up through each parent looking for method
|
||||
pub fn (t &Table) type_find_method(s &TypeSymbol, name string) ?Fn {
|
||||
// find_method searches from current type up through each parent looking for method
|
||||
pub fn (t &Table) find_method(s &TypeSymbol, name string) ?Fn {
|
||||
mut ts := unsafe { s }
|
||||
for {
|
||||
if method := ts.find_method(name) {
|
||||
|
@ -379,49 +379,17 @@ pub fn (t &Table) get_embeds(sym &TypeSymbol, options GetEmbedsOptions) [][]Type
|
|||
return embeds
|
||||
}
|
||||
|
||||
pub fn (t &Table) type_find_method_from_embeds(sym &TypeSymbol, method_name string) ?(Fn, Type) {
|
||||
pub fn (t &Table) find_method_from_embeds(sym &TypeSymbol, method_name string) ?(Fn, []Type) {
|
||||
if sym.info is Struct {
|
||||
mut found_methods := []Fn{}
|
||||
mut embed_of_found_methods := []Type{}
|
||||
for embed in sym.info.embeds {
|
||||
embed_sym := t.get_type_symbol(embed)
|
||||
if m := t.type_find_method(embed_sym, method_name) {
|
||||
found_methods << m
|
||||
embed_of_found_methods << embed
|
||||
}
|
||||
}
|
||||
if found_methods.len == 1 {
|
||||
return found_methods[0], embed_of_found_methods[0]
|
||||
} else if found_methods.len > 1 {
|
||||
return error('ambiguous method `$method_name`')
|
||||
}
|
||||
} else if sym.info is Aggregate {
|
||||
for typ in sym.info.types {
|
||||
agg_sym := t.get_type_symbol(typ)
|
||||
method, embed_type := t.type_find_method_from_embeds(agg_sym, method_name) or {
|
||||
return err
|
||||
}
|
||||
if embed_type != 0 {
|
||||
return method, embed_type
|
||||
}
|
||||
}
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
pub fn (t &Table) type_find_method_from_embeds_recursive(sym &TypeSymbol, method_name string) ?(Fn, []Type) {
|
||||
if sym.info is Struct {
|
||||
mut found_methods := []Fn{}
|
||||
mut embed_of_found_methods := []Type{}
|
||||
for embed in sym.info.embeds {
|
||||
embed_sym := t.get_type_symbol(embed)
|
||||
if m := t.type_find_method(embed_sym, method_name) {
|
||||
if m := t.find_method(embed_sym, method_name) {
|
||||
found_methods << m
|
||||
embed_of_found_methods << embed
|
||||
} else {
|
||||
method, types := t.type_find_method_from_embeds_recursive(embed_sym, method_name) or {
|
||||
continue
|
||||
}
|
||||
method, types := t.find_method_from_embeds(embed_sym, method_name) or { continue }
|
||||
found_methods << method
|
||||
embed_of_found_methods << embed
|
||||
embed_of_found_methods << types
|
||||
|
@ -435,9 +403,7 @@ pub fn (t &Table) type_find_method_from_embeds_recursive(sym &TypeSymbol, method
|
|||
} else if sym.info is Aggregate {
|
||||
for typ in sym.info.types {
|
||||
agg_sym := t.get_type_symbol(typ)
|
||||
method, embed_types := t.type_find_method_from_embeds_recursive(agg_sym, method_name) or {
|
||||
continue
|
||||
}
|
||||
method, embed_types := t.find_method_from_embeds(agg_sym, method_name) or { continue }
|
||||
if embed_types.len != 0 {
|
||||
return method, embed_types
|
||||
}
|
||||
|
@ -537,7 +503,7 @@ pub fn (t &Table) find_field(s &TypeSymbol, name string) ?StructField {
|
|||
}
|
||||
|
||||
// find_field_from_embeds is the same as find_field_from_embeds but also looks into nested embeds
|
||||
pub fn (t &Table) find_field_from_embeds_recursive(sym &TypeSymbol, field_name string) ?(StructField, []Type) {
|
||||
pub fn (t &Table) find_field_from_embeds(sym &TypeSymbol, field_name string) ?(StructField, []Type) {
|
||||
if sym.info is Struct {
|
||||
mut found_fields := []StructField{}
|
||||
mut embeds_of_found_fields := []Type{}
|
||||
|
@ -547,9 +513,7 @@ pub fn (t &Table) find_field_from_embeds_recursive(sym &TypeSymbol, field_name s
|
|||
found_fields << field
|
||||
embeds_of_found_fields << embed
|
||||
} else {
|
||||
field, types := t.find_field_from_embeds_recursive(embed_sym, field_name) or {
|
||||
continue
|
||||
}
|
||||
field, types := t.find_field_from_embeds(embed_sym, field_name) or { continue }
|
||||
found_fields << field
|
||||
embeds_of_found_fields << embed
|
||||
embeds_of_found_fields << types
|
||||
|
@ -563,45 +527,11 @@ pub fn (t &Table) find_field_from_embeds_recursive(sym &TypeSymbol, field_name s
|
|||
} else if sym.info is Aggregate {
|
||||
for typ in sym.info.types {
|
||||
agg_sym := t.get_type_symbol(typ)
|
||||
field, embed_types := t.find_field_from_embeds_recursive(agg_sym, field_name) or {
|
||||
continue
|
||||
}
|
||||
field, embed_types := t.find_field_from_embeds(agg_sym, field_name) or { continue }
|
||||
if embed_types.len > 0 {
|
||||
return field, embed_types
|
||||
}
|
||||
}
|
||||
} else if sym.info is Alias {
|
||||
unalias_sym := t.get_type_symbol(sym.info.parent_type)
|
||||
return t.find_field_from_embeds_recursive(unalias_sym, field_name)
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
// find_field_from_embeds finds and returns a field in the embeddings of a struct and the embedding type
|
||||
pub fn (t &Table) find_field_from_embeds(sym &TypeSymbol, field_name string) ?(StructField, Type) {
|
||||
if sym.info is Struct {
|
||||
mut found_fields := []StructField{}
|
||||
mut embed_of_found_fields := []Type{}
|
||||
for embed in sym.info.embeds {
|
||||
embed_sym := t.get_type_symbol(embed)
|
||||
if field := t.find_field(embed_sym, field_name) {
|
||||
found_fields << field
|
||||
embed_of_found_fields << embed
|
||||
}
|
||||
}
|
||||
if found_fields.len == 1 {
|
||||
return found_fields[0], embed_of_found_fields[0]
|
||||
} else if found_fields.len > 1 {
|
||||
return error('ambiguous field `$field_name`')
|
||||
}
|
||||
} else if sym.info is Aggregate {
|
||||
for typ in sym.info.types {
|
||||
agg_sym := t.get_type_symbol(typ)
|
||||
field, embed_type := t.find_field_from_embeds(agg_sym, field_name) or { return err }
|
||||
if embed_type != 0 {
|
||||
return field, embed_type
|
||||
}
|
||||
}
|
||||
} else if sym.info is Alias {
|
||||
unalias_sym := t.get_type_symbol(sym.info.parent_type)
|
||||
return t.find_field_from_embeds(unalias_sym, field_name)
|
||||
|
@ -616,7 +546,7 @@ pub fn (t &Table) find_field_with_embeds(sym &TypeSymbol, field_name string) ?St
|
|||
} else {
|
||||
// look for embedded field
|
||||
first_err := err
|
||||
field, _ := t.find_field_from_embeds_recursive(sym, field_name) or { return first_err }
|
||||
field, _ := t.find_field_from_embeds(sym, field_name) or { return first_err }
|
||||
return field
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2059,7 +2059,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||
mut method := ast.Fn{}
|
||||
mut has_method := false
|
||||
mut is_method_from_embed := false
|
||||
if m := c.table.type_find_method(left_sym, method_name) {
|
||||
if m := c.table.find_method(left_sym, method_name) {
|
||||
method = m
|
||||
has_method = true
|
||||
} else {
|
||||
|
@ -2074,7 +2074,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||
}
|
||||
if parent_type != 0 {
|
||||
type_sym := c.table.get_type_symbol(parent_type)
|
||||
if m := c.table.type_find_method(type_sym, method_name) {
|
||||
if m := c.table.find_method(type_sym, method_name) {
|
||||
method = m
|
||||
has_method = true
|
||||
is_generic = true
|
||||
|
@ -2084,8 +2084,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||
if !has_method {
|
||||
has_method = true
|
||||
mut embed_types := []ast.Type{}
|
||||
method, embed_types = c.table.type_find_method_from_embeds_recursive(left_sym,
|
||||
method_name) or {
|
||||
method, embed_types = c.table.find_method_from_embeds(left_sym, method_name) or {
|
||||
if err.msg != '' {
|
||||
c.error(err.msg, node.pos)
|
||||
}
|
||||
|
@ -3462,7 +3461,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||
// look for embedded field
|
||||
has_field = true
|
||||
mut embed_types := []ast.Type{}
|
||||
field, embed_types = c.table.find_field_from_embeds_recursive(sym, field_name) or {
|
||||
field, embed_types = c.table.find_field_from_embeds(sym, field_name) or {
|
||||
if err.msg != '' {
|
||||
c.error(err.msg, node.pos)
|
||||
}
|
||||
|
@ -3491,7 +3490,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||
// look for embedded field
|
||||
has_field = true
|
||||
mut embed_types := []ast.Type{}
|
||||
field, embed_types = c.table.find_field_from_embeds_recursive(gs, field_name) or {
|
||||
field, embed_types = c.table.find_field_from_embeds(gs, field_name) or {
|
||||
if err.msg != '' {
|
||||
c.error(err.msg, node.pos)
|
||||
}
|
||||
|
|
|
@ -2264,7 +2264,7 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) {
|
|||
for field in (exp_sym.info as ast.SumType).fields {
|
||||
mut ptr := 'ptr'
|
||||
mut type_cname := got_cname
|
||||
_, embed_types := g.table.find_field_from_embeds_recursive(got_sym, field.name) or {
|
||||
_, embed_types := g.table.find_field_from_embeds(got_sym, field.name) or {
|
||||
ast.StructField{}, []ast.Type{}
|
||||
}
|
||||
if embed_types.len > 0 {
|
||||
|
@ -3171,7 +3171,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
return
|
||||
} else {
|
||||
g.write(' = ${styp}_${util.replace_op(extracted_op)}(')
|
||||
method := g.table.type_find_method(left_sym, extracted_op) or {
|
||||
method := g.table.find_method(left_sym, extracted_op) or {
|
||||
// the checker will most likely have found this, already...
|
||||
g.error('assignemnt operator `$extracted_op=` used but no `$extracted_op` method defined',
|
||||
assign_stmt.pos)
|
||||
|
@ -3369,7 +3369,7 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
|
|||
}
|
||||
ast.InfixExpr {
|
||||
sym := g.table.get_type_symbol(val.left_type)
|
||||
if _ := g.table.type_find_method(sym, val.op.str()) {
|
||||
if _ := g.table.find_method(sym, val.op.str()) {
|
||||
left_styp := g.typ(val.left_type.set_nr_muls(0))
|
||||
g.write(left_styp)
|
||||
g.write('_')
|
||||
|
|
|
@ -81,7 +81,7 @@ fn (mut g Gen) infix_expr_arrow_op(node ast.InfixExpr) {
|
|||
fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||
left := g.unwrap(node.left_type)
|
||||
right := g.unwrap(node.right_type)
|
||||
has_defined_eq_operator := g.table.type_has_method(left.sym, '==')
|
||||
has_defined_eq_operator := g.table.has_method(left.sym, '==')
|
||||
has_alias_eq_op_overload := left.sym.info is ast.Alias && left.sym.has_method('==')
|
||||
if (left.typ.is_ptr() && right.typ.is_int()) || (right.typ.is_ptr() && left.typ.is_int()) {
|
||||
g.gen_plain_infix_expr(node)
|
||||
|
@ -278,7 +278,7 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
|||
fn (mut g Gen) infix_expr_cmp_op(node ast.InfixExpr) {
|
||||
left := g.unwrap(node.left_type)
|
||||
right := g.unwrap(node.right_type)
|
||||
has_operator_overloading := g.table.type_has_method(left.sym, '<')
|
||||
has_operator_overloading := g.table.has_method(left.sym, '<')
|
||||
if left.sym.kind == .struct_ && (left.sym.info as ast.Struct).generic_types.len > 0 {
|
||||
if node.op in [.le, .ge] {
|
||||
g.write('!')
|
||||
|
@ -550,7 +550,7 @@ fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) {
|
|||
g.expr(node.right)
|
||||
g.write(')')
|
||||
} else {
|
||||
method := g.table.type_find_method(left.sym, node.op.str()) or {
|
||||
method := g.table.find_method(left.sym, node.op.str()) or {
|
||||
g.gen_plain_infix_expr(node)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ fn (mut g JsGen) gen_plain_infix_expr(node ast.InfixExpr) {
|
|||
fn (mut g JsGen) infix_expr_arithmetic_op(node ast.InfixExpr) {
|
||||
left := g.unwrap(node.left_type)
|
||||
right := g.unwrap(node.right_type)
|
||||
method := g.table.type_find_method(left.sym, node.op.str()) or {
|
||||
method := g.table.find_method(left.sym, node.op.str()) or {
|
||||
g.gen_plain_infix_expr(node)
|
||||
return
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ fn (mut g JsGen) op_arg(expr ast.Expr, expected ast.Type, got ast.Type) {
|
|||
fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||
left := g.unwrap(node.left_type)
|
||||
right := g.unwrap(node.right_type)
|
||||
has_operator_overloading := g.table.type_has_method(left.sym, '==')
|
||||
has_operator_overloading := g.table.has_method(left.sym, '==')
|
||||
g.write('new bool(')
|
||||
if (left.typ.is_ptr() && right.typ.is_int()) || (right.typ.is_ptr() && left.typ.is_int()) {
|
||||
g.gen_plain_infix_expr(node)
|
||||
|
@ -209,7 +209,7 @@ fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
|||
fn (mut g JsGen) infix_expr_cmp_op(node ast.InfixExpr) {
|
||||
left := g.unwrap(node.left_type)
|
||||
right := g.unwrap(node.right_type)
|
||||
has_operator_overloading := g.table.type_has_method(left.sym, '<')
|
||||
has_operator_overloading := g.table.has_method(left.sym, '<')
|
||||
g.write('new bool(')
|
||||
if left.sym.kind == right.sym.kind && has_operator_overloading {
|
||||
if node.op in [.le, .ge] {
|
||||
|
|
|
@ -2137,8 +2137,7 @@ fn (mut g JsGen) match_expr_classic(node ast.MatchExpr, is_expr bool, cond_var M
|
|||
g.write(').val')
|
||||
}
|
||||
else {
|
||||
has_operator_overloading := g.table.type_has_method(type_sym,
|
||||
'==')
|
||||
has_operator_overloading := g.table.has_method(type_sym, '==')
|
||||
if has_operator_overloading {
|
||||
left := g.unwrap(node.cond_type)
|
||||
g.write(g.typ(left.unaliased.set_nr_muls(0)))
|
||||
|
@ -2832,7 +2831,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
|||
node := it
|
||||
left := g.unwrap(node.left_type)
|
||||
right := g.unwrap(node.right_type)
|
||||
has_operator_overloading := g.table.type_has_method(left.sym, '==')
|
||||
has_operator_overloading := g.table.has_method(left.sym, '==')
|
||||
if has_operator_overloading
|
||||
|| (l_sym.kind in js.shallow_equatables && r_sym.kind in js.shallow_equatables) {
|
||||
if node.op == .ne {
|
||||
|
@ -2896,7 +2895,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
|||
g.gen_deref_ptr(it.left_type)
|
||||
g.write(' instanceof ')
|
||||
g.write(g.typ(it.right_type))
|
||||
} else if it.op in [.lt, .gt, .ge, .le] && g.table.type_has_method(l_sym, '<')
|
||||
} else if it.op in [.lt, .gt, .ge, .le] && g.table.has_method(l_sym, '<')
|
||||
&& l_sym.kind == r_sym.kind {
|
||||
if it.op in [.le, .ge] {
|
||||
g.write('!')
|
||||
|
@ -2917,7 +2916,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
|||
g.write(')')
|
||||
}
|
||||
} else {
|
||||
has_operator_overloading := g.table.type_has_method(l_sym, it.op.str())
|
||||
has_operator_overloading := g.table.has_method(l_sym, it.op.str())
|
||||
if has_operator_overloading {
|
||||
g.expr(it.left)
|
||||
g.gen_deref_ptr(it.left_type)
|
||||
|
|
Loading…
Reference in New Issue