checker: support non-string map.keys method (#7760)

pull/7844/head
Nick Treleaven 2021-01-03 14:55:06 +00:00 committed by GitHub
parent 529f46d808
commit 38e0aa350d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 4 deletions

View File

@ -646,7 +646,7 @@ pub fn (m &map) keys() []string {
}
// Returns all keys in the map.
pub fn (m &map) keys_1() array {
fn (m &map) keys_1() array {
mut keys := __new_array(m.len, 0, m.key_bytes)
mut item := unsafe { byteptr(keys.data) }
if m.key_values.deletes == 0 {
@ -674,7 +674,7 @@ pub fn (m &map) keys_1() array {
// warning: only copies keys, does not clone
[unsafe]
pub fn (d &DenseArray) clone() DenseArray {
fn (d &DenseArray) clone() DenseArray {
res := DenseArray{
key_bytes: d.key_bytes
value_bytes: d.value_bytes

View File

@ -492,6 +492,7 @@ fn test_int_keys() {
same := mc == m
assert same
assert mc.len == 3
assert mc.keys() == [3,4,5]
mut all := []int{}
for k, v in mc {
assert m[k] == v

View File

@ -1256,9 +1256,21 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
call_expr.return_type = table.int_type
}
return call_expr.return_type
} else if left_type_sym.kind == .map && method_name == 'clone' {
call_expr.return_type = left_type
} else if left_type_sym.kind == .map && method_name in ['clone', 'keys'] {
mut ret_type := table.void_type
match method_name {
'clone' {
ret_type = left_type
}
'keys' {
info := left_type_sym.info as table.Map
typ := c.table.find_or_register_array(info.key_type, 1)
ret_type = table.Type(typ)
}
else {}
}
call_expr.receiver_type = left_type.to_ptr()
call_expr.return_type = ret_type
return call_expr.return_type
} else if left_type_sym.kind == .array && method_name in ['first', 'last', 'pop'] {
info := left_type_sym.info as table.Array

View File

@ -408,6 +408,10 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
if node.name in ['close', 'try_pop', 'try_push'] {
name = 'sync__Channel_$node.name'
}
} else if left_sym.kind == .map {
if node.name == 'keys' {
name = 'map_keys_1'
}
}
// Check if expression is: arr[a..b].clone(), arr[a..].clone()
// if so, then instead of calling array_clone(&array_slice(...))