From 61b99e19154ca133e9eea1a51a52572b07c8ce16 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 13 Nov 2021 13:41:57 +0200 Subject: [PATCH] vfmt: handle comments right after interface fields --- vlib/v/fmt/fmt.v | 55 +++++++++++-------- .../interface_declaration_comments_keep.vv | 19 +++++++ 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 5b8ceda74d..c8cac39f49 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -1096,43 +1096,50 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) { // TODO: alignment, comments, etc. for field in immut_fields { - mut ft := f.no_cur_mod(f.table.type_to_str_using_aliases(field.typ, f.mod2alias)) - f.writeln('\t$field.name $ft') - f.mark_types_import_as_used(field.typ) + f.interface_field(field) } for method in immut_methods { - f.write('\t') - f.write(method.stringify(f.table, f.cur_mod, f.mod2alias).after('fn ')) - f.comments(method.comments, inline: true, has_nl: false, level: .indent) - f.writeln('') - f.comments(method.next_comments, inline: false, has_nl: true, level: .indent) - for param in method.params { - f.mark_types_import_as_used(param.typ) - } - f.mark_types_import_as_used(method.return_type) + f.interface_method(method) } if mut_fields.len + mut_methods.len > 0 { f.writeln('mut:') for field in mut_fields { - mut ft := f.no_cur_mod(f.table.type_to_str_using_aliases(field.typ, f.mod2alias)) - f.writeln('\t$field.name $ft') - f.mark_types_import_as_used(field.typ) + f.interface_field(field) } for method in mut_methods { - f.write('\t') - f.write(method.stringify(f.table, f.cur_mod, f.mod2alias).after('fn ')) - f.comments(method.comments, inline: true, has_nl: false, level: .indent) - f.writeln('') - f.comments(method.next_comments, inline: false, has_nl: true, level: .indent) - for param in method.params { - f.mark_types_import_as_used(param.typ) - } - f.mark_types_import_as_used(method.return_type) + f.interface_method(method) } } f.writeln('}\n') } +pub fn (mut f Fmt) interface_field(field ast.StructField) { + mut ft := f.no_cur_mod(f.table.type_to_str_using_aliases(field.typ, f.mod2alias)) + end_pos := field.pos.pos + field.pos.len + before_comments := field.comments.filter(it.pos.pos < field.pos.pos) + between_comments := field.comments[before_comments.len..].filter(it.pos.pos < end_pos) + after_type_comments := field.comments[(before_comments.len + between_comments.len)..] + f.write('\t$field.name $ft') + if after_type_comments.len > 0 { + f.comments(after_type_comments, level: .indent) + } else { + f.writeln('') + } + f.mark_types_import_as_used(field.typ) +} + +pub fn (mut f Fmt) interface_method(method ast.FnDecl) { + f.write('\t') + f.write(method.stringify(f.table, f.cur_mod, f.mod2alias).after('fn ')) + f.comments(method.comments, inline: true, has_nl: false, level: .indent) + f.writeln('') + f.comments(method.next_comments, inline: false, has_nl: true, level: .indent) + for param in method.params { + f.mark_types_import_as_used(param.typ) + } + f.mark_types_import_as_used(method.return_type) +} + pub fn (mut f Fmt) mod(mod ast.Module) { f.set_current_module_name(mod.name) if mod.is_skipped { diff --git a/vlib/v/fmt/tests/interface_declaration_comments_keep.vv b/vlib/v/fmt/tests/interface_declaration_comments_keep.vv index 60c8312c77..8a7a6d94f8 100644 --- a/vlib/v/fmt/tests/interface_declaration_comments_keep.vv +++ b/vlib/v/fmt/tests/interface_declaration_comments_keep.vv @@ -29,3 +29,22 @@ interface Bar { // and between foo2() string } + +interface TestsRunner { +mut: + fn_passes u64 + fn_fails u64 + assert_passes u64 + assert_fails u64 + test_fn_info &TestFnMetaInfo // filled in by generated code, before .fn_start() is called. + start(ntests int) // called before all tests, you can initialise private data here. ntests is the number of test functions in the _test.v file. + finish() // called after all tests are finished, you should free all the private data here. + // + fn_start() // called at the start of each test_ function + fn_pass() // called at the end of each test_ function, with no failed assertion + fn_error(line_nr int, file string, mod string, fn_name string, errmsg string) // called only for `fn test_xyz() ? { return error('message') }` + fn_fail() // called at the end of each test_ function, with a failed assertion, *or* returning an error + // + assert_pass(i &AssertMetaInfo) // called for each `assert true` + assert_fail(i &AssertMetaInfo) // called for each `assert false` +}