vfmt: handle more comments in interface/struct init/match branches

pull/6615/head
Delyan Angelov 2020-10-14 22:48:49 +03:00
parent 6ad5ecf569
commit c33a748344
5 changed files with 46 additions and 21 deletions

View File

@ -184,13 +184,14 @@ pub:
is_pub bool is_pub bool
methods []FnDecl methods []FnDecl
pos token.Position pos token.Position
pre_comments []Comment
} }
pub struct StructInitField { pub struct StructInitField {
pub: pub:
expr Expr expr Expr
pos token.Position pos token.Position
comment Comment comments []Comment
pub mut: pub mut:
name string name string
typ table.Type typ table.Type
@ -542,7 +543,7 @@ pub:
exprs []Expr // left side exprs []Expr // left side
stmts []Stmt // right side stmts []Stmt // right side
pos token.Position pos token.Position
comment Comment // comment above `xxx {` comments []Comment // comment above `xxx {`
is_else bool is_else bool
post_comments []Comment post_comments []Comment
} }

View File

@ -682,6 +682,7 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) {
} }
name := node.name.after('.') name := node.name.after('.')
f.writeln('interface $name {') f.writeln('interface $name {')
f.comments_after_last_field(node.pre_comments)
for method in node.methods { for method in node.methods {
f.write('\t') f.write('\t')
f.writeln(method.stringify(f.table, f.cur_mod).after('fn ')) f.writeln(method.stringify(f.table, f.cur_mod).after('fn '))
@ -1508,8 +1509,8 @@ pub fn (mut f Fmt) match_expr(it ast.MatchExpr) {
} }
} }
for branch in it.branches { for branch in it.branches {
if branch.comment.text != '' { for cmnt in branch.comments {
f.comment(branch.comment, { f.comment(cmnt, {
inline: true inline: true
}) })
f.writeln('') f.writeln('')
@ -1780,6 +1781,11 @@ pub fn (mut f Fmt) struct_init(it ast.StructInit) {
for field in it.fields { for field in it.fields {
f.write('$field.name: ') f.write('$field.name: ')
f.prefix_expr_cast_expr(field.expr) f.prefix_expr_cast_expr(field.expr)
f.comments(field.comments, {
inline: true
has_nl: false
level: .indent
})
f.writeln('') f.writeln('')
} }
f.indent-- f.indent--

View File

@ -60,7 +60,11 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
}) })
} }
branches << ast.IfBranch{ branches << ast.IfBranch{
stmts: if prev_guard { p.parse_block_no_scope(false) } else { p.parse_block() } stmts: if prev_guard {
p.parse_block_no_scope(false)
} else {
p.parse_block()
}
pos: start_pos.extend(end_pos) pos: start_pos.extend(end_pos)
body_pos: body_pos.extend(p.tok.position()) body_pos: body_pos.extend(p.tok.position())
comments: comments comments: comments
@ -71,7 +75,9 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
comments = [] comments = []
break break
} }
if is_comptime { p.check(.dollar) } if is_comptime {
p.check(.dollar)
}
} }
// `if` or `else if` // `if` or `else if`
p.check(.key_if) p.check(.key_if)
@ -192,7 +198,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
mut branches := []ast.MatchBranch{} mut branches := []ast.MatchBranch{}
for { for {
branch_first_pos := p.tok.position() branch_first_pos := p.tok.position()
comment := p.check_comment() // comment before {} comments := p.eat_comments() // comments before {}
mut exprs := []ast.Expr{} mut exprs := []ast.Expr{}
p.open_scope() p.open_scope()
// final else // final else
@ -318,7 +324,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
exprs: exprs exprs: exprs
stmts: stmts stmts: stmts
pos: pos pos: pos
comment: comment comments: comments
is_else: is_else is_else: is_else
post_comments: post_comments post_comments: post_comments
} }
@ -366,20 +372,24 @@ fn (mut p Parser) select_expr() ast.SelectExpr {
mut stmt := ast.Stmt{} mut stmt := ast.Stmt{}
if p.tok.kind == .key_else { if p.tok.kind == .key_else {
if has_timeout { if has_timeout {
p.error_with_pos('timeout `> t` and `else` are mutually exclusive `select` keys', p.tok.position()) p.error_with_pos('timeout `> t` and `else` are mutually exclusive `select` keys',
p.tok.position())
} }
if has_else { if has_else {
p.error_with_pos('at most one `else` branch allowed in `select` block', p.tok.position()) p.error_with_pos('at most one `else` branch allowed in `select` block',
p.tok.position())
} }
is_else = true is_else = true
has_else = true has_else = true
p.next() p.next()
} else if p.tok.kind == .gt { } else if p.tok.kind == .gt {
if has_else { if has_else {
p.error_with_pos('`else` and timeout `> t` are mutually exclusive `select` keys', p.tok.position()) p.error_with_pos('`else` and timeout `> t` are mutually exclusive `select` keys',
p.tok.position())
} }
if has_timeout { if has_timeout {
p.error_with_pos('at most one timeout `> t` branch allowed in `select` block', p.tok.position()) p.error_with_pos('at most one timeout `> t` branch allowed in `select` block',
p.tok.position())
} }
is_timeout = true is_timeout = true
has_timeout = true has_timeout = true
@ -420,11 +430,13 @@ fn (mut p Parser) select_expr() ast.SelectExpr {
match stmt.expr as expr { match stmt.expr as expr {
ast.InfixExpr { ast.InfixExpr {
if expr.op != .arrow { if expr.op != .arrow {
p.error_with_pos('select key: `<-` operator expected', expr.pos) p.error_with_pos('select key: `<-` operator expected',
expr.pos)
} }
} }
else { else {
p.error_with_pos('select key: send expression (`ch <- x`) expected', stmt.pos) p.error_with_pos('select key: send expression (`ch <- x`) expected',
stmt.pos)
} }
} }
} }
@ -433,10 +445,13 @@ fn (mut p Parser) select_expr() ast.SelectExpr {
match stmt.right[0] as expr { match stmt.right[0] as expr {
ast.PrefixExpr { ast.PrefixExpr {
if expr.op != .arrow { if expr.op != .arrow {
p.error_with_pos('select key: `<-` operator expected', expr.pos) p.error_with_pos('select key: `<-` operator expected',
expr.pos)
} }
} else { }
p.error_with_pos('select key: receive expression expected', stmt.right[0].position()) else {
p.error_with_pos('select key: receive expression expected',
stmt.right[0].position())
} }
} }
} }

View File

@ -1438,7 +1438,7 @@ fn (mut p Parser) module_decl() ast.Module {
p.error_with_pos('`module` and `$name` must be at same line', pos) p.error_with_pos('`module` and `$name` must be at same line', pos)
} }
pos = p.tok.position() pos = p.tok.position()
if module_pos.line_nr == pos.line_nr { if module_pos.line_nr == pos.line_nr && p.tok.kind != .comment {
if p.tok.kind != .name { if p.tok.kind != .name {
p.error_with_pos('`module x` syntax error', pos) p.error_with_pos('`module x` syntax error', pos)
} else { } else {

View File

@ -283,21 +283,22 @@ fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit {
saved_is_amp := p.is_amp saved_is_amp := p.is_amp
p.is_amp = false p.is_amp = false
for p.tok.kind != .rcbr && p.tok.kind != .rpar { for p.tok.kind != .rcbr && p.tok.kind != .rpar {
comment := p.check_comment()
mut field_name := '' mut field_name := ''
if no_keys { if no_keys {
expr := p.expr(0) expr := p.expr(0)
comments := p.eat_comments()
// name will be set later in checker // name will be set later in checker
fields << ast.StructInitField{ fields << ast.StructInitField{
expr: expr expr: expr
pos: expr.position() pos: expr.position()
comment: comment comments: comments
} }
} else { } else {
first_field_pos := p.tok.position() first_field_pos := p.tok.position()
field_name = p.check_name() field_name = p.check_name()
p.check(.colon) p.check(.colon)
expr := p.expr(0) expr := p.expr(0)
comments := p.eat_comments()
last_field_pos := expr.position() last_field_pos := expr.position()
field_pos := token.Position{ field_pos := token.Position{
line_nr: first_field_pos.line_nr line_nr: first_field_pos.line_nr
@ -308,13 +309,13 @@ fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit {
name: field_name name: field_name
expr: expr expr: expr
pos: field_pos pos: field_pos
comments: comments
} }
} }
i++ i++
if p.tok.kind == .comma { if p.tok.kind == .comma {
p.next() p.next()
} }
p.check_comment()
} }
last_pos := p.tok.position() last_pos := p.tok.position()
if !short_syntax { if !short_syntax {
@ -346,6 +347,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
interface_name := p.prepend_mod(p.check_name()) interface_name := p.prepend_mod(p.check_name())
// println('interface decl $interface_name') // println('interface decl $interface_name')
p.check(.lcbr) p.check(.lcbr)
pre_comments := p.eat_comments()
// Declare the type // Declare the type
reg_idx := p.table.register_type_symbol(table.TypeSymbol{ reg_idx := p.table.register_type_symbol(table.TypeSymbol{
kind: .interface_ kind: .interface_
@ -416,5 +418,6 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
methods: methods methods: methods
is_pub: is_pub is_pub: is_pub
pos: start_pos pos: start_pos
pre_comments: pre_comments
} }
} }