mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker, cgen: fix contains() with array of interfaces (#18241)
This commit is contained in:
parent
37618c9465
commit
6698fe4f60
@ -2509,6 +2509,9 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
|
|||||||
c.error('${err.msg()} in argument 1 to `.contains()`', node.args[0].pos)
|
c.error('${err.msg()} in argument 1 to `.contains()`', node.args[0].pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for i, arg in node.args {
|
||||||
|
node.args[i].typ = c.expr(arg.expr)
|
||||||
|
}
|
||||||
node.return_type = ast.bool_type
|
node.return_type = ast.bool_type
|
||||||
} else if method_name == 'index' {
|
} else if method_name == 'index' {
|
||||||
if node.args.len != 1 {
|
if node.args.len != 1 {
|
||||||
|
@ -885,22 +885,32 @@ fn (mut g Gen) gen_array_contains_methods() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// `nums.contains(2)`
|
// `nums.contains(2)`
|
||||||
fn (mut g Gen) gen_array_contains(typ ast.Type, left ast.Expr, right ast.Expr) {
|
fn (mut g Gen) gen_array_contains(left_type ast.Type, left ast.Expr, right_type ast.Type, right ast.Expr) {
|
||||||
fn_name := g.get_array_contains_method(typ)
|
fn_name := g.get_array_contains_method(left_type)
|
||||||
g.write('${fn_name}(')
|
g.write('${fn_name}(')
|
||||||
g.write(strings.repeat(`*`, typ.nr_muls()))
|
g.write(strings.repeat(`*`, left_type.nr_muls()))
|
||||||
if typ.share() == .shared_t {
|
if left_type.share() == .shared_t {
|
||||||
g.go_back(1)
|
g.go_back(1)
|
||||||
}
|
}
|
||||||
g.expr(left)
|
g.expr(left)
|
||||||
if typ.share() == .shared_t {
|
if left_type.share() == .shared_t {
|
||||||
g.write('->val')
|
g.write('->val')
|
||||||
}
|
}
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
if right.is_auto_deref_var() {
|
if right.is_auto_deref_var() {
|
||||||
g.write('*')
|
g.write('*')
|
||||||
}
|
}
|
||||||
|
left_sym := g.table.final_sym(left_type)
|
||||||
|
elem_typ := if left_sym.kind == .array {
|
||||||
|
left_sym.array_info().elem_type
|
||||||
|
} else {
|
||||||
|
left_sym.array_fixed_info().elem_type
|
||||||
|
}
|
||||||
|
if g.table.sym(elem_typ).kind in [.interface_, .sum_type] {
|
||||||
|
g.expr_with_cast(right, right_type, elem_typ)
|
||||||
|
} else {
|
||||||
g.expr(right)
|
g.expr(right)
|
||||||
|
}
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,7 +891,7 @@ fn (mut g Gen) gen_array_method_call(node ast.CallExpr, left_type ast.Type) bool
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
'contains' {
|
'contains' {
|
||||||
g.gen_array_contains(left_type, node.left, node.args[0].expr)
|
g.gen_array_contains(left_type, node.left, node.args[0].typ, node.args[0].expr)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
'index' {
|
'index' {
|
||||||
|
@ -488,12 +488,21 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
|
|||||||
expr: node.left
|
expr: node.left
|
||||||
expr_type: ast.mktyp(node.left_type)
|
expr_type: ast.mktyp(node.left_type)
|
||||||
}
|
}
|
||||||
g.gen_array_contains(node.right_type, node.right, new_node_left)
|
g.gen_array_contains(node.right_type, node.right, elem_type, new_node_left)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if elem_type_.sym.kind == .interface_ {
|
||||||
|
new_node_left := ast.CastExpr{
|
||||||
|
arg: ast.empty_expr
|
||||||
|
typ: elem_type
|
||||||
|
expr: node.left
|
||||||
|
expr_type: ast.mktyp(node.left_type)
|
||||||
|
}
|
||||||
|
g.gen_array_contains(node.right_type, node.right, elem_type, new_node_left)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
g.gen_array_contains(node.right_type, node.right, node.left_type, node.left)
|
||||||
g.gen_array_contains(node.right_type, node.right, node.left)
|
|
||||||
} else if right.unaliased_sym.kind == .map {
|
} else if right.unaliased_sym.kind == .map {
|
||||||
g.write('_IN_MAP(')
|
g.write('_IN_MAP(')
|
||||||
if !left.typ.is_ptr() {
|
if !left.typ.is_ptr() {
|
||||||
@ -558,12 +567,12 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
|
|||||||
expr: node.left
|
expr: node.left
|
||||||
expr_type: ast.mktyp(node.left_type)
|
expr_type: ast.mktyp(node.left_type)
|
||||||
}
|
}
|
||||||
g.gen_array_contains(node.right_type, node.right, new_node_left)
|
g.gen_array_contains(node.right_type, node.right, elem_type, new_node_left)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.gen_array_contains(node.right_type, node.right, node.left)
|
g.gen_array_contains(node.right_type, node.right, node.left_type, node.left)
|
||||||
} else if right.unaliased_sym.kind == .string {
|
} else if right.unaliased_sym.kind == .string {
|
||||||
g.write('string_contains(')
|
g.write('string_contains(')
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
|
@ -24,8 +24,12 @@ fn get_component[T](entity Entity) !&T {
|
|||||||
|
|
||||||
fn test_array_of_interfaces_index() {
|
fn test_array_of_interfaces_index() {
|
||||||
entity := Entity{1, [IsControlledByPlayerTag{}]}
|
entity := Entity{1, [IsControlledByPlayerTag{}]}
|
||||||
id := entity.components.index(*get_component[IsControlledByPlayerTag](entity)!)
|
|
||||||
|
|
||||||
|
id := entity.components.index(*get_component[IsControlledByPlayerTag](entity)!)
|
||||||
println('id = ${id}')
|
println('id = ${id}')
|
||||||
assert id == 0
|
assert id == 0
|
||||||
|
|
||||||
|
ret := entity.components.contains(*get_component[IsControlledByPlayerTag](entity)!)
|
||||||
|
println(ret)
|
||||||
|
assert ret
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user