mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: minor cleanup of selector_expr() (#10316)
This commit is contained in:
parent
c8d5e783a3
commit
f4486d79c3
@ -2822,21 +2822,21 @@ fn is_expr_panic_or_exit(expr ast.Expr) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Type {
|
pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
prevent_sum_type_unwrapping_once := c.prevent_sum_type_unwrapping_once
|
prevent_sum_type_unwrapping_once := c.prevent_sum_type_unwrapping_once
|
||||||
c.prevent_sum_type_unwrapping_once = false
|
c.prevent_sum_type_unwrapping_once = false
|
||||||
|
|
||||||
using_new_err_struct_save := c.using_new_err_struct
|
using_new_err_struct_save := c.using_new_err_struct
|
||||||
// TODO remove; this avoids a breaking change in syntax
|
// TODO remove; this avoids a breaking change in syntax
|
||||||
if '$selector_expr.expr' == 'err' {
|
if '$node.expr' == 'err' {
|
||||||
c.using_new_err_struct = true
|
c.using_new_err_struct = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// T.name, typeof(expr).name
|
// T.name, typeof(expr).name
|
||||||
mut name_type := 0
|
mut name_type := 0
|
||||||
match mut selector_expr.expr {
|
match mut node.expr {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
name := selector_expr.expr.name
|
name := node.expr.name
|
||||||
valid_generic := util.is_generic_type_name(name) && name in c.table.cur_fn.generic_names
|
valid_generic := util.is_generic_type_name(name) && name in c.table.cur_fn.generic_names
|
||||||
if valid_generic {
|
if valid_generic {
|
||||||
name_type = ast.Type(c.table.find_type_idx(name)).set_flag(.generic)
|
name_type = ast.Type(c.table.find_type_idx(name)).set_flag(.generic)
|
||||||
@ -2845,22 +2845,21 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Typ
|
|||||||
// Note: in future typeof() should be a type known at compile-time
|
// Note: in future typeof() should be a type known at compile-time
|
||||||
// sum types should not be handled dynamically
|
// sum types should not be handled dynamically
|
||||||
ast.TypeOf {
|
ast.TypeOf {
|
||||||
name_type = c.expr(selector_expr.expr.expr)
|
name_type = c.expr(node.expr.expr)
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
if name_type > 0 {
|
if name_type > 0 {
|
||||||
if selector_expr.field_name != 'name' {
|
if node.field_name != 'name' {
|
||||||
c.error('invalid field `.$selector_expr.field_name` for type `$selector_expr.expr`',
|
c.error('invalid field `.$node.field_name` for type `$node.expr`', node.pos)
|
||||||
selector_expr.pos)
|
|
||||||
}
|
}
|
||||||
selector_expr.name_type = name_type
|
node.name_type = name_type
|
||||||
return ast.string_type
|
return ast.string_type
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
old_selector_expr := c.inside_selector_expr
|
old_selector_expr := c.inside_selector_expr
|
||||||
c.inside_selector_expr = true
|
c.inside_selector_expr = true
|
||||||
typ := c.expr(selector_expr.expr)
|
typ := c.expr(node.expr)
|
||||||
c.inside_selector_expr = old_selector_expr
|
c.inside_selector_expr = old_selector_expr
|
||||||
//
|
//
|
||||||
c.using_new_err_struct = using_new_err_struct_save
|
c.using_new_err_struct = using_new_err_struct_save
|
||||||
@ -2868,28 +2867,28 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Typ
|
|||||||
// This means that the variable's value was assigned to an
|
// This means that the variable's value was assigned to an
|
||||||
// unknown function or method, so the error was already handled
|
// unknown function or method, so the error was already handled
|
||||||
// earlier
|
// earlier
|
||||||
// c.error('unknown selector expression', selector_expr.pos)
|
// c.error('unknown selector expression', node.pos)
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
selector_expr.expr_type = typ
|
node.expr_type = typ
|
||||||
if selector_expr.expr_type.has_flag(.optional) && !((selector_expr.expr is ast.Ident
|
if node.expr_type.has_flag(.optional) && !((node.expr is ast.Ident
|
||||||
&& (selector_expr.expr as ast.Ident).kind == .constant)) {
|
&& (node.expr as ast.Ident).kind == .constant)) {
|
||||||
c.error('cannot access fields of an optional, handle the error with `or {...}` or propagate it with `?`',
|
c.error('cannot access fields of an optional, handle the error with `or {...}` or propagate it with `?`',
|
||||||
selector_expr.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
field_name := selector_expr.field_name
|
field_name := node.field_name
|
||||||
utyp := c.unwrap_generic(typ)
|
utyp := c.unwrap_generic(typ)
|
||||||
sym := c.table.get_type_symbol(utyp)
|
sym := c.table.get_type_symbol(utyp)
|
||||||
if (typ.has_flag(.variadic) || sym.kind == .array_fixed) && field_name == 'len' {
|
if (typ.has_flag(.variadic) || sym.kind == .array_fixed) && field_name == 'len' {
|
||||||
selector_expr.typ = ast.int_type
|
node.typ = ast.int_type
|
||||||
return ast.int_type
|
return ast.int_type
|
||||||
}
|
}
|
||||||
if sym.kind == .chan {
|
if sym.kind == .chan {
|
||||||
if field_name == 'closed' {
|
if field_name == 'closed' {
|
||||||
selector_expr.typ = ast.bool_type
|
node.typ = ast.bool_type
|
||||||
return ast.bool_type
|
return ast.bool_type
|
||||||
} else if field_name in ['len', 'cap'] {
|
} else if field_name in ['len', 'cap'] {
|
||||||
selector_expr.typ = ast.u32_type
|
node.typ = ast.u32_type
|
||||||
return ast.u32_type
|
return ast.u32_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2903,7 +2902,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Typ
|
|||||||
for embed in sym_info.embeds {
|
for embed in sym_info.embeds {
|
||||||
embed_sym := c.table.get_type_symbol(embed)
|
embed_sym := c.table.get_type_symbol(embed)
|
||||||
if embed_sym.embed_name() == field_name {
|
if embed_sym.embed_name() == field_name {
|
||||||
selector_expr.typ = embed
|
node.typ = embed
|
||||||
return embed
|
return embed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2926,9 +2925,9 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Typ
|
|||||||
if found_fields.len == 1 {
|
if found_fields.len == 1 {
|
||||||
field = found_fields[0]
|
field = found_fields[0]
|
||||||
has_field = true
|
has_field = true
|
||||||
selector_expr.from_embed_type = embed_of_found_fields[0]
|
node.from_embed_type = embed_of_found_fields[0]
|
||||||
} else if found_fields.len > 1 {
|
} else if found_fields.len > 1 {
|
||||||
c.error('ambiguous field `$field_name`', selector_expr.pos)
|
c.error('ambiguous field `$field_name`', node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if sym.kind in [.aggregate, .sum_type] {
|
if sym.kind in [.aggregate, .sum_type] {
|
||||||
@ -2937,38 +2936,38 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Typ
|
|||||||
}
|
}
|
||||||
if !c.inside_unsafe {
|
if !c.inside_unsafe {
|
||||||
if sym.info is ast.Struct {
|
if sym.info is ast.Struct {
|
||||||
if sym.info.is_union && selector_expr.next_token !in token.assign_tokens {
|
if sym.info.is_union && node.next_token !in token.assign_tokens {
|
||||||
c.warn('reading a union field (or its address) requires `unsafe`',
|
c.warn('reading a union field (or its address) requires `unsafe`',
|
||||||
selector_expr.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if has_field {
|
if has_field {
|
||||||
if sym.mod != c.mod && !field.is_pub && sym.language != .c {
|
if sym.mod != c.mod && !field.is_pub && sym.language != .c {
|
||||||
c.error('field `${sym.name}.$field_name` is not public', selector_expr.pos)
|
c.error('field `${sym.name}.$field_name` is not public', node.pos)
|
||||||
}
|
}
|
||||||
field_sym := c.table.get_type_symbol(field.typ)
|
field_sym := c.table.get_type_symbol(field.typ)
|
||||||
if field_sym.kind in [.sum_type, .interface_] {
|
if field_sym.kind in [.sum_type, .interface_] {
|
||||||
if !prevent_sum_type_unwrapping_once {
|
if !prevent_sum_type_unwrapping_once {
|
||||||
if scope_field := selector_expr.scope.find_struct_field(utyp, field_name) {
|
if scope_field := node.scope.find_struct_field(utyp, field_name) {
|
||||||
return scope_field.smartcasts.last()
|
return scope_field.smartcasts.last()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selector_expr.typ = field.typ
|
node.typ = field.typ
|
||||||
return field.typ
|
return field.typ
|
||||||
}
|
}
|
||||||
if sym.kind !in [.struct_, .aggregate, .interface_, .sum_type] {
|
if sym.kind !in [.struct_, .aggregate, .interface_, .sum_type] {
|
||||||
if sym.kind != .placeholder {
|
if sym.kind != .placeholder {
|
||||||
c.error('`$sym.name` has no property `$selector_expr.field_name`', selector_expr.pos)
|
c.error('`$sym.name` has no property `$node.field_name`', node.pos)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if sym.info is ast.Struct {
|
if sym.info is ast.Struct {
|
||||||
suggestion := util.new_suggestion(field_name, sym.info.fields.map(it.name))
|
suggestion := util.new_suggestion(field_name, sym.info.fields.map(it.name))
|
||||||
c.error(suggestion.say(unknown_field_msg), selector_expr.pos)
|
c.error(suggestion.say(unknown_field_msg), node.pos)
|
||||||
}
|
}
|
||||||
c.error(unknown_field_msg, selector_expr.pos)
|
c.error(unknown_field_msg, node.pos)
|
||||||
}
|
}
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user