From 4e447db883348116e3cf9cab56aa5a2641a223a3 Mon Sep 17 00:00:00 2001 From: ka-weihe Date: Tue, 23 Jun 2020 18:01:56 +0200 Subject: [PATCH] parser/fmt: fix comments in structs/consts --- vlib/v/ast/ast.v | 35 ++++++------ vlib/v/fmt/fmt.v | 80 +++++++++++++++++++++------- vlib/v/fmt/tests/consts_expected.vv | 4 ++ vlib/v/fmt/tests/consts_input.vv | 4 ++ vlib/v/fmt/tests/structs_expected.vv | 19 +++++++ vlib/v/fmt/tests/structs_input.vv | 18 +++++++ vlib/v/parser/parser.v | 10 ++-- vlib/v/parser/struct.v | 46 +++++++++++++--- 8 files changed, 167 insertions(+), 49 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 685fffb105..616154180f 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -122,7 +122,7 @@ pub struct StructField { pub: name string pos token.Position - comment Comment + comments []Comment default_expr Expr has_default_expr bool attrs []string @@ -141,13 +141,13 @@ pub mut: pub struct ConstField { pub: - name string - expr Expr - is_pub bool - pos token.Position + name string + expr Expr + is_pub bool + pos token.Position pub mut: - typ table.Type - comment Comment + typ table.Type + comments []Comment } pub struct ConstDecl { @@ -160,16 +160,17 @@ pub mut: pub struct StructDecl { pub: - pos token.Position - name string - fields []StructField - is_pub bool - mut_pos int // mut: - pub_pos int // pub: - pub_mut_pos int // pub mut: - language table.Language - is_union bool - attrs []string + pos token.Position + name string + fields []StructField + is_pub bool + mut_pos int // mut: + pub_pos int // pub: + pub_mut_pos int // pub mut: + language table.Language + is_union bool + attrs []string + end_comments []Comment } pub struct InterfaceDecl { diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 133305982c..6c5d99856e 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -498,8 +498,16 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) { f.writeln('$name {') mut max := 0 for field in node.fields { - if field.name.len > max { - max = field.name.len + end_pos := field.pos.pos + field.pos.len + mut comments_len := 0 // Length of comments between field name and type + for comment in field.comments { + if comment.pos.pos >= end_pos { break } + if comment.pos.pos > field.pos.pos { + comments_len += '/* ${comment.text} */ '.len + } + } + if comments_len + field.name.len > max { + max = comments_len + field.name.len } } for i, field in node.fields { @@ -510,13 +518,41 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) { } else if i == node.pub_mut_pos { f.writeln('pub mut:') } - if field.comment.text != '' && field.comment.pos.line_nr < field.pos.line_nr { - // Comment on the previous line - f.write('\t') - f.comment(field.comment) + end_pos := field.pos.pos + field.pos.len + comments := field.comments + if comments.len == 0 { + f.write('\t$field.name ') + f.write(strings.repeat(` `, max - field.name.len)) + f.write(f.type_to_str(field.typ)) + if field.attrs.len > 0 { + f.write(' [' + field.attrs.join(';') + ']') + } + if field.has_default_expr { + f.write(' = ') + f.struct_field_expr(field.default_expr) + } + f.write('\n') + continue + } + // Handle comments before field + mut j := 0 + for j < comments.len && comments[j].pos.pos < field.pos.pos { + f.indent++ + f.empty_line = true + f.comment(comments[j]) + f.indent-- + j++ } f.write('\t$field.name ') - f.write(strings.repeat(` `, max - field.name.len)) + // Handle comments between field name and type + mut comments_len := 0 + for j < comments.len && comments[j].pos.pos < end_pos { + comment := '/* ${comments[j].text} */ ' // TODO: handle in a function + comments_len += comment.len + f.write(comment) + j++ + } + f.write(strings.repeat(` `, max - field.name.len - comments_len)) f.write(f.type_to_str(field.typ)) if field.attrs.len > 0 { f.write(' [' + field.attrs.join(';') + ']') @@ -525,17 +561,19 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) { f.write(' = ') f.struct_field_expr(field.default_expr) } - // f.write('// $field.pos.line_nr') - if field.comment.text != '' && field.comment.pos.line_nr == field.pos.line_nr { - // Same line comment - f.write(' ') - f.comment(field.comment) - } else { - // if field.comment.text != '' { - // f.write (' // com linenr=$field.comment.pos.line_nr') - // } - f.writeln('') + // Handle comments after field type (same line) + for j < comments.len && field.pos.line_nr == comments[j].pos.line_nr{ + f.write(' // ${comments[j].text}') // TODO: handle in a function + j++ } + f.write('\n') + } + // Handle comments after last field + for comment in node.end_comments { + f.indent++ + f.empty_line = true + f.comment(comment) + f.indent-- } f.writeln('}\n') } @@ -1359,9 +1397,11 @@ pub fn (mut f Fmt) const_decl(it ast.ConstDecl) { } f.indent++ for field in it.fields { - if field.comment.text != '' { - f.comment(field.comment) - // f.writeln('// ' + field.comment.text) + comments := field.comments + mut j := 0 + for j < comments.len && comments[j].pos.pos < field.pos.pos { + f.comment(comments[j]) + j++ } name := field.name.after('.') f.write('$name ') diff --git a/vlib/v/fmt/tests/consts_expected.vv b/vlib/v/fmt/tests/consts_expected.vv index 1fcf0b57ec..94288db2e7 100644 --- a/vlib/v/fmt/tests/consts_expected.vv +++ b/vlib/v/fmt/tests/consts_expected.vv @@ -1,6 +1,10 @@ const ( + // pi // pi pi = 3.14 + // phi + // phi + // phi phi = 1.618 // Euler's constant eulers = 2.7182 diff --git a/vlib/v/fmt/tests/consts_input.vv b/vlib/v/fmt/tests/consts_input.vv index 831ab56b82..e54bf59c4a 100644 --- a/vlib/v/fmt/tests/consts_input.vv +++ b/vlib/v/fmt/tests/consts_input.vv @@ -1,6 +1,10 @@ const ( // pi +// pi pi=3.14 +// phi +// phi +// phi phi=1.618 //Euler's constant eulers=2.7182 diff --git a/vlib/v/fmt/tests/structs_expected.vv b/vlib/v/fmt/tests/structs_expected.vv index ae6d0b0e2c..1b3fde3628 100644 --- a/vlib/v/fmt/tests/structs_expected.vv +++ b/vlib/v/fmt/tests/structs_expected.vv @@ -22,3 +22,22 @@ fn new_user() User { age: 19 } } + +struct SomeStruct { +mut: + // 1 + // 2 + // 3 + somefield /* 4 */ /* 5 */ int // 6 // 7 // 8 + /* + 9 +10 + */ + somefield2 /* 11 */ int // 12 +pub: + somefield3 int + /* + 13 +14 + */ +} diff --git a/vlib/v/fmt/tests/structs_input.vv b/vlib/v/fmt/tests/structs_input.vv index 154a80be86..07bf30c51a 100644 --- a/vlib/v/fmt/tests/structs_input.vv +++ b/vlib/v/fmt/tests/structs_input.vv @@ -24,3 +24,21 @@ User age: 19 } } + +struct SomeStruct { +// 1 +mut: +// 2 +// 3 +somefield /*4*/ /*5*/ int /*6*/ /*7*/ /*8*/ /* +9 +10 +*/ +somefield2 /*11*/ int // 12 +pub: +somefield3 int +/* +13 +14 +*/ +} diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index dbd50af7fb..53fa2eefaa 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -471,6 +471,7 @@ pub fn (mut p Parser) comment() ast.Comment { p.next() // p.next_with_comment() return ast.Comment{ + is_multi: text.contains('\n') text: text pos: pos } @@ -1328,9 +1329,10 @@ fn (mut p Parser) const_decl() ast.ConstDecl { p.next() // ( mut fields := []ast.ConstField{} for p.tok.kind != .rpar { - mut comment := ast.Comment{} - if p.tok.kind == .comment { - comment = p.comment() + mut comments := []ast.Comment{} + for p.tok.kind == .comment { + comments << p.comment() + if p.tok.kind == .rpar {break} } pos := p.tok.position() name := p.check_name() @@ -1347,7 +1349,7 @@ fn (mut p Parser) const_decl() ast.ConstDecl { name: full_name expr: expr pos: pos - comment: comment + comments: comments } fields << field p.global_scope.register(field.name, field) diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index e3cf2e6f07..2ff7fc1d8d 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -55,12 +55,18 @@ fn (mut p Parser) struct_decl() ast.StructDecl { mut is_field_mut := false mut is_field_pub := false mut is_field_global := false + mut end_comments := []ast.Comment{} if !no_body { p.check(.lcbr) for p.tok.kind != .rcbr { - mut comment := ast.Comment{} - if p.tok.kind == .comment { - comment = p.comment() + mut comments := []ast.Comment{} + for p.tok.kind == .comment { + comments << p.comment() + if p.tok.kind == .rcbr {break} + } + if p.tok.kind == .rcbr { + end_comments = comments + break } if p.tok.kind == .key_pub { p.next() @@ -104,17 +110,43 @@ fn (mut p Parser) struct_decl() ast.StructDecl { is_field_mut = true is_field_global = true } + for p.tok.kind == .comment { + comments << p.comment() + if p.tok.kind == .rcbr {break} + } field_start_pos := p.tok.position() field_name := p.check_name() // p.warn('field $field_name') + + for p.tok.kind == .comment { + comments << p.comment() + if p.tok.kind == .rcbr {break} + } + + // println(p.tok.position()) typ := p.parse_type() - field_pos := field_start_pos.extend(p.tok.position()) + // field_pos := field_start_pos.extend(p.tok.position()) + field_pos := token.Position{ + line_nr: field_start_pos.line_nr + pos: field_start_pos.pos + len: p.tok.position().pos - field_start_pos.pos + } /* if name == '_net_module_s' { s := p.table.get_type_symbol(typ) println('XXXX' + s.str()) } */ + // Comments after type (same line) + line_pos := field_pos.line_nr + for p.tok.kind == .comment && line_pos + 1 == p.tok.line_nr{ + if p.tok.lit.contains('\n') { + break + } + comments << p.comment() + if p.tok.kind == .rcbr {break} + } + mut attrs := []string{} if p.tok.kind == .lsbr { parsed_attrs := p.attributes(false) @@ -137,15 +169,12 @@ fn (mut p Parser) struct_decl() ast.StructDecl { } has_default_expr = true } - if p.tok.kind == .comment { - comment = p.comment() - } // TODO merge table and ast Fields? ast_fields << ast.StructField{ name: field_name pos: field_pos typ: typ - comment: comment + comments: comments default_expr: default_expr has_default_expr: has_default_expr attrs: attrs @@ -209,6 +238,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { language: language is_union: is_union attrs: p.attrs + end_comments: end_comments } }