mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
parser,checker,cgen: remove unused err
declaration or or { }
blocks (#25034)
Some checks failed
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
json decoder benchmark CI / json-encode-benchmark (push) Has been cancelled
json encoder benchmark CI / json-encode-benchmark (push) Has been cancelled
Some checks failed
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
json decoder benchmark CI / json-encode-benchmark (push) Has been cancelled
json encoder benchmark CI / json-encode-benchmark (push) Has been cancelled
This commit is contained in:
parent
c5b6d2a1c6
commit
21d9a5ded5
15 changed files with 108 additions and 37 deletions
|
@ -1646,6 +1646,7 @@ fn (t Tree) or_expr(node ast.OrExpr) &Node {
|
|||
obj.add_terse('stmts', t.array_node_stmt(node.stmts))
|
||||
obj.add_terse('kind', t.enum_node(node.kind))
|
||||
obj.add('pos', t.pos(node.pos))
|
||||
obj.add('scope', t.number_node(int(node.scope)))
|
||||
return obj
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@ module builtin
|
|||
// The number for `degree` has been picked through vigor-
|
||||
// ous benchmarking but can be changed to any number > 1.
|
||||
// `degree` determines the maximum length of each node.
|
||||
// TODO: the @[markused] tag here is needed as a workaround for
|
||||
// compilation with `-cc clang -usecache`; added in https://github.com/vlang/v/pull/25034
|
||||
|
||||
@[markused]
|
||||
const degree = 6
|
||||
const mid_index = degree - 1
|
||||
const max_len = 2 * degree - 1
|
||||
|
|
|
@ -935,6 +935,7 @@ pub mut:
|
|||
is_tmp bool // for tmp for loop vars, so that autofree can skip them
|
||||
is_auto_heap bool // value whose address goes out of scope
|
||||
is_stack_obj bool // may be pointer to stack value (`mut` or `&` arg and not @[heap] struct)
|
||||
is_special bool // err, it, a, b vars (ignore not useds)
|
||||
}
|
||||
|
||||
// used for smartcasting only
|
||||
|
@ -1914,7 +1915,9 @@ pub struct OrExpr {
|
|||
pub:
|
||||
kind OrKind
|
||||
pos token.Pos
|
||||
scope &Scope = unsafe { nil }
|
||||
pub mut:
|
||||
err_used bool
|
||||
stmts []Stmt
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,7 @@ mut:
|
|||
type_level int // to avoid infinite recursion segfaults due to compiler bugs in ensure_type_exists
|
||||
ensure_generic_type_level int // to avoid infinite recursion segfaults in ensure_generic_type_specify_type_names
|
||||
cur_orm_ts ast.TypeSymbol
|
||||
cur_or_expr &ast.OrExpr = unsafe { nil }
|
||||
cur_anon_fn &ast.AnonFn = unsafe { nil }
|
||||
vmod_file_content string // needed for @VMOD_FILE, contents of the file, *NOT its path**
|
||||
loop_labels []string // filled, when inside labelled for loops: `a_label: for x in 0..10 {`
|
||||
|
@ -299,7 +300,7 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
|
|||
for _, obj in sc.objects {
|
||||
match obj {
|
||||
ast.Var {
|
||||
if !obj.is_used && obj.name[0] != `_` {
|
||||
if !obj.is_special && !obj.is_used && obj.name[0] != `_` {
|
||||
if !c.pref.translated && !c.file.is_translated {
|
||||
if obj.is_arg {
|
||||
if c.pref.show_unused_params {
|
||||
|
@ -310,11 +311,11 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if obj.is_mut && !obj.is_changed && !c.is_builtin_mod && obj.name != 'it' {
|
||||
// if obj.is_mut && !obj.is_changed && !c.is_builtin_mod && obj.name != 'it' {
|
||||
// if obj.is_mut && !obj.is_changed && !c.is_builtin { //TODO C error bad field not checked
|
||||
// c.warn('`$obj.name` is declared as mutable, but it was never changed',
|
||||
// obj.pos)
|
||||
}
|
||||
// }
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
@ -1338,7 +1339,10 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast.
|
|||
}
|
||||
}
|
||||
} else {
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &expr.or_block
|
||||
c.check_or_expr(expr.or_block, ret_type, expr_ret_type, expr)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
}
|
||||
return ret_type.clear_flag(.result)
|
||||
} else {
|
||||
|
@ -1365,7 +1369,10 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast.
|
|||
}
|
||||
} else {
|
||||
if expr.or_block.kind != .absent {
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &expr.or_block
|
||||
c.check_or_expr(expr.or_block, ret_type, expr.typ, expr)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
}
|
||||
}
|
||||
return ret_type.clear_flag(.result)
|
||||
|
@ -1389,8 +1396,11 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast.
|
|||
if return_none_or_error {
|
||||
c.check_expr_option_or_result_call(expr.or_expr, c.table.cur_fn.return_type)
|
||||
} else {
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &expr.or_expr
|
||||
c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.result),
|
||||
expr)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
}
|
||||
} else if expr.left is ast.SelectorExpr && expr.left_type.has_option_or_result() {
|
||||
with_modifier_kind := if expr.left_type.has_flag(.option) {
|
||||
|
@ -1464,6 +1474,10 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return
|
|||
}
|
||||
// allow `f() or {}`
|
||||
return
|
||||
} else if !node.err_used {
|
||||
if err_var := node.scope.find_var('err') {
|
||||
c.cur_or_expr.err_used = err_var.is_used
|
||||
}
|
||||
}
|
||||
mut valid_stmts := node.stmts.filter(it !is ast.SemicolonStmt)
|
||||
mut last_stmt := if valid_stmts.len > 0 { valid_stmts.last() } else { node.stmts.last() }
|
||||
|
@ -1809,7 +1823,10 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||
unwrapped_typ := c.unwrap_generic(node.typ)
|
||||
c.expected_or_type = unwrapped_typ.clear_option_and_result()
|
||||
c.stmts_ending_with_expression(mut node.or_block.stmts, c.expected_or_type)
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &node.or_block
|
||||
c.check_or_expr(node.or_block, unwrapped_typ, c.expected_or_type, node)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
c.expected_or_type = ast.void_type
|
||||
}
|
||||
return field.typ
|
||||
|
@ -4079,7 +4096,10 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
|||
unwrapped_typ := typ.clear_option_and_result()
|
||||
c.expected_or_type = unwrapped_typ
|
||||
c.stmts_ending_with_expression(mut node.or_expr.stmts, c.expected_or_type)
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &node.or_expr
|
||||
c.check_or_expr(node.or_expr, typ, c.expected_or_type, node)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
return unwrapped_typ
|
||||
}
|
||||
return typ
|
||||
|
@ -4194,7 +4214,10 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
|||
unwrapped_typ := typ.clear_option_and_result()
|
||||
c.expected_or_type = unwrapped_typ
|
||||
c.stmts_ending_with_expression(mut node.or_expr.stmts, c.expected_or_type)
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &node.or_expr
|
||||
c.check_or_expr(node.or_expr, typ, c.expected_or_type, node)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
return unwrapped_typ
|
||||
}
|
||||
return typ
|
||||
|
@ -4256,7 +4279,10 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
|||
unwrapped_typ := typ.clear_option_and_result()
|
||||
c.expected_or_type = unwrapped_typ
|
||||
c.stmts_ending_with_expression(mut node.or_expr.stmts, c.expected_or_type)
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &node.or_expr
|
||||
c.check_or_expr(node.or_expr, typ, c.expected_or_type, node)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
}
|
||||
return typ
|
||||
}
|
||||
|
|
|
@ -783,7 +783,10 @@ fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
|
|||
if node.or_block.kind == .block {
|
||||
old_inside_or_block_value := c.inside_or_block_value
|
||||
c.inside_or_block_value = true
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &node.or_block
|
||||
c.check_or_expr(node.or_block, typ, c.expected_or_type, node)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
c.inside_or_block_value = old_inside_or_block_value
|
||||
}
|
||||
c.expected_or_type = old_expected_or_type
|
||||
|
@ -3822,7 +3825,8 @@ fn scope_register_var_name(mut s ast.Scope, pos token.Pos, typ ast.Type, name st
|
|||
name: name
|
||||
pos: pos
|
||||
typ: typ
|
||||
is_used: true
|
||||
is_used: false
|
||||
is_special: true
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -192,8 +192,10 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
|||
if node.is_insert {
|
||||
node.typ = ast.int_type
|
||||
}
|
||||
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &node.or_expr
|
||||
c.check_orm_or_expr(mut node)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
|
||||
if node.is_insert {
|
||||
return ast.int_type
|
||||
|
@ -211,8 +213,10 @@ fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) ast.Type {
|
|||
for mut line in node.lines {
|
||||
c.sql_stmt_line(mut line)
|
||||
}
|
||||
|
||||
last_cur_or_expr := c.cur_or_expr
|
||||
c.cur_or_expr = &node.or_expr
|
||||
c.check_orm_or_expr(mut node)
|
||||
c.cur_or_expr = last_cur_or_expr
|
||||
|
||||
return ast.void_type
|
||||
}
|
||||
|
@ -605,7 +609,6 @@ fn (mut c Checker) check_orm_or_expr(mut expr ORMExpr) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
return_type := if mut expr is ast.SqlExpr {
|
||||
expr.typ
|
||||
} else {
|
||||
|
|
|
@ -7177,7 +7177,10 @@ 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_option_and_result()
|
||||
if !g.pref.skip_unused || or_block.err_used
|
||||
|| (g.fn_decl != unsafe { nil } && (g.fn_decl.is_main || g.fn_decl.is_test)) {
|
||||
g.writeln('\tIError err = ${cvar_name}${tmp_op}err;')
|
||||
}
|
||||
|
||||
g.inside_or_block = true
|
||||
defer {
|
||||
|
|
|
@ -310,9 +310,13 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
|||
g.writeln('{')
|
||||
// define `err` for the last branch after a `if val := opt {...}' guard
|
||||
if is_guard && guard_idx == i - 1 {
|
||||
if err_var := branch.scope.find_var('err') {
|
||||
if !g.pref.skip_unused || err_var.is_used {
|
||||
cvar_name := guard_vars[guard_idx]
|
||||
g.writeln('\tIError err = ${cvar_name}.err;')
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if branch.cond is ast.IfGuardExpr {
|
||||
mut var_name := guard_vars[i]
|
||||
mut short_opt := false
|
||||
|
|
|
@ -1124,7 +1124,7 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
|||
field_var := '${tmp}.${c_name(field.name)}'
|
||||
field_c_typ := g.styp(final_field_typ)
|
||||
if sym.kind == .struct && sym.name != 'time.Time' {
|
||||
mut sub := node.sub_structs[int(final_field_typ)]
|
||||
mut sub := node.sub_structs[int(final_field_typ)] or { continue }
|
||||
mut where_expr := sub.where_expr as ast.InfixExpr
|
||||
mut ident := where_expr.right as ast.Ident
|
||||
primitive_type_index := g.table.find_type('orm.Primitive')
|
||||
|
@ -1161,7 +1161,7 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
|||
} else {
|
||||
verror('missing fkey attribute')
|
||||
}
|
||||
sub := node.sub_structs[final_field_typ]
|
||||
sub := node.sub_structs[final_field_typ] or { continue }
|
||||
if sub.has_where {
|
||||
mut where_expr := sub.where_expr as ast.InfixExpr
|
||||
mut left_where_expr := where_expr.left as ast.Ident
|
||||
|
|
|
@ -536,10 +536,11 @@ fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
|
|||
mut or_kind := ast.OrKind.absent
|
||||
mut or_pos := p.tok.pos()
|
||||
mut or_stmts := []ast.Stmt{}
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
if p.tok.kind == .key_orelse {
|
||||
// `$method() or {}``
|
||||
or_kind = .block
|
||||
or_stmts, or_pos = p.or_block(.with_err_var)
|
||||
or_stmts, or_pos, or_scope = p.or_block(.with_err_var)
|
||||
}
|
||||
return ast.ComptimeCall{
|
||||
left: left
|
||||
|
@ -554,6 +555,7 @@ fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
|
|||
stmts: or_stmts
|
||||
kind: or_kind
|
||||
pos: or_pos
|
||||
scope: or_scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -727,11 +727,12 @@ fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_ident bo
|
|||
fn (mut p Parser) gen_or_block() ast.OrExpr {
|
||||
if p.tok.kind == .key_orelse {
|
||||
// `foo() or {}``
|
||||
or_stmts, or_pos := p.or_block(.with_err_var)
|
||||
or_stmts, or_pos, or_scope := p.or_block(.with_err_var)
|
||||
return ast.OrExpr{
|
||||
kind: ast.OrKind.block
|
||||
stmts: or_stmts
|
||||
pos: or_pos
|
||||
scope: or_scope
|
||||
}
|
||||
} else if p.tok.kind in [.question, .not] {
|
||||
or_pos := p.tok.pos()
|
||||
|
@ -820,11 +821,12 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
|
|||
mut or_stmts := []ast.Stmt{}
|
||||
mut or_kind := ast.OrKind.absent
|
||||
mut or_pos := p.tok.pos()
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
// allow `x := <-ch or {...}` to handle closed channel
|
||||
if op == .arrow {
|
||||
if p.tok.kind == .key_orelse {
|
||||
or_kind = .block
|
||||
or_stmts, or_pos = p.or_block(.with_err_var)
|
||||
or_stmts, or_pos, or_scope = p.or_block(.with_err_var)
|
||||
}
|
||||
if p.tok.kind == .question {
|
||||
p.next()
|
||||
|
@ -845,6 +847,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
|
|||
stmts: or_stmts
|
||||
kind: or_kind
|
||||
pos: or_pos
|
||||
scope: or_scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -911,6 +914,7 @@ fn (mut p Parser) prefix_expr() ast.Expr {
|
|||
mut or_stmts := []ast.Stmt{}
|
||||
mut or_kind := ast.OrKind.absent
|
||||
mut or_pos := p.tok.pos()
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
// allow `x := <-ch or {...}` to handle closed channel
|
||||
if op == .arrow {
|
||||
if mut right is ast.SelectorExpr {
|
||||
|
@ -919,7 +923,7 @@ fn (mut p Parser) prefix_expr() ast.Expr {
|
|||
right.or_block = ast.OrExpr{}
|
||||
} else if p.tok.kind == .key_orelse {
|
||||
or_kind = .block
|
||||
or_stmts, or_pos = p.or_block(.with_err_var)
|
||||
or_stmts, or_pos, or_scope = p.or_block(.with_err_var)
|
||||
} else if p.tok.kind == .question {
|
||||
p.next()
|
||||
or_kind = .propagate_option
|
||||
|
@ -935,6 +939,7 @@ fn (mut p Parser) prefix_expr() ast.Expr {
|
|||
stmts: or_stmts
|
||||
kind: or_kind
|
||||
pos: or_pos
|
||||
scope: or_scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,10 +74,11 @@ fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr {
|
|||
mut pos := first_pos.extend(last_pos)
|
||||
mut or_stmts := []ast.Stmt{} // TODO: remove unnecessary allocations by just using .absent
|
||||
mut or_pos := p.tok.pos()
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
if p.tok.kind == .key_orelse {
|
||||
// `foo() or {}``
|
||||
or_kind = .block
|
||||
or_stmts, or_pos = p.or_block(.with_err_var)
|
||||
or_stmts, or_pos, or_scope = p.or_block(.with_err_var)
|
||||
}
|
||||
if p.tok.kind in [.question, .not] {
|
||||
is_not := p.tok.kind == .not
|
||||
|
@ -108,6 +109,7 @@ fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr {
|
|||
stmts: or_stmts
|
||||
kind: or_kind
|
||||
pos: or_pos
|
||||
scope: or_scope
|
||||
}
|
||||
scope: p.scope
|
||||
comments: comments
|
||||
|
|
|
@ -53,8 +53,9 @@ fn (mut p Parser) if_expr(is_comptime bool, is_expr bool) ast.IfExpr {
|
|||
name: 'err'
|
||||
typ: ast.error_type
|
||||
pos: p.tok.pos()
|
||||
is_used: true
|
||||
is_used: false
|
||||
is_stack_obj: true
|
||||
is_special: true
|
||||
})
|
||||
}
|
||||
branches << ast.IfBranch{
|
||||
|
|
|
@ -185,10 +185,11 @@ fn (mut p Parser) parse_sql_or_block() ast.OrExpr {
|
|||
mut stmts := []ast.Stmt{}
|
||||
mut kind := ast.OrKind.absent
|
||||
mut pos := p.tok.pos()
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
|
||||
if p.tok.kind == .key_orelse {
|
||||
kind = .block
|
||||
stmts, pos = p.or_block(.with_err_var)
|
||||
stmts, pos, or_scope = p.or_block(.with_err_var)
|
||||
} else if p.tok.kind == .not {
|
||||
kind = .propagate_result
|
||||
p.next()
|
||||
|
@ -198,6 +199,7 @@ fn (mut p Parser) parse_sql_or_block() ast.OrExpr {
|
|||
stmts: stmts
|
||||
kind: kind
|
||||
pos: pos
|
||||
scope: or_scope
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1232,13 +1232,14 @@ fn (mut p Parser) ident(language ast.Language) ast.Ident {
|
|||
mut or_kind := ast.OrKind.absent
|
||||
mut or_stmts := []ast.Stmt{}
|
||||
mut or_pos := token.Pos{}
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
|
||||
if allowed_cases && p.tok.kind == .question && p.peek_tok.kind != .lpar { // var?, not var?(
|
||||
or_kind = ast.OrKind.propagate_option
|
||||
p.check(.question)
|
||||
} else if allowed_cases && p.tok.kind == .key_orelse {
|
||||
or_kind = ast.OrKind.block
|
||||
or_stmts, or_pos = p.or_block(.no_err_var)
|
||||
or_stmts, or_pos, or_scope = p.or_block(.no_err_var)
|
||||
} else if is_following_concrete_types {
|
||||
// `generic_fn[int]`
|
||||
concrete_types = p.parse_concrete_types()
|
||||
|
@ -1281,6 +1282,7 @@ fn (mut p Parser) ident(language ast.Language) ast.Ident {
|
|||
kind: or_kind
|
||||
stmts: or_stmts
|
||||
pos: or_pos
|
||||
scope: or_scope
|
||||
}
|
||||
concrete_types: concrete_types
|
||||
}
|
||||
|
@ -1752,7 +1754,7 @@ enum OrBlockErrVarMode {
|
|||
with_err_var
|
||||
}
|
||||
|
||||
fn (mut p Parser) or_block(err_var_mode OrBlockErrVarMode) ([]ast.Stmt, token.Pos) {
|
||||
fn (mut p Parser) or_block(err_var_mode OrBlockErrVarMode) ([]ast.Stmt, token.Pos, &ast.Scope) {
|
||||
was_inside_or_expr := p.inside_or_expr
|
||||
defer {
|
||||
p.inside_or_expr = was_inside_or_expr
|
||||
|
@ -1762,6 +1764,7 @@ fn (mut p Parser) or_block(err_var_mode OrBlockErrVarMode) ([]ast.Stmt, token.Po
|
|||
mut pos := p.tok.pos()
|
||||
p.next()
|
||||
p.open_scope()
|
||||
or_scope := p.scope
|
||||
defer {
|
||||
p.close_scope()
|
||||
}
|
||||
|
@ -1771,14 +1774,15 @@ fn (mut p Parser) or_block(err_var_mode OrBlockErrVarMode) ([]ast.Stmt, token.Po
|
|||
name: 'err'
|
||||
typ: ast.error_type
|
||||
pos: p.tok.pos()
|
||||
is_used: true
|
||||
is_used: false
|
||||
is_stack_obj: true
|
||||
is_special: true
|
||||
})
|
||||
}
|
||||
|
||||
stmts := p.parse_block_no_scope(false)
|
||||
pos = pos.extend(p.prev_tok.pos())
|
||||
return stmts, pos
|
||||
return stmts, pos, or_scope
|
||||
}
|
||||
|
||||
fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
|
||||
|
@ -1802,11 +1806,12 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
|
|||
mut or_kind_high := ast.OrKind.absent
|
||||
mut or_stmts_high := []ast.Stmt{}
|
||||
mut or_pos_high := token.Pos{}
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
|
||||
if !p.or_is_handled {
|
||||
// a[..end] or {...}
|
||||
if p.tok.kind == .key_orelse {
|
||||
or_stmts_high, or_pos_high = p.or_block(.no_err_var)
|
||||
or_stmts_high, or_pos_high, or_scope = p.or_block(.no_err_var)
|
||||
return ast.IndexExpr{
|
||||
left: left
|
||||
pos: pos_high
|
||||
|
@ -1821,6 +1826,7 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
|
|||
kind: .block
|
||||
stmts: or_stmts_high
|
||||
pos: or_pos_high
|
||||
scope: or_scope
|
||||
}
|
||||
is_gated: is_gated
|
||||
}
|
||||
|
@ -1870,11 +1876,11 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
|
|||
mut or_kind_low := ast.OrKind.absent
|
||||
mut or_stmts_low := []ast.Stmt{}
|
||||
mut or_pos_low := token.Pos{}
|
||||
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
if !p.or_is_handled {
|
||||
// a[start..end] or {...}
|
||||
if p.tok.kind == .key_orelse {
|
||||
or_stmts_low, or_pos_low = p.or_block(.no_err_var)
|
||||
or_stmts_low, or_pos_low, or_scope = p.or_block(.no_err_var)
|
||||
return ast.IndexExpr{
|
||||
left: left
|
||||
pos: pos_low
|
||||
|
@ -1890,6 +1896,7 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
|
|||
kind: .block
|
||||
stmts: or_stmts_low
|
||||
pos: or_pos_low
|
||||
scope: or_scope
|
||||
}
|
||||
is_gated: is_gated
|
||||
}
|
||||
|
@ -1930,10 +1937,11 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
|
|||
mut or_kind := ast.OrKind.absent
|
||||
mut or_stmts := []ast.Stmt{}
|
||||
mut or_pos := token.Pos{}
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
if !p.or_is_handled {
|
||||
// a[i] or { ... }
|
||||
if p.tok.kind == .key_orelse {
|
||||
or_stmts, or_pos = p.or_block(.no_err_var)
|
||||
or_stmts, or_pos, or_scope = p.or_block(.no_err_var)
|
||||
return ast.IndexExpr{
|
||||
left: left
|
||||
index: expr
|
||||
|
@ -1942,6 +1950,7 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
|
|||
kind: .block
|
||||
stmts: or_stmts
|
||||
pos: or_pos
|
||||
scope: or_scope
|
||||
}
|
||||
is_gated: is_gated
|
||||
}
|
||||
|
@ -2079,9 +2088,10 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
|
|||
mut or_kind := ast.OrKind.absent
|
||||
mut or_stmts := []ast.Stmt{}
|
||||
mut or_pos := token.Pos{}
|
||||
mut or_scope := &ast.Scope(unsafe { nil })
|
||||
if p.tok.kind == .key_orelse {
|
||||
or_kind = .block
|
||||
or_stmts, or_pos = p.or_block(.with_err_var)
|
||||
or_stmts, or_pos, or_scope = p.or_block(.with_err_var)
|
||||
} else if p.tok.kind == .not {
|
||||
or_kind = .propagate_result
|
||||
or_pos = p.tok.pos()
|
||||
|
@ -2101,6 +2111,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
|
|||
kind: or_kind
|
||||
stmts: or_stmts
|
||||
pos: or_pos
|
||||
scope: or_scope
|
||||
}
|
||||
scope: p.scope
|
||||
next_token: p.tok.kind
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue