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

ast, parser, fmt: fixed and optimized comments for 'for, for_c, for_in stmts' (fix: #15922) (#15950)

This commit is contained in:
shove 2022-10-03 15:45:11 +08:00 committed by GitHub
parent ffaca82ff8
commit dc2ba1c33f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 99 additions and 9 deletions

View File

@ -1028,8 +1028,9 @@ pub mut:
pub struct ForStmt { pub struct ForStmt {
pub: pub:
is_inf bool // `for {}` is_inf bool // `for {}`
pos token.Pos pos token.Pos
comments []Comment
pub mut: pub mut:
cond Expr cond Expr
stmts []Stmt stmts []Stmt
@ -1046,6 +1047,7 @@ pub:
high Expr // `10` in `for i in 0..10 {` high Expr // `10` in `for i in 0..10 {`
stmts []Stmt stmts []Stmt
pos token.Pos pos token.Pos
comments []Comment
val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array
// and the array cannot be indexed inside the loop // and the array cannot be indexed inside the loop
pub mut: pub mut:
@ -1067,6 +1069,7 @@ pub:
has_inc bool has_inc bool
is_multi bool // for a,b := 0,1; a < 10; a,b = a+b, a {...} is_multi bool // for a,b := 0,1; a < 10; a,b = a+b, a {...}
pos token.Pos pos token.Pos
comments []Comment
pub mut: pub mut:
init Stmt // i := 0; init Stmt // i := 0;
cond Expr // i < 10; cond Expr // i < 10;

View File

@ -1008,6 +1008,9 @@ pub fn (mut f Fmt) for_c_stmt(node ast.ForCStmt) {
if node.label.len > 0 { if node.label.len > 0 {
f.write('$node.label: ') f.write('$node.label: ')
} }
if node.comments.len > 0 {
f.comments(node.comments)
}
f.write('for ') f.write('for ')
if node.has_init { if node.has_init {
f.single_line_if = true // to keep all for ;; exprs on the same line f.single_line_if = true // to keep all for ;; exprs on the same line
@ -1031,6 +1034,9 @@ pub fn (mut f Fmt) for_in_stmt(node ast.ForInStmt) {
if node.label.len > 0 { if node.label.len > 0 {
f.write('$node.label: ') f.write('$node.label: ')
} }
if node.comments.len > 0 {
f.comments(node.comments)
}
f.write('for ') f.write('for ')
if node.key_var != '' { if node.key_var != '' {
f.write(node.key_var) f.write(node.key_var)
@ -1062,15 +1068,13 @@ pub fn (mut f Fmt) for_stmt(node ast.ForStmt) {
if node.label.len > 0 { if node.label.len > 0 {
f.write('$node.label: ') f.write('$node.label: ')
} }
if node.cond is ast.Comment { if node.comments.len > 0 {
f.comments([node.cond]) f.comments(node.comments)
} }
f.write('for ') f.write('for ')
if node.cond !is ast.Comment { f.expr(node.cond)
f.expr(node.cond) if !node.is_inf {
if !node.is_inf { f.write(' ')
f.write(' ')
}
} }
f.write('{') f.write('{')
if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line {

View File

@ -108,3 +108,43 @@ fn between_if_branches() {
for { for {
break break
} }
// comments
for {
break
}
// comments
for i := 0; i < 1; i++ {
break
}
// comments
for i := 0; i < 1; i++ {
break
}
// comments1
// comments2
// comments3
// comments4
for i := 0; i < 1; i++ {
break
}
// comments
for _ in [1, 2] {
break
}
// comments
for _ in [1, 2] {
break
}
// comments1
// comments2
// comments3
for _ in [1, 2] {
break
}

View File

@ -92,3 +92,33 @@ for // comments
{ {
break break
} }
for /* comments */ {
break
}
for i := 0; i < 1; i++ // comments
{
break
}
for i := 0; i < 1; i++ /* comments */ {
break
}
for /* comments1 */ i := 0; /* comments2 */ i < 1; /* comments3 */ i++ /* comments4 */ {
break
}
for _ in [1, 2] /* comments */ {
break
}
for _ in [1, 2] // comments
{
break
}
for /* comments1 */ _ in /* comments2 */ [1, 2] /* comments3 */ {
break
}

View File

@ -15,6 +15,8 @@ fn (mut p Parser) for_stmt() ast.Stmt {
} }
// defer { p.close_scope() } // defer { p.close_scope() }
// Infinite loop // Infinite loop
mut comments := []ast.Comment{}
comments << p.eat_comments()
if p.tok.kind == .lcbr { if p.tok.kind == .lcbr {
p.inside_for = false p.inside_for = false
stmts := p.parse_block_no_scope(false) stmts := p.parse_block_no_scope(false)
@ -22,6 +24,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
for_stmt := ast.ForStmt{ for_stmt := ast.ForStmt{
stmts: stmts stmts: stmts
pos: pos pos: pos
comments: comments
is_inf: true is_inf: true
scope: p.scope scope: p.scope
} }
@ -46,6 +49,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
init = p.assign_stmt() init = p.assign_stmt()
has_init = true has_init = true
} }
comments << p.eat_comments()
// Allow `for ;; i++ {` // Allow `for ;; i++ {`
// Allow `for i = 0; i < ...` // Allow `for i = 0; i < ...`
p.check(.semicolon) p.check(.semicolon)
@ -54,17 +58,21 @@ fn (mut p Parser) for_stmt() ast.Stmt {
if p.tok.kind == .name && p.peek_tok.kind in [.inc, .dec] { if p.tok.kind == .name && p.peek_tok.kind in [.inc, .dec] {
return p.error('cannot use $p.tok.lit$p.peek_tok.kind as value') return p.error('cannot use $p.tok.lit$p.peek_tok.kind as value')
} }
comments << p.eat_comments()
cond = p.expr(0) cond = p.expr(0)
has_cond = true has_cond = true
} }
comments << p.eat_comments()
p.check(.semicolon) p.check(.semicolon)
if !is_multi { if !is_multi {
is_multi = p.peek_tok.kind == .comma is_multi = p.peek_tok.kind == .comma
} }
comments << p.eat_comments()
if p.tok.kind != .lcbr { if p.tok.kind != .lcbr {
inc = p.stmt(false) inc = p.stmt(false)
has_inc = true has_inc = true
} }
comments << p.eat_comments()
p.inside_for = false p.inside_for = false
stmts := p.parse_block_no_scope(false) stmts := p.parse_block_no_scope(false)
pos.update_last_line(p.prev_tok.line_nr) pos.update_last_line(p.prev_tok.line_nr)
@ -78,6 +86,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
cond: cond cond: cond
inc: inc inc: inc
pos: pos pos: pos
comments: comments
scope: p.scope scope: p.scope
} }
p.close_scope() p.close_scope()
@ -128,10 +137,12 @@ fn (mut p Parser) for_stmt() ast.Stmt {
return p.error_with_pos('redefinition of value iteration variable `$val_var_name`, use `for ($val_var_name in array) {` if you want to check for a condition instead', return p.error_with_pos('redefinition of value iteration variable `$val_var_name`, use `for ($val_var_name in array) {` if you want to check for a condition instead',
val_var_pos) val_var_pos)
} }
comments << p.eat_comments()
p.check(.key_in) p.check(.key_in)
if p.tok.kind == .name && p.tok.lit in [key_var_name, val_var_name] { if p.tok.kind == .name && p.tok.lit in [key_var_name, val_var_name] {
return p.error('in a `for x in array` loop, the key or value iteration variable `$p.tok.lit` can not be the same as the array variable') return p.error('in a `for x in array` loop, the key or value iteration variable `$p.tok.lit` can not be the same as the array variable')
} }
comments << p.eat_comments()
// arr_expr // arr_expr
cond := p.expr(0) cond := p.expr(0)
// 0 .. 10 // 0 .. 10
@ -168,6 +179,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
is_stack_obj: true is_stack_obj: true
}) })
} }
comments << p.eat_comments()
p.inside_for = false p.inside_for = false
stmts := p.parse_block_no_scope(false) stmts := p.parse_block_no_scope(false)
pos.update_last_line(p.prev_tok.line_nr) pos.update_last_line(p.prev_tok.line_nr)
@ -180,6 +192,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
high: high_expr high: high_expr
is_range: is_range is_range: is_range
pos: pos pos: pos
comments: comments
val_is_mut: val_is_mut val_is_mut: val_is_mut
scope: p.scope scope: p.scope
} }