1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: refactor and clean up c.check_basic() (#8508)

This commit is contained in:
Ruofan XU 2021-02-03 17:57:06 +08:00 committed by GitHub
parent 4b99d6af95
commit a73c20916d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -22,110 +22,52 @@ pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.T
}
pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
if got == expected {
return true
}
t := c.table
got_idx := t.unalias_num_type(got).idx()
exp_idx := t.unalias_num_type(expected).idx()
// exp_is_optional := expected.has_flag(.optional)
// got_is_optional := got.has_flag(.optional)
// if (exp_is_optional && !got_is_optional) || (!exp_is_optional && got_is_optional) {
// return false
//}
// println('check: $got_type_sym.name, $exp_type_sym.name')
// # NOTE: use idxs here, and symbols below for perf
// got_is_ptr := got.is_ptr()
if got_idx == exp_idx {
got_, exp_ := c.table.unalias_num_type(got), c.table.unalias_num_type(expected)
if got_.idx() == exp_.idx() {
// this is returning true even if one type is a ptr
// and the other is not, is this correct behaviour?
return true
}
if got_idx == table.none_type_idx && expected.has_flag(.optional) {
return false
if (exp_.is_pointer() || exp_.is_number()) && (got_.is_pointer() || got_.is_number()) {
return true
}
exp_is_ptr := expected.is_ptr()
// allow pointers to be initialized with 0. TODO: use none instead
if exp_is_ptr && got_idx == table.int_type_idx {
if expected.is_ptr() && got_.idx() == table.int_type_idx {
return true
}
if exp_idx == table.voidptr_type_idx || got_idx == table.voidptr_type_idx {
// TODO: use sym so it can be absorbed into below [.voidptr, .any] logic
if expected.idx() == table.array_type_idx || got.idx() == table.array_type_idx {
return true
}
if exp_idx == table.any_type_idx || got_idx == table.any_type_idx {
return true
}
// TODO i64 as int etc
if (exp_idx in table.pointer_type_idxs || exp_idx in table.number_type_idxs)
&& (got_idx in table.pointer_type_idxs || got_idx in table.number_type_idxs) {
return true
}
// if exp_idx in pointer_type_idxs && got_idx in pointer_type_idxs {
// return true
// }
// see hack in checker IndexExpr line #691
if (got_idx == table.byte_type_idx && exp_idx == table.byteptr_type_idx)
|| (exp_idx == table.byte_type_idx && got_idx == table.byteptr_type_idx) {
return true
}
if (got_idx == table.char_type_idx && exp_idx == table.charptr_type_idx)
|| (exp_idx == table.char_type_idx && got_idx == table.charptr_type_idx) {
return true
}
// TODO: this should no longer be needed
// if expected == table.t_type && got == table.t_type {
// return true
// }
// # NOTE: use symbols from this point on for perf
got_type_sym := t.get_type_symbol(got)
exp_type_sym := t.get_type_symbol(expected)
//
if exp_type_sym.kind == .function && got_type_sym.kind == .int {
// TODO temporary
// fn == 0
return true
}
// array/map fn
if got_type_sym.kind in [.array, .map] && exp_type_sym.kind == got_type_sym.kind {
got_sym, exp_sym := c.table.get_type_symbol(got), c.table.get_type_symbol(expected)
// array/map as argument
if got_sym.kind in [.array, .map, .array_fixed] && exp_sym.kind == got_sym.kind {
if c.table.type_to_str(got) == c.table.type_to_str(expected).trim('&') {
return true
}
}
// fixed array fn
if got_type_sym.kind == .array_fixed && exp_type_sym.kind == .array_fixed {
if c.table.type_to_str(got) == c.table.type_to_str(expected).trim('&') {
// e.g. [4096]byte vs byteptr
if got_sym.kind == .array_fixed {
info := got_sym.info as table.ArrayFixed
if c.table.type_to_str(info.elem_type) == c.table.type_to_str(expected).trim('ptr') {
return true
}
}
if got_type_sym.kind == .array_fixed && exp_type_sym.kind == .byteptr {
info := got_type_sym.info as table.ArrayFixed
if info.elem_type.idx() == table.byte_type_idx {
return true
}
}
// TODO
// if exp_type_sym.name == 'array' || got_type_sym.name == 'array' {
if got_idx == table.array_type_idx || exp_idx == table.array_type_idx {
return true
}
// TODO
// accept [] when an expected type is an array
if got_type_sym.kind == .array && exp_type_sym.kind == .array
&& got_type_sym.name == 'array_void' {
return true
}
// type alias
if (got_type_sym.kind == .alias && got_type_sym.parent_idx == exp_idx)
|| (exp_type_sym.kind == .alias && exp_type_sym.parent_idx == got_idx) {
if exp_sym.kind in [.voidptr, .any] || got_sym.kind in [.voidptr, .any] {
return true
}
// sum type
if c.table.sumtype_has_variant(expected, c.table.mktyp(got)) {
return true
}
// type alias
if (got_sym.kind == .alias && got_sym.parent_idx == expected.idx())
|| (exp_sym.kind == .alias && exp_sym.parent_idx == got.idx()) {
return true
}
// fn type
if got_type_sym.kind == .function && exp_type_sym.kind == .function {
return c.check_matching_function_symbols(got_type_sym, exp_type_sym)
if got_sym.kind == .function && exp_sym.kind == .function {
return c.check_matching_function_symbols(got_sym, exp_sym)
}
return false
}