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

ast: minor optimization of clear_flags() (#17938)

This commit is contained in:
yuyi 2023-04-13 13:27:26 +08:00 committed by GitHub
parent 87ca877c83
commit 92cb7468ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 54 additions and 40 deletions

View File

@ -354,10 +354,18 @@ pub fn (t Type) clear_flag(flag TypeFlag) Type {
return int(t) & ~(1 << (int(flag) + 24))
}
// clear all flags
// clear all flags or multi flags
[inline]
pub fn (t Type) clear_flags() Type {
return int(t) & 0xffffff
pub fn (t Type) clear_flags(flags ...TypeFlag) Type {
if flags.len == 0 {
return int(t) & 0xffffff
} else {
mut typ := int(t)
for flag in flags {
typ = typ & ~(1 << (int(flag) + 24))
}
return typ
}
}
// return true if `flag` is set on `t`

View File

@ -154,7 +154,7 @@ fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
&& expected.has_flag(.result)) {
// IError
return true
} else if !c.check_basic(got, expected.clear_flag(.option).clear_flag(.result)) {
} else if !c.check_basic(got, expected.clear_flags(.option, .result)) {
return false
}
}

View File

@ -1116,7 +1116,7 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return
return
}
last_stmt := node.stmts.last()
c.check_or_last_stmt(last_stmt, ret_type, expr_return_type.clear_flag(.option).clear_flag(.result))
c.check_or_last_stmt(last_stmt, ret_type, expr_return_type.clear_flags(.option, .result))
}
fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_return_type ast.Type) {
@ -1124,13 +1124,14 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
match stmt {
ast.ExprStmt {
c.expected_type = ret_type
c.expected_or_type = ret_type.clear_flag(.option).clear_flag(.result)
c.expected_or_type = ret_type.clear_flags(.option, .result)
last_stmt_typ := c.expr(stmt.expr)
if ret_type.has_flag(.option)
&& (last_stmt_typ.has_flag(.option) || last_stmt_typ == ast.none_type) {
if stmt.expr in [ast.Ident, ast.SelectorExpr, ast.CallExpr, ast.None] {
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result))
expected_type_name := c.table.type_to_str(ret_type.clear_flags(.option,
.result))
got_type_name := c.table.type_to_str(last_stmt_typ)
c.error('`or` block must provide a value of type `${expected_type_name}`, not `${got_type_name}`',
stmt.expr.pos())
@ -1161,7 +1162,8 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
}
return
}
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result))
expected_type_name := c.table.type_to_str(ret_type.clear_flags(.option,
.result))
c.error('`or` block must provide a default value of type `${expected_type_name}`, or return/continue/break or call a [noreturn] function like panic(err) or exit(1)',
stmt.expr.pos())
} else {
@ -1173,7 +1175,8 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
return
}
type_name := c.table.type_to_str(last_stmt_typ)
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result))
expected_type_name := c.table.type_to_str(ret_type.clear_flags(.option,
.result))
c.error('wrong return type `${type_name}` in the `or {}` block, expected `${expected_type_name}`',
stmt.expr.pos())
}
@ -1187,7 +1190,8 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
}
ast.Return {}
else {
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result))
expected_type_name := c.table.type_to_str(ret_type.clear_flags(.option,
.result))
c.error('last statement in the `or {}` block should be an expression of type `${expected_type_name}` or exit parent scope',
stmt.pos)
}
@ -1434,7 +1438,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
}
node.typ = field.typ
if node.or_block.kind == .block {
c.expected_or_type = node.typ.clear_flag(.option).clear_flag(.result)
c.expected_or_type = node.typ.clear_flags(.option, .result)
c.stmts_ending_with_expression(node.or_block.stmts)
c.expected_or_type = ast.void_type
}
@ -3179,7 +3183,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
c.error('cannot use `or {}` block on non-option variable', node.pos)
}
}
unwrapped_typ := info.typ.clear_flag(.option).clear_flag(.result)
unwrapped_typ := info.typ.clear_flags(.option, .result)
c.expected_or_type = unwrapped_typ
c.stmts_ending_with_expression(node.or_expr.stmts)
c.check_or_expr(node.or_expr, info.typ, c.expected_or_type, node)
@ -3245,7 +3249,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
}
}
} else {
typ = obj.expr.expr_type.clear_flag(.option).clear_flag(.result)
typ = obj.expr.expr_type.clear_flags(.option, .result)
}
} else if obj.expr is ast.EmptyExpr {
c.error('invalid variable `${node.name}`', node.pos)
@ -3278,7 +3282,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
node.pos)
}
}
unwrapped_typ := typ.clear_flag(.option).clear_flag(.result)
unwrapped_typ := typ.clear_flags(.option, .result)
c.expected_or_type = unwrapped_typ
c.stmts_ending_with_expression(node.or_expr.stmts)
c.check_or_expr(node.or_expr, typ, c.expected_or_type, node)
@ -3323,7 +3327,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
if mut obj.expr is ast.CallExpr {
if obj.expr.or_block.kind != .absent {
typ = typ.clear_flag(.option).clear_flag(.result)
typ = typ.clear_flags(.option, .result)
}
}
}

View File

@ -235,7 +235,7 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
unwrapped_expr_type := c.unwrap_generic(field.typ)
tsym := c.table.sym(unwrapped_expr_type)
c.table.dumps[int(unwrapped_expr_type.clear_flag(.option).clear_flag(.result).clear_flag(.atomic_f))] = tsym.cname
c.table.dumps[int(unwrapped_expr_type.clear_flags(.option, .result, .atomic_f))] = tsym.cname
}
c.comptime_for_field_var = ''
c.inside_comptime_for_field = false

View File

@ -138,7 +138,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
c.expected_type.clear_flag(.shared_f).deref()
} else {
c.expected_type
}.clear_flag(.option).clear_flag(.result)
}.clear_flags(.option, .result)
}
// [1,2,3]
if node.exprs.len > 0 && node.elem_type == ast.void_type {
@ -299,7 +299,7 @@ fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
sym := c.table.sym(c.expected_type)
if sym.kind == .map {
info := sym.map_info()
node.typ = c.expected_type.clear_flag(.option).clear_flag(.result)
node.typ = c.expected_type.clear_flags(.option, .result)
node.key_type = info.key_type
node.value_type = info.value_type
return node.typ

View File

@ -2285,7 +2285,7 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ ast.Type, node ast
} else if !is_map && arg_expr.return_type != ast.bool_type {
if arg_expr.or_block.kind != .absent && (arg_expr.return_type.has_flag(.option)
|| arg_expr.return_type.has_flag(.result))
&& arg_expr.return_type.clear_flag(.option).clear_flag(.result) == ast.bool_type {
&& arg_expr.return_type.clear_flags(.option, .result) == ast.bool_type {
return
}
c.error('type mismatch, `${arg_expr.name}` must return a bool', arg_expr.pos)

View File

@ -135,7 +135,7 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
if next_fn.params.len != 1 {
c.error('iterator method `next()` must have 0 parameters', node.cond.pos())
}
mut val_type := next_fn.return_type.clear_flag(.option).clear_flag(.result)
mut val_type := next_fn.return_type.clear_flags(.option, .result)
if node.val_is_mut {
val_type = val_type.ref()
}

View File

@ -71,7 +71,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
}
}
if mut branch.cond is ast.IfGuardExpr {
if branch.cond.expr_type.clear_flag(.option).clear_flag(.result) == ast.void_type
if branch.cond.expr_type.clear_flags(.option, .result) == ast.void_type
&& !(branch.cond.vars.len == 1 && branch.cond.vars[0].name == '_') {
c.error('if guard expects non-propagate option or result', branch.pos)
continue

View File

@ -705,7 +705,7 @@ fn (mut g Gen) gen_multi_return_assign(node &ast.AssignStmt, return_type ast.Typ
mut mr_styp := g.typ(return_type.clear_flag(.result))
if node.right[0] is ast.CallExpr && (node.right[0] as ast.CallExpr).or_block.kind != .absent {
is_option = false
mr_styp = g.typ(return_type.clear_flag(.option).clear_flag(.result))
mr_styp = g.typ(return_type.clear_flags(.option, .result))
}
g.write('${mr_styp} ${mr_var_name} = ')
g.expr(node.right[0])

View File

@ -1388,7 +1388,7 @@ pub fn (mut g Gen) write_typedef_types() {
g.type_definitions.writeln(def_str)
} else {
g.type_definitions.writeln('typedef ${fixed} ${styp} [${len}];')
base := g.typ(info.elem_type.clear_flag(.option).clear_flag(.result))
base := g.typ(info.elem_type.clear_flags(.option, .result))
if info.elem_type.has_flag(.option) && base !in g.options_forward {
g.options_forward << base
} else if info.elem_type.has_flag(.result) && base !in g.results_forward {
@ -3031,7 +3031,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
ret_type := if node.or_block.kind == .absent {
node.return_type
} else {
node.return_type.clear_flag(.option).clear_flag(.result)
node.return_type.clear_flags(.option, .result)
}
mut shared_styp := ''
if g.is_shared && !ret_type.has_flag(.shared_f) && !g.inside_or_block {
@ -3457,7 +3457,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
g.or_block(tmp_var, node.or_block, node.typ)
g.write(stmt_str)
g.write(' ')
unwrapped_typ := node.typ.clear_flag(.option).clear_flag(.result)
unwrapped_typ := node.typ.clear_flags(.option, .result)
unwrapped_styp := g.typ(unwrapped_typ)
g.write('(*(${unwrapped_styp}*)${tmp_var}.data)')
return
@ -3817,7 +3817,7 @@ fn (mut g Gen) unlock_locks() {
fn (mut g Gen) map_init(node ast.MapInit) {
unwrap_key_typ := g.unwrap_generic(node.key_type)
unwrap_val_typ := g.unwrap_generic(node.value_type).clear_flag(.option).clear_flag(.result)
unwrap_val_typ := g.unwrap_generic(node.value_type).clear_flags(.option, .result)
key_typ_str := g.typ(unwrap_key_typ)
value_typ_str := g.typ(unwrap_val_typ)
value_sym := g.table.sym(unwrap_val_typ)
@ -4288,11 +4288,11 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
}
fn (mut g Gen) concat_expr(node ast.ConcatExpr) {
mut styp := g.typ(node.return_type.clear_flag(.option).clear_flag(.result))
mut styp := g.typ(node.return_type.clear_flags(.option, .result))
if g.inside_return {
styp = g.typ(g.fn_decl.return_type.clear_flag(.option).clear_flag(.result))
styp = g.typ(g.fn_decl.return_type.clear_flags(.option, .result))
} else if g.inside_or_block {
styp = g.typ(g.or_expr_return_type.clear_flag(.option).clear_flag(.result))
styp = g.typ(g.or_expr_return_type.clear_flags(.option, .result))
}
sym := g.table.sym(node.return_type)
is_multi := sym.kind == .multi_return
@ -4761,7 +4761,8 @@ fn (mut g Gen) return_stmt(node ast.Return) {
}
}
for i, expr in node.exprs {
g.expr_with_cast(expr, node.types[i], fn_ret_type.clear_flag(.option).clear_flag(.result))
g.expr_with_cast(expr, node.types[i], fn_ret_type.clear_flags(.option,
.result))
if i < node.exprs.len - 1 {
g.write(', ')
}
@ -5830,7 +5831,8 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
}
old_inside_opt_data := g.inside_opt_data
g.inside_opt_data = true
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_flag(.option).clear_flag(.result))
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_flags(.option,
.result))
g.inside_opt_data = old_inside_opt_data
g.writeln(';')
g.stmt_path_pos.delete_last()
@ -5866,7 +5868,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
}
}
if or_block.kind == .block {
g.or_expr_return_type = return_type.clear_flag(.option).clear_flag(.result)
g.or_expr_return_type = return_type.clear_flags(.option, .result)
if g.inside_or_block {
g.writeln('\terr = ${cvar_name}.err;')
} else {

View File

@ -20,8 +20,8 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) {
if node.expr is ast.Ident {
// var
if node.expr.info is ast.IdentVar && node.expr.language == .v {
name = g.typ(g.unwrap_generic(node.expr.info.typ.clear_flag(.shared_f).clear_flag(.result))).replace('*',
'')
name = g.typ(g.unwrap_generic(node.expr.info.typ.clear_flags(.shared_f,
.result))).replace('*', '')
}
}
}
@ -32,14 +32,14 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) {
if node.expr.field_expr.expr.name == g.comptime_for_field_var
&& node.expr.field_expr.field_name == 'name' {
field, _ := g.get_comptime_selector_var_type(node.expr)
name = g.typ(g.unwrap_generic(field.typ.clear_flag(.shared_f).clear_flag(.result)))
name = g.typ(g.unwrap_generic(field.typ.clear_flags(.shared_f, .result)))
expr_type = field.typ
}
}
}
} else if node.expr is ast.Ident && g.inside_comptime_for_field && g.is_comptime_var(node.expr) {
expr_type = g.get_comptime_var_type(node.expr)
name = g.typ(g.unwrap_generic(expr_type.clear_flag(.shared_f).clear_flag(.result))).replace('*',
name = g.typ(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*',
'')
}
@ -83,7 +83,7 @@ fn (mut g Gen) dump_expr_definitions() {
typ := ast.Type(dump_type)
is_ptr := typ.is_ptr()
deref, _ := deref_kind(str_method_expects_ptr, is_ptr, dump_type)
to_string_fn_name := g.get_str_fn(typ.clear_flag(.shared_f).clear_flag(.result))
to_string_fn_name := g.get_str_fn(typ.clear_flags(.shared_f, .result))
ptr_asterisk := if is_ptr { '*'.repeat(typ.nr_muls()) } else { '' }
mut str_dumparg_type := ''
if dump_sym.kind == .none_ {

View File

@ -779,11 +779,11 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
}
if gen_or {
g.or_block(tmp_opt, node.or_block, node.return_type)
mut unwrapped_typ := node.return_type.clear_flag(.option).clear_flag(.result)
mut unwrapped_typ := node.return_type.clear_flags(.option, .result)
if g.table.sym(unwrapped_typ).kind == .alias {
unaliased_type := g.table.unaliased_type(unwrapped_typ)
if unaliased_type.has_flag(.option) || unaliased_type.has_flag(.result) {
unwrapped_typ = unaliased_type.clear_flag(.option).clear_flag(.result)
unwrapped_typ = unaliased_type.clear_flags(.option, .result)
}
}
unwrapped_styp := g.typ(unwrapped_typ)

View File

@ -397,7 +397,7 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
if g.inside_return {
g.typ(elem_type)
} else {
g.typ(elem_type.clear_flag(.option).clear_flag(.result))
g.typ(elem_type.clear_flags(.option, .result))
}
}
get_and_set_types := elem_sym.kind in [.struct_, .map, .array]