mirror of
https://github.com/vlang/v.git
synced 2025-09-11 08:25:42 -04:00
ast: minimise allocations done for the common case in find_struct_field
This commit is contained in:
parent
e9ac9f1410
commit
a9ff1a2624
@ -61,21 +61,23 @@ pub fn (s &Scope) find(name string) ?ScopeObject {
|
||||
}
|
||||
|
||||
// selector_expr: name.field_name
|
||||
pub fn (s &Scope) find_struct_field(name string, struct_type Type, field_name string) ?ScopeStructField {
|
||||
pub fn (s &Scope) find_struct_field(name string, struct_type Type, field_name string) &ScopeStructField {
|
||||
if s == unsafe { nil } {
|
||||
return none
|
||||
return unsafe { nil }
|
||||
}
|
||||
for sc := unsafe { s }; true; sc = sc.parent {
|
||||
if field := sc.struct_fields[name] {
|
||||
if field.struct_type == struct_type && field.name == field_name {
|
||||
return field
|
||||
return &ScopeStructField{
|
||||
...field
|
||||
}
|
||||
}
|
||||
}
|
||||
if sc.dont_lookup_parent() {
|
||||
break
|
||||
}
|
||||
}
|
||||
return none
|
||||
return unsafe { nil }
|
||||
}
|
||||
|
||||
pub fn (s &Scope) find_var(name string) ?&Var {
|
||||
|
@ -1794,7 +1794,8 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||
}
|
||||
if field_sym.kind in [.sum_type, .interface] || field.typ.has_flag(.option) {
|
||||
if !prevent_sum_type_unwrapping_once {
|
||||
if scope_field := node.scope.find_struct_field(node.expr.str(), typ, field_name) {
|
||||
scope_field := node.scope.find_struct_field(node.expr.str(), typ, field_name)
|
||||
if scope_field != unsafe { nil } {
|
||||
return scope_field.smartcasts.last()
|
||||
}
|
||||
}
|
||||
@ -4379,7 +4380,8 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast.
|
||||
}
|
||||
}
|
||||
expr_str := expr.expr.str()
|
||||
if mut field := scope.find_struct_field(expr_str, expr.expr_type, expr.field_name) {
|
||||
field := scope.find_struct_field(expr_str, expr.expr_type, expr.field_name)
|
||||
if field != unsafe { nil } {
|
||||
smartcasts << field.smartcasts
|
||||
}
|
||||
// smartcast either if the value is immutable or if the mut argument is explicitly given
|
||||
|
@ -2164,9 +2164,9 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
mut field_typ := field.typ
|
||||
if field.typ.has_flag(.option) {
|
||||
// unwrapped callback (if f.func != none {})
|
||||
if scope_field := node.scope.find_struct_field(node.left.str(), node.left_type,
|
||||
scope_field := node.scope.find_struct_field(node.left.str(), node.left_type,
|
||||
method_name)
|
||||
{
|
||||
if scope_field != unsafe { nil } {
|
||||
field_typ = scope_field.smartcasts.last()
|
||||
node.is_unwrapped_fn_selector = true
|
||||
} else {
|
||||
|
@ -3008,7 +3008,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
|
||||
}
|
||||
}
|
||||
} else if expr is ast.SelectorExpr {
|
||||
if v := scope.find_struct_field(expr.expr.str(), expr.expr_type, expr.field_name) {
|
||||
v := scope.find_struct_field(expr.expr.str(), expr.expr_type, expr.field_name)
|
||||
if v != unsafe { nil } {
|
||||
if v.smartcasts.len > 0 && unwrapped_expected_type == v.orig_type {
|
||||
is_already_sum_type = true
|
||||
}
|
||||
@ -4178,7 +4179,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||
if !prevent_sum_type_unwrapping_once {
|
||||
// check first if field is sum type because scope searching is expensive
|
||||
scope := g.file.scope.innermost(node.pos.pos)
|
||||
if field := scope.find_struct_field(node.expr.str(), node.expr_type, node.field_name) {
|
||||
field := scope.find_struct_field(node.expr.str(), node.expr_type, node.field_name)
|
||||
if field != unsafe { nil } {
|
||||
nested_unwrap := is_option && field.smartcasts.len > 1
|
||||
is_option_unwrap = is_option && field.smartcasts.len > 0
|
||||
&& field.typ.clear_flag(.option) == field.smartcasts.last()
|
||||
|
@ -1125,7 +1125,8 @@ fn (mut g Gen) comptime_selector_type(node ast.SelectorExpr) ast.Type {
|
||||
field_sym := g.table.sym(field.typ)
|
||||
if field_sym.kind in [.sum_type, .interface] {
|
||||
if !prevent_sum_type_unwrapping_once {
|
||||
if scope_field := node.scope.find_struct_field(node.expr.str(), typ, field_name) {
|
||||
scope_field := node.scope.find_struct_field(node.expr.str(), typ, field_name)
|
||||
if scope_field != unsafe { nil } {
|
||||
return scope_field.smartcasts.last()
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,8 @@ pub fn (mut t TypeResolver) typeof_type(node ast.Expr, default_type ast.Type) as
|
||||
if node.expr is ast.Ident && node.is_field_typ {
|
||||
return t.get_type_from_comptime_var(node.expr)
|
||||
}
|
||||
if field := node.scope.find_struct_field(node.expr.str(), node.expr_type, node.field_name) {
|
||||
field := node.scope.find_struct_field(node.expr.str(), node.expr_type, node.field_name)
|
||||
if field != unsafe { nil } {
|
||||
if field.smartcasts.len > 0 {
|
||||
return field.smartcasts.last()
|
||||
}
|
||||
|
@ -234,9 +234,9 @@ pub fn (mut t TypeResolver) get_type(node ast.Expr) ast.Type {
|
||||
// Struct[T] can have field with generic type
|
||||
if struct_sym.info is ast.Struct && struct_sym.info.generic_types.len > 0 {
|
||||
if field := t.table.find_field(struct_sym, node.field_name) {
|
||||
if f_unwrap := node.scope.find_struct_field(ast.Expr(node.expr).str(),
|
||||
f_unwrap := node.scope.find_struct_field(ast.Expr(node.expr).str(),
|
||||
t.get_type_or_default(node.expr, node.expr_type), node.field_name)
|
||||
{
|
||||
if f_unwrap != unsafe { nil } {
|
||||
return f_unwrap.smartcasts.last()
|
||||
}
|
||||
return field.typ
|
||||
|
Loading…
x
Reference in New Issue
Block a user