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

cgen: refactor need_tmp_var_in_expr/match() (fix #15675) (#15676)

This commit is contained in:
yuyi 2022-09-06 18:09:28 +08:00 committed by GitHub
parent 862d91ed0a
commit e3d3863fbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 28 deletions

View File

@ -31,42 +31,91 @@ fn (mut g Gen) need_tmp_var_in_expr(expr ast.Expr) bool {
if is_noreturn_callexpr(expr) {
return true
}
if expr is ast.MatchExpr {
return true
}
if expr is ast.CallExpr {
if expr.is_method {
left_sym := g.table.sym(expr.receiver_type)
if left_sym.kind in [.array, .array_fixed, .map] {
match expr {
ast.IfExpr {
if g.need_tmp_var_in_if(expr) {
return true
}
}
if expr.or_block.kind != .absent {
ast.MatchExpr {
return true
}
}
if expr is ast.CastExpr {
return g.need_tmp_var_in_expr(expr.expr)
}
if expr is ast.ParExpr {
return g.need_tmp_var_in_expr(expr.expr)
}
if expr is ast.ConcatExpr {
for val in expr.vals {
if val is ast.CallExpr {
if val.return_type.has_flag(.optional) {
ast.CallExpr {
if expr.is_method {
left_sym := g.table.sym(expr.receiver_type)
if left_sym.kind in [.array, .array_fixed, .map] {
return true
}
}
if expr.or_block.kind != .absent {
return true
}
}
ast.CastExpr {
return g.need_tmp_var_in_expr(expr.expr)
}
ast.ParExpr {
return g.need_tmp_var_in_expr(expr.expr)
}
ast.ConcatExpr {
for val in expr.vals {
if val is ast.CallExpr {
if val.return_type.has_flag(.optional) {
return true
}
}
}
}
ast.IndexExpr {
if expr.or_expr.kind != .absent {
return true
}
if g.need_tmp_var_in_expr(expr.index) {
return true
}
}
ast.ArrayInit {
if g.need_tmp_var_in_expr(expr.len_expr) {
return true
}
if g.need_tmp_var_in_expr(expr.cap_expr) {
return true
}
if g.need_tmp_var_in_expr(expr.default_expr) {
return true
}
for elem_expr in expr.exprs {
if g.need_tmp_var_in_expr(elem_expr) {
return true
}
}
}
}
if expr is ast.IndexExpr {
if expr.or_expr.kind != .absent {
return true
ast.MapInit {
for key in expr.keys {
if g.need_tmp_var_in_expr(key) {
return true
}
}
for val in expr.vals {
if g.need_tmp_var_in_expr(val) {
return true
}
}
}
if g.need_tmp_var_in_expr(expr.index) {
return true
ast.StructInit {
if g.need_tmp_var_in_expr(expr.update_expr) {
return true
}
for field in expr.fields {
if g.need_tmp_var_in_expr(field.expr) {
return true
}
}
}
ast.SelectorExpr {
return g.need_tmp_var_in_expr(expr.expr)
}
else {}
}
return false
}

View File

@ -28,9 +28,7 @@ fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool {
if branch.stmts.len == 1 {
if branch.stmts[0] is ast.ExprStmt {
stmt := branch.stmts[0] as ast.ExprStmt
if stmt.expr in [ast.CallExpr, ast.IfExpr, ast.MatchExpr, ast.StructInit]
|| (stmt.expr is ast.IndexExpr
&& (stmt.expr as ast.IndexExpr).or_expr.kind != .absent) {
if g.need_tmp_var_in_expr(stmt.expr) {
return true
}
}

View File

@ -7,3 +7,15 @@ fn test_if_expr_with_index_expr() {
println(b)
assert true
}
struct Foo {
name string
}
fn test_if_expr_with_selector_expr() {
a := [Foo{'abc1'}, Foo{'abc2'}, Foo{'abc3'}]
b := if true { a[rand.intn(a.len) or { 0 }].name } else { 'not found' }
println(b)
assert true
}