diff --git a/doc/docs.md b/doc/docs.md index ecf8f6b4bd..4782b6ec01 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -1509,8 +1509,7 @@ fn main() { ## References ```v -struct Foo { -} +struct Foo {} fn (foo Foo) bar_method() { // ... @@ -1730,8 +1729,7 @@ struct Dog { breed string } -struct Cat { -} +struct Cat {} fn (d Dog) speak() string { return 'woof' @@ -1800,14 +1798,11 @@ A sum type instance can hold a value of several different types. Use the `type` keyword to declare a sum type: ```v -struct Moon { -} +struct Moon {} -struct Mars { -} +struct Mars {} -struct Venus { -} +struct Venus {} type World = Mars | Moon | Venus @@ -1824,14 +1819,11 @@ To check whether a sum type instance holds a certain type, use `sum is Type`. To cast a sum type to one of its variants you can use `sum as Type`: ```v -struct Moon { -} +struct Moon {} -struct Mars { -} +struct Mars {} -struct Venus { -} +struct Venus {} type World = Mars | Moon | Venus @@ -1883,14 +1875,11 @@ complex expression than just a variable name. You can also use `match` to determine the variant: ```v -struct Moon { -} +struct Moon {} -struct Mars { -} +struct Mars {} -struct Venus { -} +struct Venus {} type World = Mars | Moon | Venus diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index abe779df5a..eb0f4c3fb1 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -297,8 +297,11 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) { if node.is_unsafe { f.write('unsafe ') } - f.writeln('{') - f.stmts(node.stmts) + f.write('{') + if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { + f.writeln('') + f.stmts(node.stmts) + } f.writeln('}') } ast.BranchStmt { @@ -306,36 +309,26 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) { } ast.CompFor { typ := f.no_cur_mod(f.table.type_to_str(node.typ)) - f.writeln('\$for $node.val_var in ${typ}.$node.kind.str() {') - f.stmts(node.stmts) + f.write('\$for $node.val_var in ${typ}.$node.kind.str() {') + if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { + f.writeln('') + f.stmts(node.stmts) + } f.writeln('}') } ast.ConstDecl { f.const_decl(node) } ast.DeferStmt { - f.writeln('defer {') - f.stmts(node.stmts) + f.write('defer {') + if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { + f.writeln('') + f.stmts(node.stmts) + } f.writeln('}') } ast.EnumDecl { - f.attrs(node.attrs) - if node.is_pub { - f.write('pub ') - } - name := node.name.after('.') - f.writeln('enum $name {') - f.comments(node.comments, inline: true, level: .indent) - for field in node.fields { - f.write('\t$field.name') - if field.has_expr { - f.write(' = ') - f.expr(field.expr) - } - f.comments(field.comments, inline: true, has_nl: false, level: .indent) - f.writeln('') - } - f.writeln('}\n') + f.enum_decl(node) } ast.ExprStmt { f.comments(node.comments, {}) @@ -362,8 +355,11 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) { f.write('; ') f.stmt(node.inc) f.remove_new_line() - f.writeln(' {') - f.stmts(node.stmts) + f.write(' {') + if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { + f.writeln('') + f.stmts(node.stmts) + } f.writeln('}') } ast.ForInStmt { @@ -389,8 +385,11 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) { f.write(' .. ') f.expr(node.high) } - f.writeln(' {') - f.stmts(node.stmts) + f.write(' {') + if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { + f.writeln('') + f.stmts(node.stmts) + } f.writeln('}') } ast.ForStmt { @@ -400,11 +399,14 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) { f.write('for ') f.expr(node.cond) if node.is_inf { - f.writeln('{') + f.write('{') } else { - f.writeln(' {') + f.write(' {') + } + if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { + f.writeln('') + f.stmts(node.stmts) } - f.stmts(node.stmts) f.writeln('}') } ast.GlobalDecl { @@ -597,6 +599,10 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) { f.write(gtypes) f.write('>') } + if node.fields.len == 0 && node.pos.line_nr == node.pos.last_line { + f.writeln(' {}\n') + return + } f.writeln(' {') mut max := 0 mut max_type := 0 @@ -701,7 +707,10 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) { f.write('pub ') } name := node.name.after('.') - f.writeln('interface $name {') + f.write('interface $name {') + if node.methods.len > 0 || node.pos.line_nr < node.pos.last_line { + f.writeln('') + } f.comments_after_last_field(node.pre_comments) for method in node.methods { f.write('\t') @@ -712,6 +721,30 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) { f.writeln('}\n') } +pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) { + f.attrs(node.attrs) + if node.is_pub { + f.write('pub ') + } + name := node.name.after('.') + if node.fields.len == 0 && node.pos.line_nr == node.pos.last_line { + f.writeln('enum $name {}\n') + return + } + f.writeln('enum $name {') + f.comments(node.comments, inline: true, level: .indent) + for field in node.fields { + f.write('\t$field.name') + if field.has_expr { + f.write(' = ') + f.expr(field.expr) + } + f.comments(field.comments, inline: true, has_nl: false, level: .indent) + f.writeln('') + } + f.writeln('}\n') +} + pub fn (mut f Fmt) prefix_expr_cast_expr(fexpr ast.Expr) { mut is_pe_amp_ce := false mut ce := ast.CastExpr{} @@ -1254,8 +1287,11 @@ pub fn (mut f Fmt) fn_decl(node ast.FnDecl) { f.write(node.stringify(f.table, f.cur_mod, f.mod2alias)) // `Expr` instead of `ast.Expr` in mod ast if node.language == .v { if !node.no_body { - f.writeln(' {') - f.stmts(node.stmts) + f.write(' {') + if node.stmts.len > 0 || node.pos.line_nr < node.pos.last_line { + f.writeln('') + f.stmts(node.stmts) + } f.write('}') } if !node.is_anon { @@ -1908,6 +1944,10 @@ pub fn (mut f Fmt) const_decl(it ast.ConstDecl) { if it.is_pub { f.write('pub ') } + if it.fields.len == 0 && it.pos.line_nr == it.pos.last_line { + f.writeln('const ()\n') + return + } f.writeln('const (') mut max := 0 for field in it.fields { diff --git a/vlib/v/fmt/tests/empty_curlies_and_parens_keep.vv b/vlib/v/fmt/tests/empty_curlies_and_parens_keep.vv new file mode 100644 index 0000000000..30e4420672 --- /dev/null +++ b/vlib/v/fmt/tests/empty_curlies_and_parens_keep.vv @@ -0,0 +1,44 @@ +const () + +const ( +) + +struct Bar {} + +struct Bar2 { +} + +interface Spam {} + +interface Spam2 { +} + +enum Baz {} + +enum Baz2 { +} + +fn foo() {} + +fn foo2() { +} + +fn main() { + arr := []int{} + x := 1 + for s in arr {} + for s in arr { + } + for i := 0; i < 5; i++ {} + for j := 0; j < 5; j++ { + } + for false {} + for false { + } + defer {} + defer { + } + unsafe {} + unsafe { + } +} diff --git a/vlib/v/fmt/tests/struct_embed_expected.vv b/vlib/v/fmt/tests/struct_embed_expected.vv index 154c736569..a7dae553b0 100644 --- a/vlib/v/fmt/tests/struct_embed_expected.vv +++ b/vlib/v/fmt/tests/struct_embed_expected.vv @@ -2,8 +2,7 @@ struct Foo { x int } -struct Test { -} +struct Test {} struct Bar { Foo diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ff2bd670d5..0990e43dca 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1827,7 +1827,7 @@ fn (mut p Parser) const_decl() ast.ConstDecl { p.top_level_statement_end() p.check(.rpar) return ast.ConstDecl{ - pos: start_pos.extend(end_pos) + pos: start_pos.extend_with_last_line(end_pos, p.prev_tok.line_nr) fields: fields is_pub: is_pub end_comments: comments diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index f3326b2ef2..e720d678a6 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -459,7 +459,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { } p.top_level_statement_end() p.check(.rcbr) - start_pos.last_line = p.prev_tok.line_nr + start_pos.last_line = p.prev_tok.line_nr - 1 return ast.InterfaceDecl{ name: interface_name methods: methods