parent
a3c3fd4d20
commit
8ab59c5f0f
|
@ -1431,6 +1431,20 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
|||
f = f1
|
||||
}
|
||||
}
|
||||
if !found && call_expr.left is ast.IndexExpr {
|
||||
c.expr(call_expr.left)
|
||||
expr := call_expr.left as ast.IndexExpr
|
||||
sym := c.table.get_type_symbol(expr.left_type)
|
||||
if sym.kind == .array {
|
||||
info := sym.info as table.Array
|
||||
elem_typ := c.table.get_type_symbol(info.elem_type)
|
||||
if elem_typ.info is table.FnType {
|
||||
return elem_typ.info.func.return_type
|
||||
}
|
||||
}
|
||||
found = true
|
||||
return table.string_type
|
||||
}
|
||||
// already prefixed (mod.fn) or C/builtin/main
|
||||
if !found {
|
||||
if f1 := c.table.find_fn(fn_name) {
|
||||
|
|
|
@ -116,6 +116,7 @@ mut:
|
|||
called_fn_name string
|
||||
cur_mod ast.Module
|
||||
is_js_call bool // for handling a special type arg #1 `json.decode(User, ...)`
|
||||
is_fn_index_call bool
|
||||
// nr_vars_to_free int
|
||||
// doing_autofree_tmp bool
|
||||
inside_lambda bool
|
||||
|
@ -3763,6 +3764,12 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
|||
}
|
||||
if is_direct_array_access {
|
||||
g.write('(($array_ptr_type_str)')
|
||||
} else if g.is_fn_index_call {
|
||||
if elem_typ.info is table.FnType {
|
||||
g.write('((')
|
||||
g.write_fn_ptr_decl(&elem_typ.info, '')
|
||||
g.write(')(*($array_ptr_type_str)/*ee elem_typ */array_get(')
|
||||
}
|
||||
} else {
|
||||
g.write('(*($array_ptr_type_str)/*ee elem_typ */array_get(')
|
||||
if left_is_ptr && !node.left_type.has_flag(.shared_f) {
|
||||
|
@ -3790,7 +3797,11 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
|||
} else {
|
||||
g.write(', ')
|
||||
g.expr(node.index)
|
||||
g.write('))')
|
||||
if g.is_fn_index_call {
|
||||
g.write(')))')
|
||||
} else {
|
||||
g.write('))')
|
||||
}
|
||||
}
|
||||
if needs_clone {
|
||||
g.write(')')
|
||||
|
@ -4314,6 +4325,9 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
if field.name in inited_fields {
|
||||
sfield := struct_init.fields[inited_fields[field.name]]
|
||||
field_name := c_name(sfield.name)
|
||||
if sfield.typ == 0 {
|
||||
continue
|
||||
}
|
||||
g.write('.$field_name = ')
|
||||
field_type_sym := g.table.get_type_symbol(sfield.typ)
|
||||
mut cloned := false
|
||||
|
|
|
@ -254,6 +254,11 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
|||
if node.left is ast.AnonFn {
|
||||
g.expr(node.left)
|
||||
}
|
||||
if node.left is ast.IndexExpr && node.name == '' {
|
||||
g.is_fn_index_call = true
|
||||
g.expr(node.left)
|
||||
g.is_fn_index_call = false
|
||||
}
|
||||
if node.should_be_skipped {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -263,6 +263,19 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden
|
|||
} else if p.tok.kind == .lsbr {
|
||||
node = p.index_expr(node)
|
||||
p.is_stmt_ident = is_stmt_ident
|
||||
if p.tok.kind == .lpar && p.tok.line_nr == p.prev_tok.line_nr && node is ast.IndexExpr {
|
||||
p.next()
|
||||
pos := p.tok.position()
|
||||
args := p.call_args()
|
||||
p.check(.rpar)
|
||||
node = ast.CallExpr{
|
||||
left: node
|
||||
args: args
|
||||
pos: pos
|
||||
scope: p.scope
|
||||
}
|
||||
p.is_stmt_ident = is_stmt_ident
|
||||
}
|
||||
} else if p.tok.kind == .key_as {
|
||||
// sum type as cast `x := SumType as Variant`
|
||||
pos := p.tok.position()
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
struct Placeholder {
|
||||
name string
|
||||
}
|
||||
|
||||
struct FnStruct {
|
||||
mut:
|
||||
array_of_fn []fn(int, &Placeholder, string)bool
|
||||
}
|
||||
|
||||
fn test_fn_array_direct_call() {
|
||||
mut fs := FnStruct{}
|
||||
fs.array_of_fn << fn(x int, y &Placeholder, z string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
assert fs.array_of_fn[0](1, &Placeholder{name: 'Bob'}, 'Builder') == false
|
||||
}
|
Loading…
Reference in New Issue