fmt: fix labelled break & continue (#6889)

pull/6892/head
Nick Treleaven 2020-11-20 13:12:40 +00:00 committed by GitHub
parent 09090bd29f
commit 9871d24929
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 58 deletions

View File

@ -293,6 +293,14 @@ pub fn args2str(args []CallArg) string {
return res.join(', ') return res.join(', ')
} }
pub fn (node &BranchStmt) str() string {
mut s := '$node.kind'
if node.label.len > 0 {
s += ' $node.label'
}
return s
}
pub fn (node Stmt) str() string { pub fn (node Stmt) str() string {
match node { match node {
AssignStmt { AssignStmt {
@ -318,6 +326,9 @@ pub fn (node Stmt) str() string {
} }
return out return out
} }
BranchStmt {
return node.str()
}
ExprStmt { ExprStmt {
return node.expr.str() return node.expr.str()
} }

View File

@ -302,38 +302,34 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
f.writeln('}') f.writeln('}')
} }
ast.BranchStmt { ast.BranchStmt {
match node.kind { f.writeln(node.str())
.key_break { f.writeln('break') }
.key_continue { f.writeln('continue') }
else {}
}
} }
ast.CompFor { ast.CompFor {
typ := f.no_cur_mod(f.table.type_to_str(it.typ)) typ := f.no_cur_mod(f.table.type_to_str(node.typ))
f.writeln('\$for $it.val_var in ${typ}.$it.kind.str() {') f.writeln('\$for $node.val_var in ${typ}.$node.kind.str() {')
f.stmts(it.stmts) f.stmts(node.stmts)
f.writeln('}') f.writeln('}')
} }
ast.ConstDecl { ast.ConstDecl {
f.const_decl(it) f.const_decl(node)
} }
ast.DeferStmt { ast.DeferStmt {
f.writeln('defer {') f.writeln('defer {')
f.stmts(it.stmts) f.stmts(node.stmts)
f.writeln('}') f.writeln('}')
} }
ast.EnumDecl { ast.EnumDecl {
f.attrs(it.attrs) f.attrs(node.attrs)
if it.is_pub { if node.is_pub {
f.write('pub ') f.write('pub ')
} }
name := it.name.after('.') name := node.name.after('.')
f.writeln('enum $name {') f.writeln('enum $name {')
f.comments(it.comments, { f.comments(node.comments, {
inline: true inline: true
level: .indent level: .indent
}) })
for field in it.fields { for field in node.fields {
f.write('\t$field.name') f.write('\t$field.name')
if field.has_expr { if field.has_expr {
f.write(' = ') f.write(' = ')
@ -349,133 +345,142 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
f.writeln('}\n') f.writeln('}\n')
} }
ast.ExprStmt { ast.ExprStmt {
f.comments(it.comments, {}) f.comments(node.comments, {})
f.expr(it.expr) f.expr(node.expr)
if !f.single_line_if { if !f.single_line_if {
f.writeln('') f.writeln('')
} }
} }
ast.FnDecl { ast.FnDecl {
f.fn_decl(it) f.fn_decl(node)
} }
ast.ForCStmt { ast.ForCStmt {
if node.label.len > 0 {
f.write('$node.label: ')
}
f.write('for ') f.write('for ')
if it.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
f.stmt(it.init) f.stmt(node.init)
f.single_line_if = false f.single_line_if = false
} }
f.write('; ') f.write('; ')
f.expr(it.cond) f.expr(node.cond)
f.write('; ') f.write('; ')
f.stmt(it.inc) f.stmt(node.inc)
f.remove_new_line() f.remove_new_line()
f.writeln(' {') f.writeln(' {')
f.stmts(it.stmts) f.stmts(node.stmts)
f.writeln('}') f.writeln('}')
} }
ast.ForInStmt { ast.ForInStmt {
f.write('for ') if node.label.len > 0 {
if it.key_var != '' { f.write('$node.label: ')
f.write(it.key_var)
} }
if it.val_var != '' { f.write('for ')
if it.key_var != '' { if node.key_var != '' {
f.write(node.key_var)
}
if node.val_var != '' {
if node.key_var != '' {
f.write(', ') f.write(', ')
} }
if it.val_is_mut { if node.val_is_mut {
f.write('mut ') f.write('mut ')
} }
f.write(it.val_var) f.write(node.val_var)
} }
f.write(' in ') f.write(' in ')
f.expr(it.cond) f.expr(node.cond)
if it.is_range { if node.is_range {
f.write(' .. ') f.write(' .. ')
f.expr(it.high) f.expr(node.high)
} }
f.writeln(' {') f.writeln(' {')
f.stmts(it.stmts) f.stmts(node.stmts)
f.writeln('}') f.writeln('}')
} }
ast.ForStmt { ast.ForStmt {
if node.label.len > 0 {
f.write('$node.label: ')
}
f.write('for ') f.write('for ')
f.expr(it.cond) f.expr(node.cond)
if it.is_inf { if node.is_inf {
f.writeln('{') f.writeln('{')
} else { } else {
f.writeln(' {') f.writeln(' {')
} }
f.stmts(it.stmts) f.stmts(node.stmts)
f.writeln('}') f.writeln('}')
} }
ast.GlobalDecl { ast.GlobalDecl {
f.global_decl(it) f.global_decl(node)
} }
ast.GoStmt { ast.GoStmt {
f.write('go ') f.write('go ')
f.expr(it.call_expr) f.expr(node.call_expr)
f.writeln('') f.writeln('')
} }
ast.GotoLabel { ast.GotoLabel {
f.writeln('$it.name:') f.writeln('$node.name:')
} }
ast.GotoStmt { ast.GotoStmt {
f.writeln('goto $it.name') f.writeln('goto $node.name')
} }
ast.HashStmt { ast.HashStmt {
f.writeln('#$it.val') f.writeln('#$node.val')
} }
ast.Import { ast.Import {
// Imports are handled after the file is formatted, to automatically add necessary modules // Imports are handled after the file is formatted, to automatically add necessary modules
// f.imports(f.file.imports) // f.imports(f.file.imports)
} }
ast.InterfaceDecl { ast.InterfaceDecl {
f.interface_decl(it) f.interface_decl(node)
} }
ast.Module { ast.Module {
f.mod(it) f.mod(node)
} }
ast.Return { ast.Return {
f.comments(it.comments, {}) f.comments(node.comments, {})
f.write('return') f.write('return')
if it.exprs.len > 1 { if node.exprs.len > 1 {
// multiple returns // multiple returns
f.write(' ') f.write(' ')
for i, expr in it.exprs { for i, expr in node.exprs {
f.expr(expr) f.expr(expr)
if i < it.exprs.len - 1 { if i < node.exprs.len - 1 {
f.write(', ') f.write(', ')
} }
} }
} else if it.exprs.len == 1 { } else if node.exprs.len == 1 {
// normal return // normal return
f.write(' ') f.write(' ')
f.expr(it.exprs[0]) f.expr(node.exprs[0])
} }
f.writeln('') f.writeln('')
} }
ast.SqlStmt { ast.SqlStmt {
f.write('sql ') f.write('sql ')
f.expr(it.db_expr) f.expr(node.db_expr)
f.writeln(' {') f.writeln(' {')
match it.kind as k { match node.kind as k {
.insert { .insert {
f.writeln('\tinsert $it.object_var_name into ${util.strip_mod_name(it.table_name)}') f.writeln('\tinsert $node.object_var_name into ${util.strip_mod_name(node.table_name)}')
} }
.update { .update {
f.write('\tupdate ${util.strip_mod_name(it.table_name)} set ') f.write('\tupdate ${util.strip_mod_name(node.table_name)} set ')
for i, col in it.updated_columns { for i, col in node.updated_columns {
f.write('$col = ') f.write('$col = ')
f.expr(it.update_exprs[i]) f.expr(node.update_exprs[i])
if i < it.updated_columns.len - 1 { if i < node.updated_columns.len - 1 {
f.write(', ') f.write(', ')
} else { } else {
f.write(' ') f.write(' ')
} }
} }
f.write('where ') f.write('where ')
f.expr(it.where_expr) f.expr(node.where_expr)
f.writeln('') f.writeln('')
} }
.delete { .delete {

View File

@ -0,0 +1,38 @@
fn test_labelled_for() {
mut i := 4
goto L1
L1: for {
i++
for {
if i < 7 {
continue L1
} else {
break L1
}
}
}
assert i == 7
goto L2
L2: for ; true; i++ {
for {
if i < 17 {
continue L2
} else {
break L2
}
}
}
assert i == 17
goto L3
L3: for e in [1, 2, 3, 4] {
i = e
for {
if i < 3 {
continue L3
} else {
break L3
}
}
}
assert i == 3
}