v: implement expr.remove_para (#24669)

This commit is contained in:
Swastik Baranwal 2025-06-08 15:21:29 +05:30 committed by GitHub
parent a5f400ee77
commit c0bdb4a47b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 19 additions and 30 deletions

View File

@ -1571,7 +1571,7 @@ pub:
has_len bool
has_cap bool
has_init bool
has_index bool // true if temp variable index is used
has_index bool // true if temp variable index is used
pub mut:
exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array
len_expr Expr // len: expr
@ -2728,6 +2728,15 @@ pub fn (expr Expr) is_reference() bool {
}
}
// remove_par removes all parenthesis and gets the innermost Expr
pub fn (mut expr Expr) remove_par() Expr {
mut e := expr
for mut e is ParExpr {
e = e.expr
}
return e
}
// is `expr` a literal, i.e. it does not depend on any other declarations (C compile time constant)
pub fn (expr Expr) is_literal() bool {
return match expr {

View File

@ -339,10 +339,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
if left is ast.ParExpr && is_decl {
c.error('parentheses are not supported on the left side of `:=`', left.pos())
}
for left is ast.ParExpr {
left = (left as ast.ParExpr).expr
}
left = left.remove_par()
is_assign := node.op in [.assign, .decl_assign]
match mut left {
ast.Ident {
@ -943,9 +940,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
c.inside_ref_lit = old_inside_ref_lit
if right_node.op == .amp {
mut expr := right_node.right
for mut expr is ast.ParExpr {
expr = expr.expr
}
expr = expr.remove_par()
if mut expr is ast.Ident {
if mut expr.obj is ast.Var {
v := expr.obj

View File

@ -4767,10 +4767,7 @@ fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
c.inside_ref_lit = old_inside_ref_lit
node.right_type = right_type
mut expr := node.right
// if ParExpr get the innermost expr
for mut expr is ast.ParExpr {
expr = expr.expr
}
expr = expr.remove_par()
if node.op == .amp {
if expr is ast.Nil {
c.error('invalid operation: cannot take address of nil', expr.pos())

View File

@ -1983,9 +1983,7 @@ fn (mut c Checker) check_type_and_visibility(name string, type_idx int, expected
fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) ast.Type {
// `(if true { 'foo.bar' } else { 'foo.bar.baz' }).all_after('foo.')`
mut left_expr := node.left
for mut left_expr is ast.ParExpr {
left_expr = left_expr.expr
}
left_expr = left_expr.remove_par()
if mut left_expr is ast.IfExpr {
if left_expr.branches.len > 0 && left_expr.has_else {
mut last_stmt := left_expr.branches[0].stmts.last()

View File

@ -856,9 +856,7 @@ fn expr_is_single_line(expr ast.Expr) bool {
pub fn (mut f Fmt) assert_stmt(node ast.AssertStmt) {
f.write('assert ')
mut expr := node.expr
for mut expr is ast.ParExpr {
expr = expr.expr
}
expr = expr.remove_par()
f.expr(expr)
if node.extra !is ast.EmptyExpr {
f.write(', ')
@ -2935,9 +2933,7 @@ pub fn (mut f Fmt) or_expr(node ast.OrExpr) {
pub fn (mut f Fmt) par_expr(node ast.ParExpr) {
mut expr := node.expr
for mut expr is ast.ParExpr {
expr = expr.expr
}
expr = expr.remove_par()
requires_paren := expr !is ast.Ident || node.comments.len > 0
if requires_paren {
f.par_level++

View File

@ -729,9 +729,7 @@ fn expr_is_single_line(expr ast.Expr) bool {
pub fn (mut f Gen) assert_stmt(node ast.AssertStmt) {
f.write('assert ')
mut expr := node.expr
for mut expr is ast.ParExpr {
expr = expr.expr
}
expr = expr.remove_par()
f.expr(expr)
f.writeln('')
}
@ -2058,9 +2056,7 @@ pub fn (mut f Gen) par_expr(node ast.ParExpr) {
f.write('(')
}
mut expr := node.expr
for mut expr is ast.ParExpr {
expr = expr.expr
}
expr = expr.remove_par()
f.expr(expr)
if requires_paren {
f.par_level--

View File

@ -790,9 +790,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
p.inside_assign_rhs = old_assign_rhs
if op in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && mut right is ast.PrefixExpr {
mut right_expr := right.right
for mut right_expr is ast.ParExpr {
right_expr = right_expr.expr
}
right_expr = right_expr.remove_par()
if right.op in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && right_expr.is_pure_literal() {
p.error_with_pos('invalid expression: unexpected token `${op}`', right_op_pos)
}