diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index 2bed68d5a9c037..39fe599921fb19 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -707,12 +707,14 @@ fn (t Tree) attr(node ast.Attr) &Node { obj.add_terse('ast_type', t.string_node('Attr')) obj.add_terse('name', t.string_node(node.name)) obj.add_terse('has_arg', t.bool_node(node.has_arg)) + obj.add_terse('arg', t.string_node(node.arg)) obj.add_terse('kind', t.enum_node(node.kind)) - obj.add_terse('ct_expr', t.expr(node.ct_expr)) obj.add_terse('ct_opt', t.bool_node(node.ct_opt)) + obj.add_terse('has_at', t.bool_node(node.has_at)) + obj.add_terse('ct_expr', t.expr(node.ct_expr)) obj.add_terse('ct_evaled', t.bool_node(node.ct_evaled)) obj.add_terse('ct_skip', t.bool_node(node.ct_skip)) - obj.add_terse('arg', t.string_node(node.arg)) + obj.add('pos', t.pos(node.pos)) return obj } diff --git a/doc/docs.md b/doc/docs.md index ee1e8fac587681..d0349a976e86aa 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -2271,7 +2271,7 @@ It's also possible to define custom default values. ```v struct Foo { - n int [required] + n int @[required] } ``` @@ -4389,12 +4389,12 @@ struct User { // If a field is not [required], but is missing, it will be assumed // to have its default value, like 0 for numbers, or '' for strings, // and decoding will not fail. - name string [required] + name string @[required] age int // Use the `skip` attribute to skip certain fields - foo Foo [skip] + foo Foo @[skip] // If the field name is different in JSON, it can be specified - last_name string [json: lastName] + last_name string @[json: lastName] } data := '{ "name": "Frodo", "lastName": "Baggins", "age": 25 }' @@ -4976,10 +4976,10 @@ import db.sqlite // sets a custom table name. Default is struct name (case-sensitive) @[table: 'customers'] struct Customer { - id int [primary; sql: serial] // a field named `id` of integer type must be the first field - name string [nonull] + id int @[primary; sql: serial] // a field named `id` of integer type must be the first field + name string @[nonull] nr_orders int - country string [nonull] + country string @[nonull] } db := sqlite.connect('customers.db')! @@ -5385,7 +5385,7 @@ module abc pub struct Xyz { pub mut: a int - d int [deprecated: 'use Xyz.a instead'; deprecated_after: '2999-03-01'] + d int @[deprecated: 'use Xyz.a instead'; deprecated_after: '2999-03-01'] // the tags above, will produce a notice, since the deprecation date is in the far future } ``` @@ -7111,4 +7111,4 @@ Assignment Operators += -= *= /= %= &= |= ^= >>= <<= >>>= -``` +``` \ No newline at end of file diff --git a/examples/js_dom_draw_bechmark_chart/v_vweb_orm/src/main.v b/examples/js_dom_draw_bechmark_chart/v_vweb_orm/src/main.v index d2caa0037f2dfe..f2920ec125ef46 100644 --- a/examples/js_dom_draw_bechmark_chart/v_vweb_orm/src/main.v +++ b/examples/js_dom_draw_bechmark_chart/v_vweb_orm/src/main.v @@ -11,7 +11,7 @@ struct App { @[table: 'benchmark'] struct Task { mut: - id u32 [primary; serial; sql: serial] + id u32 @[primary; serial; sql: serial] title string status string } diff --git a/tutorials/building_a_simple_web_blog_with_vweb/README.md b/tutorials/building_a_simple_web_blog_with_vweb/README.md index 9d57ff9b545943..26135053571a1f 100644 --- a/tutorials/building_a_simple_web_blog_with_vweb/README.md +++ b/tutorials/building_a_simple_web_blog_with_vweb/README.md @@ -234,7 +234,7 @@ Create a new file `article.v`: module main struct Article { - id int [primary; sql: serial] + id int @[primary; sql: serial] title string text string } @@ -411,4 +411,4 @@ app is run you will see the articles created from the previous executions To be continued... -For an example of a more sophisticated web app written in V, check out Vorum: https://github.com/vlang/vorum +For an example of a more sophisticated web app written in V, check out Vorum: https://github.com/vlang/vorum \ No newline at end of file diff --git a/vlib/json/README.md b/vlib/json/README.md index 31cb924ebcc69d..6aca285b524079 100644 --- a/vlib/json/README.md +++ b/vlib/json/README.md @@ -21,10 +21,10 @@ enum JobTitle { struct Employee { mut: name string - family string [json: '-'] // this field will be skipped + family string @[json: '-'] // this field will be skipped age int salary f32 - title JobTitle [json: 'ETitle'] // the key for this field will be 'ETitle', not 'title' + title JobTitle @[json: 'ETitle'] // the key for this field will be 'ETitle', not 'title' } fn main() { @@ -43,4 +43,4 @@ fn main() { println('JSON encoding of employee y: ${ss}') assert ss == s } -``` +``` \ No newline at end of file diff --git a/vlib/json/json_encode_recursive_ptr_test.v b/vlib/json/json_encode_recursive_ptr_test.v index 550471edc1ef5e..eb98ba5902077c 100644 --- a/vlib/json/json_encode_recursive_ptr_test.v +++ b/vlib/json/json_encode_recursive_ptr_test.v @@ -4,8 +4,8 @@ struct PostTag { id string parent ?&PostTag visibility string - created_at string [json: 'createdAt'] - metadata string [raw] + created_at string @[json: 'createdAt'] + metadata string @[raw] } fn test_main() { diff --git a/vlib/orm/orm_null_test.v b/vlib/orm/orm_null_test.v index 73514338a9dc28..cd55ab2fb116f5 100644 --- a/vlib/orm/orm_null_test.v +++ b/vlib/orm/orm_null_test.v @@ -101,7 +101,7 @@ fn (db MockDB) last_id() int { @[table: 'foo'] struct Foo { mut: - id u64 [primary; sql: serial] + id u64 @[primary; sql: serial] a string // b string [default: '"yes"'] c ?string @@ -222,7 +222,7 @@ fn test_option_struct_fields_and_none() { } struct Bar { - id u64 [primary; sql: serial] + id u64 @[primary; sql: serial] name ?string age int } diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 097546c1586b3b..b4a64fbae1ee12 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -153,7 +153,7 @@ pub fn (t &Table) fn_type_source_signature(f &Fn) string { sig += ' ?' } else if f.return_type == rvoid_type { sig += ' !' - } else if f.return_type != void_type { + } else if f.return_type != void_type && f.return_type != 0 { return_type_sym := t.sym(f.return_type) if f.return_type.has_flag(.option) { sig += ' ?${return_type_sym.name}' diff --git a/vlib/v/fmt/attrs.v b/vlib/v/fmt/attrs.v index 04177e18b56ab2..bee64da2503716 100644 --- a/vlib/v/fmt/attrs.v +++ b/vlib/v/fmt/attrs.v @@ -17,10 +17,7 @@ pub fn (mut f Fmt) attrs(attrs []ast.Attr) { f.single_line_attrs(sorted_attrs[i..]) break } - if attr.has_at { - f.write('@') - } - f.writeln('[${attr}]') + f.writeln('@[${attr}]') } } @@ -38,10 +35,7 @@ pub fn (mut f Fmt) single_line_attrs(attrs []ast.Attr, options AttrsOptions) { if options.same_line { f.write(' ') } - if attrs[0].has_at { - f.write('@') - } - f.write('[') + f.write('@[') for i, attr in sorted_attrs { if i > 0 { f.write('; ') diff --git a/vlib/v/fmt/fmt_keep_test.v b/vlib/v/fmt/fmt_keep_test.v index 39207ec2eecf62..ef6d7ec2178ce8 100644 --- a/vlib/v/fmt/fmt_keep_test.v +++ b/vlib/v/fmt/fmt_keep_test.v @@ -30,7 +30,7 @@ fn test_fmt() { } vroot := os.dir(vexe) os.chdir(vroot) or {} - basepath := os.join_path(vroot, '') + basepath := vroot + '/' tmpfolder := os.temp_dir() diff_cmd := diff.find_working_diff_command() or { '' } mut fmt_bench := benchmark.new_benchmark() @@ -40,6 +40,7 @@ fn test_fmt() { input_files << keep_input_files input_files << expected_input_files input_files = vtest.filter_vtest_only(input_files, basepath: vroot) + input_files.sort() fmt_bench.set_total_expected_steps(input_files.len + 1) prepare_bin2v_file(mut fmt_bench) for istep, ipath in input_files { diff --git a/vlib/v/fmt/struct.v b/vlib/v/fmt/struct.v index 0d68d817c34b8a..44de9951c0e2ad 100644 --- a/vlib/v/fmt/struct.v +++ b/vlib/v/fmt/struct.v @@ -124,7 +124,8 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) { f.mark_types_import_as_used(field.typ) attrs_len := inline_attrs_len(field.attrs) has_attrs := field.attrs.len > 0 - has_at := if has_attrs { field.attrs[0].has_at } else { false } + // has_at := if has_attrs { field.attrs[0].has_at } else { false } + has_at := true // TODO: this will get removed in next stage if has_attrs && !has_at { f.write(strings.repeat(` `, field_align.max_type_len - field_types[i].len)) diff --git a/vlib/v/fmt/tests/old_attrs_to_new_expected.vv b/vlib/v/fmt/tests/old_attrs_to_new_expected.vv new file mode 100644 index 00000000000000..1089c7f4719805 --- /dev/null +++ b/vlib/v/fmt/tests/old_attrs_to_new_expected.vv @@ -0,0 +1,26 @@ +module main + +import os + +@[export: 'Java_io_vlang_V_callStaticMethods'] +@[tom: 'jerry'] +@[direct_array_access; inline; unsafe] +fn heavily_tagged() {} + +// a console attribute to force-open a console for easier diagnostics on windows +// also it's not safe to use +@[a_console; unsafe] +fn dangerous_console() {} + +@[attribute_on_struct] +struct Generic[T] { + x T @[required] +} + +struct Abc { + f fn () int = fn () int { + return 456 + os.args.len + } @[atr1; atr2] + // + g Generic[int] = Generic[int]{123} @[atr3; atr4] +} diff --git a/vlib/v/fmt/tests/old_attrs_to_new_input.vv b/vlib/v/fmt/tests/old_attrs_to_new_input.vv new file mode 100644 index 00000000000000..b735a5ca9c0ceb --- /dev/null +++ b/vlib/v/fmt/tests/old_attrs_to_new_input.vv @@ -0,0 +1,23 @@ +module main +import os +[inline] +[export: 'Java_io_vlang_V_callStaticMethods'] +[direct_array_access] +[unsafe] +[tom: 'jerry'] +fn heavily_tagged() {} + +[a_console] // a console attribute to force-open a console for easier diagnostics on windows +[unsafe] // also it's not safe to use +fn dangerous_console() {} + +[attribute_on_struct] +struct Generic[T] { + x T [required] +} + +struct Abc { + f fn () int [atr1] = fn () int { return 456 + os.args.len } @[atr2] + // + g Generic[int] [atr3] = Generic[int] { 123 } @[atr4] +} diff --git a/vlib/v/tests/enum_attr_2_test.v b/vlib/v/tests/enum_attr_2_test.v index 2d9d492b1aee31..0558da68656971 100644 --- a/vlib/v/tests/enum_attr_2_test.v +++ b/vlib/v/tests/enum_attr_2_test.v @@ -1,6 +1,6 @@ enum Color { - red = 1 + 1 [json: 'Red'] - blue = 10 / 2 [json: 'Blue'] + red = 1 + 1 @[json: 'Red'] + blue = 10 / 2 @[json: 'Blue'] } fn test_main() { diff --git a/vlib/v/tests/generics_for_in_iterate_test.v b/vlib/v/tests/generics_for_in_iterate_test.v index 7b93f2c7633cd3..8254f0736895e2 100644 --- a/vlib/v/tests/generics_for_in_iterate_test.v +++ b/vlib/v/tests/generics_for_in_iterate_test.v @@ -21,7 +21,7 @@ pub fn (ar &Vec[T]) iter() Iter[T] { pub struct Iter[T] { mut: - v &Vec[T] [required] + v &Vec[T] @[required] pos usize } diff --git a/vlib/v/tests/struct_fields_required_test.v b/vlib/v/tests/struct_fields_required_test.v index 56cd76e86a7e5d..3fd09a39ab4039 100644 --- a/vlib/v/tests/struct_fields_required_test.v +++ b/vlib/v/tests/struct_fields_required_test.v @@ -1,6 +1,6 @@ struct Fns { - f1 fn () [required] - f2 fn () [attr1; required] + f1 fn () @[required] + f2 fn () @[attr1; required] } fn func() { diff --git a/vlib/v/tests/struct_test.v b/vlib/v/tests/struct_test.v index 901e5aa4fb4790..5c6dc46764364c 100644 --- a/vlib/v/tests/struct_test.v +++ b/vlib/v/tests/struct_test.v @@ -360,8 +360,8 @@ fn test_struct_with_default_values_no_init() { } struct FieldsWithOptionVoidReturnType { - f fn () ! [required] - g fn () ? [required] + f fn () ! @[required] + g fn () ? @[required] } fn test_fields_anon_fn_with_option_void_return_type() {