diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 068343b710..36bc85c3c2 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -211,8 +211,7 @@ pub fn (mut a array) trim(index int) { } // we manually inline this for single operations for performance without -prod -[inline] -[unsafe] +[inline; unsafe] fn (a array) get_unsafe(i int) voidptr { unsafe { return byteptr(a.data) + i * a.element_size @@ -398,8 +397,7 @@ fn (a &array) slice_clone(start int, _end int) array { } // we manually inline this for single operations for performance without -prod -[inline] -[unsafe] +[inline; unsafe] fn (mut a array) set_unsafe(i int, val voidptr) { unsafe { C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size) } } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index b3681ff55d..90ee9d4ca1 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -761,7 +761,7 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) { has_attrs := field.attrs.len > 0 if has_attrs { f.write(strings.repeat(` `, field_align.max_type_len - field_types[i].len)) - f.inline_attrs(field.attrs) + f.single_line_attrs(field.attrs, inline: true) } if field.has_default_expr { mut align := default_expr_aligns[default_expr_align_i] @@ -1098,24 +1098,43 @@ pub fn (mut f Fmt) or_expr(node ast.OrExpr) { } } -fn (mut f Fmt) attrs(attrs []table.Attr) { - for attr in attrs { +pub fn (mut f Fmt) attrs(attrs []table.Attr) { + mut sorted_attrs := attrs.clone() + // Sort the attributes. The ones with arguments come first. + sorted_attrs.sort(a.arg.len > b.arg.len) + for i, attr in sorted_attrs { + if attr.arg.len == 0 { + f.single_line_attrs(sorted_attrs[i..], {}) + break + } f.writeln('[$attr]') } } -fn (mut f Fmt) inline_attrs(attrs []table.Attr) { +pub struct AttrsOptions { + inline bool +} + +pub fn (mut f Fmt) single_line_attrs(attrs []table.Attr, options AttrsOptions) { if attrs.len == 0 { return } - f.write(' [') - for i, attr in attrs { + mut sorted_attrs := attrs.clone() + sorted_attrs.sort(a.name < b.name) + if options.inline { + f.write(' ') + } + f.write('[') + for i, attr in sorted_attrs { if i > 0 { f.write('; ') } f.write('$attr') } f.write(']') + if !options.inline { + f.writeln('') + } } fn inline_attrs_len(attrs []table.Attr) int { diff --git a/vlib/v/fmt/tests/attrs_expected.vv b/vlib/v/fmt/tests/attrs_expected.vv new file mode 100644 index 0000000000..ec76cea00a --- /dev/null +++ b/vlib/v/fmt/tests/attrs_expected.vv @@ -0,0 +1,4 @@ +[export: 'JNICALL Java_io_vlang_V_callStaticMethods'] +[tom: 'jerry'] +[direct_array_access; inline; unsafe] +fn heavily_tagged() {} diff --git a/vlib/v/fmt/tests/attrs_input.vv b/vlib/v/fmt/tests/attrs_input.vv new file mode 100644 index 0000000000..4190d27689 --- /dev/null +++ b/vlib/v/fmt/tests/attrs_input.vv @@ -0,0 +1,6 @@ +[inline] +[export: 'JNICALL Java_io_vlang_V_callStaticMethods'] +[direct_array_access] +[unsafe] +[tom: 'jerry'] +fn heavily_tagged() {} diff --git a/vlib/v/fmt/tests/attrs_keep.vv b/vlib/v/fmt/tests/attrs_keep.vv index 57788c1046..da2606da89 100644 --- a/vlib/v/fmt/tests/attrs_keep.vv +++ b/vlib/v/fmt/tests/attrs_keep.vv @@ -1,18 +1,23 @@ -[inline] -[if debug] -[foo: bar] [deprecated: 'use bar() instead'] +[foo: bar] +[if debug; inline] fn keep_attributes() { println('hi !') } +[bar: 'foo'] +fn attr_with_arg() {} + +['a_string_name'] +fn name_only_attr() {} + struct User { age int nums []int last_name string [json: lastName] is_registered bool [json: IsRegistered] typ int [json: 'type'] - pets string [raw; json: 'pet_animals'] + pets string [json: 'pet_animals'; raw] } [_allow_multiple_values] diff --git a/vlib/vweb/tests/vweb_test_server.v b/vlib/vweb/tests/vweb_test_server.v index bf1f8ccc56..a956d69e15 100644 --- a/vlib/vweb/tests/vweb_test_server.v +++ b/vlib/vweb/tests/vweb_test_server.v @@ -78,8 +78,7 @@ pub fn (mut app App) user_repo_settings(username string, repository string) vweb return app.html('username: $username | repository: $repository') } -[post] -['/json_echo'] +['/json_echo'; post] pub fn (mut app App) json_echo() vweb.Result { // eprintln('>>>>> received http request at /json_echo is: $app.req') app.set_content_type(app.req.headers['Content-Type'])