From e2e5cf8db56f3562c7baa735061690be936bdf3e Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Mon, 13 Apr 2026 04:04:28 +0300 Subject: [PATCH] all: super_batch3 fixes --- .gitignore | 1 + ci/macos_ci.vsh | 13 +- cmd/tools/bench/wyhash.v | 3 +- cmd/tools/check_os_api_parity.v | 3 +- cmd/tools/fast/fast_job.v | 3 +- cmd/tools/gen_vc.v | 9 +- cmd/tools/gg_split_memdump_to_frames.vsh | 3 +- cmd/tools/git_pre_commit_hook.vsh | 3 +- cmd/tools/measure/fmt_speed.v | 3 +- cmd/tools/measure/parser_speed.v | 3 +- cmd/tools/measure/scanner_speed.v | 3 +- cmd/tools/modules/testing/common.v | 24 +- cmd/tools/modules/vgit/vgit.v | 27 +- cmd/tools/modules/vshare/clipboard.v | 3 +- cmd/tools/oldv.v | 38 +- cmd/tools/performance_compare.v | 12 +- cmd/tools/regress.v | 6 +- .../report_v_module_folders_without_tests.v | 3 +- cmd/tools/show_ancient_deprecations.v | 9 +- cmd/tools/test_if_v_test_system_works.v | 6 +- cmd/tools/translate.v | 6 +- cmd/tools/vast/vast.v | 15 +- cmd/tools/vbin2v.v | 3 +- cmd/tools/vbug.v | 9 +- cmd/tools/vcheck-md.v | 66 +- cmd/tools/vcheck_test.v | 37 +- cmd/tools/vcomplete.v | 3 +- cmd/tools/vcover/cover_test.v | 18 +- cmd/tools/vcover/main.v | 12 +- cmd/tools/vcreate/tests/init.expect | 2 +- .../init_in_dir_with_invalid_mod_name.expect | 2 +- .../vcreate/tests/init_with_model_arg.expect | 2 +- .../vcreate/tests/new_with_model_arg.expect | 2 +- .../vcreate/tests/new_with_name_arg.expect | 2 +- .../vcreate/tests/new_with_no_arg.expect | 2 +- cmd/tools/vcreate/vcreate_init_test.v | 9 +- cmd/tools/vdoc/document/doc_private_fn_test.v | 3 +- cmd/tools/vdoc/highlight.v | 4 +- cmd/tools/vdoc/html.v | 11 +- cmd/tools/vdoc/run_examples.v | 3 +- cmd/tools/vdoc/vdoc.v | 3 +- cmd/tools/vdoc/vdoc_file_test.v | 6 +- cmd/tools/vdownload.v | 24 +- cmd/tools/vfmt.v | 18 - cmd/tools/vgret.v | 33 +- cmd/tools/vls.v | 15 +- cmd/tools/vmissdoc.v | 18 +- cmd/tools/vpm/common.v | 9 +- cmd/tools/vpm/install_local_test.v | 8 +- cmd/tools/vpm/install_test.v | 12 +- cmd/tools/vpm/install_version_input_test.v | 6 +- cmd/tools/vquest.v | 15 +- cmd/tools/vreduce.v | 21 +- cmd/tools/vrepeat.v | 42 +- cmd/tools/vrepl.v | 10 +- cmd/tools/vretry.v | 6 +- cmd/tools/vschannel_16kb_httpbin_probe.v | 6 +- cmd/tools/vself.v | 3 +- cmd/tools/vsetup-freetype.v | 3 +- cmd/tools/vshader.v | 6 +- cmd/tools/vsqlite/main.v | 6 +- cmd/tools/vsymlink/vsymlink_windows.c.v | 4 +- cmd/tools/vtest-cleancode.v | 10 +- cmd/tools/vtest-parser.v | 18 +- cmd/tools/vtest.v | 6 +- cmd/tools/vtest_test.v | 3 +- cmd/tools/vup.v | 3 +- cmd/tools/vvet/analyze.v | 19 +- cmd/tools/vvet/vet_test.v | 3 +- cmd/tools/vvet/vvet.v | 8 +- cmd/v/v.v | 4 +- cmd/v/vvm_test.v | 11 +- cmd/v2/guiprof/draw.v | 4 +- cmd/v2/test_ssa_backends.v | 3 +- examples/1brc/make-samples/main.v | 3 +- examples/1brc/solution/main.v | 6 +- examples/2048/2048.v | 29 +- examples/archive/tar_gz_reader.v | 21 +- examples/breakout/breakout.v | 10 +- examples/c_interop_wkhtmltopdf.v | 3 +- examples/clock/clock.v | 6 +- examples/database/mysql_pool.v | 6 +- examples/fireworks/modules/objects/particle.v | 4 +- examples/fireworks/modules/objects/rocket.v | 4 +- examples/flappylearning/game.v | 19 +- examples/game_of_life/life.v | 4 - examples/game_of_life/life_gg.v | 4 +- .../modules/automaton/automaton.v | 4 +- examples/gg/15.v | 9 +- examples/gg/arcs_and_slices.v | 9 +- examples/gg/digital_rain.v | 6 +- examples/gg/easing_animation.v | 6 +- examples/gg/fire.v | 1 + examples/gg/grid_of_rectangles.v | 4 +- .../path_finding_algorithm_visualizer/aStar.v | 11 +- examples/gg/pong/pong.v | 6 +- examples/gg/raycaster.v | 6 +- examples/gg/spirograph.v | 7 +- examples/gg/worker_thread.v | 1 - examples/hot_reload/bounce.v | 7 +- examples/hot_reload/graph.v | 1 + examples/js_dom_cube/cube.js.v | 10 +- examples/js_dom_draw/draw.js.v | 5 +- .../chart/draw.js.v | 18 +- .../js_dom_draw_benchmark_chart/chart/main.v | 21 +- examples/lorem.v | 3 +- examples/macos_tray/tray.v | 4 +- examples/password/password_test.v | 6 +- examples/path_tracing.v | 5 +- .../modules/sim/args/parser.v | 51 +- .../modules/sim/params_test.v | 6 +- ...write_and_read_from_a_bash_child_process.v | 3 +- examples/quadtree_demo/quadtree_demo.v | 16 +- examples/readline/readline_test.v | 6 +- examples/snek/snek.js.v | 4 +- examples/snek/snek.v | 14 +- examples/sokol/01_cubes/cube.v | 15 - .../sokol/03_march_tracing_glsl/rt_glsl.v | 3 +- examples/sokol/06_obj_viewer/show_obj.v | 3 +- examples/sokol/fonts.v | 3 +- examples/sokol/freetype_raven.v | 8 - .../sokol/particles/modules/particle/system.v | 10 +- examples/templates/templates.v | 167 ----- examples/term.ui/pong.v | 1 - examples/term.ui/term_drawing.v | 7 +- examples/term.ui/vyper.v | 37 +- examples/tetris/tetris.js.v | 7 +- examples/tetris/tetris.v | 7 +- examples/veb/veb_assets/vweb_assets.v | 2 - examples/viewer/view.v | 3 +- examples/viewer/zip_container.v | 3 +- examples/wasm_codegen/bf_compiler.v | 10 +- examples/wasm_codegen/hello_wasi.v | 5 +- vlib/arrays/arrays_fold_test.v | 2 +- vlib/benchmark/benchmark.v | 3 +- vlib/bitfield/bitfield_test.v | 3 +- vlib/builtin/array.v | 25 +- vlib/builtin/array_d_gcboehm_opt.v | 3 +- vlib/builtin/builtin_windows.c.v | 6 +- vlib/builtin/cfns_wrapper.c.v | 16 +- vlib/builtin/chan_option_result.v | 3 +- vlib/builtin/closure/closure_nix.c.v | 4 +- vlib/builtin/linux_bare/memory_managment.v | 3 +- vlib/builtin/map.v | 9 +- vlib/builtin/map_d_gcboehm_opt.v | 6 +- vlib/builtin/map_notd_gcboehm_opt.v | 12 +- vlib/builtin/prealloc.c.v | 22 +- vlib/builtin/string.v | 2 +- vlib/builtin/string_interpolation.v | 6 +- vlib/builtin/string_strip_margin_test.v | 12 +- vlib/builtin/utf8.c.v | 12 +- vlib/builtin/utf8.v | 2 +- vlib/builtin/vgc_d_vgc.c.v | 3 +- vlib/cli/command.v | 12 +- vlib/cli/help.v | 9 +- vlib/clipboard/clipboard_windows.c.v | 5 +- vlib/clipboard/x11/clipboard.c.v | 30 +- vlib/compress/compress.c.v | 4 +- vlib/compress/szip/szip_test.v | 3 +- vlib/compress/zstd/zstd_test.v | 9 +- vlib/crypto/README.md | 3 +- vlib/crypto/bcrypt/bcrypt_test.v | 3 +- vlib/crypto/blake3/blake3.v | 4 +- vlib/crypto/ecdsa/ecdsa.c.v | 8 +- vlib/crypto/ecdsa/ecdsa.v | 3 +- vlib/crypto/ecdsa/example/ecdsa_seed_test.v | 3 +- vlib/crypto/ecdsa/util_test.v | 6 +- .../internal/edwards25519/element_test.v | 6 +- .../internal/edwards25519/scalar_test.v | 3 +- vlib/crypto/hmac/hmac.v | 3 +- vlib/crypto/hmac/hmac_test.v | 12 +- vlib/crypto/pbkdf2/pbkdf2_test.v | 6 +- vlib/crypto/pem/decode.v | 3 +- vlib/crypto/rand/rand_linux.c.v | 2 + vlib/db/mssql/mssql.c.v | 16 +- vlib/db/mssql/stmt_handle.c.v | 15 +- vlib/db/mysql/mysql_test.v | 6 +- vlib/db/mysql/orm.c.v | 12 +- vlib/db/pg/orm.v | 7 +- vlib/db/pg/pg.c.v | 41 +- vlib/db/sqlite/orm.v | 12 +- vlib/db/sqlite/sqlite.c.v | 9 +- vlib/db/sqlite/vfs_lowlevel.c.v | 64 +- vlib/dlmalloc/dlmalloc.v | 12 +- vlib/encoding/base64/base64.c.v | 10 +- vlib/encoding/binary/little_endian_test.v | 15 +- vlib/encoding/binary/stream.v | 18 + vlib/encoding/csv/README_csv_reader.md | 3 +- vlib/encoding/csv/csv_reader_test.v | 3 +- vlib/encoding/iconv/iconv_windows.c.v | 8 +- vlib/encoding/utf8/utf8_util.v | 2 +- vlib/encoding/vorbis/vorbis.v | 3 +- .../12_doctype_entity/spec_entity_test.v | 3 +- vlib/fasthttp/fasthttp_darwin.v | 7 +- vlib/fasthttp/fasthttp_linux.v | 8 +- vlib/fasthttp/fasthttp_windows.v | 2 +- vlib/flag/default_flag_options_test.v | 3 +- vlib/flag/flag.v | 4 +- vlib/flag/flag_parse_test.v | 3 +- vlib/flag/flag_test.v | 9 +- vlib/flag/flag_to.v | 62 +- vlib/flag/usage_example_test.v | 3 +- vlib/gg/bezier.c.v | 4 +- vlib/gg/draw.c.v | 27 +- vlib/gg/draw_rect_empty_test.v | 3 +- vlib/gg/gg.c.v | 16 +- vlib/gg/gg.js.v | 3 +- vlib/gg/gg_ui.c.v | 4 +- vlib/gg/image.c.v | 4 +- .../goroutines/examples/goroutine_benchmark.v | 6 +- vlib/hash/hash_compiles_test.v | 3 +- .../tests/json_decode_with_sumtype_test.v | 14 +- vlib/json/tests/json_encode_enum_test.v | 3 +- vlib/json/tests/json_generic_array_test.v | 3 +- vlib/json/tests/json_raw_test.v | 3 +- vlib/json/tests/json_test.v | 12 +- vlib/math/big/division_array_ops.v | 4 +- vlib/math/bits/bits_test.v | 3 +- vlib/math/erf_test.v | 13 +- vlib/math/fractions/approximations_test.v | 63 +- vlib/math/gamma.v | 40 +- vlib/math/interpolation_bezier.v | 3 +- vlib/math/invtrig.v | 4 +- vlib/math/unsigned/uint256.v | 9 +- vlib/math/unsigned/uint256_test.v | 6 +- vlib/net/address.c.v | 3 +- vlib/net/errors.c.v | 3 + vlib/net/http/backend.c.v | 3 +- vlib/net/http/cookie.v | 6 +- vlib/net/http/file/static_server.v | 4 +- vlib/net/http/http_proxy.v | 7 +- vlib/net/http/http_proxy_test.v | 6 +- vlib/net/http/request_receive_test.v | 3 +- vlib/net/http/request_test.v | 3 +- vlib/net/jsonrpc/jsonrpc.v | 6 +- vlib/net/mbedtls/mbedtls.c.v | 6 +- vlib/net/mbedtls/ssl_connection.c.v | 35 +- vlib/net/openssl/openssl.c.v | 3 +- vlib/net/openssl/ssl_connection.c.v | 8 +- vlib/net/smtp/smtp.v | 9 +- vlib/net/smtp/smtp_timeout_test.v | 2 +- vlib/net/tcp.c.v | 6 +- vlib/net/unix/stream.c.v | 9 +- vlib/net/urllib/urllib.v | 6 +- vlib/net/urllib/urllib_test.v | 6 +- vlib/net/websocket/handshake.v | 9 +- vlib/orm/orm.v | 3 +- vlib/orm/orm_fn_test.v | 4 +- vlib/orm/orm_func.v | 4 +- vlib/orm/orm_func_test.v | 4 +- vlib/orm/orm_mut_connection_test.v | 8 +- vlib/orm/orm_null_test.v | 7 +- vlib/os/dir_expansions_test.v | 3 +- vlib/os/filelock/lib_nix.c.v | 3 +- vlib/os/filelock/lib_windows.c.v | 7 +- vlib/os/os.c.v | 6 +- vlib/os/os_test.c.v | 6 +- vlib/os/os_windows.c.v | 21 +- vlib/os/process_args_test.v | 3 +- vlib/os/process_windows.c.v | 27 +- vlib/picoev/loop_freebsd.c.v | 10 +- vlib/picoev/loop_macos.c.v | 10 +- vlib/picoev/loop_openbsd.c.v | 10 +- vlib/picoev/socket_util.c.v | 7 +- vlib/regex/pcre/regex.v | 3 +- vlib/regex/regex.v | 5 +- vlib/sokol/memory/memory.c.v | 3 +- vlib/sokol/sapp/sapp.c.v | 12 + vlib/sokol/sapp/sapp_egl_linux.v | 8 +- vlib/sokol/sapp/sapp_state_linux.v | 4 +- vlib/sokol/sapp/sapp_wayland_linux.v | 45 +- vlib/sokol/sapp/sapp_x11_linux.v | 112 +-- vlib/stbi/stbi.c.v | 10 +- vlib/strconv/f64_str.c.v | 3 +- vlib/strconv/f64_str.js.v | 3 +- vlib/strconv/vprintf.c.v | 3 +- vlib/strings/builder.c.v | 9 +- vlib/sync/channels.c.v | 14 +- vlib/sync/waitgroup_test.v | 2 +- vlib/term/ui/input_windows.c.v | 2 +- vlib/time/custom_format_test.v | 3 +- vlib/time/date_time_parser.v | 45 +- vlib/time/parse.c.v | 10 +- vlib/time/time_test.v | 9 +- vlib/time/unix.v | 3 +- vlib/toml/parser/parser.v | 120 ++-- vlib/toml/scanner/scanner.v | 87 ++- vlib/toml/tests/iarna_toml_spec_test.v | 15 +- vlib/toml/tests/large_toml_file_test.v | 3 +- vlib/toml/tests/toml_bom_test.v | 15 +- vlib/toml/tests/toml_lang_test.v | 10 +- vlib/toml/tests/toml_rs_test.v | 5 +- vlib/toml/toml.v | 29 +- vlib/v/ast/ast.v | 24 +- vlib/v/ast/cflags_test.v | 3 +- vlib/v/ast/scope.v | 8 + vlib/v/ast/str.v | 3 +- vlib/v/ast/table.v | 218 +++++- vlib/v/builder/builder.v | 9 +- vlib/v/builder/builder_test.v | 6 +- vlib/v/builder/cbuilder/parallel_cc.v | 3 +- vlib/v/builder/cc.v | 107 ++- vlib/v/builder/cc_test.v | 22 +- vlib/v/builder/compile.v | 17 +- vlib/v/builder/msvc_windows.v | 22 +- vlib/v/builder/parallel_cc_failure_test.v | 21 +- vlib/v/builder/rebuilding.v | 3 +- vlib/v/checker/assign.v | 27 +- vlib/v/checker/autocomplete.v | 9 +- vlib/v/checker/check_types.v | 68 +- vlib/v/checker/checker.v | 509 ++++++++----- vlib/v/checker/comptime.v | 42 +- vlib/v/checker/containers.v | 19 +- vlib/v/checker/errors.v | 3 +- vlib/v/checker/fn.v | 212 +++--- vlib/v/checker/for.v | 6 +- vlib/v/checker/if.v | 45 +- vlib/v/checker/infix.v | 44 +- vlib/v/checker/interface.v | 12 +- vlib/v/checker/lambda_expr.v | 3 +- vlib/v/checker/match.v | 100 ++- vlib/v/checker/orm.v | 79 +- vlib/v/checker/postfix.v | 3 +- vlib/v/checker/return.v | 16 +- vlib/v/checker/str.v | 29 +- vlib/v/checker/struct.v | 67 +- vlib/v/checker/tests/anon_fn_without_body.out | 4 +- .../checker/tests/array_declare_element_a.out | 2 +- .../checker/tests/array_declare_element_b.out | 2 +- .../checker/tests/array_declare_element_c.out | 2 +- .../tests/array_filter_arg_mismatch_err.out | 6 +- .../array_init_decompose_extra_params.out | 4 +- .../tests/array_init_with_void_value_err.out | 2 +- .../array_of_generic_struct_init_err.out | 4 +- vlib/v/checker/tests/asm_immutable_err.out | 6 +- vlib/v/checker/tests/assert_option_err.out | 4 +- ...assign_anon_struct_to_typed_struct_err.out | 2 +- .../tests/assign_var_redefinition_err.out | 2 +- .../tests/c_binding_confusable_c_err.out | 2 +- vlib/v/checker/tests/cast_expr_T_type_err.out | 2 +- .../tests/cast_sumtype_as_generic_err.out | 4 +- vlib/v/checker/tests/cast_sumtype_err.out | 4 +- .../checker/tests/cast_to_ref_struct_err.out | 2 +- .../tests/cast_voidptr_to_struct_err.out | 4 +- .../tests/clash_ident_module_name_prefix.out | 8 +- .../tests/closure_undefined_ident_err.out | 2 +- .../checker/tests/compare_unsigned_signed.out | 6 +- .../tests/comptime_call_method_args_err.out | 2 +- .../v/checker/tests/deference_nil_ptr_err.out | 2 +- .../tests/enum_field_value_overflow.out | 8 +- .../tests/enum_from_string_args_err.out | 2 +- vlib/v/checker/tests/enum_init_err.out | 2 +- .../checker/tests/eq_ne_op_wrong_type_err.out | 12 +- .../tests/fixed_array_init_with_default.out | 2 +- .../fn_array_decompose_arg_mismatch_err_b.out | 2 +- .../tests/fn_call_arg_mismatch_err_d.out | 2 +- .../tests/fn_ptr_undereferenced_err.out | 2 +- .../checker/tests/fn_return_type_mismatch.out | 2 +- vlib/v/checker/tests/fn_selector_expr_err.out | 6 +- vlib/v/checker/tests/for_in_index_option.out | 4 +- .../checker/tests/for_in_key_redefinition.out | 2 +- vlib/v/checker/tests/for_in_mut_string.out | 4 +- .../tests/for_in_value_redefinition.out | 2 +- vlib/v/checker/tests/for_match_err.out | 14 +- .../tests/generic_closure_fn_decl_err_a.out | 2 +- ...od_call_with_short_syntax_fn_field_err.out | 7 + .../tests/generic_sumtype_decl_err_b.out | 4 +- ...nerics_fn_called_outside_of_generic_fn.out | 2 +- ...nerics_fn_called_variadic_arg_mismatch.out | 2 +- .../generics_inst_non_generic_struct_err.out | 2 +- ...generics_interface_decl_no_mention_err.out | 2 +- ...generic_struct_used_like_a_generic_one.out | 4 +- .../tests/generics_ref_array_arg_mismatch.out | 22 +- .../tests/generics_ref_array_arg_mismatch.vv | 16 +- .../generics_struct_decl_no_mention_err.out | 2 +- .../tests/generics_struct_declaration_err.out | 2 +- .../generics_struct_in_non_generic_fn_err.out | 2 +- .../tests/generics_struct_infer_err.out | 2 +- .../generics_struct_type_mismatch_err.out | 2 +- .../tests/generics_undefined_operation.out | 2 +- .../globals/closure_capture_global_var.out | 2 +- .../tests/globals/nested_unknown_typ.out | 2 +- vlib/v/checker/tests/if_expr_option_err.out | 4 +- vlib/v/checker/tests/if_guard_expr_err.out | 2 +- vlib/v/checker/tests/if_match_expr_err.out | 14 +- .../checker/tests/implements_generic_err.out | 6 +- vlib/v/checker/tests/implements_keyword.out | 6 +- .../v/checker/tests/import_mod_as_mod_err.out | 10 +- .../tests/import_sym_builtin_override_err.out | 6 +- .../checker/tests/import_symbol_type_err.out | 4 +- vlib/v/checker/tests/inc_dec_fun_call.out | 4 +- .../tests/incorrect_smartcast2_err.out | 14 + ...ex_sumtype_interface_struct_params_err.out | 8 +- .../tests/infix_compare_option_err.out | 2 +- vlib/v/checker/tests/infix_err.out | 36 +- .../interface_implemented_by_function.out | 4 +- ...ace_sameness_check_for_mutable_methods.out | 2 +- .../checker/tests/invalid_vweb_param_type.out | 70 ++ .../tests/map_index_reference_value.out | 6 +- .../tests/map_of_generic_struct_init_err.out | 4 +- .../match_type_node_with_non_sum_type_err.out | 2 +- .../missing_import_or_block_path_err.out | 16 +- .../tests/missing_import_or_block_path_err.vv | 2 + .../tests/non_matching_functional_args.out | 2 +- vlib/v/checker/tests/none_type_cast_err.out | 150 ++-- .../tests/option_in_println_mismatch.out | 4 +- .../tests/option_or_block_mismatch.out | 6 +- ...rm_right_side_field_ref_in_where_error.out | 2 +- vlib/v/checker/tests/pass_mut_lit.out | 2 +- .../v/checker/tests/result_alias_type_err.out | 2 +- .../tests/short_struct_wrong_number.out | 2 +- .../slice_clone_in_struct_init_notice.out | 4 +- vlib/v/checker/tests/slice_clone_notice.out | 8 +- .../tests/str_interpol_invalid_err.out | 110 +-- .../string_interpolation_invalid_fmt.out | 2 +- .../tests/struct_multiple_attrs_test.out | 2 +- vlib/v/checker/tests/struct_scope_err.out | 2 +- .../tests/sum_type_multiple_type_define.out | 2 +- .../tests/sumtype_of_fntype_assign_err.out | 2 +- .../checker/tests/template_call_position.out | 4 +- .../tests/top_level_fn_builtin_decl_err.out | 22 +- ..._alias_struct_generic_unknown_name_err.out | 4 +- .../tests/undeclared_c_identifier_err.out | 6 - .../tests/undeclared_c_identifier_err.vv | 5 - .../undefined_ident_in_if_guard_err_a.out | 2 +- .../tests/undefined_type_on_sumtype.out | 2 +- vlib/v/checker/tests/unknown_method.out | 2 +- vlib/v/checker/tests/unknown_struct_name.out | 2 +- .../checker/tests/unwrapped_option_infix.out | 2 +- ...use_byte_instead_of_u8_array_param_err.out | 2 +- .../tests/use_byte_instead_of_u8_err.out | 8 +- vlib/v/checker/tests/var_duplicate_const.out | 15 + vlib/v/checker/tests/vweb_missing_result.out | 49 ++ vlib/v/checker/tests/vweb_routing_checks.out | 70 ++ vlib/v/checker/tests/vweb_tmpl_used_var.out | 70 ++ ...wrong_type_casted_fixed_array_size_err.out | 4 +- vlib/v/checker/used_features.v | 6 +- vlib/v/compiler_errors_test.v | 9 +- vlib/v/debug/interactive_test.v | 7 +- vlib/v/depgraph/depgraph.v | 2 +- vlib/v/eval/expr.c.v | 6 +- vlib/v/eval/stmt.v | 4 +- vlib/v/eval/tests/push_val_test.v | 3 +- vlib/v/eval/var.v | 4 +- vlib/v/fmt/fmt.v | 37 +- vlib/v/fmt/struct.v | 40 +- vlib/v/fmt/tests/additive_infix_wrap_input.vv | 6 +- vlib/v/fmt/tests/long_assign_wrap_input.vv | 9 +- vlib/v/gen/c/array.v | 41 +- vlib/v/gen/c/assign.v | 81 ++- vlib/v/gen/c/auto_eq_methods.v | 4 +- vlib/v/gen/c/auto_str_methods.v | 44 +- vlib/v/gen/c/cgen.v | 675 +++++++++++------- vlib/v/gen/c/cheaders.v | 3 +- vlib/v/gen/c/cmain.v | 3 +- vlib/v/gen/c/comptime.v | 28 +- vlib/v/gen/c/consts_and_globals.v | 9 +- vlib/v/gen/c/coutput_test.v | 6 +- vlib/v/gen/c/coverage.v | 3 +- vlib/v/gen/c/custom_start_freestanding_test.v | 11 +- vlib/v/gen/c/dumpexpr.v | 40 +- vlib/v/gen/c/fn.v | 530 +++++++++++--- vlib/v/gen/c/for.v | 6 +- vlib/v/gen/c/if.v | 9 +- vlib/v/gen/c/infix.v | 119 +-- vlib/v/gen/c/json.v | 46 +- vlib/v/gen/c/or_block_line_info_test.v | 3 +- vlib/v/gen/c/orm.v | 39 +- vlib/v/gen/c/reflection.v | 25 +- vlib/v/gen/c/spawn_and_go.v | 33 +- vlib/v/gen/c/struct.v | 30 +- .../c_extern_on_C_global_declarations.vv | 4 +- .../testdata/freestanding_module_import_2.out | 1 + .../freestanding_net_const_memcpy.c.must_have | 8 +- ...face_method_embed_ptr_receiver.c.must_have | 4 +- .../iface_method_mut_receiver.c.must_have | 6 +- .../c/testdata/sumtype_pass_by_reference.out | 40 +- vlib/v/gen/c/utils.v | 70 +- vlib/v/gen/golang/golang.v | 6 +- vlib/v/gen/golang/struct.v | 3 +- vlib/v/gen/golang/tests/golang_test.v | 3 +- vlib/v/gen/js/auto_str_methods.v | 24 + vlib/v/gen/js/global_export_test.v | 3 +- vlib/v/gen/js/js.v | 97 +-- vlib/v/gen/js/jsgen_test.v | 9 +- vlib/v/gen/js/sourcemap/source_map.v | 4 +- vlib/v/gen/native/amd64.v | 33 +- vlib/v/gen/native/elf.v | 22 +- vlib/v/gen/native/gen.v | 3 +- vlib/v/gen/native/pe.v | 13 +- vlib/v/gen/native/readdll.c.v | 3 +- vlib/v/gen/native/stmt.c.v | 8 +- vlib/v/gen/wasm/gen.v | 15 +- vlib/v/gen/wasm/mem.v | 7 +- vlib/v/gen/wasm/tests/wasm_test.v | 3 +- vlib/v/generics/generics.v | 22 +- .../v/generics/new_generics_regression_test.v | 41 +- vlib/v/live/live_test.v | 4 +- vlib/v/markused/markused.v | 20 +- vlib/v/markused/walker.v | 480 +++++++++++-- vlib/v/parser/asm.v | 3 +- vlib/v/parser/attribute.v | 3 +- vlib/v/parser/codegen.v | 3 +- vlib/v/parser/comptime.v | 17 +- vlib/v/parser/containers.v | 3 +- vlib/v/parser/expr.v | 9 +- vlib/v/parser/fn.v | 33 +- vlib/v/parser/if_match.v | 6 +- vlib/v/parser/lock.v | 4 + vlib/v/parser/messages.v | 34 +- vlib/v/parser/module.v | 6 +- vlib/v/parser/orm.v | 12 +- vlib/v/parser/parse_type.v | 15 +- vlib/v/parser/parser.v | 58 +- vlib/v/parser/struct.v | 23 +- vlib/v/parser/tmpl.v | 15 +- vlib/v/parser/v_print_v_files_works_test.v | 3 +- vlib/v/parser/v_silent_works_test.v | 3 +- vlib/v/pkgconfig/bin/pkgconfig_test.v | 3 +- vlib/v/pkgconfig/main.v | 15 +- vlib/v/pref/arch.c.v | 2 +- vlib/v/pref/default.v | 64 +- vlib/v/pref/options_test.v | 3 +- vlib/v/pref/pref.v | 31 +- vlib/v/pref/pref_test.v | 60 +- vlib/v/pref/vsh_envbang_test.v | 3 +- vlib/v/scanner/scanner.v | 3 +- vlib/v/slow_tests/inout/compiler_test.v | 3 +- vlib/v/slow_tests/profile/profile_test.v | 3 +- vlib/v/slow_tests/repl/repl_test.v | 5 +- vlib/v/slow_tests/run_project_folders_test.v | 3 +- .../valgrind/1.strings_and_arrays.v | 6 +- vlib/v/tests/bench/math_big_gcd/prime/maker.v | 2 +- .../array_filter_using_direct_closure_test.v | 2 +- .../array_fixed_op_overload_test.v | 8 +- ...array_ops_create_just_one_closure_test.c.v | 3 + .../comptime_else_map_init_markused_test.v | 4 +- .../comptime_indirection_check_test.v | 3 +- .../comptime_ppc_closure_codegen_test.v | 3 +- .../matches/match_with_return_result_test.v | 3 +- .../tests/fns/anon_fn_with_alias_args_test.v | 4 +- vlib/v/tests/fns/fn_index_direct_call_test.v | 8 +- .../fns/lambda_expr_with_mut_param_test.v | 4 +- vlib/v/tests/generics/generic_array_test.v | 3 +- vlib/v/tests/generics/generics_test.v | 3 +- vlib/v/tests/interfaces/interface_arg_test.v | 2 +- .../vmodules_overrides_test.v | 3 +- .../options/option_call_on_orexpr_test.v | 3 +- vlib/v/tests/options/option_if_option_test.v | 3 +- vlib/v/tests/parse_invalid_map_type_test.v | 3 +- vlib/v/tests/printing/print_option_ref_test.v | 6 +- ...to_wasm_works_with_d_and_notd_files_test.v | 3 +- .../tests/projects_that_should_compile_test.v | 38 +- .../relative_nested_module_lookup_test.v | 9 +- .../skip_unused/nested_generics_method.vv | 1 + .../tests/structs/struct_field_fn_call_test.v | 2 +- vlib/v/tests/structs/struct_test.v | 3 +- .../sumtypes/init_multiple_branches_test.v | 3 +- vlib/v/tests/vls/autocomplete_module_test.v | 3 +- vlib/v/tests/vls/goto_def_test.v | 3 +- vlib/v/type_resolver/comptime_resolver.v | 3 +- vlib/v/type_resolver/type_resolver.v | 4 +- vlib/v/util/module.v | 29 +- vlib/v/util/util.v | 9 +- vlib/v/vcache/vcache.v | 3 +- vlib/v2/builder/builder.v | 54 +- vlib/v2/builder/cache_headers.v | 7 +- vlib/v2/builder/ssa_build_parallel.v | 3 +- vlib/v2/eval/eval.v | 27 +- vlib/v2/eval/eval_test.v | 21 +- vlib/v2/gen/arm64/arm64.v | 136 ++-- vlib/v2/gen/cleanc/array.v | 3 +- vlib/v2/gen/cleanc/cleanc.v | 3 +- vlib/v2/gen/cleanc/expr.v | 4 +- vlib/v2/gen/cleanc/fn.v | 82 +-- vlib/v2/gen/cleanc/stmt.v | 11 +- vlib/v2/gen/cleanc/struct.v | 5 +- vlib/v2/gen/x64/elf.v | 12 +- vlib/v2/gen/x64/x64.v | 6 +- vlib/v2/markused/markused.v | 3 +- vlib/v2/ssa/builder.v | 183 +++-- vlib/v2/ssa/optimize/mem2reg.v | 7 +- vlib/v2/ssa/optimize/phi.v | 4 +- vlib/v2/transformer/expr.v | 51 +- vlib/v2/transformer/fn.v | 16 +- vlib/v2/transformer/for.v | 11 +- vlib/v2/transformer/if.v | 5 +- vlib/v2/transformer/struct.v | 6 +- vlib/v2/transformer/transformer.v | 62 +- vlib/v2/types/checker.v | 17 +- vlib/veb/context.v | 14 +- vlib/veb/controller.v | 4 +- vlib/veb/csrf/csrf.v | 3 +- vlib/veb/static_handler.v | 3 +- vlib/veb/tests/memory_leak_test.v | 3 +- vlib/veb/tests/veb_test.v | 6 +- vlib/veb/veb.v | 7 +- vlib/veb/veb_d_new_veb.v | 7 +- vlib/veb/veb_picoev.v | 19 +- vlib/vweb/csrf/csrf.v | 3 +- vlib/vweb/tests/controller_test.v | 6 +- vlib/vweb/tests/middleware_test.v | 3 +- vlib/vweb/vweb.v | 12 +- vlib/wasm/tests/common.v | 3 +- vlib/wasm/tests/debug_test.v | 5 +- vlib/x/crypto/ascon/examples/use_of_cxof.v | 6 +- vlib/x/crypto/ascon/examples/use_of_xof.v | 6 +- vlib/x/crypto/chacha20poly1305/bench/bench.v | 6 +- .../chacha20poly1305/chacha20poly1305_test.v | 18 +- vlib/x/crypto/chacha20poly1305/psiv.v | 3 +- vlib/x/crypto/chacha20poly1305/usage_test.v | 12 +- .../chacha20poly1305/xchacha20poly1305_test.v | 6 +- vlib/x/crypto/mldsa/mldsa_test.v | 3 +- vlib/x/crypto/mldsa/ntt.v | 6 +- vlib/x/crypto/poly1305/usage_test.v | 3 +- vlib/x/crypto/slhdsa/base_test.v | 3 +- vlib/x/crypto/slhdsa/const.c.v | 28 +- vlib/x/encoding/asn1/README.md | 3 +- vlib/x/encoding/asn1/examples/examples2.v | 21 +- vlib/x/encoding/asn1/integer_test.v | 3 +- vlib/x/encoding/asn1/sequence_test.v | 3 +- vlib/x/json2/decode.v | 55 +- vlib/x/json2/decode_sumtype.v | 3 +- vlib/x/json2/encode.v | 56 +- vlib/x/json2/scanner.v | 13 +- vlib/x/json2/strict/strict.v | 10 +- .../tests/encode_embedded_structs_test.v | 3 +- vlib/x/sessions/memory_store.v | 2 +- .../templating/dtm/dynamic_template_manager.v | 22 +- ...namic_template_manager_cache_system_test.v | 3 +- .../dtm/dynamic_template_manager_test.v | 19 +- vlib/x/templating/dtm/tmpl.v | 6 +- vlib/x/ttf/render_bmp.v | 14 +- vlib/x/ttf/ttf.v | 10 +- 634 files changed, 6379 insertions(+), 4284 deletions(-) delete mode 100644 vlib/v/checker/tests/undeclared_c_identifier_err.out delete mode 100644 vlib/v/checker/tests/undeclared_c_identifier_err.vv diff --git a/.gitignore b/.gitignore index 73cbd990fa..3370af3bf0 100644 --- a/.gitignore +++ b/.gitignore @@ -173,3 +173,4 @@ issue* # ignore cmd2/v stuff cmd/v2/*.txt cmd/v2/*.json +.claude/ diff --git a/ci/macos_ci.vsh b/ci/macos_ci.vsh index f6b2a68261..a1f56264b2 100644 --- a/ci/macos_ci.vsh +++ b/ci/macos_ci.vsh @@ -1,4 +1,5 @@ import common { Task, exec } +import os fn test_symlink() { exec('v symlink') @@ -17,7 +18,8 @@ fn all_code_is_formatted() { if common.is_github_job { exec('VJOBS=1 v -silent test-cleancode') } else { - exec('v -progress test-cleancode') + vjobs := os.getenv_opt('VJOBS') or { '1' } + exec('VJOBS=${vjobs} v -progress test-cleancode') } } @@ -38,7 +40,11 @@ fn verify_v_test_works() { } fn install_iconv() { - exec('brew install libiconv') + // Skip Homebrew when iconv is already linkable for V on this machine. + if os.system('v -silent test vlib/encoding/iconv/') == 0 { + return + } + exec('brew list --versions libiconv >/dev/null 2>&1 || brew install libiconv') } fn test_pure_v_math_module() { @@ -49,7 +55,8 @@ fn self_tests() { if common.is_github_job { exec('VJOBS=1 v -silent test-self vlib') } else { - exec('v -progress test-self vlib') + vjobs := os.getenv_opt('VJOBS') or { '1' } + exec('VJOBS=${vjobs} v -progress test-self vlib') } } diff --git a/cmd/tools/bench/wyhash.v b/cmd/tools/bench/wyhash.v index 04bc5f6123..be6ebc2c6b 100644 --- a/cmd/tools/bench/wyhash.v +++ b/cmd/tools/bench/wyhash.v @@ -30,8 +30,7 @@ fn main() { checksum = 0 for len in str_lens { end_pos := start_pos + len - checksum ^= wyhash.wyhash_c(unsafe { &u8(bytepile.data) + start_pos }, u64(len), - 1) + checksum ^= wyhash.wyhash_c(unsafe { &u8(bytepile.data) + start_pos }, u64(len), 1) start_pos = end_pos } bhashing_1.measure('wyhash.wyhash_c | checksum: ${checksum:22}') diff --git a/cmd/tools/check_os_api_parity.v b/cmd/tools/check_os_api_parity.v index 18eee491dd..f03a8f717d 100644 --- a/cmd/tools/check_os_api_parity.v +++ b/cmd/tools/check_os_api_parity.v @@ -55,8 +55,7 @@ fn main() { } } if diff_modules.len > 0 { - eprintln(term.header('Found ${diff_modules.len} modules with different APIs', - '=')) + eprintln(term.header('Found ${diff_modules.len} modules with different APIs', '=')) for m in diff_modules.keys() { eprintln('Module: ${m}') } diff --git a/cmd/tools/fast/fast_job.v b/cmd/tools/fast/fast_job.v index 542bf01fde..a493f0f851 100644 --- a/cmd/tools/fast/fast_job.v +++ b/cmd/tools/fast/fast_job.v @@ -62,7 +62,8 @@ fn main() { elog('fast_job clone output repos...') check_output_repo('https://github.com/vlang/website', 'gh-pages', 'fast.vlang.io/') check_output_repo('https://github.com/vlang/docs/', 'main', 'docs.vlang.io/') - check_output_repo('https://github.com/vlang/docs/', 'generator', 'docs.vlang.io/docs_generator/') + check_output_repo('https://github.com/vlang/docs/', 'generator', + 'docs.vlang.io/docs_generator/') mut i := 0 for { diff --git a/cmd/tools/gen_vc.v b/cmd/tools/gen_vc.v index a704889fbd..d745ba5131 100644 --- a/cmd/tools/gen_vc.v +++ b/cmd/tools/gen_vc.v @@ -230,8 +230,10 @@ fn (mut gen_vc GenVC) generate() { gen_vc.cmd_exec('git clone --filter=blob:none https://${git_repo_v} ${git_repo_dir_v}') gen_vc.cmd_exec('git clone --filter=blob:none https://${git_repo_vc} ${git_repo_dir_vc}') // get output of git log -1 (last commit) - git_log_v := gen_vc.cmd_exec('git -C ${git_repo_dir_v} log -1 --format="commit %H%nDate: %ci%nDate Unix: %ct%nSubject: %s"') - git_log_vc := gen_vc.cmd_exec('git -C ${git_repo_dir_vc} log -1 --format="Commit %H%nDate: %ci%nDate Unix: %ct%nSubject: %s"') + git_log_v := + gen_vc.cmd_exec('git -C ${git_repo_dir_v} log -1 --format="commit %H%nDate: %ci%nDate Unix: %ct%nSubject: %s"') + git_log_vc := + gen_vc.cmd_exec('git -C ${git_repo_dir_vc} log -1 --format="Commit %H%nDate: %ci%nDate Unix: %ct%nSubject: %s"') // date of last commit in each repo ts_v := git_log_v.find_between('Date:', '\n').trim_space() ts_vc := git_log_vc.find_between('Date:', '\n').trim_space() @@ -246,8 +248,7 @@ fn (mut gen_vc GenVC) generate() { last_commit_hash_v := git_log_v.find_between('commit', '\n').trim_space() last_commit_hash_v_short := last_commit_hash_v[..7] // subject - last_commit_subject := git_log_v.find_between('Subject:', '\n').trim_space().replace("'", - '"') + last_commit_subject := git_log_v.find_between('Subject:', '\n').trim_space().replace("'", '"') // log some info gen_vc.logger.debug('last commit time (${git_repo_v}): ' + last_commit_time_v.format_ss()) gen_vc.logger.debug('last commit time (${git_repo_vc}): ' + last_commit_time_vc.format_ss()) diff --git a/cmd/tools/gg_split_memdump_to_frames.vsh b/cmd/tools/gg_split_memdump_to_frames.vsh index 0d428362df..02faa9355b 100755 --- a/cmd/tools/gg_split_memdump_to_frames.vsh +++ b/cmd/tools/gg_split_memdump_to_frames.vsh @@ -28,7 +28,8 @@ fn main() { mut n := 0 for start := 0; start < original.len; { gc_collect() - idx := original.index_after_(separator, start + separator.len) // ensure that we advance each time + idx := + original.index_after_(separator, start + separator.len) // ensure that we advance each time if idx < 0 { write_chunk(n, min_size, original, start, original.len) break diff --git a/cmd/tools/git_pre_commit_hook.vsh b/cmd/tools/git_pre_commit_hook.vsh index 7468abc96d..798840488e 100755 --- a/cmd/tools/git_pre_commit_hook.vsh +++ b/cmd/tools/git_pre_commit_hook.vsh @@ -29,7 +29,8 @@ import term fn main() { // This hook cares only about the changed V files, that will be committed, as reported by git itself: - changed := os.execute('git diff --cached --name-only --diff-filter=ACMR -- "*.v" "*.vsh" "*.vv"') + changed := + os.execute('git diff --cached --name-only --diff-filter=ACMR -- "*.v" "*.vsh" "*.vv"') all_changed_vfiles := changed.output.trim_space().split('\n') // _input.vv files are NOT formatted on purpose. diff --git a/cmd/tools/measure/fmt_speed.v b/cmd/tools/measure/fmt_speed.v index 4a9ba57a6a..412ac6a704 100644 --- a/cmd/tools/measure/fmt_speed.v +++ b/cmd/tools/measure/fmt_speed.v @@ -83,7 +83,8 @@ fn process_files(files []string) ! { theader() hline() speed_mb_s := term.colorize(term.bright_yellow, '${(f64(total_bytes) / total_us):6.3f} MB/s') - speed_lines_s := term.colorize(term.bright_yellow, '${(1_000_000 * f64(total_lines) / total_us):10.1f} lines/s') + speed_lines_s := term.colorize(term.bright_yellow, + '${(1_000_000 * f64(total_lines) / total_us):10.1f} lines/s') println('${total_us:10}us ${total_tokens:10} ${total_bytes:10} ${total_lines:10} ${(f64(total_bytes) / total_tokens):13.3} ${total_errors:10} ${total_fmt_len:7} FMT speed: ${speed_mb_s}, ${speed_lines_s}, ${nthreads:3} thread(s), ${total_files:5} files.') } diff --git a/cmd/tools/measure/parser_speed.v b/cmd/tools/measure/parser_speed.v index 5d894aaa8e..3c7abc72f7 100644 --- a/cmd/tools/measure/parser_speed.v +++ b/cmd/tools/measure/parser_speed.v @@ -81,7 +81,8 @@ fn process_files(files []string) ! { theader() hline() speed_mb_s := term.colorize(term.bright_yellow, '${(f64(total_bytes) / total_us):6.3f} MB/s') - speed_lines_s := term.colorize(term.bright_yellow, '${(1_000_000 * f64(total_lines) / total_us):10.1f} lines/s') + speed_lines_s := term.colorize(term.bright_yellow, + '${(1_000_000 * f64(total_lines) / total_us):10.1f} lines/s') println('${total_us:10}us ${total_tokens:10} ${total_bytes:10} ${total_lines:10} ${(f64(total_bytes) / total_tokens):13.3} ${total_errors:10} Parser speed: ${speed_mb_s}, ${speed_lines_s}, ${nthreads:3} thread(s), ${total_files:5} files.') } diff --git a/cmd/tools/measure/scanner_speed.v b/cmd/tools/measure/scanner_speed.v index 9bef10a45d..01be6017d9 100644 --- a/cmd/tools/measure/scanner_speed.v +++ b/cmd/tools/measure/scanner_speed.v @@ -70,6 +70,7 @@ fn process_files(files []string) ! { theader() hline() speed_mb_s := term.colorize(term.bright_yellow, '${(f64(total_bytes) / total_us):6.3f} MB/s') - speed_lines_s := term.colorize(term.bright_yellow, '${(1_000_000 * f64(total_lines) / total_us):10.1f} lines/s') + speed_lines_s := term.colorize(term.bright_yellow, + '${(1_000_000 * f64(total_lines) / total_us):10.1f} lines/s') println('${total_us:10}us ${total_tokens:10} ${total_bytes:10} ${total_lines:10} ${(f64(total_bytes) / total_tokens):13.3} ${total_errors:10} Scanner speed: ${speed_mb_s}, ${speed_lines_s}, ${nthreads:3} thread(s), ${total_files:5} files.') } diff --git a/cmd/tools/modules/testing/common.v b/cmd/tools/modules/testing/common.v index 43284ad51c..b51d873153 100644 --- a/cmd/tools/modules/testing/common.v +++ b/cmd/tools/modules/testing/common.v @@ -331,7 +331,8 @@ fn (mut ts TestSession) handle_test_runner_option() { if test_runner !in pref.supported_test_runners { eprintln('v test: `-test-runner ${test_runner}` is not using one of the supported test runners: ${pref.supported_test_runners_list()}') } - test_runner_implementation_file := os.join_path(ts.vroot, 'cmd/tools/modules/testing/output_${test_runner}.v') + test_runner_implementation_file := os.join_path(ts.vroot, + 'cmd/tools/modules/testing/output_${test_runner}.v') if !os.exists(test_runner_implementation_file) { eprintln('v test: using `-test-runner ${test_runner}` needs ${test_runner_implementation_file} to exist, and contain a valid testing.Reporter implementation for that runner. See `cmd/tools/modules/testing/output_dump.v` for an example.') exit(1) @@ -452,7 +453,8 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { tls_bench.njobs = ts.benchmark.njobs abs_path := os.real_path(p.get_item[string](idx)) mut relative_file := abs_path - mut cmd_options := vflags.tokenize_to_args(ts.vargs) // make sure that `'-W -silent'` becomes `['-W', '-silent']`, while keeping quoted spaces intact + mut cmd_options := + vflags.tokenize_to_args(ts.vargs) // make sure that `'-W -silent'` becomes `['-W', '-silent']`, while keeping quoted spaces intact mut run_js := false is_fmt := ts.vargs.contains('fmt') @@ -590,7 +592,8 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { os.setenv('VTEST_RETRY_MAX', '${details.retry}', true) for retry := 1; retry <= details.retry; retry++ { if !details.hide_retries { - ts.append_message(.info, ' [stats] retrying ${retry}/${details.retry} of ${relative_file} ; known flaky: ${details.flaky} ...', + ts.append_message(.info, + ' [stats] retrying ${retry}/${details.retry} of ${relative_file} ; known flaky: ${details.flaky} ...', mtc) } os.setenv('VTEST_RETRY', '${retry}', true) @@ -613,7 +616,8 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { time.sleep(fail_retry_delay_ms) } if details.flaky && !fail_flaky { - ts.append_message(.info, ' *FAILURE* of the known flaky test file ${relative_file} is ignored, since VTEST_FAIL_FLAKY is 0 . Retry count: ${details.retry} .\ncmd: ${cmd}', + ts.append_message(.info, + ' *FAILURE* of the known flaky test file ${relative_file} is ignored, since VTEST_FAIL_FLAKY is 0 . Retry count: ${details.retry} .\ncmd: ${cmd}', mtc) unsafe { goto test_passed_system @@ -630,8 +634,7 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { } } else { if show_start { - ts.append_message(.info, ' starting ${relative_file} ...', - mtc) + ts.append_message(.info, ' starting ${relative_file} ...', mtc) } ts.append_message(.compile_begin, cmd, mtc) compile_d_cmd := time.new_stopwatch() @@ -645,8 +648,7 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { } random_sleep_ms(50, 100 * cretry) } - ts.append_message_with_duration(.compile_end, compile_r.output, compile_cmd_duration, - mtc) + ts.append_message_with_duration(.compile_end, compile_r.output, compile_cmd_duration, mtc) if compile_r.exit_code != 0 { ts.benchmark.fail() tls_bench.fail() @@ -690,7 +692,8 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { os.setenv('VTEST_RETRY_MAX', '${details.retry}', true) for retry = 1; retry <= details.retry; retry++ { if !details.hide_retries { - ts.append_message(.info, ' retrying ${retry}/${details.retry} of ${relative_file} ; known flaky: ${details.flaky} ...', + ts.append_message(.info, + ' retrying ${retry}/${details.retry} of ${relative_file} ; known flaky: ${details.flaky} ...', mtc) } os.setenv('VTEST_RETRY', '${retry}', true) @@ -717,7 +720,8 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { for line in full_failure_output.split_into_lines() { ts.append_message(.info, '>>>>>> ${line}', mtc) } - ts.append_message(.info, ' *FAILURE* of the known flaky test file ${relative_file} is ignored, since VTEST_FAIL_FLAKY is 0 . Retry count: ${details.retry} .\n comp_cmd: ${cmd}\n run_cmd: ${run_cmd}', + ts.append_message(.info, + ' *FAILURE* of the known flaky test file ${relative_file} is ignored, since VTEST_FAIL_FLAKY is 0 . Retry count: ${details.retry} .\n comp_cmd: ${cmd}\n run_cmd: ${run_cmd}', mtc) unsafe { goto test_passed_execute diff --git a/cmd/tools/modules/vgit/vgit.v b/cmd/tools/modules/vgit/vgit.v index 22abb741fb..9c080f7732 100644 --- a/cmd/tools/modules/vgit/vgit.v +++ b/cmd/tools/modules/vgit/vgit.v @@ -80,12 +80,14 @@ pub fn prepare_vc_source(vcdir string, cdir string, commit string) (string, stri // we need the following, otherwise --grep= below would find a93ef6e, which does include 5b7a1e8 in the commit message ... 🤦‍♂️ partial_hash = '5b7a1e84a4d283071d12cb86dc17aeda9b5306a8' } - vcbefore_subject_match := scripting.run('git rev-list HEAD -n1 --timestamp --grep=${partial_hash} ') + vcbefore_subject_match := + scripting.run('git rev-list HEAD -n1 --timestamp --grep=${partial_hash} ') scripting.verbose_trace(@FN, 'vcbefore_subject_match: ${vcbefore_subject_match}') if vcbefore_subject_match.len > 3 { _, vccommit = line_to_timestamp_and_commit(vcbefore_subject_match) } else { - scripting.verbose_trace(@FN, 'the v commit did not match anything in the vc log; try --timestamp instead.') + scripting.verbose_trace(@FN, + 'the v commit did not match anything in the vc log; try --timestamp instead.') vcbefore := scripting.run('git rev-list HEAD -n1 --timestamp --before=${v_timestamp} ') _, vccommit = line_to_timestamp_and_commit(vcbefore) } @@ -170,7 +172,8 @@ pub mut: pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() { vgit_context.vexename = if os.user_os() == 'windows' { 'v.exe' } else { 'v' } - vgit_context.vexepath = os.real_path(os.join_path_single(vgit_context.path_v, vgit_context.vexename)) + vgit_context.vexepath = os.real_path(os.join_path_single(vgit_context.path_v, + vgit_context.vexename)) if os.is_dir(vgit_context.path_v) && os.is_executable(vgit_context.vexepath) && !vgit_context.show_vccommit { // already compiled, no need to compile that specific v executable again @@ -253,11 +256,15 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() { if vgit_context.commit_v__ts >= 1699341818 && !vgit_context.cc.contains('msvc') { c_flags += '-lws2_32' } - command_for_building_v_from_c_source = c(vgit_context.cc, '${vc_v_cpermissive_flags} ${c_flags} -o cv.exe "${vc_source_file_location}" ${c_ldflags}') - command_for_selfbuilding = c('.\\cv.exe', '${vc_v_bootstrap_flags} -cflags "${vc_v_cpermissive_flags}" -o ${vgit_context.vexename} {SOURCE}') + command_for_building_v_from_c_source = c(vgit_context.cc, + '${vc_v_cpermissive_flags} ${c_flags} -o cv.exe "${vc_source_file_location}" ${c_ldflags}') + command_for_selfbuilding = c('.\\cv.exe', + '${vc_v_bootstrap_flags} -cflags "${vc_v_cpermissive_flags}" -o ${vgit_context.vexename} {SOURCE}') } else { - command_for_building_v_from_c_source = c(vgit_context.cc, '${vc_v_cpermissive_flags} ${c_flags} -o cv "${vc_source_file_location}" ${c_ldflags}') - command_for_selfbuilding = c('./cv', '${vc_v_bootstrap_flags} -cflags "${vc_v_cpermissive_flags}" -o ${vgit_context.vexename} {SOURCE}') + command_for_building_v_from_c_source = c(vgit_context.cc, + '${vc_v_cpermissive_flags} ${c_flags} -o cv "${vc_source_file_location}" ${c_ldflags}') + command_for_selfbuilding = c('./cv', + '${vc_v_bootstrap_flags} -cflags "${vc_v_cpermissive_flags}" -o ${vgit_context.vexename} {SOURCE}') } scripting.run(command_for_building_v_from_c_source) @@ -282,8 +289,10 @@ pub mut: } pub fn add_common_tool_options(mut context VGitOptions, mut fp flag.FlagParser) []string { - context.workdir = os.real_path(fp.string('workdir', `w`, context.workdir, 'A writable base folder. Default: ${context.workdir}')) - context.v_repo_url = fp.string('vrepo', 0, context.v_repo_url, 'The url of the V repository. You can clone it locally too. See also --vcrepo below.') + context.workdir = os.real_path(fp.string('workdir', `w`, context.workdir, + 'A writable base folder. Default: ${context.workdir}')) + context.v_repo_url = fp.string('vrepo', 0, context.v_repo_url, + 'The url of the V repository. You can clone it locally too. See also --vcrepo below.') context.vc_repo_url = fp.string('vcrepo', 0, context.vc_repo_url, 'The url of the vc repository. You can clone it ${flag.space}beforehand, and then just give the local folder ${flag.space}path here. That will eliminate the network ops diff --git a/cmd/tools/modules/vshare/clipboard.v b/cmd/tools/modules/vshare/clipboard.v index 44734c4881..52a4f280fa 100644 --- a/cmd/tools/modules/vshare/clipboard.v +++ b/cmd/tools/modules/vshare/clipboard.v @@ -17,7 +17,8 @@ fn copy_to_clipboard_with_commands(text string, commands []ClipboardCommand) boo if text.len == 0 || commands.len == 0 { return false } - temp_file := os.join_path(os.vtmp_dir(), 'vshare_clipboard_${os.getpid()}_${time.now().unix_micro()}.txt') + temp_file := os.join_path(os.vtmp_dir(), + 'vshare_clipboard_${os.getpid()}_${time.now().unix_micro()}.txt') os.write_file(temp_file, text) or { return false } defer { os.rm(temp_file) or {} diff --git a/cmd/tools/oldv.v b/cmd/tools/oldv.v index f3757638da..5efc4116fd 100644 --- a/cmd/tools/oldv.v +++ b/cmd/tools/oldv.v @@ -83,23 +83,9 @@ fn sync_cache() { scripting.chdir(cache_oldv_folder) for reponame in ['v', 'vc'] { repofolder := os.join_path(cache_oldv_folder, reponame) - if !os.exists(repofolder) { - scripting.verbose_trace(@FN, 'cloning to ${repofolder}') - mut repo_options := '' - if reponame == 'vc' { - repo_options = '--filter=blob:none' - } - scripting.exec('git clone ${repo_options} --quiet https://github.com/vlang/${reponame} ${repofolder}') or { - scripting.verbose_trace(@FN, '## error during clone: ${err}') - exit(1) - } - } - scripting.chdir(repofolder) - scripting.exec('git pull --quiet') or { - scripting.verbose_trace(@FN, 'pulling to ${repofolder}') - scripting.verbose_trace(@FN, '## error during pull: ${err}') - exit(1) - } + repo_url := 'https://github.com/vlang/${reponame}' + scripting.verbose_trace(@FN, 'syncing ${repo_url} to ${repofolder}') + vgit.clone_or_pull(repo_url, repofolder) } scripting.verbose_trace(@FN, 'done') } @@ -124,7 +110,8 @@ fn main() { fp.description(tool_description) fp.arguments_description('VCOMMIT') fp.skip_executable() - context.use_cache = fp.bool('cache', `u`, true, 'Use a cache of local repositories for --vrepo and --vcrepo in \$HOME/.cache/oldv/') + context.use_cache = fp.bool('cache', `u`, true, + 'Use a cache of local repositories for --vrepo and --vcrepo in \$HOME/.cache/oldv/') if context.use_cache { context.vgo.v_repo_url = cache_oldv_folder_v context.vgo.vc_repo_url = cache_oldv_folder_vc @@ -132,17 +119,22 @@ fn main() { context.vgo.v_repo_url = 'https://github.com/vlang/v' context.vgo.vc_repo_url = 'https://github.com/vlang/vc' } - context.cc = fp.string('cc', 0, 'cc', 'Use this C compiler for bootstrapping v.c (defaults to `cc`).') - context.cc_options = fp.string('ccoptions', 0, '', 'Use these C compiler options for bootstrapping v.c (defaults to ``).') + context.cc = fp.string('cc', 0, 'cc', + 'Use this C compiler for bootstrapping v.c (defaults to `cc`).') + context.cc_options = fp.string('ccoptions', 0, '', + 'Use these C compiler options for bootstrapping v.c (defaults to ``).') env_cc_options := os.getenv('OLDV_CCOPTIONS') if env_cc_options != '' { context.cc_options = env_cc_options } context.cleanup = fp.bool('clean', 0, false, 'Clean before running (slower).') - context.fresh_tcc = fp.bool('fresh_tcc', 0, true, 'Do `make fresh_tcc` when preparing a V compiler.') + context.fresh_tcc = fp.bool('fresh_tcc', 0, true, + 'Do `make fresh_tcc` when preparing a V compiler.') context.cmd_to_run = fp.string('command', `c`, '', 'Command to run in the old V repo.\n') - context.show_vccommit = fp.bool('show_VC_commit', 0, false, 'Show the VC commit, that can be used to compile the given V commit, and exit.\n') - context.is_bisect = fp.bool('bisect', `b`, false, 'Bisect mode. Use the current commit in the repo where oldv is.') + context.show_vccommit = fp.bool('show_VC_commit', 0, false, + 'Show the VC commit, that can be used to compile the given V commit, and exit.\n') + context.is_bisect = fp.bool('bisect', `b`, false, + 'Bisect mode. Use the current commit in the repo where oldv is.') should_sync := fp.bool('cache-sync', `s`, false, 'Update the local cache') if !should_sync && !context.is_bisect { diff --git a/cmd/tools/performance_compare.v b/cmd/tools/performance_compare.v index 56304441c0..a590b5c267 100644 --- a/cmd/tools/performance_compare.v +++ b/cmd/tools/performance_compare.v @@ -144,8 +144,10 @@ fn (c Context) compare_v_performance(label string, commands []string) string { } else { source_location_b = if os.exists('${c.b}/v.v') { 'v.v ' } else { 'compiler/ ' } } - timestamp_a, _ := vgit.line_to_timestamp_and_commit(scripting.run('cd ${c.a}/ ; git rev-list -n1 --timestamp HEAD')) - timestamp_b, _ := vgit.line_to_timestamp_and_commit(scripting.run('cd ${c.b}/ ; git rev-list -n1 --timestamp HEAD')) + timestamp_a, _ := + vgit.line_to_timestamp_and_commit(scripting.run('cd ${c.a}/ ; git rev-list -n1 --timestamp HEAD')) + timestamp_b, _ := + vgit.line_to_timestamp_and_commit(scripting.run('cd ${c.b}/ ; git rev-list -n1 --timestamp HEAD')) // 1570877641 is 065ce39 2019-10-12 debug_option_a := if timestamp_a > 1570877641 { '-cg ' } else { '-debug ' } debug_option_b := if timestamp_b > 1570877641 { '-cg ' } else { '-debug ' } @@ -170,7 +172,8 @@ fn (c Context) compare_v_performance(label string, commands []string) string { ]) } // ///////////////////////////////////////////////////////////////////////////// - cmd_stats_file := os.real_path([c.vgo.workdir, 'v_performance_stats_${label}.json'].join(os.path_separator)) + cmd_stats_file := + os.real_path([c.vgo.workdir, 'v_performance_stats_${label}.json'].join(os.path_separator)) comparison_cmd := 'hyperfine ${c.hyperfineopts} ' + '--export-json ${cmd_stats_file} ' + '--time-unit millisecond ' + '--style full --warmup ${c.warmups} ' + hyperfine_commands_arguments.join(' ') @@ -197,7 +200,8 @@ fn main() { fp.arguments_description('COMMIT_BEFORE [COMMIT_AFTER]') fp.skip_executable() fp.limit_free_args(1, 2)! - context.vflags = fp.string('vflags', 0, '', 'Additional options to pass to the v commands, for example "-cc tcc"') + context.vflags = fp.string('vflags', 0, '', + 'Additional options to pass to the v commands, for example "-cc tcc"') context.hyperfineopts = fp.string('hyperfine_options', 0, '', 'Additional options passed to hyperfine. ${flag.space}For example on linux, you may want to pass: ${flag.space}--hyperfine_options "--prepare \'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches\'" diff --git a/cmd/tools/regress.v b/cmd/tools/regress.v index 6b18553032..0e31ea287c 100644 --- a/cmd/tools/regress.v +++ b/cmd/tools/regress.v @@ -43,8 +43,10 @@ fn main() { fp.skip_executable() context.new_commit = fp.string('new', `n`, 'master', 'The new commit, by default: master.') - context.old_commit = fp.string('old', `o`, '', 'A known old commit, required (for it, COMMAND should exit with 0).') - context.command = fp.string('command', `c`, '', 'A command to execute. Should exit with 0 for the *old* commits.') + context.old_commit = fp.string('old', `o`, '', + 'A known old commit, required (for it, COMMAND should exit with 0).') + context.command = fp.string('command', `c`, '', + 'A command to execute. Should exit with 0 for the *old* commits.') fp.finalize() or {} if context.old_commit == '' { eprintln('--old COMMIT is required') diff --git a/cmd/tools/report_v_module_folders_without_tests.v b/cmd/tools/report_v_module_folders_without_tests.v index f9a8e5edbb..2910a2ab65 100644 --- a/cmd/tools/report_v_module_folders_without_tests.v +++ b/cmd/tools/report_v_module_folders_without_tests.v @@ -55,7 +55,8 @@ fn main() { n_test_v_files := v_test_files[folder] if n_v_files > 1 && n_test_v_files == 0 { println('> ${n_test_v_files:5} _test.v files, with ${n_v_files:5} .v files, in folder: ${folder}') - compilation := os.execute('${os.quoted_path(vexe)} -shared -W -Wfatal-errors -check ${os.quoted_path(folder)}') + compilation := + os.execute('${os.quoted_path(vexe)} -shared -W -Wfatal-errors -check ${os.quoted_path(folder)}') if compilation.exit_code != 0 { eprintln('> ${folder} has parser/checker errors!') eprintln(compilation.output) diff --git a/cmd/tools/show_ancient_deprecations.v b/cmd/tools/show_ancient_deprecations.v index 572d932d16..92143ae0e3 100644 --- a/cmd/tools/show_ancient_deprecations.v +++ b/cmd/tools/show_ancient_deprecations.v @@ -16,13 +16,15 @@ fn (mut ctx Context) analyze_line(line string, position_file string, position_li ts := blame_for_time.output.all_after('committer-time').all_before('\n').trim_space().int() t := time.unix(ts) if ctx.cut_time < t { - println(term.colorize(term.gray, '>>> SKIPPING since t: ${t} > ${ctx.cut_time}, ${position_file}:${position_line}: ${line}')) + println(term.colorize(term.gray, + '>>> SKIPPING since t: ${t} > ${ctx.cut_time}, ${position_file}:${position_line}: ${line}')) return } ctx.deprecations++ blame_for_context := os.execute('git blame -L${position_line},+5 -- ${position_file}') context := blame_for_context.output.trim_space().split_into_lines() - println(term.colorize(term.red, '${position_file}:${position_line}: deprecation: ${ctx.deprecations}, timestamp: ${ts} - ${t}')) + println(term.colorize(term.red, + '${position_file}:${position_line}: deprecation: ${ctx.deprecations}, timestamp: ${ts} - ${t}')) for cline in context { println(' ${cline}') } @@ -42,7 +44,8 @@ fn main() { all_v_files := os.walk_ext('.', '.v') for v_file in all_v_files { if v_file == './vlib/v/fmt/tests/attrs_keep.vv' { - println(term.colorize(term.gray, '>>> SKIPPING deprecations attrs formatting test file ${v_file}')) + println(term.colorize(term.gray, + '>>> SKIPPING deprecations attrs formatting test file ${v_file}')) continue } if v_file.starts_with('./vlib/v/checker/tests') && v_file.contains('deprec') { diff --git a/cmd/tools/test_if_v_test_system_works.v b/cmd/tools/test_if_v_test_system_works.v index f6e3d86733..aed6b1965d 100644 --- a/cmd/tools/test_if_v_test_system_works.v +++ b/cmd/tools/test_if_v_test_system_works.v @@ -68,7 +68,8 @@ fn create_test(tname string, tcontent string) !string { fn check_assert_continues_works() ! { os.chdir(tdir)! - create_test('assert_continues_option_works_test.v', 'fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false }')! + create_test('assert_continues_option_works_test.v', + 'fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false }')! result := check_fail('${vexe} -assert continues assert_continues_option_works_test.v') result.has('assert_continues_option_works_test.v:1: fn test_fail1') result.has('assert_continues_option_works_test.v:2: fn test_fail1') @@ -76,7 +77,8 @@ fn check_assert_continues_works() ! { result.has('assert_continues_option_works_test.v:5: fn test_fail2') result.has('> assert 2 == 4').has('> assert 2 == 1').has('> assert 2 == 0') // Check if a test function, tagged with [assert_continues], has the same behaviour, without needing additional options - create_test('assert_continues_tag_works_test.v', '@[assert_continues]fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false\n assert false }')! + create_test('assert_continues_tag_works_test.v', + '@[assert_continues]fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false\n assert false }')! tag_res := check_fail('${vexe} assert_continues_tag_works_test.v') tag_res.has('assert_continues_tag_works_test.v:1: fn test_fail1') tag_res.has('assert_continues_tag_works_test.v:2: fn test_fail1') diff --git a/cmd/tools/translate.v b/cmd/tools/translate.v index 3e6f20b8d4..28fe56f25a 100644 --- a/cmd/tools/translate.v +++ b/cmd/tools/translate.v @@ -19,7 +19,8 @@ fn main() { os.mkdir_all(vmodules)! println('C2V is not installed. Cloning C2V to ${c2v_dir} ...') os.chdir(vmodules)! - res := os.execute('${os.quoted_path(vexe)} retry -- git clone --filter=blob:none https://github.com/vlang/c2v') + res := + os.execute('${os.quoted_path(vexe)} retry -- git clone --filter=blob:none https://github.com/vlang/c2v') if res.exit_code != 0 { eprintln('Failed to download C2V.') exit(1) @@ -29,7 +30,8 @@ fn main() { if !os.exists(c2v_bin) { os.chdir(c2v_dir)! println('Compiling c2v ...') - res2 := os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(c2v_bin)} -keepc -g -experimental .') + res2 := + os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(c2v_bin)} -keepc -g -experimental .') if res2.exit_code != 0 { eprintln(res2.output) eprintln('Failed to compile C2V. This should not happen. Please report it via GitHub.') diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index ee2001c4fb..9fde76fa76 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -40,13 +40,18 @@ fn main() { fp.description('Dump a JSON representation of the V AST for a given .v or .vsh file.') fp.description('By default, `v ast` will save the JSON to a .json file, named after the .v file.') fp.description('Pass -p to see it instead.') - ctx.is_watch = fp.bool('watch', `w`, false, 'watch a .v file for changes, rewrite the .json file, when a change is detected') + ctx.is_watch = fp.bool('watch', `w`, false, + 'watch a .v file for changes, rewrite the .json file, when a change is detected') ctx.is_print = fp.bool('print', `p`, false, 'print the AST to stdout') - ctx.is_compile = fp.bool('compile', `c`, false, 'watch the .v file for changes, rewrite the .json file, *AND* generate a .c file too on any change') - ctx.is_terse = fp.bool('terse', `t`, false, 'terse output, only with tree node names (AST structure), no details') - ctx.is_skip_defaults = fp.bool('skip-defaults', `s`, false, 'skip properties that have default values like false, 0, "", etc') + ctx.is_compile = fp.bool('compile', `c`, false, + 'watch the .v file for changes, rewrite the .json file, *AND* generate a .c file too on any change') + ctx.is_terse = fp.bool('terse', `t`, false, + 'terse output, only with tree node names (AST structure), no details') + ctx.is_skip_defaults = fp.bool('skip-defaults', `s`, false, + 'skip properties that have default values like false, 0, "", etc') ctx.check = fp.bool('check', `k`, false, 'run v.checker as well (it may modify the AST)') - hfields := fp.string_multi('hide', 0, 'hide the specified fields. You can give several, by separating them with `,`').join(',') + hfields := fp.string_multi('hide', 0, + 'hide the specified fields. You can give several, by separating them with `,`').join(',') for hf in hfields.split(',') { ctx.hide_names[hf] = true } diff --git a/cmd/tools/vbin2v.v b/cmd/tools/vbin2v.v index bc23033d13..87e3d60dfb 100644 --- a/cmd/tools/vbin2v.v +++ b/cmd/tools/vbin2v.v @@ -98,7 +98,8 @@ fn main() { context.show_help = fp.bool('help', `h`, false, 'Show this help screen.') context.module_name = fp.string('module', `m`, 'binary', 'Name of the generated module.') context.prefix = fp.string('prefix', `p`, '', 'A prefix put before each resource name.') - context.write_file = fp.string('write', `w`, '', 'Write directly to a file with the given name.') + context.write_file = fp.string('write', `w`, '', + 'Write directly to a file with the given name.') if context.show_help { println(fp.usage()) exit(0) diff --git a/cmd/tools/vbug.v b/cmd/tools/vbug.v index c278fb4d67..b5024b4cfb 100644 --- a/cmd/tools/vbug.v +++ b/cmd/tools/vbug.v @@ -57,7 +57,8 @@ fn get_v_build_output(is_verbose bool, is_yes bool, file_path string, user_args elog('> unable to compile V in debug mode: ${result.output}\ncommand: ${vdbg_compilation_cmd}\n') } - result = runv('Compile', '${os.quoted_path(vexe)} ${verbose_flag} ${user_args} ${os.quoted_path(file_path)}') + result = runv('Compile', + '${os.quoted_path(vexe)} ${verbose_flag} ${user_args} ${os.quoted_path(file_path)}') defer { os.rm(vdbg_path) or { if is_verbose { @@ -185,11 +186,13 @@ ${build_output}``` ${expected_result} ' - mut encoded_body := urllib.query_escape(raw_body.replace_once('{file_content}', '```v\n${file_content}\n```')) + mut encoded_body := urllib.query_escape(raw_body.replace_once('{file_content}', + '```v\n${file_content}\n```')) mut generated_uri := 'https://github.com/vlang/v/issues/new?labels=Bug&body=${encoded_body}' if generated_uri.len > 8192 { // GitHub doesn't support URLs longer than 8192 characters - encoded_body = urllib.query_escape(raw_body.replace_once('{file_content}', 'See attached file `${file_path}`')) + encoded_body = urllib.query_escape(raw_body.replace_once('{file_content}', + 'See attached file `${file_path}`')) generated_uri = 'https://github.com/vlang/v/issues/new?labels=Bug&body=${encoded_body}' elog('> Your file is too big to be submitted.') elog('> Go to the following URL, and attach your file:') diff --git a/cmd/tools/vcheck-md.v b/cmd/tools/vcheck-md.v index 9f9a3c826b..ba7e05ad26 100644 --- a/cmd/tools/vcheck-md.v +++ b/cmd/tools/vcheck-md.v @@ -400,17 +400,21 @@ fn (mut f MDFile) check() CheckResult { if !f.skip_line_length_check { ctx := CheckResultContext{f.path, j, line} if f.state == .vexample { - f.wcheck(line.len, too_long_line_length_example, ctx, 'example lines must be less than @ characters') + f.wcheck(line.len, too_long_line_length_example, ctx, + 'example lines must be less than @ characters') } else if f.state == .codeblock { - f.wcheck(line.len, too_long_line_length_codeblock, ctx, 'code lines must be less than @ characters') + f.wcheck(line.len, too_long_line_length_codeblock, ctx, + 'code lines must be less than @ characters') } else if line.starts_with('|') { - f.wcheck(line.len, too_long_line_length_table, ctx, 'table lines must be less than @ characters') + f.wcheck(line.len, too_long_line_length_table, ctx, + 'table lines must be less than @ characters') } else if line.contains('http') { // vfmt off f.wcheck(line.all_after('https').len, too_long_line_length_link, ctx, 'link lines must be less than @ characters') // vfmt on } else { - f.echeck(line.len, too_long_line_length_other, ctx, 'must be less than @ characters') + f.echeck(line.len, too_long_line_length_other, ctx, + 'must be less than @ characters') } } if f.state == .markdown { @@ -557,14 +561,16 @@ fn (mut f MDFile) check_link_target_match(ad AnchorData) { found_error_warning = true f.errors++ for anchordata in ad.anchors[link] { - eprintln(eline(f.path, anchordata.line, 0, 'multiple link targets of existing link (#${link})')) + eprintln(eline(f.path, anchordata.line, 0, + 'multiple link targets of existing link (#${link})')) } } } else { found_error_warning = true f.errors++ for brokenlink in linkdata { - eprintln(eline(f.path, brokenlink.line, 0, 'no link target found for existing link [${brokenlink.label}](#${link})')) + eprintln(eline(f.path, brokenlink.line, 0, + 'no link target found for existing link [${brokenlink.label}](#${link})')) } } } @@ -580,7 +586,8 @@ fn (mut f MDFile) check_link_target_match(ad AnchorData) { anchor.line } } - wprintln(wline(f.path, line, 0, 'multiple link target for non existing link (#${link})')) + wprintln(wline(f.path, line, 0, + 'multiple link target for non existing link (#${link})')) found_error_warning = true f.warnings++ } @@ -657,8 +664,10 @@ fn (mut f MDFile) check_examples() { fname := os.base(f.path).replace('.md', '_md') uid := rand.ulid() cfile := os.join_path(vcheckfolder, '${uid}.c') - vfile := os.join_path(vcheckfolder, 'check_${fname}_example_${e.sline}__${e.eline}__${uid}.v') - efile := os.join_path(vcheckfolder, 'check_${fname}_example_${e.sline}__${e.eline}__${uid}.exe') + vfile := os.join_path(vcheckfolder, + 'check_${fname}_example_${e.sline}__${e.eline}__${uid}.v') + efile := os.join_path(vcheckfolder, + 'check_${fname}_example_${e.sline}__${e.eline}__${uid}.exe') mut should_cleanup_vfile := true // eprintln('>>> checking example ${vfile} ...') vcontent := e.text.join('\n') + '\n' @@ -672,7 +681,8 @@ fn (mut f MDFile) check_examples() { f.ferrors += fmt_res match command { 'compile' { - res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o ${os.quoted_path(efile)} ${os.quoted_path(vfile)}') + res := + cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o ${os.quoted_path(efile)} ${os.quoted_path(vfile)}') if res != 0 || fmt_res != 0 { if res != 0 { eprintln(eline(f.path, e.sline, 0, 'example failed to compile')) @@ -690,7 +700,8 @@ fn (mut f MDFile) check_examples() { f.oks++ } 'cgen' { - res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') + res := + cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') if res != 0 || fmt_res != 0 { if res != 0 { eprintln(eline(f.path, e.sline, 0, 'example failed to generate C code')) @@ -708,10 +719,12 @@ fn (mut f MDFile) check_examples() { f.oks++ } 'globals' { - res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -enable-globals -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') + res := + cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -enable-globals -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') if res != 0 || fmt_res != 0 { if res != 0 { - eprintln(eline(f.path, e.sline, 0, '`example failed to compile with -enable-globals')) + eprintln(eline(f.path, e.sline, 0, + '`example failed to compile with -enable-globals')) } f.report_not_formatted_example_if_needed(e, fmt_res, vfile) or { unsafe { @@ -726,10 +739,12 @@ fn (mut f MDFile) check_examples() { f.oks++ } 'live' { - res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -live -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') + res := + cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -live -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') if res != 0 || fmt_res != 0 { if res != 0 { - eprintln(eline(f.path, e.sline, 0, 'example failed to compile with -live')) + eprintln(eline(f.path, e.sline, 0, + 'example failed to compile with -live')) } f.report_not_formatted_example_if_needed(e, fmt_res, vfile) or { unsafe { @@ -744,10 +759,12 @@ fn (mut f MDFile) check_examples() { f.oks++ } 'shared' { - res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -shared -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') + res := + cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -shared -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') if res != 0 || fmt_res != 0 { if res != 0 { - eprintln(eline(f.path, e.sline, 0, 'module example failed to compile with -shared')) + eprintln(eline(f.path, e.sline, 0, + 'module example failed to compile with -shared')) } f.report_not_formatted_example_if_needed(e, fmt_res, vfile) or { unsafe { @@ -762,7 +779,8 @@ fn (mut f MDFile) check_examples() { f.oks++ } 'failcompile' { - res := silent_cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') + res := + silent_cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}') if res == 0 || fmt_res != 0 { if res == 0 { eprintln(eline(f.path, e.sline, 0, '`failcompile` example compiled')) @@ -780,10 +798,12 @@ fn (mut f MDFile) check_examples() { f.oks++ } 'oksyntax' { - res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -check-syntax ${os.quoted_path(vfile)}') + res := + cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -check-syntax ${os.quoted_path(vfile)}') if res != 0 || fmt_res != 0 { if res != 0 { - eprintln(eline(f.path, e.sline, 0, '`oksyntax` example with invalid syntax')) + eprintln(eline(f.path, e.sline, 0, + '`oksyntax` example with invalid syntax')) } f.report_not_formatted_example_if_needed(e, fmt_res, vfile) or { unsafe { @@ -812,7 +832,8 @@ fn (mut f MDFile) check_examples() { f.oks++ } 'badsyntax' { - res := silent_cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -check-syntax ${os.quoted_path(vfile)}') + res := + silent_cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -check-syntax ${os.quoted_path(vfile)}') if res == 0 { eprintln(eline(f.path, e.sline, 0, '`badsyntax` example can be parsed fine')) eprintln(vcontent) @@ -830,7 +851,8 @@ fn (mut f MDFile) check_examples() { // when ```vmod 'mod' {} else { - eprintln(eline(f.path, e.sline, 0, 'unrecognized command: "${command}", use one of: wip/ignore/compile/failcompile/okfmt/nofmt/oksyntax/badsyntax/cgen/globals/live/shared')) + eprintln(eline(f.path, e.sline, 0, + 'unrecognized command: "${command}", use one of: wip/ignore/compile/failcompile/okfmt/nofmt/oksyntax/badsyntax/cgen/globals/live/shared')) should_cleanup_vfile = false f.errors++ } diff --git a/cmd/tools/vcheck_test.v b/cmd/tools/vcheck_test.v index 89e33b755d..32f9e532dc 100644 --- a/cmd/tools/vcheck_test.v +++ b/cmd/tools/vcheck_test.v @@ -87,8 +87,8 @@ fn test_check_md_respects_vcheckignore_glob_in_scanned_dir() { write_text_file(os.join_path(repo_dir, 'doc', 'plans', 'keep3.md'), '# keep\n')! write_text_file(os.join_path(repo_dir, 'doc', 'plans', '.vcheckignore'), 'ignored*.md\n')! - res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent doc/plans', - true)! + res := run_in_dir(repo_dir, + '${os.quoted_path(vexe)} check-md -hide-warnings -silent doc/plans', true)! assert res.exit_code == 0, res.output assert res.output.contains('SKIP: doc/plans/ignored1.md'), res.output assert res.output.contains('SKIP: doc/plans/ignored2.md'), res.output @@ -119,8 +119,8 @@ fn test_check_md_respects_vcheckignore_anchored_pattern() { write_text_file(os.join_path(repo_dir, 'docs', 'keep.md'), '# keep\n')! write_text_file(os.join_path(repo_dir, 'docs', '.vcheckignore'), '/root_only.md\n')! - res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs', - true)! + res := + run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs', true)! assert res.exit_code == 0, res.output assert res.output.contains('SKIP: docs/root_only.md'), res.output assert res.output.contains('from docs/.vcheckignore: /root_only.md'), res.output @@ -150,8 +150,8 @@ fn test_check_md_respects_vcheckignore_anchored_directory_pattern() { write_text_file(os.join_path(repo_dir, 'docs', 'keep.md'), '# keep\n')! write_text_file(os.join_path(repo_dir, 'docs', '.vcheckignore'), '/sub/\n')! - res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs', - true)! + res := + run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs', true)! assert res.exit_code == 0, res.output assert res.output.contains('SKIP: docs/sub/ignored.md'), res.output assert res.output.contains('from docs/.vcheckignore: /sub/'), res.output @@ -181,8 +181,8 @@ fn test_check_md_respects_vcheckignore_non_anchored_directory_pattern() { write_text_file(os.join_path(repo_dir, 'docs', 'keep.md'), '# keep\n')! write_text_file(os.join_path(repo_dir, 'docs', '.vcheckignore'), 'sub/\n')! - res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs', - true)! + res := + run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs', true)! assert res.exit_code == 0, res.output assert res.output.contains('SKIP: docs/sub/ignored1.md'), res.output assert res.output.contains('SKIP: docs/nested/sub/ignored2.md'), res.output @@ -212,8 +212,7 @@ fn test_check_md_respects_vcheckignore_anchored_directory_glob_pattern() { write_text_file(os.join_path(repo_dir, 'other', 'keep.md'), '# keep\n')! write_text_file(os.join_path(repo_dir, '.vcheckignore'), '/docs-*/\n')! - res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent .', - true)! + res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent .', true)! assert res.exit_code == 0, res.output assert res.output.contains('SKIP: docs-a/sub/ignored1.md'), res.output assert res.output.contains('SKIP: docs-b/sub/ignored2.md'), res.output @@ -242,10 +241,11 @@ fn test_check_md_respects_vcheckignore_comments_and_blank_lines() { write_text_file(os.join_path(repo_dir, 'docs', 'ignored.md'), '# ignored\n')! write_text_file(os.join_path(repo_dir, 'docs', 'ignored2.md'), '# ignored2\n')! write_text_file(os.join_path(repo_dir, 'docs', 'keep.md'), '# keep\n')! - write_text_file(os.join_path(repo_dir, 'docs', '.vcheckignore'), '# comment\n\nignored.md # inline comment\nignored2.md\n')! + write_text_file(os.join_path(repo_dir, 'docs', '.vcheckignore'), + '# comment\n\nignored.md # inline comment\nignored2.md\n')! - res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs', - true)! + res := + run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs', true)! assert res.exit_code == 0, res.output assert res.output.contains('SKIP: docs/ignored.md'), res.output assert res.output.contains('SKIP: docs/ignored2.md'), res.output @@ -275,8 +275,8 @@ fn test_check_md_file_argument_does_not_use_vcheckignore_directory_filtering() { write_text_file(os.join_path(repo_dir, 'docs', 'ignored.md'), '# ignored by dir scan\n')! write_text_file(os.join_path(repo_dir, 'docs', '.vcheckignore'), 'ignored.md\n')! - res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs/ignored.md', - true)! + res := run_in_dir(repo_dir, + '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs/ignored.md', true)! assert res.exit_code == 0, res.output assert !res.output.contains('SKIP: docs/ignored.md'), res.output assert res.output.contains('> Found: 1 .md files.'), res.output @@ -303,7 +303,8 @@ fn test_check_md_uses_scanned_dir_repo_root_for_vcheckignore() { os.execute_or_exit('${os.quoted_path(git_exe)} init ${os.quoted_path(repo_b)}') write_text_file(os.join_path(base_dir, '.vcheckignore'), 'outside*.md\n')! - write_text_file(os.join_path(repo_b, 'docs', 'outside1.md'), '# outside but should not be skipped\n')! + write_text_file(os.join_path(repo_b, 'docs', 'outside1.md'), + '# outside but should not be skipped\n')! write_text_file(os.join_path(repo_b, 'docs', 'keep1.md'), '# keep\n')! res := run_in_dir(repo_a, '${os.quoted_path(vexe)} check-md -hide-warnings -silent ${os.quoted_path(os.join_path(repo_b, @@ -336,8 +337,8 @@ fn test_check_md_multiple_directories_accumulate_skipped_count() { write_text_file(os.join_path(repo_dir, 'notes', 'keep.md'), '# keep\n')! write_text_file(os.join_path(repo_dir, '.vcheckignore'), 'docs/ignored.md\nnotes/ignored.md\n')! - res := run_in_dir(repo_dir, '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs notes', - true)! + res := run_in_dir(repo_dir, + '${os.quoted_path(vexe)} check-md -hide-warnings -silent docs notes', true)! assert res.exit_code == 0, res.output assert res.output.contains('SKIP: docs/ignored.md'), res.output assert res.output.contains('SKIP: notes/ignored.md'), res.output diff --git a/cmd/tools/vcomplete.v b/cmd/tools/vcomplete.v index c2dcf691db..8a83f77d5f 100644 --- a/cmd/tools/vcomplete.v +++ b/cmd/tools/vcomplete.v @@ -684,7 +684,8 @@ fn auto_complete_request(args []string) []string { add_sep := if part == '~' { os.path_separator } else { '' } part = part.replace_once('~', os.home_dir().trim_right(os.path_separator)) + add_sep } - is_abs_path := part.starts_with(os.path_separator) // TODO: Windows support for drive prefixes + is_abs_path := + part.starts_with(os.path_separator) // TODO: Windows support for drive prefixes if part.ends_with(os.path_separator) || part == '.' || part == '..' { // 'v (.*/$|.|..)' -> output full directory list ls_path = '.' + os.path_separator + part diff --git a/cmd/tools/vcover/cover_test.v b/cmd/tools/vcover/cover_test.v index ef2f1af737..a62680d396 100644 --- a/cmd/tools/vcover/cover_test.v +++ b/cmd/tools/vcover/cover_test.v @@ -43,7 +43,8 @@ fn test_simple() { assert !os.exists(t2), t2 assert !os.exists(t3), t3 - r1 := execute('${os.quoted_path(vexe)} -no-skip-unused -coverage ${os.quoted_path(t1)} cmd/tools/vcover/testdata/simple/t1_test.v') + r1 := + execute('${os.quoted_path(vexe)} -no-skip-unused -coverage ${os.quoted_path(t1)} cmd/tools/vcover/testdata/simple/t1_test.v') assert r1.exit_code == 0, r1.str() assert r1.output.trim_space() == '10', r1.str() assert os.exists(t1), t1 @@ -52,7 +53,8 @@ fn test_simple() { assert filter1.exit_code == 0, filter1.output assert filter1.output.contains('cmd/tools/vcover/testdata/simple/simple.v'), filter1.output assert filter1.output.trim_space().ends_with('| 4 | 9 | 44.44%'), filter1.output - hfilter1 := execute('${os.quoted_path(vexe)} cover ${os.quoted_path(t1)} --filter vcover/testdata/simple/ -H -P false') + hfilter1 := + execute('${os.quoted_path(vexe)} cover ${os.quoted_path(t1)} --filter vcover/testdata/simple/ -H -P false') assert hfilter1.exit_code == 0, hfilter1.output assert !hfilter1.output.contains('%'), hfilter1.output houtput1 := hfilter1.output.trim_space().split_into_lines() @@ -70,15 +72,18 @@ fn test_simple() { assert nzeros1.any(it.contains('simple.v:8')), nzeros1.str() assert nzeros1.any(it.contains('simple.v:25')), nzeros1.str() - r2 := execute('${os.quoted_path(vexe)} -no-skip-unused -coverage ${os.quoted_path(t2)} cmd/tools/vcover/testdata/simple/t2_test.v') + r2 := + execute('${os.quoted_path(vexe)} -no-skip-unused -coverage ${os.quoted_path(t2)} cmd/tools/vcover/testdata/simple/t2_test.v') assert r2.exit_code == 0, r2.str() assert r2.output.trim_space() == '24', r2.str() assert os.exists(t2), t2 - filter2 := execute('${os.quoted_path(vexe)} cover ${os.quoted_path(t2)} --filter vcover/testdata/simple') + filter2 := + execute('${os.quoted_path(vexe)} cover ${os.quoted_path(t2)} --filter vcover/testdata/simple') assert filter2.exit_code == 0, filter2.output assert filter2.output.contains('cmd/tools/vcover/testdata/simple/simple.v') assert filter2.output.trim_space().ends_with('| 6 | 9 | 66.67%'), filter2.output - hfilter2 := execute('${os.quoted_path(vexe)} cover ${os.quoted_path(t2)} --filter testdata/simple -H -P false') + hfilter2 := + execute('${os.quoted_path(vexe)} cover ${os.quoted_path(t2)} --filter testdata/simple -H -P false') assert hfilter2.exit_code == 0, hfilter2.output assert !hfilter2.output.contains('%'), hfilter2.output houtput2 := hfilter2.output.trim_space().split_into_lines() @@ -95,7 +100,8 @@ fn test_simple() { assert nzeros2.any(it.contains('simple.v:25')), nzeros2.str() // Run both tests. The coverage should be combined and == 100% - r3 := execute('${os.quoted_path(vexe)} -no-skip-unused -coverage ${os.quoted_path(t3)} test cmd/tools/vcover/testdata/simple/') + r3 := + execute('${os.quoted_path(vexe)} -no-skip-unused -coverage ${os.quoted_path(t3)} test cmd/tools/vcover/testdata/simple/') assert r3.exit_code == 0, r3.str() assert r3.output.trim_space().contains('Summary for all V _test.v files: '), r3.str() assert os.exists(t3), t3 diff --git a/cmd/tools/vcover/main.v b/cmd/tools/vcover/main.v index 9d09cc5692..f23109022f 100644 --- a/cmd/tools/vcover/main.v +++ b/cmd/tools/vcover/main.v @@ -158,11 +158,15 @@ fn main() { fp.arguments_description('[folder1/ file2 ...]') fp.skip_executable() ctx.show_help = fp.bool('help', `h`, false, 'Show this help text.') - ctx.be_verbose = fp.bool('verbose', `v`, false, 'Be more verbose while processing the coverages.') - ctx.show_hotspots = fp.bool('hotspots', `H`, false, 'Show most frequently executed covered lines.') + ctx.be_verbose = fp.bool('verbose', `v`, false, + 'Be more verbose while processing the coverages.') + ctx.show_hotspots = fp.bool('hotspots', `H`, false, + 'Show most frequently executed covered lines.') ctx.show_percentages = fp.bool('percentages', `P`, true, 'Show coverage percentage per file.') - ctx.show_test_files = fp.bool('show_test_files', `S`, false, 'Show `_test.v` files as well (normally filtered).') - ctx.use_absolute_paths = fp.bool('absolute', `A`, false, 'Use absolute paths for all files, no matter the current folder. By default, files inside the current folder, are shown with a relative path.') + ctx.show_test_files = fp.bool('show_test_files', `S`, false, + 'Show `_test.v` files as well (normally filtered).') + ctx.use_absolute_paths = fp.bool('absolute', `A`, false, + 'Use absolute paths for all files, no matter the current folder. By default, files inside the current folder, are shown with a relative path.') ctx.filter = fp.string('filter', `f`, '', 'Filter only the matching source path patterns.') if ctx.show_help { println(fp.usage()) diff --git a/cmd/tools/vcreate/tests/init.expect b/cmd/tools/vcreate/tests/init.expect index 314331e9e4..a9fe6709c9 100755 --- a/cmd/tools/vcreate/tests/init.expect +++ b/cmd/tools/vcreate/tests/init.expect @@ -1,6 +1,6 @@ #!/usr/bin/env expect -set timeout 3 +set timeout 10 # Pass v_root as arg, since we chdir into a temp directory during testing and create a project there. set v_root [lindex $argv 0] diff --git a/cmd/tools/vcreate/tests/init_in_dir_with_invalid_mod_name.expect b/cmd/tools/vcreate/tests/init_in_dir_with_invalid_mod_name.expect index e043b76eda..7cb85afce0 100755 --- a/cmd/tools/vcreate/tests/init_in_dir_with_invalid_mod_name.expect +++ b/cmd/tools/vcreate/tests/init_in_dir_with_invalid_mod_name.expect @@ -1,6 +1,6 @@ #!/usr/bin/env expect -set timeout 3 +set timeout 10 # Pass v_root as arg, since we chdir into a temp directory during testing and create a project there. set v_root [lindex $argv 0] diff --git a/cmd/tools/vcreate/tests/init_with_model_arg.expect b/cmd/tools/vcreate/tests/init_with_model_arg.expect index 168c450e0f..00deef741a 100755 --- a/cmd/tools/vcreate/tests/init_with_model_arg.expect +++ b/cmd/tools/vcreate/tests/init_with_model_arg.expect @@ -1,6 +1,6 @@ #!/usr/bin/env expect -set timeout 3 +set timeout 10 # Pass v_root as arg, since we chdir into a temp directory during testing and create a project there. set v_root [lindex $argv 0] diff --git a/cmd/tools/vcreate/tests/new_with_model_arg.expect b/cmd/tools/vcreate/tests/new_with_model_arg.expect index e7c13985ed..3c6aae467e 100755 --- a/cmd/tools/vcreate/tests/new_with_model_arg.expect +++ b/cmd/tools/vcreate/tests/new_with_model_arg.expect @@ -1,6 +1,6 @@ #!/usr/bin/env expect -set timeout 3 +set timeout 10 # Pass v_root as arg, since we chdir into a temp directory during testing and create a project there. set v_root [lindex $argv 0] diff --git a/cmd/tools/vcreate/tests/new_with_name_arg.expect b/cmd/tools/vcreate/tests/new_with_name_arg.expect index 3f38c7388d..ea146364f7 100755 --- a/cmd/tools/vcreate/tests/new_with_name_arg.expect +++ b/cmd/tools/vcreate/tests/new_with_name_arg.expect @@ -1,6 +1,6 @@ #!/usr/bin/env expect -set timeout 3 +set timeout 10 # Pass v_root as arg, since we chdir into a temp directory during testing and create a project there. set v_root [lindex $argv 0] diff --git a/cmd/tools/vcreate/tests/new_with_no_arg.expect b/cmd/tools/vcreate/tests/new_with_no_arg.expect index 19ea965b59..1ed9e440ab 100755 --- a/cmd/tools/vcreate/tests/new_with_no_arg.expect +++ b/cmd/tools/vcreate/tests/new_with_no_arg.expect @@ -1,6 +1,6 @@ #!/usr/bin/env expect -set timeout 3 +set timeout 10 # Pass v_root as arg, since we chdir into a temp directory during testing and create a project there. set v_root [lindex $argv 0] diff --git a/cmd/tools/vcreate/vcreate_init_test.v b/cmd/tools/vcreate/vcreate_init_test.v index 663a19fcfe..916d644a9b 100644 --- a/cmd/tools/vcreate/vcreate_init_test.v +++ b/cmd/tools/vcreate/vcreate_init_test.v @@ -150,7 +150,8 @@ indent_style = tab prepare_test_path()! os.write_file('.gitattributes', git_attributes_content)! os.write_file('.editorconfig', editor_config_content)! - res := os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, 'init.expect')} ${vroot}') + res := + os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, 'init.expect')} ${vroot}') assert res.output.contains('Created binary (application) project `${test_project_dir_name}`') assert os.read_file('.gitattributes')! == git_attributes_content assert os.read_file('.editorconfig')! == editor_config_content @@ -163,7 +164,8 @@ fn test_v_init_in_dir_with_invalid_mod_name_input() { proj_path := os.join_path(os.vtmp_dir(), dir_name_with_invalid_mod_name) os.mkdir_all(proj_path) or {} os.chdir(proj_path)! - os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, 'init_in_dir_with_invalid_mod_name.expect')} ${vroot} ${dir_name_with_invalid_mod_name} ${corrected_mod_name}') + os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, + 'init_in_dir_with_invalid_mod_name.expect')} ${vroot} ${dir_name_with_invalid_mod_name} ${corrected_mod_name}') // Assert mod data set in `new_with_model_arg.expect`. mod := vmod.from_file(os.join_path(proj_path, 'v.mod')) or { assert false, err.str() @@ -175,7 +177,8 @@ fn test_v_init_in_dir_with_invalid_mod_name_input() { fn test_v_init_with_model_arg_input() { prepare_test_path()! model := '--lib' - res := os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, 'init_with_model_arg.expect')} ${vroot} ${model}') + res := os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, + 'init_with_model_arg.expect')} ${vroot} ${model}') assert res.output.contains('Created library project `${test_project_dir_name}`'), res.output project_path := os.join_path(test_path) mod := vmod.from_file(os.join_path(project_path, 'v.mod')) or { diff --git a/cmd/tools/vdoc/document/doc_private_fn_test.v b/cmd/tools/vdoc/document/doc_private_fn_test.v index 208fc4433b..38b86bfe7e 100644 --- a/cmd/tools/vdoc/document/doc_private_fn_test.v +++ b/cmd/tools/vdoc/document/doc_private_fn_test.v @@ -40,6 +40,5 @@ fn test_get_parent_mod_normal_cases() { assert get_parent_mod(os.join_path(@VMODROOT, 'vlib', 'v', 'token'))! == 'v' assert get_parent_mod(os.join_path(@VMODROOT, 'vlib', 'os', 'os.v'))! == 'os' assert get_parent_mod(os.join_path(@VMODROOT, 'cmd'))! == '' - assert get_parent_mod(os.join_path(@VMODROOT, 'cmd', 'tools', 'modules', 'testing', - 'common.v'))! == 'tools.modules.testing' + assert get_parent_mod(os.join_path(@VMODROOT, 'cmd', 'tools', 'modules', 'testing', 'common.v'))! == 'tools.modules.testing' } diff --git a/cmd/tools/vdoc/highlight.v b/cmd/tools/vdoc/highlight.v index 78ea72298f..04e353def5 100644 --- a/cmd/tools/vdoc/highlight.v +++ b/cmd/tools/vdoc/highlight.v @@ -67,7 +67,9 @@ fn color_highlight(code string, tb &ast.Table) string { } return lit } - mut s := scanner.new_scanner(code, .parse_comments, &pref.Preferences{ is_fmt: true }) + mut s := scanner.new_scanner(code, .parse_comments, &pref.Preferences{ + is_fmt: true + }) mut prev_prev := token.Token{} mut prev := token.Token{} mut tok := s.scan() diff --git a/cmd/tools/vdoc/html.v b/cmd/tools/vdoc/html.v index e4ae055259..2c4b87951f 100644 --- a/cmd/tools/vdoc/html.v +++ b/cmd/tools/vdoc/html.v @@ -64,7 +64,8 @@ fn (vd &VDoc) render_search_index(out Output) { for i, title in vd.search_module_index { data := vd.search_module_data[i] js_search_index.write_string('"${title}",\n') - description := data.description.replace('\n', '').replace('\r', '') // fix multiline js string bug + description := + data.description.replace('\n', '').replace('\r', '') // fix multiline js string bug js_search_data.write_string('["${description}","${data.link}"],\n') } js_search_index.writeln('];\n') @@ -191,6 +192,7 @@ fn (vd &VDoc) write_content(cn &doc.DocNode, d &doc.Doc, mut hw strings.Builder) cfg := vd.cfg file_path_name := vd.get_repo_file_path_for_links(cn.file_path) src_link := get_src_link(vd.manifest.repo_url, vd.manifest.repo_branch, file_path_name, + cn.pos.line_nr + 1) md_link_base := get_src_dir_link(vd.manifest.repo_url, vd.manifest.repo_branch, file_path_name) if cn.content.len != 0 || cn.name == 'Constants' { @@ -510,7 +512,9 @@ fn write_token(tok token.Token, typ HighlightTokenTyp, mut buf strings.Builder) } fn html_highlight(code string, tb &ast.Table) string { - mut s := scanner.new_scanner(code, .parse_comments, &pref.Preferences{ output_mode: .silent }) + mut s := scanner.new_scanner(code, .parse_comments, &pref.Preferences{ + output_mode: .silent + }) mut tok := s.scan() mut prev_tok := tok mut next_tok := s.scan() @@ -697,7 +701,8 @@ fn (vd &VDoc) doc_node_html(dn doc.DocNode, link string, md_link_base string, he dnw.write_string('\n') } if deprecated_tags.len > 0 { - attributes := deprecated_tags.map('
${it.replace_each(quote_escape_seq)}
\n').join('') + attributes := + deprecated_tags.map('
${it.replace_each(quote_escape_seq)}
\n').join('') dnw.writeln('
${attributes}
\n') } if tags.len > 0 { diff --git a/cmd/tools/vdoc/run_examples.v b/cmd/tools/vdoc/run_examples.v index 7cd085a2bc..1cea5d1dc6 100644 --- a/cmd/tools/vdoc/run_examples.v +++ b/cmd/tools/vdoc/run_examples.v @@ -75,7 +75,8 @@ fn (mut vd VDoc) run_examples(dn doc.DocNode) { cmd := '${os.quoted_path(vexe)} ${voptions} ${os.quoted_path(vsource_path)}' res := os.execute(cmd) if res.exit_code != 0 { - eprintln('${dn_to_location(dn)}:${term.ecolorize(term.red, 'error in documentation example')}') + eprintln('${dn_to_location(dn)}:${term.ecolorize(term.red, + 'error in documentation example')}') eprintln(' cmd: ${cmd}') eprintln(' example line: ${term.colorize(term.bright_yellow, example)}') eprintln(' result:') diff --git a/cmd/tools/vdoc/vdoc.v b/cmd/tools/vdoc/vdoc.v index 337270c91e..17ce17588b 100644 --- a/cmd/tools/vdoc/vdoc.v +++ b/cmd/tools/vdoc/vdoc.v @@ -245,7 +245,8 @@ fn (vd &VDoc) get_readme(path string) Readme { mut readme_frontmatter := map[string]string{} if readme_contents.starts_with('---\n') { if frontmatter_lines_end_idx := readme_contents.index('\n---\n') { - front_matter_lines := readme_contents#[4..frontmatter_lines_end_idx].trim_space().split_into_lines() + front_matter_lines := + readme_contents#[4..frontmatter_lines_end_idx].trim_space().split_into_lines() for line in front_matter_lines { x := line.split(': ') if x.len == 2 { diff --git a/cmd/tools/vdoc/vdoc_file_test.v b/cmd/tools/vdoc/vdoc_file_test.v index af06f4736a..a6861f65c2 100644 --- a/cmd/tools/vdoc/vdoc_file_test.v +++ b/cmd/tools/vdoc/vdoc_file_test.v @@ -27,14 +27,16 @@ fn test_output() { should_sort: false ) fails += check_output('${vexe} doc -comments ${qpath}', '${path_no_ext}.comments.out') - fails += check_output('${vexe} doc -readme -comments ${qpath}', '${path_no_ext}.readme.comments.out') + fails += check_output('${vexe} doc -readme -comments ${qpath}', + '${path_no_ext}.readme.comments.out') // test the main 3 different formats: program_dir := os.quoted_path(if os.is_dir(path) { path } else { os.dir(path) }) for fmt in ['html', 'ansi', 'text'] { fails += check_output('${vexe} doc -no-timestamp -f ${fmt} -o - -html-only-contents -readme -comments ${program_dir}', '${path_no_ext}.${fmt}') } - fails += check_output('${vexe} doc -no-timestamp -f md -o - ${program_dir}', '${path_no_ext}.md') + fails += check_output('${vexe} doc -no-timestamp -f md -o - ${program_dir}', + '${path_no_ext}.md') if fails == 0 { println(term.green('OK')) } else { diff --git a/cmd/tools/vdownload.v b/cmd/tools/vdownload.v index 2bef4df4f9..ab063eed6f 100644 --- a/cmd/tools/vdownload.v +++ b/cmd/tools/vdownload.v @@ -36,16 +36,24 @@ fn main() { fp.skip_executable() fp.limit_free_args_to_at_least(1)! ctx.show_help = fp.bool('help', `h`, false, 'Show this help screen.') - ctx.target_folder = fp.string('target-folder', `t`, '.', 'The target folder, where the file will be stored. It will be created, if it does not exist. Default is current folder.') - ctx.output = fp.string('output', `o`, '', 'Write output to the given file, instead of inferring it from the final part of the URL. All intermediate folders will be created, if they do not exist.') + ctx.target_folder = fp.string('target-folder', `t`, '.', + 'The target folder, where the file will be stored. It will be created, if it does not exist. Default is current folder.') + ctx.output = fp.string('output', `o`, '', + 'Write output to the given file, instead of inferring it from the final part of the URL. All intermediate folders will be created, if they do not exist.') ctx.show_sha1 = fp.bool('sha1', `1`, false, 'Show the SHA1 hash of the downloaded file.') ctx.show_sha256 = fp.bool('sha256', `2`, false, 'Show the SHA256 hash of the downloaded file.') - ctx.show_sha3_256 = fp.bool('sha3-256', `3`, false, 'Show the SHA3-256 (Keccak) hash of the downloaded file.') - ctx.continue_on_failure = fp.bool('continue', `c`, false, 'Continue on download failures. If you download 5 URLs, and several of them fail, continue without error. False by default.') - ctx.retries = fp.int('retries', `r`, 10, 'Number of retries, when an URL fails to download. The default is 10.') - ctx.delay = time.Duration(u64(fp.float('delay', `d`, 1.0, 'Delay in seconds, after each retry. The default is 1 second.') * time.second)) - ctx.should_run = fp.bool('run', `R`, false, 'Run, after the script/program is completely downloaded.') - ctx.delete_after_run = fp.bool('delete-after-run', `D`, false, 'Delete the downloaded script/program, after it has been run.') + ctx.show_sha3_256 = fp.bool('sha3-256', `3`, false, + 'Show the SHA3-256 (Keccak) hash of the downloaded file.') + ctx.continue_on_failure = fp.bool('continue', `c`, false, + 'Continue on download failures. If you download 5 URLs, and several of them fail, continue without error. False by default.') + ctx.retries = fp.int('retries', `r`, 10, + 'Number of retries, when an URL fails to download. The default is 10.') + ctx.delay = time.Duration(u64(fp.float('delay', `d`, 1.0, + 'Delay in seconds, after each retry. The default is 1 second.') * time.second)) + ctx.should_run = fp.bool('run', `R`, false, + 'Run, after the script/program is completely downloaded.') + ctx.delete_after_run = fp.bool('delete-after-run', `D`, false, + 'Delete the downloaded script/program, after it has been run.') if ctx.show_help { println(fp.usage()) exit(0) diff --git a/cmd/tools/vfmt.v b/cmd/tools/vfmt.v index f21824fcd8..769436b4fe 100644 --- a/cmd/tools/vfmt.v +++ b/cmd/tools/vfmt.v @@ -232,19 +232,6 @@ fn (foptions &FormatOptions) format_pipe() { foptions.vlog('fmt.fmt worked and ${formatted_content.len} bytes were written to stdout.') } -fn print_compiler_options(compiler_params &pref.Preferences) { - eprintln(' os: ' + compiler_params.os.str()) - eprintln(' ccompiler: ${compiler_params.ccompiler}') - eprintln(' path: ${compiler_params.path} ') - eprintln(' out_name: ${compiler_params.out_name} ') - eprintln(' vroot: ${compiler_params.vroot} ') - eprintln('lookup_path: ${compiler_params.lookup_path} ') - eprintln(' out_name: ${compiler_params.out_name} ') - eprintln(' cflags: ${compiler_params.cflags} ') - eprintln(' is_test: ${compiler_params.is_test} ') - eprintln(' is_script: ${compiler_params.is_script} ') -} - fn (mut foptions FormatOptions) post_process_file(file string, formatted_file_path string) ! { if formatted_file_path == '' { return @@ -310,11 +297,6 @@ fn (mut foptions FormatOptions) post_process_file(file string, formatted_file_pa flush_stdout() } -fn read_source_lines(file string) ![]string { - source_lines := os.read_lines(file) or { return error('can not read ${file}') } - return source_lines -} - @[noreturn] fn verror(s string) { util.verror('vfmt error', s) diff --git a/cmd/tools/vgret.v b/cmd/tools/vgret.v index 0a0d84e7b6..79057cc6c2 100644 --- a/cmd/tools/vgret.v +++ b/cmd/tools/vgret.v @@ -163,11 +163,13 @@ fn main() { // Collect tool options mut opt := Options{ verbose: fp.bool('verbose', `v`, false, "Be verbose about the tool's progress.") - compare_only: fp.bool('compare-only', `c`, false, "Don't generate screenshots - only compare input directories") + compare_only: fp.bool('compare-only', `c`, false, + "Don't generate screenshots - only compare input directories") root_path: fp.string('root-path', `r`, v_root, 'Root path of the comparison') } - toml_conf := fp.string('toml-config', `t`, default_toml, 'Path or string with TOML configuration') + toml_conf := fp.string('toml-config', `t`, default_toml, + 'Path or string with TOML configuration') arg_paths := fp.finalize()! if show_help { println(fp.usage()) @@ -230,7 +232,8 @@ fn generate_screenshots(mut opt Options, output_path string) ! { if app_config.capture.method == 'gg_record' { opt.verbose_eprintln('Compiling shaders (if needed) for `${file}`') - sh_result := opt.verbose_execute('${os.quoted_path(v_exe)} shader ${os.quoted_path(app_path)}') + sh_result := + opt.verbose_execute('${os.quoted_path(v_exe)} shader ${os.quoted_path(app_path)}') if sh_result.exit_code != 0 { opt.verbose_eprintln('Skipping shader compile for `${file}` v shader failed with:\n${sh_result.output}') continue @@ -339,7 +342,8 @@ fn take_screenshots(opt Options, app AppConfig) ![]string { } flags := app.capture.flags.join(' ') - result := opt.verbose_execute('${os.quoted_path(v_exe)} ${flags} -d gg_record run ${os.quoted_path(app.abs_path)}') + result := + opt.verbose_execute('${os.quoted_path(v_exe)} ${flags} -d gg_record run ${os.quoted_path(app.abs_path)}') if result.exit_code != 0 { return error('Failed taking screenshot of `${app.abs_path}`:\n${result.output}') } @@ -400,7 +404,8 @@ fn take_screenshots(opt Options, app AppConfig) ![]string { } continue } - extract_result := opt.verbose_execute('convert -extract ${region.width}x${region.height}+${region.x}+${region.y} "${out_file}" "${region_out_file}"') + extract_result := + opt.verbose_execute('convert -extract ${region.width}x${region.height}+${region.x}+${region.y} "${out_file}" "${region_out_file}"') if extract_result.exit_code != 0 { p_app.signal_kill() return error('Failed extracting region ${region_id} from screenshot of `${app.abs_path}` to "${region_out_file}":\n${result.output}') @@ -482,8 +487,10 @@ fn new_config(root_path string, toml_config string) !Config { // Merge, per app, overwrites mut merged_compare := CompareOptions{} - merged_compare.method = app_any.value('compare.method').default_to(default_compare.method).string() - merged_compare_flags := app_any.value('compare.flags').default_to(empty_toml_array).array().as_strings() + merged_compare.method = + app_any.value('compare.method').default_to(default_compare.method).string() + merged_compare_flags := + app_any.value('compare.flags').default_to(empty_toml_array).array().as_strings() if merged_compare_flags.len > 0 { merged_compare.flags = merged_compare_flags } else { @@ -491,15 +498,18 @@ fn new_config(root_path string, toml_config string) !Config { } mut merged_capture := CaptureOptions{} - merged_capture.method = app_any.value('capture.method').default_to(default_capture.method).string() - merged_capture_flags := app_any.value('capture.flags').default_to(empty_toml_array).array().as_strings() + merged_capture.method = + app_any.value('capture.method').default_to(default_capture.method).string() + merged_capture_flags := + app_any.value('capture.flags').default_to(empty_toml_array).array().as_strings() if merged_capture_flags.len > 0 { merged_capture.flags = merged_capture_flags } else { merged_capture.flags = default_capture.flags } - app_capture_regions_any := app_any.value('capture.regions').default_to(empty_toml_array).array() + app_capture_regions_any := + app_any.value('capture.regions').default_to(empty_toml_array).array() mut app_capture_regions := []CaptureRegion{} for capture_region_any in app_capture_regions_any { region := CaptureRegion{ @@ -523,7 +533,8 @@ fn new_config(root_path string, toml_config string) !Config { } merged_capture.regions = merged_capture_regions - merged_capture.wait_ms = app_any.value('capture.wait_ms').default_to(default_capture.wait_ms).int() + merged_capture.wait_ms = + app_any.value('capture.wait_ms').default_to(default_capture.wait_ms).int() merge_capture_env := app_any.value('capture.env').default_to(empty_toml_map).as_map() mut merge_env_map := default_capture.env.clone() for k, v in merge_capture_env { diff --git a/cmd/tools/vls.v b/cmd/tools/vls.v index 0071bb9b2e..1423be81af 100644 --- a/cmd/tools/vls.v +++ b/cmd/tools/vls.v @@ -61,8 +61,7 @@ const vls_manifest_path = os.join_path(vls_folder, 'vls.config.json') const vls_src_folder = os.join_path(vls_folder, 'src') -const server_not_found_err = error_with_code('Language server is not installed nor found.', - 101) +const server_not_found_err = error_with_code('Language server is not installed nor found.', 101) fn (upd VlsUpdater) check_or_create_vls_folder() ! { if !os.exists(vls_folder) { @@ -240,13 +239,15 @@ fn (upd VlsUpdater) compile_from_source() ! { if !os.exists(vls_src_folder) { upd.log('Cloning VLS repo...') - clone_result := os.execute('${os.quoted_path(vexe)} retry -- ${git} clone --filter=blob:none https://github.com/vlang/vls ${vls_src_folder}') + clone_result := + os.execute('${os.quoted_path(vexe)} retry -- ${git} clone --filter=blob:none https://github.com/vlang/vls ${vls_src_folder}') if clone_result.exit_code != 0 { return error('Failed to build VLS from source. Reason: ${clone_result.output}') } } else { upd.log('Updating VLS repo...') - pull_result := os.execute('${os.quoted_path(vexe)} retry -- ${git} -C ${vls_src_folder} pull') + pull_result := + os.execute('${os.quoted_path(vexe)} retry -- ${git} -C ${vls_src_folder} pull') if !upd.is_force && pull_result.output.trim_space() == 'Already up to date.' { upd.log('VLS was already updated to its latest version.') return @@ -308,7 +309,8 @@ fn (mut upd VlsUpdater) parse(mut fp flag.FlagParser) ! { upd.output = .silent } - is_install := fp.bool('install', ` `, false, 'Installs the language server. You may also use this flag to re-download or force update your existing installation.') + is_install := fp.bool('install', ` `, false, + 'Installs the language server. You may also use this flag to re-download or force update your existing installation.') is_update := fp.bool('update', ` `, false, 'Updates the installed language server.') upd.is_check = fp.bool('check', ` `, false, 'Checks if the language server is installed.') upd.is_force = fp.bool('force', ` `, false, 'Force install or update the language server.') @@ -339,7 +341,8 @@ fn (mut upd VlsUpdater) parse(mut fp flag.FlagParser) ! { } } - upd.is_help = fp.bool('help', `h`, false, "Show this updater's help text. To show the help text for the language server, pass the `--ls` flag before it.") + upd.is_help = fp.bool('help', `h`, false, + "Show this updater's help text. To show the help text for the language server, pass the `--ls` flag before it.") if !upd.is_help && !upd.pass_to_ls { // automatically set the cli launcher to language server mode diff --git a/cmd/tools/vmissdoc.v b/cmd/tools/vmissdoc.v index 86f5ff334a..713dc638cd 100644 --- a/cmd/tools/vmissdoc.v +++ b/cmd/tools/vmissdoc.v @@ -155,10 +155,12 @@ fn (opt &Options) diff_undocumented_functions_in_paths(path_old string, path_new mut differs := []UndocumentedFN{} if new_undocumented_functions.len > old_undocumented_functions.len { for new_undoc_fn in new_undocumented_functions { - new_relative_file := new_undoc_fn.file.replace(new, '').trim_string_left(os.path_separator) + new_relative_file := + new_undoc_fn.file.replace(new, '').trim_string_left(os.path_separator) mut found := false for old_undoc_fn in old_undocumented_functions { - old_relative_file := old_undoc_fn.file.replace(old, '').trim_string_left(os.path_separator) + old_relative_file := + old_undoc_fn.file.replace(old, '').trim_string_left(os.path_separator) if new_relative_file == old_relative_file && new_undoc_fn.signature == old_undoc_fn.signature { found = true @@ -229,15 +231,18 @@ fn main() { // Collect tool options mut opt := Options{ show_help: fp.bool('help', `h`, false, 'Show this help text.') - deprecated: fp.bool('deprecated', `d`, false, 'Include deprecated functions in output.') + deprecated: fp.bool('deprecated', `d`, false, + 'Include deprecated functions in output.') private: fp.bool('private', `p`, false, 'Include private functions in output.') js: fp.bool('js', 0, false, 'Include JavaScript functions in output.') no_line_numbers: fp.bool('no-line-numbers', `n`, false, 'Exclude line numbers in output.') collect_tags: fp.bool('tags', `t`, false, 'Also print function tags if any is found.') exclude: fp.string_multi('exclude', `e`, '') relative_paths: fp.bool('relative-paths', `r`, false, 'Use relative paths in output.') - diff: fp.bool('diff', 0, false, 'exit(1) and show difference between two PATH inputs, return 0 otherwise.') - verify: fp.bool('verify', 0, false, 'exit(1) if documentation is missing, 0 otherwise.') + diff: fp.bool('diff', 0, false, + 'exit(1) and show difference between two PATH inputs, return 0 otherwise.') + verify: fp.bool('verify', 0, false, + 'exit(1) if documentation is missing, 0 otherwise.') } opt.additional_args = fp.finalize() or { panic(err) } if opt.show_help { @@ -283,8 +288,7 @@ fn main() { for path in opt.additional_args { if path in ['@vlib', '@cmd', '@examples'] { rpath := path[1..] - total += opt.report_undocumented_functions_in_path(os.join_path(@VEXEROOT, - rpath)) + total += opt.report_undocumented_functions_in_path(os.join_path(@VEXEROOT, rpath)) continue } if os.is_file(path) || os.is_dir(path) { diff --git a/cmd/tools/vpm/common.v b/cmd/tools/vpm/common.v index 2cd8bd58bb..6650ba2447 100644 --- a/cmd/tools/vpm/common.v +++ b/cmd/tools/vpm/common.v @@ -83,7 +83,8 @@ fn get_mod_vpm_info_with_selector(name string, mut selector VpmInstallServerSele is_initial_selection := selected_server_url(false, '') == '' for url in selector.metadata_server_urls() { modurl := url + '/api/packages/${name}' - verbose_println_more(@FILE_LINE, @FN, 'Retrieving metadata for `${name}` from `${modurl}` by making a GET request ...') + verbose_println_more(@FILE_LINE, @FN, + 'Retrieving metadata for `${name}` from `${modurl}` by making a GET request ...') r := http.get(modurl) or { errors << 'Http server did not respond to our request for `${modurl}`.' errors << 'Error details: ${err}' @@ -179,7 +180,8 @@ fn get_ident_from_url(raw_url string) !(string, string) { return error(final_error) } name = name.trim_string_right('.git') - verbose_println_more(@FILE_LINE, @FN, 'raw_url: ${raw_url}; publisher: ${publisher}; name: ${name}') + verbose_println_more(@FILE_LINE, @FN, + 'raw_url: ${raw_url}; publisher: ${publisher}; name: ${name}') return publisher, name } @@ -273,7 +275,8 @@ fn normalize_repo_lookup_url(raw_url string) !string { return error('failed to parse module URL `${raw_url}`.') } host := url.hostname().trim_space().to_lower() - path := url.path.trim_space().trim_right('/').trim_left('/').trim_string_right('.git').to_lower() + path := + url.path.trim_space().trim_right('/').trim_left('/').trim_string_right('.git').to_lower() if host == '' || path == '' { return error('failed to normalize module URL `${raw_url}`.') } diff --git a/cmd/tools/vpm/install_local_test.v b/cmd/tools/vpm/install_local_test.v index 4f0ba3f670..7a5baf8d4e 100644 --- a/cmd/tools/vpm/install_local_test.v +++ b/cmd/tools/vpm/install_local_test.v @@ -93,12 +93,12 @@ fn test_install_from_local_git_repository_variants() { fn create_local_git_module(repo_path string, module_name string) { os.mkdir_all(repo_path) or { panic(err) } - os.write_file(os.join_path(repo_path, 'v.mod'), "Module{\n\tname: '${module_name}'\n\tversion: '0.0.1'\n}\n") or { - panic(err) - } + os.write_file(os.join_path(repo_path, 'v.mod'), + "Module{\n\tname: '${module_name}'\n\tversion: '0.0.1'\n}\n") or { panic(err) } cmd_ok(@LOCATION, 'git init ${os.quoted_path(repo_path)}') cmd_ok(@LOCATION, 'git -C ${os.quoted_path(repo_path)} add v.mod') - cmd_ok(@LOCATION, 'git -C ${os.quoted_path(repo_path)} -c user.email="ci@vlang.io" -c user.name="V CI" commit -m "initial commit"') + cmd_ok(@LOCATION, + 'git -C ${os.quoted_path(repo_path)} -c user.email="ci@vlang.io" -c user.name="V CI" commit -m "initial commit"') } fn file_url(path string) string { diff --git a/cmd/tools/vpm/install_test.v b/cmd/tools/vpm/install_test.v index 89b95b073a..2a906ff051 100644 --- a/cmd/tools/vpm/install_test.v +++ b/cmd/tools/vpm/install_test.v @@ -105,14 +105,12 @@ fn test_install_once() { assert manifest.name == 'pcre' assert manifest.description == 'A simple regex library for V.' // Ensure the before installed markdown module wasn't modified. - assert md_last_modified == os.file_last_mod_unix(os.join_path(test_path, 'markdown', - 'v.mod')) + assert md_last_modified == os.file_last_mod_unix(os.join_path(test_path, 'markdown', 'v.mod')) // Try installing two modules that are both already installed. res = cmd_ok(@LOCATION, install_cmd) assert res.output.contains('All modules are already installed.'), res.output - assert md_last_modified == os.file_last_mod_unix(os.join_path(test_path, 'markdown', - 'v.mod')) + assert md_last_modified == os.file_last_mod_unix(os.join_path(test_path, 'markdown', 'v.mod')) } fn test_missing_repo_name_in_url() { @@ -161,7 +159,8 @@ fn test_get_installed_version() { // Create a tag -> latests commit and tag are at the same state, // but it should not be treated as a version installation, when there is another head branch. - res = cmd_ok(@LOCATION, 'git tag v0.1.0 -m "some tag message"') // note: without a tag message, git will try to start an editor when you run this test locally, which will block + res = + cmd_ok(@LOCATION, 'git tag v0.1.0 -m "some tag message"') // note: without a tag message, git will try to start an editor when you run this test locally, which will block mod.is_installed = false mod.get_installed() assert mod.is_installed @@ -195,7 +194,8 @@ fn test_install_from_hg_url() ! { println('> writing .hg/hgrc to the new mercurial repo ...') os.mkdir_all(os.join_path(test_module_path, '.hg'))! - os.write_file(os.join_path(test_module_path, '.hg/hgrc'), '[ui]\nusername = v_ci \nverbose = False\n')! + os.write_file(os.join_path(test_module_path, '.hg/hgrc'), + '[ui]\nusername = v_ci \nverbose = False\n')! println('> writing .hg/hgrc done.') mut p, mut port := test_utils.hg_serve(hg_path, test_module_path, 2000) diff --git a/cmd/tools/vpm/install_version_input_test.v b/cmd/tools/vpm/install_version_input_test.v index 7277fb7de3..88bde48288 100644 --- a/cmd/tools/vpm/install_version_input_test.v +++ b/cmd/tools/vpm/install_version_input_test.v @@ -53,14 +53,16 @@ fn test_reinstall_mod_with_version_installation() { expect_args := [vexe, ident, tag, new_tag, install_path].join(' ') // Decline. - decline_test := os.join_path(expect_tests_path, 'decline_reinstall_mod_with_version_installation.expect') + decline_test := os.join_path(expect_tests_path, + 'decline_reinstall_mod_with_version_installation.expect') manifest_path := os.join_path(install_path, 'v.mod') last_modified := os.file_last_mod_unix(manifest_path) cmd_ok(@LOCATION, '${expect_exe} ${decline_test} ${expect_args}') assert last_modified == os.file_last_mod_unix(manifest_path) // Accept. - accept_test := os.join_path(expect_tests_path, 'accept_reinstall_mod_with_version_installation.expect') + accept_test := os.join_path(expect_tests_path, + 'accept_reinstall_mod_with_version_installation.expect') cmd_ok(@LOCATION, '${expect_exe} ${accept_test} ${expect_args}') manifest = get_vmod(ident) assert manifest.name == ident diff --git a/cmd/tools/vquest.v b/cmd/tools/vquest.v index 6dbe921ae9..1e853abf7a 100644 --- a/cmd/tools/vquest.v +++ b/cmd/tools/vquest.v @@ -152,7 +152,8 @@ const solve_flags = [ ] fn run_confirm(cmd cli.Command) ! { - run_issue(cmd, confirm_search_query, 'still unconfirmed', 'Help us by confirming and triaging this issue:')! + run_issue(cmd, confirm_search_query, 'still unconfirmed', + 'Help us by confirming and triaging this issue:')! } fn run_fix(cmd cli.Command) ! { @@ -160,7 +161,8 @@ fn run_fix(cmd cli.Command) ! { } fn run_implement(cmd cli.Command) ! { - run_issue(cmd, feature_search_query, 'feature request', 'Help us by implementing the issue in a PR, or triage it:')! + run_issue(cmd, feature_search_query, 'feature request', + 'Help us by implementing the issue in a PR, or triage it:')! } fn run_solve(cmd cli.Command) ! { @@ -188,7 +190,8 @@ fn run_solve(cmd cli.Command) ! { } start_page, end_page := resolve_page_range(cmd, max_pages)! page := start_page + (rand.intn(end_page - start_page + 1) or { 0 }) - eprintln(term.colorize(term.gray, 'Found: ${total} bugs reproducible on ${os_label}. Fetching from page: ${page} in [${start_page}, ${end_page}] ...')) + eprintln(term.colorize(term.gray, + 'Found: ${total} bugs reproducible on ${os_label}. Fetching from page: ${page} in [${start_page}, ${end_page}] ...')) issue := fetch_issue_from_page(query, page)! details := fetch_issue_details(issue.number)! @@ -273,7 +276,8 @@ fn run_issue(cmd cli.Command, issue_query string, issue_label string, help_label } start_page, end_page := resolve_page_range(cmd, max_pages)! page := start_page + (rand.intn(end_page - start_page + 1) or { 0 }) - eprintln(term.colorize(term.gray, 'Found: ${total} ${issue_label} issues. Fetching issue from page: ${page} in [${start_page}, ${end_page}] ...')) + eprintln(term.colorize(term.gray, + 'Found: ${total} ${issue_label} issues. Fetching issue from page: ${page} in [${start_page}, ${end_page}] ...')) issue := fetch_issue_from_page(issue_query, page)! println(term.colorize(term.green, help_label)) println(issue.html_url) @@ -284,7 +288,8 @@ fn run_issue(cmd cli.Command, issue_query string, issue_label string, help_label } fn run_document(_cmd cli.Command) ! { - res := os.execute('${os.quoted_path(@VEXE)} missdoc --exclude vlib/v --exclude /linux_bare/ --exclude /wasm_bare/ @vlib') + res := + os.execute('${os.quoted_path(@VEXE)} missdoc --exclude vlib/v --exclude /linux_bare/ --exclude /wasm_bare/ @vlib') if res.exit_code != 0 { return error('v missdoc failed: ${res.output}') } diff --git a/cmd/tools/vreduce.v b/cmd/tools/vreduce.v index 24054ec3e5..cb41bcc343 100644 --- a/cmd/tools/vreduce.v +++ b/cmd/tools/vreduce.v @@ -19,9 +19,12 @@ fn main() { fp.description('This tool will reduce the code file and try to make the smallest one it can that reproduces the error when the command is executed') fp.version(version) - error_msg := fp.string('error_msg', `m`, default_error_msg, 'the error message you want to reproduce, default: \'${default_error_msg}\'') - mut command := fp.string('command', `c`, default_command, 'the command used to try to reproduce the error, default: \'${default_command}\', will replace PATH with the path of the folder where it is run') - copy_project := fp.bool('cp', `p`, false, 'if used v reduce will copy the whole folder of the project') + error_msg := fp.string('error_msg', `m`, default_error_msg, + 'the error message you want to reproduce, default: \'${default_error_msg}\'') + mut command := fp.string('command', `c`, default_command, + 'the command used to try to reproduce the error, default: \'${default_command}\', will replace PATH with the path of the folder where it is run') + copy_project := fp.bool('cp', `p`, false, + 'if used v reduce will copy the whole folder of the project') timeout := fp.int('to', `t`, 0, 'sets a timeout for the command, default=0 : no timeout') do_fmt := fp.bool('fmt', `w`, false, 'enable v fmt for the output (rpdc_file_name.v)') file_paths := fp.finalize() or { @@ -80,8 +83,8 @@ fn main() { // start tests tmp_code := create_code(parse(content)) - warn_on_false(string_reproduces(tmp_code, error_msg, command, full_file_path, true, - timeout), 'string_reproduces', @LOCATION) + warn_on_false(string_reproduces(tmp_code, error_msg, command, full_file_path, true, timeout), + 'string_reproduces', @LOCATION) show_code_stats(tmp_code, label: 'Code size without comments') // reduce the code @@ -334,9 +337,7 @@ fn reduce_scope(content string, error_msg string, command string, do_fmt bool, f item.tmp_ignored = true // try to ignore it code := create_code(sc) item.tmp_ignored = false // dont need it anymore - if string_reproduces(code, error_msg, command, file_path, false, - timeout) - { + if string_reproduces(code, error_msg, command, file_path, false, timeout) { item.ignored = true modified_smth = true outer_modified_smth = true @@ -411,9 +412,7 @@ fn reduce_scope(content string, error_msg string, command string, do_fmt bool, f item.tmp_ignored = true code := create_code(line_tree) item.tmp_ignored = false // dont need it anymore - if string_reproduces(code, error_msg, command, file_path, false, - timeout) - { + if string_reproduces(code, error_msg, command, file_path, false, timeout) { item.ignored = true modified_smth = true outer_modified_smth = true diff --git a/cmd/tools/vrepeat.v b/cmd/tools/vrepeat.v index a63ab1f786..19017b2359 100644 --- a/cmd/tools/vrepeat.v +++ b/cmd/tools/vrepeat.v @@ -424,24 +424,38 @@ fn (mut context Context) parse_options() ! { fp.limit_free_args_to_at_least(1)! context.show_help = fp.bool('help', `h`, false, 'Show this help screen.') context.run_count = fp.int('runs', `r`, 10, 'Run count. Default: 10') - context.repeats_count = fp.int('repeats', `R`, 1, 'Repeats count (it repeats everything, including reporting). Default: 1') - context.warmup = fp.int('warmup', `w`, 2, 'Warmup run count. These are done *at the start* of each series, and the timings are ignored. Default: 2') - context.series = fp.int('series', `s`, 1, 'Series count. `-s 2 -r 4 a b` => aaaabbbbaaaabbbb, while `-s 3 -r 2 a b` => aabbaabbaabb. Default: 1') - context.ignore_failed = fp.bool('ignore', `e`, false, 'Ignore failed commands (returning a non 0 exit code).') - context.no_vexe_setenv = fp.bool('no_vexe_reset', `N`, false, 'Do not reset the VEXE env variable at the start. \n By default, VEXE will be set to "", to allow for measuring different V executables. Use this option to override it') - context.use_newline = fp.bool('newline', `n`, false, 'Use \\n, do not overwrite the last line. Produces more output, but easier to diagnose.') - context.is_silent = fp.bool('silent', `S`, false, 'Do not show progress lines, print only the final summary. Suitable for CIs.') + context.repeats_count = fp.int('repeats', `R`, 1, + 'Repeats count (it repeats everything, including reporting). Default: 1') + context.warmup = fp.int('warmup', `w`, 2, + 'Warmup run count. These are done *at the start* of each series, and the timings are ignored. Default: 2') + context.series = fp.int('series', `s`, 1, + 'Series count. `-s 2 -r 4 a b` => aaaabbbbaaaabbbb, while `-s 3 -r 2 a b` => aabbaabbaabb. Default: 1') + context.ignore_failed = fp.bool('ignore', `e`, false, + 'Ignore failed commands (returning a non 0 exit code).') + context.no_vexe_setenv = fp.bool('no_vexe_reset', `N`, false, + 'Do not reset the VEXE env variable at the start. \n By default, VEXE will be set to "", to allow for measuring different V executables. Use this option to override it') + context.use_newline = fp.bool('newline', `n`, false, + 'Use \\n, do not overwrite the last line. Produces more output, but easier to diagnose.') + context.is_silent = fp.bool('silent', `S`, false, + 'Do not show progress lines, print only the final summary. Suitable for CIs.') if os.getenv('VREPEAT_SILENT') != '' { context.is_silent = true } - context.show_output = fp.bool('output', `O`, false, 'Show command stdout/stderr in the progress indicator for each command. Note: slower, for verbose commands.') + context.show_output = fp.bool('output', `O`, false, + 'Show command stdout/stderr in the progress indicator for each command. Note: slower, for verbose commands.') context.verbose = fp.bool('verbose', `v`, false, 'Be more verbose.') - context.fail_on_maxtime = fp.int('max_time', `m`, max_time, 'Fail with exit code 2, when first cmd takes above M milliseconds (regression). Default: ${max_time}') - context.fail_on_regress_percent = fp.int('fail_percent', `f`, max_fail_percent, 'Fail with exit code 3, when first cmd is X% slower than the rest (regression). Default: ${max_fail_percent}') - context.cmd_template = fp.string('template', `t`, '{T}', 'Command template. {T} will be substituted with the current command. Default: {T}. \n Here is an example, that will produce and run 24 permutations = (3 for opt) x (2 for source) x (4 = v names):\n v repeat -p opt=-check-syntax,-check,"-o x.c" -p source=examples/hello_world.v,examples/hanoi.v --template "./{T} {opt} {source}" vold vnew vold_prod vnew_prod') - cmd_params := fp.string_multi('parameter', `p`, 'A parameter substitution list. `pp=val1,val2,val2` means that {pp} in the template, will be substituted with *each* of val1, val2, val3.') - context.nmins = fp.int('nmins', `i`, 0, 'Ignore the BOTTOM X results (minimum execution time). Makes the results more robust to performance flukes. Default: 0') - context.nmaxs = fp.int('nmaxs', `a`, 0, 'Ignore the TOP X results (maximum execution time). Makes the results more robust to performance flukes. Default: 0') + context.fail_on_maxtime = fp.int('max_time', `m`, max_time, + 'Fail with exit code 2, when first cmd takes above M milliseconds (regression). Default: ${max_time}') + context.fail_on_regress_percent = fp.int('fail_percent', `f`, max_fail_percent, + 'Fail with exit code 3, when first cmd is X% slower than the rest (regression). Default: ${max_fail_percent}') + context.cmd_template = fp.string('template', `t`, '{T}', + 'Command template. {T} will be substituted with the current command. Default: {T}. \n Here is an example, that will produce and run 24 permutations = (3 for opt) x (2 for source) x (4 = v names):\n v repeat -p opt=-check-syntax,-check,"-o x.c" -p source=examples/hello_world.v,examples/hanoi.v --template "./{T} {opt} {source}" vold vnew vold_prod vnew_prod') + cmd_params := fp.string_multi('parameter', `p`, + 'A parameter substitution list. `pp=val1,val2,val2` means that {pp} in the template, will be substituted with *each* of val1, val2, val3.') + context.nmins = fp.int('nmins', `i`, 0, + 'Ignore the BOTTOM X results (minimum execution time). Makes the results more robust to performance flukes. Default: 0') + context.nmaxs = fp.int('nmaxs', `a`, 0, + 'Ignore the TOP X results (maximum execution time). Makes the results more robust to performance flukes. Default: 0') for p in cmd_params { parts := p.split('=') if parts.len > 1 { diff --git a/cmd/tools/vrepl.v b/cmd/tools/vrepl.v index bb40faf80c..ba22954daa 100644 --- a/cmd/tools/vrepl.v +++ b/cmd/tools/vrepl.v @@ -306,7 +306,8 @@ fn (r &Repl) check_fn_type_kind(new_line string) FnType { // -usecache keeps repeated REPL checks responsive by reusing cached modules. // -w suppresses warnings from this synthetic println probe. // -check just does syntax and checker analysis without generating/running code. - os_response := os.execute('${os.quoted_path(vexe)} -usecache -w -check ${os.quoted_path(check_file)}') + os_response := + os.execute('${os.quoted_path(vexe)} -usecache -w -check ${os.quoted_path(check_file)}') str_response := convert_output(os_response.output) if os_response.exit_code != 0 && str_response.contains('can not print void expressions') { return FnType.void @@ -612,8 +613,8 @@ fn run_repl(workdir string, vrepl_prefix string) int { } } else { func_call, fntype := r.function_call(r.line) - filter_line := r.line.replace(r.line.find_between("'", "'"), '').replace(r.line.find_between('"', - '"'), '') + filter_line := + r.line.replace(r.line.find_between("'", "'"), '').replace(r.line.find_between('"', '"'), '') mut is_statement := false if filter_line.count('=') % 2 == 1 && (filter_line.count('!=') + filter_line.count('>=') + filter_line.count('<=')) == 0 { @@ -855,7 +856,8 @@ fn repl_check_vfile(file string) !os.Result { } // Declaration-only REPL lines do not need code generation or execution. // Cached checks keep repeated imports and definitions responsive. - s := os.execute('${os.quoted_path(vexe)} -usecache -message-limit 1 -repl -check ${os.quoted_path(file)}') + s := + os.execute('${os.quoted_path(vexe)} -usecache -message-limit 1 -repl -check ${os.quoted_path(file)}') if s.exit_code < 0 { rerror(s.output) return error(s.output) diff --git a/cmd/tools/vretry.v b/cmd/tools/vretry.v index f62262c1d1..227ba362d7 100644 --- a/cmd/tools/vretry.v +++ b/cmd/tools/vretry.v @@ -22,8 +22,10 @@ fn main() { fp.skip_executable() fp.limit_free_args_to_at_least(1)! context.show_help = fp.bool('help', `h`, false, 'Show this help screen.') - context.timeout = fp.float('timeout', `t`, 900.0, 'Timeout in seconds (for all retries). Default: 900.0 seconds (15 minutes).') * time.second - context.delay = fp.float('delay', `d`, 1.0, 'Delay between each retry in seconds. Default: 1.0 second.') * time.second + context.timeout = fp.float('timeout', `t`, 900.0, + 'Timeout in seconds (for all retries). Default: 900.0 seconds (15 minutes).') * time.second + context.delay = fp.float('delay', `d`, 1.0, + 'Delay between each retry in seconds. Default: 1.0 second.') * time.second context.retries = fp.int('retries', `r`, 10, 'Maximum number of retries. Default: 10.') if context.show_help { println(fp.usage()) diff --git a/cmd/tools/vschannel_16kb_httpbin_probe.v b/cmd/tools/vschannel_16kb_httpbin_probe.v index bb2e7710ba..1a6a019898 100644 --- a/cmd/tools/vschannel_16kb_httpbin_probe.v +++ b/cmd/tools/vschannel_16kb_httpbin_probe.v @@ -58,8 +58,10 @@ fn run_parent_mode() { fp.description('Probe net.http HTTPS POST behavior around 16KB payloads using https://httpbin.org/post.') fp.skip_executable() - expect_mode := fp.string('expect', `e`, 'after', 'Expected behavior mode: before|after|none. before expects >16KB failures, after expects all succeed.') - sizes_csv := fp.string('sizes', `s`, default_sizes_csv, 'Comma separated payload sizes in bytes.') + expect_mode := fp.string('expect', `e`, 'after', + 'Expected behavior mode: before|after|none. before expects >16KB failures, after expects all succeed.') + sizes_csv := fp.string('sizes', `s`, default_sizes_csv, + 'Comma separated payload sizes in bytes.') verbose := fp.bool('verbose', `v`, false, 'Print child process output for all sizes.') show_help := fp.bool('help', `h`, false, 'Show this help screen.') free_args := fp.finalize() or { diff --git a/cmd/tools/vself.v b/cmd/tools/vself.v index 15042b92ae..c55ed760fc 100644 --- a/cmd/tools/vself.v +++ b/cmd/tools/vself.v @@ -23,7 +23,8 @@ fn main() { vexe_name := os.file_name(vexe) short_v_name := vexe_name.all_before('.') - recompilation.must_be_enabled(vroot, 'Please install V from source, to use `${vexe_name} self` .') + recompilation.must_be_enabled(vroot, + 'Please install V from source, to use `${vexe_name} self` .') os.chdir(vroot)! os.setenv('VCOLORS', 'always', true) repeat_count, mut args := extract_repeat_count(args_[1..].filter(it != 'self')) diff --git a/cmd/tools/vsetup-freetype.v b/cmd/tools/vsetup-freetype.v index 15578b826c..52398852dc 100644 --- a/cmd/tools/vsetup-freetype.v +++ b/cmd/tools/vsetup-freetype.v @@ -15,7 +15,8 @@ fn main() { if os.is_dir(freetype_folder) { println('Thirdparty "freetype" is already installed.') } else { - s := os.execute('${os.quoted_path(vexe)} retry -- git clone --filter=blob:none ${freetype_repo_url} ${freetype_folder}') + s := + os.execute('${os.quoted_path(vexe)} retry -- git clone --filter=blob:none ${freetype_repo_url} ${freetype_folder}') if s.exit_code != 0 { panic(s.output) } diff --git a/cmd/tools/vshader.v b/cmd/tools/vshader.v index df48904b23..9198edfb52 100644 --- a/cmd/tools/vshader.v +++ b/cmd/tools/vshader.v @@ -87,7 +87,8 @@ fn main() { show_help: fp.bool('help', `h`, false, 'Show this help text.') force_update: fp.bool('force-update', `u`, false, 'Force update of the sokol-shdc tool.') verbose: fp.bool('verbose', `v`, false, 'Be verbose about the tools progress.') - slangs: fp.string_multi('slang', `l`, 'Shader dialects to generate code for. Default is all.\n Available dialects: ${supported_slangs}') + slangs: fp.string_multi('slang', `l`, + 'Shader dialects to generate code for. Default is all.\n Available dialects: ${supported_slangs}') } if opt.show_help { println(fp.usage()) @@ -247,8 +248,7 @@ fn ensure_external_tools(opt Options) ! { if is_shdc_available { eprintln(' file path: ${shdc_exe}') eprintln(' file size: ${os.file_size(shdc_exe)}') - eprintln(' file time: ${time.unix_microsecond(os.file_last_mod_unix(shdc_exe), - 0)}') + eprintln(' file time: ${time.unix_microsecond(os.file_last_mod_unix(shdc_exe), 0)}') } } if is_shdc_available && is_shdc_executable { diff --git a/cmd/tools/vsqlite/main.v b/cmd/tools/vsqlite/main.v index abee619d5c..1c950b9809 100644 --- a/cmd/tools/vsqlite/main.v +++ b/cmd/tools/vsqlite/main.v @@ -330,7 +330,8 @@ fn (mut app App) exec_file(path string) { trimmed := stmt.trim_space() // Strip comment-only lines to decide if the chunk has real SQL, // but pass the original (with comments) to SQLite so it can parse them. - sql_content := trimmed.split('\n').filter(!it.trim_space().starts_with('--')).join('\n').trim_space() + sql_content := + trimmed.split('\n').filter(!it.trim_space().starts_with('--')).join('\n').trim_space() if sql_content == '' { continue } @@ -348,7 +349,8 @@ fn (mut app App) read_file_repl(path string) { mut count := 0 for stmt in split_statements(content) { trimmed := stmt.trim_space() - sql_content := trimmed.split('\n').filter(!it.trim_space().starts_with('--')).join('\n').trim_space() + sql_content := + trimmed.split('\n').filter(!it.trim_space().starts_with('--')).join('\n').trim_space() if sql_content == '' { continue } diff --git a/cmd/tools/vsymlink/vsymlink_windows.c.v b/cmd/tools/vsymlink/vsymlink_windows.c.v index a2fd6c3e0f..957749f3d1 100644 --- a/cmd/tools/vsymlink/vsymlink_windows.c.v +++ b/cmd/tools/vsymlink/vsymlink_windows.c.v @@ -150,8 +150,8 @@ fn set_reg_value(reg_key voidptr, key string, value string) !bool { // letting them know that the system environment has changed and should be reloaded fn send_setting_change_msg(message_data string) !bool { message_data_wide := message_data.to_wide() - if C.SendMessageTimeoutW(os.hwnd_broadcast, os.wm_settingchange, 0, unsafe { &u32(message_data_wide) }, - os.smto_abortifhung, 5000, 0) == 0 { + if C.SendMessageTimeoutW(os.hwnd_broadcast, os.wm_settingchange, 0, + unsafe { &u32(message_data_wide) }, os.smto_abortifhung, 5000, 0) == 0 { return error('Could not broadcast WM_SETTINGCHANGE') } return true diff --git a/cmd/tools/vtest-cleancode.v b/cmd/tools/vtest-cleancode.v index 3ae033f7d5..493e04aafc 100644 --- a/cmd/tools/vtest-cleancode.v +++ b/cmd/tools/vtest-cleancode.v @@ -43,7 +43,9 @@ const vfmt_verify_list = [ 'vlib/', ] -const vfmt_known_failing_exceptions = arrays.merge(verify_known_failing_exceptions, []string{}) +const vfmt_known_failing_exceptions = arrays.merge(verify_known_failing_exceptions, [ + 'vlib/v/tests/structs/anon_struct_local_init_test.v', +]) const vexe = os.getenv('VEXE') @@ -88,10 +90,10 @@ fn v_test_vetting(vargs string) ! { '${os.quoted_path(vexe)} fmt -inprocess -verify', 'fmt -inprocess -verify' } vfmt_list := util.find_all_v_files(vfmt_verify_list) or { return } - exceptions := (util.find_all_v_files(vfmt_known_failing_exceptions) or { return }).map(os.abs_path) + exceptions := + (util.find_all_v_files(vfmt_known_failing_exceptions) or { return }).map(os.abs_path) filtered_vfmt_list := vfmt_list.filter(os.abs_path(it) !in exceptions) - verify_session := tsession(vargs, 'vfmt.v', fmt_cmd, fmt_args, filtered_vfmt_list, - exceptions) + verify_session := tsession(vargs, 'vfmt.v', fmt_cmd, fmt_args, filtered_vfmt_list, exceptions) if vet_session.benchmark.nfail > 0 || verify_session.benchmark.nfail > 0 { eprintln('\n') diff --git a/cmd/tools/vtest-parser.v b/cmd/tools/vtest-parser.v index 9dcbd88114..1321b0f66b 100644 --- a/cmd/tools/vtest-parser.v +++ b/cmd/tools/vtest-parser.v @@ -106,12 +106,18 @@ fn process_cli_args() &Context { context.is_verbose = fp.bool('verbose', `v`, false, 'Be more verbose.') context.is_silent = fp.bool('silent', `S`, false, 'Do not print progress at all.') context.is_linear = fp.bool('linear', `L`, false, 'Print linear progress log. Suitable for CI.') - context.show_src = fp.bool('show_source', `E`, false, 'Print the partial source code that caused a fault/panic in the parser.') - context.period_ms = fp.int('progress_ms', `s`, 500, 'print a status report periodically, the period is given in milliseconds.') - context.is_worker = fp.bool('worker', `w`, false, 'worker specific flag - is this a worker process, that can crash/panic.') - context.cut_index = fp.int('cut_index', `c`, 1, 'worker specific flag - cut index in the source file, everything before that will be parsed, the rest - ignored.') - context.timeout_ms = fp.int('timeout_ms', `t`, 250, 'worker specific flag - timeout in ms; a worker taking longer, will self terminate.') - context.path = fp.string('path', `p`, '', 'worker specific flag - path to the current source file, which will be parsed.') + context.show_src = fp.bool('show_source', `E`, false, + 'Print the partial source code that caused a fault/panic in the parser.') + context.period_ms = fp.int('progress_ms', `s`, 500, + 'print a status report periodically, the period is given in milliseconds.') + context.is_worker = fp.bool('worker', `w`, false, + 'worker specific flag - is this a worker process, that can crash/panic.') + context.cut_index = fp.int('cut_index', `c`, 1, + 'worker specific flag - cut index in the source file, everything before that will be parsed, the rest - ignored.') + context.timeout_ms = fp.int('timeout_ms', `t`, 250, + 'worker specific flag - timeout in ms; a worker taking longer, will self terminate.') + context.path = fp.string('path', `p`, '', + 'worker specific flag - path to the current source file, which will be parsed.') if context.is_help { println(fp.usage()) diff --git a/cmd/tools/vtest.v b/cmd/tools/vtest.v index 481fc891ed..ebd8009728 100644 --- a/cmd/tools/vtest.v +++ b/cmd/tools/vtest.v @@ -40,8 +40,7 @@ fn main() { for targ in args_after { if os.is_dir(targ) { // Fetch all tests from the directory - files, skip_files := ctx.should_test_dir(targ.trim_right(os.path_separator), - backend) + files, skip_files := ctx.should_test_dir(targ.trim_right(os.path_separator), backend) ts.files << files ts.skip_files << skip_files continue @@ -200,7 +199,8 @@ fn (mut ctx Context) should_test_when_it_contains_matching_fns(path string, _bac fn extract_flag_bool(flag_name string, mut after []string, flag_default bool) bool { mut res := flag_default - orig_after := after.clone() // workaround for after.filter() codegen bug, when `mut after []string` + orig_after := + after.clone() // workaround for after.filter() codegen bug, when `mut after []string` matches_after := orig_after.filter(it != flag_name) if matches_after.len < after.len { after = matches_after.clone() diff --git a/cmd/tools/vtest_test.v b/cmd/tools/vtest_test.v index b9934f890c..7bee41f512 100644 --- a/cmd/tools/vtest_test.v +++ b/cmd/tools/vtest_test.v @@ -56,7 +56,8 @@ fn test_with_several_test_files() { fn test_with_stats_and_several_test_files() { // There should be more OKs here, since the output will have the inner OKs for each individual test fn: - res := os.execute_or_exit('${os.quoted_path(mytest_exe)} -stats test ${os.quoted_path(tpath_passing)}') + res := + os.execute_or_exit('${os.quoted_path(mytest_exe)} -stats test ${os.quoted_path(tpath_passing)}') assert res.output.contains('1 assert'), res.output assert res.output.contains('3 asserts'), res.output assert res.output.contains('2 passed, 2 total'), res.output diff --git a/cmd/tools/vup.v b/cmd/tools/vup.v index 86cb3a6e03..7e71a165b8 100644 --- a/cmd/tools/vup.v +++ b/cmd/tools/vup.v @@ -232,7 +232,8 @@ fn (app App) install_git() { } println('Downloading git 32 bit for Windows, please wait.') // We'll use 32 bit because maybe someone out there is using 32-bit windows - res_download := os.execute('bitsadmin.exe /transfer "vgit" https://github.com/git-for-windows/git/releases/download/v2.30.0.windows.2/Git-2.30.0.2-32-bit.exe "${os.getwd()}/git32.exe"') + res_download := + os.execute('bitsadmin.exe /transfer "vgit" https://github.com/git-for-windows/git/releases/download/v2.30.0.windows.2/Git-2.30.0.2-32-bit.exe "${os.getwd()}/git32.exe"') if res_download.exit_code != 0 { eprintln('Unable to install git automatically: please install git manually') panic(res_download.output) diff --git a/cmd/tools/vvet/analyze.v b/cmd/tools/vvet/analyze.v index 1e84a046d2..a1f939e776 100644 --- a/cmd/tools/vvet/analyze.v +++ b/cmd/tools/vvet/analyze.v @@ -42,8 +42,8 @@ fn (mut vt VetAnalyze) stmt(vet &Vet, stmt ast.Stmt) { ast.AssignStmt { if stmt.op == .plus_assign { if stmt.right[0] in [ast.StringLiteral, ast.StringInterLiteral] { - vt.save_expr(stringconcat_cutoff, '${stmt.left[0].str()} += ${stmt.right[0].str()}', - vet.file, stmt.pos) + vt.save_expr(stringconcat_cutoff, + '${stmt.left[0].str()} += ${stmt.right[0].str()}', vet.file, stmt.pos) } } } @@ -102,14 +102,15 @@ fn (mut vt VetAnalyze) expr(vet &Vet, expr ast.Expr) { vt.call_counter['${int(vt.cur_fn.receiver.typ)}.${expr.name}']++ } } - vt.save_expr(callexpr_cutoff, '${left_str}.${expr.name}(${expr.args.map(it.str()).join(', ')})', - vet.file, expr.pos) + vt.save_expr(callexpr_cutoff, + '${left_str}.${expr.name}(${expr.args.map(it.str()).join(', ')})', vet.file, + expr.pos) } else { lock vt.call_counter { vt.call_counter[expr.name]++ } - vt.save_expr(callexpr_cutoff, '${expr.name}(${expr.args.map(it.str()).join(', ')})', - vet.file, expr.pos) + vt.save_expr(callexpr_cutoff, + '${expr.name}(${expr.args.map(it.str()).join(', ')})', vet.file, expr.pos) } } ast.AsCast { @@ -162,7 +163,8 @@ fn (mut vt VetAnalyze) vet_repeated_code(mut vet Vet) { } for file, info_pos in info { for k, pos in info_pos { - vet.notice_with_file(file, '${expr} occurs ${k + 1}/${occurrences} times in ${scope_name}.', + vet.notice_with_file(file, + '${expr} occurs ${k + 1}/${occurrences} times in ${scope_name}.', pos.line_nr, .repeated_code) } } @@ -179,7 +181,8 @@ fn (mut vt VetAnalyze) vet_inlining_fn(mut vet Vet) { if calls < fns_call_cutoff { continue } - vet.notice_with_file(file, '${fn_name.all_after('.')} fn might be inlined (possibly called at least ${calls} times)', + vet.notice_with_file(file, + '${fn_name.all_after('.')} fn might be inlined (possibly called at least ${calls} times)', pos.line_nr, .inline_fn) } } diff --git a/cmd/tools/vvet/vet_test.v b/cmd/tools/vvet/vet_test.v index a5e56b4ef9..674edaae44 100644 --- a/cmd/tools/vvet/vet_test.v +++ b/cmd/tools/vvet/vet_test.v @@ -43,7 +43,8 @@ fn check_path(vexe string, dir string, tests []string) int { program := path print(path + ' ') file_options := get_file_options(path) - res := os.execute('${os.quoted_path(vexe)} vet -nocolor ${file_options.vflags} ${os.quoted_path(program)}') + res := + os.execute('${os.quoted_path(vexe)} vet -nocolor ${file_options.vflags} ${os.quoted_path(program)}') if res.exit_code < 0 { panic(res.output) } diff --git a/cmd/tools/vvet/vvet.v b/cmd/tools/vvet/vvet.v index c78184f4dd..ddf7d456c5 100644 --- a/cmd/tools/vvet/vvet.v +++ b/cmd/tools/vvet/vvet.v @@ -226,8 +226,8 @@ fn (mut vt Vet) vet_fn_documentation(lines []string, line string, lnumber int) { } if grab { clean_line := line.all_before_last('{').trim(' ') - vt.warn('Function documentation seems to be missing for "${clean_line}".', - lnumber, .doc) + vt.warn('Function documentation seems to be missing for "${clean_line}".', lnumber, + .doc) } } else { fn_name := ident_fn_name(line) @@ -247,8 +247,8 @@ fn (mut vt Vet) vet_fn_documentation(lines []string, line string, lnumber int) { && !prev_prev_line.starts_with('//') { grab = false clean_line := line.all_before_last('{').trim(' ') - vt.warn('The documentation for "${clean_line}" seems incomplete.', - lnumber, .doc) + vt.warn('The documentation for "${clean_line}" seems incomplete.', lnumber, + .doc) break } diff --git a/cmd/v/v.v b/cmd/v/v.v index 7776296467..cdeb1eeac8 100644 --- a/cmd/v/v.v +++ b/cmd/v/v.v @@ -63,7 +63,6 @@ const external_tools = [ 'watch', 'where', ] -const list_of_flags_that_allow_duplicates = ['cc', 'd', 'define', 'cf', 'cflags'] const delegated_v2_exe_env = 'V_V2_EXE' @[unsafe] @@ -115,8 +114,7 @@ fn main() { return } mut args_and_flags := util.join_env_vflags_and_os_args()[1..] - prefs, command := pref.parse_args_and_show_errors(external_tools, args_and_flags, - true) + prefs, command := pref.parse_args_and_show_errors(external_tools, args_and_flags, true) maybe_delegate_to_vvmrc(command, prefs) maybe_delegate_to_v2(command, prefs) if prefs.use_cache && os.user_os() == 'windows' { diff --git a/cmd/v/vvm_test.v b/cmd/v/vvm_test.v index 9ae5f10d14..ec940d69a8 100644 --- a/cmd/v/vvm_test.v +++ b/cmd/v/vvm_test.v @@ -50,7 +50,8 @@ fn test_vvmrc_delegates_to_matching_compiler_executable() { bin_dir := os.join_path(tmp_root, 'bin') os.mkdir_all(bin_dir) or { panic(err) } fake_compiler_source := os.join_path(tmp_root, 'fake_compiler.v') - os.write_file(fake_compiler_source, "import os\nfn main() {\n\tprintln('${delegated_marker} ' + os.args[1..].join(' '))\n}\n") or { + os.write_file(fake_compiler_source, + "import os\nfn main() {\n\tprintln('${delegated_marker} ' + os.args[1..].join(' '))\n}\n") or { panic(err) } fake_compiler_exe := os.join_path(bin_dir, if os.user_os() == 'windows' { @@ -58,14 +59,14 @@ fn test_vvmrc_delegates_to_matching_compiler_executable() { } else { 'v${requested_vvm_test_version}' }) - compile_res := os.execute('${os.quoted_path(current_vexe)} -o ${os.quoted_path(fake_compiler_exe)} ${os.quoted_path(fake_compiler_source)}') + compile_res := + os.execute('${os.quoted_path(current_vexe)} -o ${os.quoted_path(fake_compiler_exe)} ${os.quoted_path(fake_compiler_source)}') assert compile_res.exit_code == 0, compile_res.output project_dir := os.join_path(tmp_root, 'project') os.mkdir_all(project_dir) or { panic(err) } os.write_file(os.join_path(project_dir, '.vvmrc'), requested_vvm_test_version) or { panic(err) } - os.write_file(os.join_path(project_dir, 'main.v'), "fn main() {\n\tprintln('from project')\n}\n") or { - panic(err) - } + os.write_file(os.join_path(project_dir, 'main.v'), + "fn main() {\n\tprintln('from project')\n}\n") or { panic(err) } mut envs := os.environ() path_key := find_path_env_key(envs) envs[path_key] = '${bin_dir}${os.path_delimiter}${envs[path_key]}' diff --git a/cmd/v2/guiprof/draw.v b/cmd/v2/guiprof/draw.v index 26b4b3ea55..837c69fb79 100644 --- a/cmd/v2/guiprof/draw.v +++ b/cmd/v2/guiprof/draw.v @@ -189,6 +189,7 @@ fn draw_timeline(mut app App) { cursor_x := margin + f32(app.selected_frame) * tick_spacing // Triangle cursor draw_triangle_filled(ctx, cursor_x, timeline_y + 15, cursor_x - 8, timeline_y + 5, + cursor_x + 8, timeline_y + 5, timeline_cursor) // Vertical line @@ -296,7 +297,8 @@ fn draw_details(mut app App) { } } else { // Instructions - ctx.draw_text(20, int(details_y) + 20, 'Click on a histogram bar to select a frame, or use keyboard arrows to navigate', + ctx.draw_text(20, int(details_y) + 20, + 'Click on a histogram bar to select a frame, or use keyboard arrows to navigate', color: text_color size: 16 ) diff --git a/cmd/v2/test_ssa_backends.v b/cmd/v2/test_ssa_backends.v index 6814082dd4..0f6e717797 100644 --- a/cmd/v2/test_ssa_backends.v +++ b/cmd/v2/test_ssa_backends.v @@ -154,8 +154,7 @@ fn main() { } // Strip terminal control characters that script command may prepend - mut cleaned := gen_out.replace('\r\n', '\n').replace('\x04', '').replace('\x08', - '') + mut cleaned := gen_out.replace('\r\n', '\n').replace('\x04', '').replace('\x08', '') // Remove "^D" literal string that macOS script may add if cleaned.starts_with('^D') { cleaned = cleaned[2..] diff --git a/examples/1brc/make-samples/main.v b/examples/1brc/make-samples/main.v index d05301af2b..c42f1fbc13 100644 --- a/examples/1brc/make-samples/main.v +++ b/examples/1brc/make-samples/main.v @@ -14,7 +14,8 @@ fn main() { fp.skip_executable() fp.application('Sample generator for 1 billion rows challenge') fp.description('The 1 billion rows challenge solved in V.\nFor details, see https://www.morling.dev/blog/one-billion-row-challenge/') - input_file := fp.string('city-file', `i`, 'cities.txt', 'Path to input file with cities and means list') + input_file := fp.string('city-file', `i`, 'cities.txt', + 'Path to input file with cities and means list') fp.limit_free_args_to_exactly(1)! sample_count := fp.remaining_parameters()[0].u64() diff --git a/examples/1brc/solution/main.v b/examples/1brc/solution/main.v index e8b7af09e4..3a9b53dfee 100644 --- a/examples/1brc/solution/main.v +++ b/examples/1brc/solution/main.v @@ -178,8 +178,10 @@ fn main() { fp.application('1 billion rows challenge') fp.description('The 1 billion rows challenge solved in V.\nFor details, see https://www.morling.dev/blog/one-billion-row-challenge/') thread_count := u32(fp.int('threads', `n`, 1, 'number of threads for parallel processing.')) - print_nicely := fp.bool('human-readable', `h`, false, 'Print results with new lines rather than following challenge spec') - quiet := fp.bool('quiet', `q`, false, 'Suppress the results output (e.g., if you only care about timing)') + print_nicely := fp.bool('human-readable', `h`, false, + 'Print results with new lines rather than following challenge spec') + quiet := fp.bool('quiet', `q`, false, + 'Suppress the results output (e.g., if you only care about timing)') fp.limit_free_args_to_exactly(1)! path := fp.remaining_parameters()[0] diff --git a/examples/2048/2048.v b/examples/2048/2048.v index fc288c6f59..3cd7c928af 100644 --- a/examples/2048/2048.v +++ b/examples/2048/2048.v @@ -503,26 +503,6 @@ fn ai_empty_count(board AiBoard) int { return empty_tiles } -@[inline] -fn ai_has_moves(board AiBoard) bool { - if ai_empty_count(board) > 0 { - return true - } - for y in 0 .. 4 { - for x in 0 .. 4 { - idx := y << 2 + x - value := ai_tile(board, idx) - if x < 3 && value == ai_tile(board, idx + 1) { - return true - } - if y < 3 && value == ai_tile(board, idx + 4) { - return true - } - } - } - return false -} - fn (ai &AiEngine) move_left(board AiBoard) (AiBoard, bool) { mut res := AiBoard(0) mut changed := false @@ -1144,7 +1124,8 @@ fn (app &App) draw_tiles() { th := tw // square tiles, w == h xoffset := xstart + app.ui.padding_size + x * toffset yoffset := ystart + app.ui.padding_size + y * toffset - app.gg.draw_rounded_rect_filled(xoffset, yoffset, tw, th, tw / 8, app.theme.tile_colors[0]) + app.gg.draw_rounded_rect_filled(xoffset, yoffset, tw, th, tw / 8, + app.theme.tile_colors[0]) } } @@ -1184,10 +1165,12 @@ fn (app &App) draw_one_tile(x int, y int, tidx int) { if oidx != 0xFFFF_FFFF { scaling := app.ui.tile_size * easing.in_out_quint(app.mtickers[y][x]) if ox != x { - dx = math.clip(int(scaling * (f64(ox) - f64(x))), -4 * app.ui.tile_size, 4 * app.ui.tile_size) + dx = math.clip(int(scaling * (f64(ox) - f64(x))), -4 * app.ui.tile_size, + 4 * app.ui.tile_size) } if oy != y { - dy = math.clip(int(scaling * (f64(oy) - f64(y))), -4 * app.ui.tile_size, 4 * app.ui.tile_size) + dy = math.clip(int(scaling * (f64(oy) - f64(y))), -4 * app.ui.tile_size, + 4 * app.ui.tile_size) } } tile_color := if tidx < app.theme.tile_colors.len { diff --git a/examples/archive/tar_gz_reader.v b/examples/archive/tar_gz_reader.v index 0867ac6cb4..46a663eec5 100644 --- a/examples/archive/tar_gz_reader.v +++ b/examples/archive/tar_gz_reader.v @@ -30,11 +30,16 @@ fn new_context() !&Context { fp.description('Reads into memory selected sections of *.tar.gz. archives from https or home_dir.') fp.skip_executable() ctx := &Context{ - url: fp.string('url', `u`, default_url, 'archive *.tar.gz URL, default(${default_url}). Start name with file:/// for local') - chunks: fp.bool('chunks', `c`, false, 'decompress with chunks to reduce RAM usage, default(false)') - debug: fp.int('debug', `d`, 0, 'prints blocks: 1=other, 2:+dirs, 3=+files, 4=+data, default(0=silent)') - max_blocks: fp.int('max_blocks', `m`, 0, 'maximum blocks to read, stop early. Default(0=read all)') - filename: fp.string('filename', `f`, '', 'filename content complete print, stop early. Default(empty means none)') + url: fp.string('url', `u`, default_url, + 'archive *.tar.gz URL, default(${default_url}). Start name with file:/// for local') + chunks: fp.bool('chunks', `c`, false, + 'decompress with chunks to reduce RAM usage, default(false)') + debug: fp.int('debug', `d`, 0, + 'prints blocks: 1=other, 2:+dirs, 3=+files, 4=+data, default(0=silent)') + max_blocks: fp.int('max_blocks', `m`, 0, + 'maximum blocks to read, stop early. Default(0=read all)') + filename: fp.string('filename', `f`, '', + 'filename content complete print, stop early. Default(empty means none)') } additional := fp.finalize()! if additional.len > 0 { @@ -84,12 +89,6 @@ mut: content []u8 } -fn new_file_reader(ctx &Context) FileReader { - return FileReader{ - ctx: ctx - } -} - fn (mut f FileReader) other_block(mut read tar.Read, details string) { if f.ctx.read_last_block(mut read) { return diff --git a/examples/breakout/breakout.v b/examples/breakout/breakout.v index 5f906937d3..396c1997c9 100644 --- a/examples/breakout/breakout.v +++ b/examples/breakout/breakout.v @@ -127,8 +127,7 @@ fn (mut g Game) draw() { ws := gg.window_size() g.ctx.begin() sgl.push_matrix() - sgl.scale(f32(ws.width) / f32(designed_width), f32(ws.height) / f32(designed_height), - 0) + sgl.scale(f32(ws.width) / f32(designed_width), f32(ws.height) / f32(designed_height), 0) g.draw_paddle() g.draw_ball() @@ -160,8 +159,7 @@ fn (g &Game) draw_paddle() { roffset, rradius := -5, 18 g.ctx.draw_circle_filled(g.paddle_x - roffset, g.height, rradius, gg.blue) g.ctx.draw_circle_filled(g.paddle_x + g.paddle_w + roffset, g.height, rradius, gg.blue) - g.ctx.draw_rect_filled(g.paddle_x, g.height - g.paddle_h + 2, g.paddle_w, g.paddle_h, - gg.blue) + g.ctx.draw_rect_filled(g.paddle_x, g.height - g.paddle_h + 2, g.paddle_w, g.paddle_h, gg.blue) g.ctx.draw_rect_filled(g.paddle_x, g.height - g.paddle_h + 2, g.paddle_w, bevel_size, highlight_color) } @@ -170,8 +168,8 @@ fn (g &Game) draw_brick(brick Brick) { g.ctx.draw_rect_filled(brick.x, brick.y, brick.w, brick.h, brick.c) g.ctx.draw_rect_filled(brick.x, brick.y, brick.w, bevel_size, highlight_color) g.ctx.draw_rect_filled(brick.x, brick.y, bevel_size, brick.h - bevel_size, highlight_color) - g.ctx.draw_rect_filled(brick.x + brick.w - bevel_size, brick.y, bevel_size, brick.h - bevel_size, - shade_color) + g.ctx.draw_rect_filled(brick.x + brick.w - bevel_size, brick.y, bevel_size, + brick.h - bevel_size, shade_color) g.ctx.draw_rect_filled(brick.x, brick.y + brick.h - bevel_size, brick.w, bevel_size, shade_color) } diff --git a/examples/c_interop_wkhtmltopdf.v b/examples/c_interop_wkhtmltopdf.v index 384e0a8b9b..e3ff8cd3b1 100644 --- a/examples/c_interop_wkhtmltopdf.v +++ b/examples/c_interop_wkhtmltopdf.v @@ -63,7 +63,8 @@ fn main() { converter := C.wkhtmltopdf_create_converter(global_settings) println('wkhtmltopdf_create_converter: ${voidptr(converter)}') // convert - mut result := C.wkhtmltopdf_set_object_setting(object_settings, c'page', c'http://www.google.com.br') + mut result := C.wkhtmltopdf_set_object_setting(object_settings, c'page', + c'http://www.google.com.br') println('wkhtmltopdf_set_object_setting: ${result} [page = http://www.google.com.br]') C.wkhtmltopdf_add_object(converter, object_settings, 0) println('wkhtmltopdf_add_object') diff --git a/examples/clock/clock.v b/examples/clock/clock.v index 05bf0f7e6b..23cf79e322 100644 --- a/examples/clock/clock.v +++ b/examples/clock/clock.v @@ -50,15 +50,13 @@ fn on_frame(mut app App) { app.gg.begin() for i in 0 .. 60 { // draw minute tics - draw_convex_poly_rotate(mut app.gg, app.dpi_scale, app.minutes_tic, tic_color, - i * 6) + draw_convex_poly_rotate(mut app.gg, app.dpi_scale, app.minutes_tic, tic_color, i * 6) } for i in 0 .. 12 { // hours draw_convex_poly_rotate(mut app.gg, app.dpi_scale, app.hours_tic, tic_color, i * 30) } for i in 0 .. 4 { // 3 hours - draw_convex_poly_rotate(mut app.gg, app.dpi_scale, app.hours3_tic, tic_color, - i * 90) + draw_convex_poly_rotate(mut app.gg, app.dpi_scale, app.hours3_tic, tic_color, i * 90) } n := time.now() diff --git a/examples/database/mysql_pool.v b/examples/database/mysql_pool.v index 75b7d9b2b8..b9b8fe3824 100644 --- a/examples/database/mysql_pool.v +++ b/examples/database/mysql_pool.v @@ -86,8 +86,10 @@ fn main() { vals: ['1', 'jackson', ''] } - response = db.exec_param_many('select * from users where username = ? and id = ?', - ['bailey', '3'])! + response = db.exec_param_many('select * from users where username = ? and id = ?', [ + 'bailey', + '3', + ])! assert response[0] == mysql.Row{ vals: ['3', 'bailey', ''] } diff --git a/examples/fireworks/modules/objects/particle.v b/examples/fireworks/modules/objects/particle.v index 8b2b46276d..6b053cf002 100644 --- a/examples/fireworks/modules/objects/particle.v +++ b/examples/fireworks/modules/objects/particle.v @@ -12,8 +12,8 @@ pub mut: } pub fn (particle Particle) draw(mut ctx gg.Context) { - ctx.draw_circle_filled(particle.pos.x, get_params().height - particle.pos.y, get_params().particle_radius, - particle.color) + ctx.draw_circle_filled(particle.pos.x, get_params().height - particle.pos.y, + get_params().particle_radius, particle.color) } pub fn (mut particle Particle) tick(mut rocket Rocket, mut ctx gg.Context) { diff --git a/examples/fireworks/modules/objects/rocket.v b/examples/fireworks/modules/objects/rocket.v index 46e47c2311..cf68e91bee 100644 --- a/examples/fireworks/modules/objects/rocket.v +++ b/examples/fireworks/modules/objects/rocket.v @@ -15,8 +15,8 @@ pub mut: } pub fn (rocket Rocket) draw(mut ctx gg.Context) { - ctx.draw_circle_filled(rocket.pos.x, get_params().height - rocket.pos.y, get_params().rocket_radius, - rocket.color) + ctx.draw_circle_filled(rocket.pos.x, get_params().height - rocket.pos.y, + get_params().rocket_radius, rocket.color) } pub fn (mut rocket Rocket) explode() { diff --git a/examples/flappylearning/game.v b/examples/flappylearning/game.v index 1d7599a289..6634eeaacd 100644 --- a/examples/flappylearning/game.v +++ b/examples/flappylearning/game.v @@ -208,9 +208,12 @@ fn (mut app App) init_images_wrapper() { fn (mut app App) init_images() ! { app.bird = app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/bird.png')!)! - app.pipetop = app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/pipetop.png')!)! - app.pipebottom = app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/pipebottom.png')!)! - app.background = app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/background.png')!)! + app.pipetop = + app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/pipetop.png')!)! + app.pipebottom = app.gg.create_image_from_byte_array(asset.read_bytes('assets', + 'img/pipebottom.png')!)! + app.background = app.gg.create_image_from_byte_array(asset.read_bytes('assets', + 'img/background.png')!)! } fn frame(app &App) { @@ -230,20 +233,18 @@ fn (app &App) display() { app.gg.draw_image(f32(pipe.x), f32(pipe.y + pipe.height - app.pipetop.height), app.pipetop.width, app.pipetop.height, app.pipetop) } else { - app.gg.draw_image(f32(pipe.x), f32(pipe.y), app.pipebottom.width, app.pipebottom.height, - app.pipebottom) + app.gg.draw_image(f32(pipe.x), f32(pipe.y), app.pipebottom.width, + app.pipebottom.height, app.pipebottom) } } for bird in app.birds { if bird.alive { - app.gg.draw_image(f32(bird.x), f32(bird.y), app.bird.width, app.bird.height, - app.bird) + app.gg.draw_image(f32(bird.x), f32(bird.y), app.bird.width, app.bird.height, app.bird) } } app.gg.draw_rect_filled(0, 510, app.background.width * 3, 5, gg.Color{0x21, 0x19, 0x28, 255}) app.gg.draw_rect_filled(0, 513, app.background.width * 3, app.background.height, bg_color) - app.gg.draw_rect_filled(550, 0, app.background.width + 50, app.background.height + 20, - bg_color) + app.gg.draw_rect_filled(550, 0, app.background.width + 50, app.background.height + 20, bg_color) app.gg.draw_text_def(10, 25, 'Score: ${app.score}') app.gg.draw_text_def(10, 50, 'Max Score: ${app.max_score}') app.gg.draw_text_def(10, 75, 'Generation: ${app.generation}') diff --git a/examples/game_of_life/life.v b/examples/game_of_life/life.v index 33382d778a..8ffb63148d 100644 --- a/examples/game_of_life/life.v +++ b/examples/game_of_life/life.v @@ -4,10 +4,6 @@ import time const cell = '█' const nothing = ' ' -const switches = { - cell: nothing - nothing: cell -} const transformers = [nothing, cell] struct Game { diff --git a/examples/game_of_life/life_gg.v b/examples/game_of_life/life_gg.v index 757e715f93..5a4dbb0a24 100644 --- a/examples/game_of_life/life_gg.v +++ b/examples/game_of_life/life_gg.v @@ -14,8 +14,8 @@ fn print_automaton(app &App) { for x := 1; x < app.a.field.maxx; x++ { cell := app.a.field.get(x, y) if cell == 1 { - app.gg.draw_rect_filled(f32(square_size * x), f32(square_size * y), f32(square_size), - f32(square_size), filled_color) + app.gg.draw_rect_filled(f32(square_size * x), f32(square_size * y), + f32(square_size), f32(square_size), filled_color) } } } diff --git a/examples/game_of_life/modules/automaton/automaton.v b/examples/game_of_life/modules/automaton/automaton.v index f3711f2e37..0c581252fa 100644 --- a/examples/game_of_life/modules/automaton/automaton.v +++ b/examples/game_of_life/modules/automaton/automaton.v @@ -80,8 +80,8 @@ pub fn (mut aa Automaton) update() { for y := 1; y < aa.field.maxy; y++ { for x := 1; x < aa.field.maxx; x++ { moore_sum := (0 + aa.field.get(x - 1, y - 1) + aa.field.get(x, y - 1) + aa.field.get(x + - 1, y - 1) + aa.field.get(x - 1, y) + 0 + aa.field.get(x + 1, y) + - aa.field.get(x - 1, y + 1) + aa.field.get(x, y + 1) + aa.field.get(x + 1, y + 1)) + 1, y - 1) + aa.field.get(x - 1, y) + 0 + aa.field.get(x + 1, y) + aa.field.get(x - + 1, y + 1) + aa.field.get(x, y + 1) + aa.field.get(x + 1, y + 1)) cell := aa.field.get(x, y) v := if cell == 1 { moore_sum in [2, 3] } else { moore_sum == 3 } aa.new_field.set(x, y, if v { 1 } else { 0 }) diff --git a/examples/gg/15.v b/examples/gg/15.v index 70b811c8fb..9cde6e39fb 100644 --- a/examples/gg/15.v +++ b/examples/gg/15.v @@ -111,8 +111,7 @@ fn (mut g Game) header() { } fn (mut g Game) board() { - g.ctx.draw_rect_filled(pad - 8, head - 8, board_px + 16, board_px + 16, gg.rgb(218, - 206, 188)) + g.ctx.draw_rect_filled(pad - 8, head - 8, board_px + 16, board_px + 16, gg.rgb(218, 206, 188)) for i, v in g.board { if g.anim && i == g.from { continue @@ -123,10 +122,10 @@ fn (mut g Game) board() { if g.anim { x0, y0 := xy(g.from) x1, y1 := xy(g.to) - g.tile(int(f32(x0) + f32(x1 - x0) * g.t), int(f32(y0) + f32(y1 - y0) * g.t), g.val, - false) + g.tile(int(f32(x0) + f32(x1 - x0) * g.t), int(f32(y0) + f32(y1 - y0) * g.t), g.val, false) } - g.ctx.draw_text(pad, head + board_px + 22, 'Arrow keys / WASD or click a tile next to the empty space.', + g.ctx.draw_text(pad, head + board_px + 22, + 'Arrow keys / WASD or click a tile next to the empty space.', size: 16 color: wcolor ) diff --git a/examples/gg/arcs_and_slices.v b/examples/gg/arcs_and_slices.v index fc0484a223..ca4c707481 100644 --- a/examples/gg/arcs_and_slices.v +++ b/examples/gg/arcs_and_slices.v @@ -117,9 +117,12 @@ fn on_frame(mut app App) { y += 150 app.gg.draw_text_def(10, y + 20, 'Use arrow keys to increase/decrease number of segments.') - app.gg.draw_text_def(10, y + 36, 'Use the mouse to adjust the start/end angles, in radians. Mouse position (0,0) is at the top-left of the window.') - app.gg.draw_text_def(10, y + 52, 'Note: because y=0 is at the top of the screen and not the bottom, angle=0 is at the bottom of an arc, not the top!') - app.gg.draw_text_def(10, y + 68, 'Compared to a graph, where y=0 is at the bottom, arcs therefore appear y-flipped.') + app.gg.draw_text_def(10, y + 36, + 'Use the mouse to adjust the start/end angles, in radians. Mouse position (0,0) is at the top-left of the window.') + app.gg.draw_text_def(10, y + 52, + 'Note: because y=0 is at the top of the screen and not the bottom, angle=0 is at the bottom of an arc, not the top!') + app.gg.draw_text_def(10, y + 68, + 'Compared to a graph, where y=0 is at the bottom, arcs therefore appear y-flipped.') app.gg.end() } diff --git a/examples/gg/digital_rain.v b/examples/gg/digital_rain.v index 6885cd740b..37e8cef21f 100644 --- a/examples/gg/digital_rain.v +++ b/examples/gg/digital_rain.v @@ -82,7 +82,8 @@ fn frame(mut app App) { update_rain_column(mut rc, app.cols, app.rows) draw_rain_column(rc, app) } - app.ctx.draw_text(app.screen_size.width / 2 - 190, app.screen_size.height - 15, 'press `f` to toggle fullscreen, Up/Down arrows to change speed', + app.ctx.draw_text(app.screen_size.width / 2 - 190, app.screen_size.height - 15, + 'press `f` to toggle fullscreen, Up/Down arrows to change speed', color: gg.gray ) app.ctx.end() @@ -149,8 +150,7 @@ fn draw_rain_column(rc RainColumn, app App) { } if i < rc.drops.len { app.ctx.draw_text(x, y, rc.drops[i].ascii_str(), cfg) - app.ctx.draw_text(x, y, rc.drops[(i + 10) % rc.drops.len].ascii_str(), - cfg) + app.ctx.draw_text(x, y, rc.drops[(i + 10) % rc.drops.len].ascii_str(), cfg) } else { vprintln('BAD i: ${i} | rc.drops.len: ${rc.drops.len}') } diff --git a/examples/gg/easing_animation.v b/examples/gg/easing_animation.v index e51ab7ac99..3cd761f4bb 100644 --- a/examples/gg/easing_animation.v +++ b/examples/gg/easing_animation.v @@ -60,8 +60,7 @@ fn (mut app App) draw_circle(label string, f easing.EasingFN) { offset := 30 app.gg.draw_text_def(int(app.x) - 30, 5, label) app.gg.draw_line(f32(app.x), offset, f32(app.x), f32(app.h + offset), gg.gray) - app.gg.draw_circle_filled(f32(app.x), f32(offset + f(app.t) * app.h), 10, gg.rgb(0, - 0, 255)) + app.gg.draw_circle_filled(f32(app.x), f32(offset + f(app.t) * app.h), 10, gg.rgb(0, 0, 255)) app.x += 120 } @@ -77,7 +76,8 @@ fn (mut app App) frame() { for k, e in current_map { app.draw_circle(k, e) } - app.gg.draw_text_def(50, int(app.h + 50), 'Note: use left and right arrows to change functions. Frame: ${app.gg.frame:010} | t: ${app.t:6.3f} | kind: ${app.kind}.') + app.gg.draw_text_def(50, int(app.h + 50), + 'Note: use left and right arrows to change functions. Frame: ${app.gg.frame:010} | t: ${app.t:6.3f} | kind: ${app.kind}.') app.gg.end() } diff --git a/examples/gg/fire.v b/examples/gg/fire.v index d41c95ce3a..d644f5aa85 100644 --- a/examples/gg/fire.v +++ b/examples/gg/fire.v @@ -86,6 +86,7 @@ fn (mut app App) draw() { for y, row in app.buf { for x, i in row { app.gg.draw_square_filled(t * width * scale + x * scale, + (size.height - height * scale) + y * scale, scale, palette[i]) } } diff --git a/examples/gg/grid_of_rectangles.v b/examples/gg/grid_of_rectangles.v index 0a7ab15569..7bd6c1644a 100644 --- a/examples/gg/grid_of_rectangles.v +++ b/examples/gg/grid_of_rectangles.v @@ -13,7 +13,6 @@ const cmax_y = 81 const cs = 10 const c_fg = gg.rgb(20, 30, 255) -const c_em = gg.rgb(255, 50, 0) fn main() { mut app := &App{} @@ -64,7 +63,8 @@ fn frame(app &App) { for y in 0 .. cmax_y { for x in 0 .. cmax_x { cy, cx := y * cs, x * cs - app.gg.draw_rect_empty_no_context(cx + 2, cy + 2, cs - 3, cs - 3, c_em) + app.gg.draw_rect_empty_no_context(cx + 2, cy + 2, cs - 3, cs - 3, + gg.rgb(255, 50, 0)) } } sgl.end() diff --git a/examples/gg/path_finding_algorithm_visualizer/aStar.v b/examples/gg/path_finding_algorithm_visualizer/aStar.v index 154c5adc63..2fb46572a2 100644 --- a/examples/gg/path_finding_algorithm_visualizer/aStar.v +++ b/examples/gg/path_finding_algorithm_visualizer/aStar.v @@ -84,7 +84,8 @@ fn main() { event_fn: on_event // it calls on every event user_data: app // store user data ) - mut grid := initialise_grid() // initialize the grid variable and populate the matrix with each cell as empty + mut grid := + initialise_grid() // initialize the grid variable and populate the matrix with each cell as empty app.grid = grid // set grid to app attribute so you can access it by just passing app variable or with method of app app.ui.dpi_scale = 1.0 // set scale this is use to make it responsive app.start = &Point{ // set start point to -1, -1 @@ -452,11 +453,3 @@ fn (mut heap MinHeap) right_child(idx int) !int { fn (mut heap MinHeap) parent(idx int) int { return (idx - 1) / 2 } - -// comaparator of heap //TODO not used -fn comparator(n1 Node, n2 Node) bool { - if n1.f_score == n2.f_score { - return n1.count > n2.count - } - return n1.f_score > n2.f_score -} diff --git a/examples/gg/pong/pong.v b/examples/gg/pong/pong.v index 140e786fa5..e7de1a7f75 100644 --- a/examples/gg/pong/pong.v +++ b/examples/gg/pong/pong.v @@ -142,8 +142,7 @@ fn on_frame(data voidptr) { } // Draw paddles - app.ctx.draw_rounded_rect_filled(20, app.p1_y, app.paddle_width, app.paddle_height, - 5, color_p1) + app.ctx.draw_rounded_rect_filled(20, app.p1_y, app.paddle_width, app.paddle_height, 5, color_p1) app.ctx.draw_rounded_rect_filled(f32(app.width) - 20 - app.paddle_width, app.p2_y, app.paddle_width, app.paddle_height, 5, color_p2) @@ -198,7 +197,8 @@ fn on_frame(data voidptr) { align: .center ) } else { - app.ctx.draw_text(app.width / 2, app.height - 25, 'SPACE: Pause | W/S: P1 | UP/DOWN: P2 | R: Reset', + app.ctx.draw_text(app.width / 2, app.height - 25, + 'SPACE: Pause | W/S: P1 | UP/DOWN: P2 | R: Reset', size: 16 color: color_text_dim align: .center diff --git a/examples/gg/raycaster.v b/examples/gg/raycaster.v index 3c04a360eb..4c311083a0 100644 --- a/examples/gg/raycaster.v +++ b/examples/gg/raycaster.v @@ -15,7 +15,6 @@ import gg import math const player_size = 8 -const player_move_delta = 10 const map_x_size = 8 const map_y_size = 8 const map_square = 64 @@ -79,8 +78,8 @@ fn draw_map_2d(app App) { for y := 0; y < map_y_size; y++ { for x := 0; x < map_x_size; x++ { color := if app.map[y * map_x_size + x] == 1 { gg.white } else { gg.black } - app.ctx.draw_rect_filled(x * map_square, y * map_square, map_square - 1, map_square - 1, - color) + app.ctx.draw_rect_filled(x * map_square, y * map_square, map_square - 1, + map_square - 1, color) } } } @@ -215,6 +214,7 @@ fn draw_rays_and_walls(app App) { wall_height := math.min((map_square * max_wall_height) / distance, max_wall_height) wall_offset := max_wall_height / 2 - wall_height / 2 app.ctx.draw_line_with_config(step * line_thickeness + offset_3d_view, wall_offset, + step * line_thickeness + offset_3d_view, wall_offset + wall_height, gg.PenConfig{ color: color thickness: line_thickeness diff --git a/examples/gg/spirograph.v b/examples/gg/spirograph.v index 0cdbd13dce..a15248d675 100644 --- a/examples/gg/spirograph.v +++ b/examples/gg/spirograph.v @@ -60,10 +60,11 @@ gg.start( x += pdj[j] * math.sin(a - t) * cd600 y += pdj[j] * math.cos(a - t) * cd600 } - ctx.draw_rect_filled(f32(wsize.width / 2 + scale * x), f32(wsize.height / 2 + scale * y), - 1, 1, colors[i % colors.len]) + ctx.draw_rect_filled(f32(wsize.width / 2 + scale * x), + f32(wsize.height / 2 + scale * y), 1, 1, colors[i % colors.len]) } - ctx.draw_text(wsize.width / 2 - 170, wsize.height - 15, 'frame: ${ctx.frame:06}, k: ${k:4}, scale: ${scale:4}, arrows to change', + ctx.draw_text(wsize.width / 2 - 170, wsize.height - 15, + 'frame: ${ctx.frame:06}, k: ${k:4}, scale: ${scale:4}, arrows to change', color: colors[1] ) ctx.end(how: .passthru) diff --git a/examples/gg/worker_thread.v b/examples/gg/worker_thread.v index 4e7b913cd6..08d7b93900 100644 --- a/examples/gg/worker_thread.v +++ b/examples/gg/worker_thread.v @@ -11,7 +11,6 @@ import time const win_width = 600 const win_height = 700 const bg_color = gg.white -const count_color = gg.black struct App { mut: diff --git a/examples/hot_reload/bounce.v b/examples/hot_reload/bounce.v index c82d0db245..286c8af0e6 100644 --- a/examples/hot_reload/bounce.v +++ b/examples/hot_reload/bounce.v @@ -52,10 +52,9 @@ fn frame(mut game Game) { game.gg.begin() game.gg.draw_text_def(10, 5, 'Modify examples/hot_reload/bounce.v to get instant updates') game.gg.draw_rect_filled(game.x, game.y, width, width, gg.black) - game.gg.draw_rect_filled(window_width - width - game.x + 10, 200 - game.y + width, - width, width, gg.rgb(228, 10, 55)) - game.gg.draw_rect_filled(game.x - 25, 250 - game.y, width, width, gg.rgb(28, 240, - 55)) + game.gg.draw_rect_filled(window_width - width - game.x + 10, 200 - game.y + width, width, + width, gg.rgb(228, 10, 55)) + game.gg.draw_rect_filled(game.x - 25, 250 - game.y, width, width, gg.rgb(28, 240, 55)) game.gg.end() } diff --git a/examples/hot_reload/graph.v b/examples/hot_reload/graph.v index 3200364a12..6ec0eb5c2e 100644 --- a/examples/hot_reload/graph.v +++ b/examples/hot_reload/graph.v @@ -75,6 +75,7 @@ fn (ctx &Context) draw() { ctx.gg.draw_rect_filled(f32((w / 2) + x * scale), f32((h / 2) - y * scale), 2, (f32(y) * scale), blue) ctx.gg.draw_rect_filled(f32((w / 2) + x * scale), f32((h / 2) + y * scale), 2, + (f32(y) * scale) + 32, red) } } diff --git a/examples/js_dom_cube/cube.js.v b/examples/js_dom_cube/cube.js.v index 4c4c6a1a8a..72d078f8e6 100644 --- a/examples/js_dom_cube/cube.js.v +++ b/examples/js_dom_cube/cube.js.v @@ -389,8 +389,8 @@ fn main() { gl.bindBuffer(dom.gl_array_buffer(), vertex_buffer) position := gl.getAttribLocation(shader_program, 'position'.str) - gl.vertexAttribPointer(position, JS.Number(3), dom.gl_float(), JS.Boolean(false), - JS.Number(0), JS.Number(0)) + gl.vertexAttribPointer(position, JS.Number(3), dom.gl_float(), JS.Boolean(false), JS.Number(0), + JS.Number(0)) gl.enableVertexAttribArray(position) gl.bindBuffer(dom.gl_array_buffer(), color_buffer) @@ -400,14 +400,14 @@ fn main() { gl.enableVertexAttribArray(color) gl.useProgram(shader_program) - mut proj_matrix := get_projection(40.0, f64(canvas.width) / f64(canvas.height), 1.0, - 100.0) + mut proj_matrix := get_projection(40.0, f64(canvas.width) / f64(canvas.height), 1.0, 100.0) mut mo_matrix := [f64(1), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] mut view_matrix := [f64(1), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] view_matrix[14] = view_matrix[14] - 6 - mut state := State{false, gl, canvas, 0, 0, 0, 0, 0, 0, 0, mo_matrix, view_matrix, proj_matrix, pmatrix, vmatrix, mmatrix, index_buffer} + mut state := + State{false, gl, canvas, 0, 0, 0, 0, 0, 0, 0, mo_matrix, view_matrix, proj_matrix, pmatrix, vmatrix, mmatrix, index_buffer} canvas.addEventListener('mousedown'.str, fn [mut state] (e JS.Event) { state.drag = true diff --git a/examples/js_dom_draw/draw.js.v b/examples/js_dom_draw/draw.js.v index 446048da51..e3f91fa570 100644 --- a/examples/js_dom_draw/draw.js.v +++ b/examples/js_dom_draw/draw.js.v @@ -36,9 +36,10 @@ fn main() { canvas_elem := document.getElementById('canvas'.str)? canvas := get_canvas(canvas_elem) ctx := canvas.getContext('2d'.str, js_undefined())? - context := match ctx { + mut context := JS.CanvasRenderingContext2D{} + match ctx { JS.CanvasRenderingContext2D { - ctx + context = ctx } else { panic('can not get 2d context') diff --git a/examples/js_dom_draw_benchmark_chart/chart/draw.js.v b/examples/js_dom_draw_benchmark_chart/chart/draw.js.v index d0e2843e6f..456fd69576 100644 --- a/examples/js_dom_draw_benchmark_chart/chart/draw.js.v +++ b/examples/js_dom_draw_benchmark_chart/chart/draw.js.v @@ -15,16 +15,6 @@ fn get_canvas(elem JS.HTMLElement) JS.HTMLCanvasElement { } } -fn draw_line(mut context JS.CanvasRenderingContext2D, _x1 int, _y1 int, _x2 int, _y2 int) { - context.beginPath() - context.strokeStyle = 'black'.str - context.lineWidth = JS.Number(1) - context.moveTo(JS.Number(0), JS.Number(0)) - context.lineTo(JS.Number(100), JS.Number(100)) - context.stroke() - context.closePath() -} - struct DrawState { mut: context JS.CanvasRenderingContext2D @@ -86,9 +76,10 @@ fn main() { ctx := canvas[orm_stmt_kind].getContext('2d'.str, js_undefined())? - context := match ctx { + mut context := JS.CanvasRenderingContext2D{} + match ctx { JS.CanvasRenderingContext2D { - ctx + context = ctx } else { panic('can not get 2d context') @@ -97,7 +88,8 @@ fn main() { mut state := DrawState{context, false, 0, 0} - mut inserts_from_framework := canvas_elem[orm_stmt_kind].getAttribute('inserts_from_framework'.str)? + mut inserts_from_framework := + canvas_elem[orm_stmt_kind].getAttribute('inserts_from_framework'.str)? mut max_benchmark := canvas_elem[orm_stmt_kind].getAttribute('max_benchmark'.str)? diff --git a/examples/js_dom_draw_benchmark_chart/chart/main.v b/examples/js_dom_draw_benchmark_chart/chart/main.v index 67912ba310..a2b8fcb3e6 100644 --- a/examples/js_dom_draw_benchmark_chart/chart/main.v +++ b/examples/js_dom_draw_benchmark_chart/chart/main.v @@ -106,7 +106,8 @@ pub fn (mut app App) controller_get_all_task() !vweb.Result { } from_framework[orm_stmt_kind] = json.encode(framework_platform[orm_stmt_kind]) - table[orm_stmt_kind] = gen_table_info(attribute_names[orm_stmt_kind], framework_platform[orm_stmt_kind]) + table[orm_stmt_kind] = gen_table_info(attribute_names[orm_stmt_kind], + framework_platform[orm_stmt_kind]) max_benchmark[orm_stmt_kind] = arrays.max(maxs[orm_stmt_kind]) or { continue } } @@ -157,18 +158,6 @@ fn v_sqlite_memory() !FrameworkBenchmarkResponse { return framework_benchmark_response } -fn v_sqlite_file() !FrameworkBenchmarkResponse { - // url := 'http://localhost:3000/sqlite-memory/${benchmark_loop_length}' - // res := http.get(url) or { panic(err) } - // framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)! - framework_benchmark_response := FrameworkBenchmarkResponse{ - insert: [] - select: [] - update: [] - } - return framework_benchmark_response -} - fn gen_table_info(attribute_names []string, framework_platform map[string][]int) map[string]map[string]string { mut table := map[string]map[string]string{} @@ -243,11 +232,9 @@ fn gen_table_info(attribute_names []string, framework_platform map[string][]int) for name in attribute_names { table[name]['max.'] = '${math.round_sig(f64(max_times[name]) / 1000000, 2)} ms (${max_fast[name]}x faster)' - table[name]['10% max.'] = '${math.round_sig(f64(ten_perc_max_times[name]) / 1000000, - 2)} ms (${ten_perc_max_fast[name]}x faster)' + table[name]['10% max.'] = '${math.round_sig(f64(ten_perc_max_times[name]) / 1000000, 2)} ms (${ten_perc_max_fast[name]}x faster)' table[name]['min.'] = '${math.round_sig(f64(min_times[name]) / 1000000, 2)} ms (${min_fast[name]}x faster)' - table[name]['10% min.'] = '${math.round_sig(f64(ten_perc_min_times[name]) / 1000000, - 2)} ms (${ten_perc_min_fast[name]}x faster)' + table[name]['10% min.'] = '${math.round_sig(f64(ten_perc_min_times[name]) / 1000000, 2)} ms (${ten_perc_min_fast[name]}x faster)' } return table } diff --git a/examples/lorem.v b/examples/lorem.v index 741a2116be..ae445fd6db 100644 --- a/examples/lorem.v +++ b/examples/lorem.v @@ -30,7 +30,8 @@ fn main() { words_per_sentence := fp.int('words', `w`, 10, 'Words per sentence [default: 10]') sentences_per_paragraph := fp.int('sentences', `s`, 5, 'Sentences per paragraph [default: 5]') paragraphs := fp.int('paragraphs', `p`, 3, 'Paragraph count [default: 3]') - corpus_name := fp.string('corpus', `c`, 'lorem', 'Corpus name (lorem, poe, darwin, bard) [default: lorem]') + corpus_name := fp.string('corpus', `c`, 'lorem', + 'Corpus name (lorem, poe, darwin, bard) [default: lorem]') seed_text := fp.string('seed', `S`, '', 'Seed phrase (random if omitted)') mut rng_seed := fp.int('rngseed', `r`, 0, 'RNG seed (0 = random)') diff --git a/examples/macos_tray/tray.v b/examples/macos_tray/tray.v index a2becd0f82..bab562e1ff 100644 --- a/examples/macos_tray/tray.v +++ b/examples/macos_tray/tray.v @@ -21,8 +21,8 @@ struct TrayMenuItem { // Parameters to configure the tray button. struct TrayParams { - items []TrayMenuItem @[required] - on_click fn (item TrayMenuItem) @[required] + items []TrayMenuItem @[required] + on_click fn (item main.TrayMenuItem) @[required] } // Internal Cocoa application state. diff --git a/examples/password/password_test.v b/examples/password/password_test.v index 266bcf10dc..bb9238d123 100644 --- a/examples/password/password_test.v +++ b/examples/password/password_test.v @@ -16,10 +16,12 @@ fn test_password_input() { assert incorrect.exit_code == 0, incorrect.output expected_out := 'Enter your password : ' - mut res := os.execute('${os.join_path(expect_tests_path, 'output_from_expect_arg.expect')} "${expected_out}"') + mut res := + os.execute('${os.join_path(expect_tests_path, 'output_from_expect_arg.expect')} "${expected_out}"') assert res.exit_code == 0, res.output not_exptectd_out := 'Enter your passwords : ' - res = os.execute('${os.join_path(expect_tests_path, 'output_from_expect_arg.expect')} "${not_exptectd_out}"') + res = + os.execute('${os.join_path(expect_tests_path, 'output_from_expect_arg.expect')} "${not_exptectd_out}"') assert res.exit_code == 1, res.output } diff --git a/examples/path_tracing.v b/examples/path_tracing.v index f93d016411..9bea55ecb2 100644 --- a/examples/path_tracing.v +++ b/examples/path_tracing.v @@ -33,7 +33,6 @@ import math.vec const inf = 1e+10 const eps = 1e-4 -const f_0 = 0.0 type Vec = vec.Vec3[f64] @@ -424,8 +423,8 @@ fn radiance(r Ray, depthi int, scene_id int) Vec { return obj.e + f * radiance(Ray{x, d}, depth, scene_id) } else { if obj.refl == .spec { // Ideal SPECULAR reflection - return obj.e + - f * radiance(Ray{x, r.d - n.mul_scalar(2.0 * n.dot(r.d))}, depth, scene_id) + return obj.e + f * radiance(Ray{x, r.d - + n.mul_scalar(2.0 * n.dot(r.d))}, depth, scene_id) } } diff --git a/examples/pendulum-simulation/modules/sim/args/parser.v b/examples/pendulum-simulation/modules/sim/args/parser.v index 0ff8ad56db..2dc7365e00 100644 --- a/examples/pendulum-simulation/modules/sim/args/parser.v +++ b/examples/pendulum-simulation/modules/sim/args/parser.v @@ -51,17 +51,25 @@ fn parse_sequential_args() !SequentialArgs { fp.skip_executable() // output parameters - width := fp.int('width', `w`, sim.default_width, 'width of the image output. Defaults to ${sim.default_width}') - height := fp.int('height', `h`, sim.default_height, 'height of the image output. Defaults to ${sim.default_height}') + width := fp.int('width', `w`, sim.default_width, + 'width of the image output. Defaults to ${sim.default_width}') + height := fp.int('height', `h`, sim.default_height, + 'height of the image output. Defaults to ${sim.default_height}') filename := fp.string('output', `o`, 'out.ppm', 'name of the image output. Defaults to out.ppm') // simulation parameters - rope_length := fp.float('rope-length', 0, sim.default_rope_length, 'rope length to use on simulation. Defaults to ${sim.default_rope_length}') - bearing_mass := fp.float('bearing-mass', 0, sim.default_bearing_mass, 'bearing mass to use on simulation. Defaults to ${sim.default_bearing_mass}') - magnet_spacing := fp.float('magnet-spacing', 0, sim.default_magnet_spacing, 'magnet spacing to use on simulation. Defaults to ${sim.default_magnet_spacing}') - magnet_height := fp.float('magnet-height', 0, sim.default_magnet_height, 'magnet height to use on simulation. Defaults to ${sim.default_magnet_height}') - magnet_strength := fp.float('magnet-strength', 0, sim.default_magnet_strength, 'magnet strength to use on simulation. Defaults to ${sim.default_magnet_strength}') - gravity := fp.float('gravity', 0, sim.default_gravity, 'gravity to use on simulation. Defaults to ${sim.default_gravity}') + rope_length := fp.float('rope-length', 0, sim.default_rope_length, + 'rope length to use on simulation. Defaults to ${sim.default_rope_length}') + bearing_mass := fp.float('bearing-mass', 0, sim.default_bearing_mass, + 'bearing mass to use on simulation. Defaults to ${sim.default_bearing_mass}') + magnet_spacing := fp.float('magnet-spacing', 0, sim.default_magnet_spacing, + 'magnet spacing to use on simulation. Defaults to ${sim.default_magnet_spacing}') + magnet_height := fp.float('magnet-height', 0, sim.default_magnet_height, + 'magnet height to use on simulation. Defaults to ${sim.default_magnet_height}') + magnet_strength := fp.float('magnet-strength', 0, sim.default_magnet_strength, + 'magnet strength to use on simulation. Defaults to ${sim.default_magnet_strength}') + gravity := fp.float('gravity', 0, sim.default_gravity, + 'gravity to use on simulation. Defaults to ${sim.default_gravity}') fp.finalize() or { println(fp.usage()) @@ -101,20 +109,29 @@ fn parse_parallel_args(extra_workers int) !ParallelArgs { fp.description('This is a pendulum simulation written in pure V') fp.skip_executable() - workers := fp.int('workers', 0, max_parallel_workers, 'amount of workers to use on simulation. Defaults to ${max_parallel_workers}') + workers := fp.int('workers', 0, max_parallel_workers, + 'amount of workers to use on simulation. Defaults to ${max_parallel_workers}') // output parameters - width := fp.int('width', `w`, sim.default_width, 'width of the image output. Defaults to ${sim.default_width}') - height := fp.int('height', `h`, sim.default_height, 'height of the image output. Defaults to ${sim.default_height}') + width := fp.int('width', `w`, sim.default_width, + 'width of the image output. Defaults to ${sim.default_width}') + height := fp.int('height', `h`, sim.default_height, + 'height of the image output. Defaults to ${sim.default_height}') filename := fp.string('output', `o`, 'out.ppm', 'name of the image output. Defaults to out.ppm') // simulation parameters - rope_length := fp.float('rope-length', 0, sim.default_rope_length, 'rope length to use on simulation. Defaults to ${sim.default_rope_length}') - bearing_mass := fp.float('bearing-mass', 0, sim.default_bearing_mass, 'bearing mass to use on simulation. Defaults to ${sim.default_bearing_mass}') - magnet_spacing := fp.float('magnet-spacing', 0, sim.default_magnet_spacing, 'magnet spacing to use on simulation. Defaults to ${sim.default_magnet_spacing}') - magnet_height := fp.float('magnet-height', 0, sim.default_magnet_height, 'magnet height to use on simulation. Defaults to ${sim.default_magnet_height}') - magnet_strength := fp.float('magnet-strength', 0, sim.default_magnet_strength, 'magnet strength to use on simulation. Defaults to ${sim.default_magnet_strength}') - gravity := fp.float('gravity', 0, sim.default_gravity, 'gravity to use on simulation. Defaults to ${sim.default_gravity}') + rope_length := fp.float('rope-length', 0, sim.default_rope_length, + 'rope length to use on simulation. Defaults to ${sim.default_rope_length}') + bearing_mass := fp.float('bearing-mass', 0, sim.default_bearing_mass, + 'bearing mass to use on simulation. Defaults to ${sim.default_bearing_mass}') + magnet_spacing := fp.float('magnet-spacing', 0, sim.default_magnet_spacing, + 'magnet spacing to use on simulation. Defaults to ${sim.default_magnet_spacing}') + magnet_height := fp.float('magnet-height', 0, sim.default_magnet_height, + 'magnet height to use on simulation. Defaults to ${sim.default_magnet_height}') + magnet_strength := fp.float('magnet-strength', 0, sim.default_magnet_strength, + 'magnet strength to use on simulation. Defaults to ${sim.default_magnet_strength}') + gravity := fp.float('gravity', 0, sim.default_gravity, + 'gravity to use on simulation. Defaults to ${sim.default_gravity}') fp.finalize() or { println(fp.usage()) diff --git a/examples/pendulum-simulation/modules/sim/params_test.v b/examples/pendulum-simulation/modules/sim/params_test.v index 204badeba7..55eb51e922 100644 --- a/examples/pendulum-simulation/modules/sim/params_test.v +++ b/examples/pendulum-simulation/modules/sim/params_test.v @@ -68,7 +68,8 @@ pub fn test_get_magnet_position() { } pub fn test_get_magnet_force() { - result := params_test_mock_params.get_magnet_force(params_test_mock_tetha, params_test_mock_state) + result := params_test_mock_params.get_magnet_force(params_test_mock_tetha, + params_test_mock_state) expected := vector( x: -157.4572297692556 y: 1422.736432604726 @@ -78,7 +79,8 @@ pub fn test_get_magnet_force() { } pub fn test_get_magnet_dist() { - result := params_test_mock_params.get_magnet_dist(params_test_mock_tetha, params_test_mock_state) + result := params_test_mock_params.get_magnet_dist(params_test_mock_tetha, + params_test_mock_state) expected := 0.07993696666249227 assert result == expected } diff --git a/examples/process/write_and_read_from_a_bash_child_process.v b/examples/process/write_and_read_from_a_bash_child_process.v index 40934201e9..c511ac4191 100644 --- a/examples/process/write_and_read_from_a_bash_child_process.v +++ b/examples/process/write_and_read_from_a_bash_child_process.v @@ -76,7 +76,8 @@ fn main() { os.write_file(os.join_path(tmp_folder, '${i}.txt'), '${i}\n${i}\n')! } - out, ecode, er = exec("find ${os.quoted_path(tmp_folder)} ; sleep 0.1; find ${os.quoted_path(tmp_folder)} ; echo '******'") + out, ecode, er = + exec("find ${os.quoted_path(tmp_folder)} ; sleep 0.1; find ${os.quoted_path(tmp_folder)} ; echo '******'") assert out.ends_with('******\n') assert er == '' diff --git a/examples/quadtree_demo/quadtree_demo.v b/examples/quadtree_demo/quadtree_demo.v index 45cea66e6d..1d3495806a 100644 --- a/examples/quadtree_demo/quadtree_demo.v +++ b/examples/quadtree_demo/quadtree_demo.v @@ -14,10 +14,6 @@ const font_small = gg.TextCfg{ color: gg.black size: 20 } -const font_large = gg.TextCfg{ - color: gg.black - size: 40 -} struct App { mut: @@ -157,20 +153,20 @@ fn frame(app &App) { fn (app &App) display() { for player in app.players { - app.gg.draw_rect_filled(f32(player.x), f32(player.y), f32(player.width), f32(player.height), - gg.black) + app.gg.draw_rect_filled(f32(player.x), f32(player.y), f32(player.width), + f32(player.height), gg.black) } for particle in app.particles { app.gg.draw_rect_empty(f32(particle.pmt.x), f32(particle.pmt.y), f32(particle.pmt.width), f32(particle.pmt.height), gg.blue) } for node in app.nodes { - app.gg.draw_rect_empty(f32(node.perimeter.x), f32(node.perimeter.y), f32(node.perimeter.width), - f32(node.perimeter.height), gg.red) + app.gg.draw_rect_empty(f32(node.perimeter.x), f32(node.perimeter.y), + f32(node.perimeter.width), f32(node.perimeter.height), gg.red) } for retrieved in app.retrieveds { - app.gg.draw_rect_filled(f32(retrieved.x + 1), f32(retrieved.y + 1), f32(retrieved.width - 2), - f32(retrieved.height - 2), gg.green) + app.gg.draw_rect_filled(f32(retrieved.x + 1), f32(retrieved.y + 1), + f32(retrieved.width - 2), f32(retrieved.height - 2), gg.green) } app.gg.draw_text(1200, 25, 'Nodes: ${app.nodes.len}', font_small) app.gg.draw_text(1200, 50, 'Particles: ${app.particles.len}', font_small) diff --git a/examples/readline/readline_test.v b/examples/readline/readline_test.v index 21231f58e1..e2e5b0b4c4 100644 --- a/examples/readline/readline_test.v +++ b/examples/readline/readline_test.v @@ -14,11 +14,13 @@ fn test_password_input() { send_a := 'a' expect_a := 'got 97' // readline output for `a` - a_res := os.execute('${os.join_path(expect_tests_path, 'readline_from_expect_arg.expect')} ${send_a} "${expect_a}"') + a_res := + os.execute('${os.join_path(expect_tests_path, 'readline_from_expect_arg.expect')} ${send_a} "${expect_a}"') assert a_res.exit_code == 0, a_res.output send_b := 'b' - b_res := os.execute('${os.join_path(expect_tests_path, 'readline_from_expect_arg.expect')} ${send_b} "${expect_a}"') + b_res := + os.execute('${os.join_path(expect_tests_path, 'readline_from_expect_arg.expect')} ${send_b} "${expect_a}"') assert b_res.exit_code == 1, b_res.output assert b_res.output.contains('got 98') } diff --git a/examples/snek/snek.js.v b/examples/snek/snek.js.v index ab311d7e62..d73bd38320 100644 --- a/examples/snek/snek.js.v +++ b/examples/snek/snek.js.v @@ -140,8 +140,8 @@ fn on_frame(mut app App) { } // drawing snake for pos in app.snake { - app.gg.draw_rect(tile_size * pos.x, tile_size * pos.y + top_height, tile_size, - tile_size, gg.blue) + app.gg.draw_rect(tile_size * pos.x, tile_size * pos.y + top_height, tile_size, tile_size, + gg.blue) } // drawing food diff --git a/examples/snek/snek.v b/examples/snek/snek.v index 3a9b33262a..879f8bfbe4 100644 --- a/examples/snek/snek.v +++ b/examples/snek/snek.v @@ -75,8 +75,8 @@ fn on_frame(mut app App) { // draw everything: app.gg.begin() // draw food - app.gg.draw_rect_filled(tile_size * app.food.x, tile_size * app.food.y + top_height, - tile_size, tile_size, gg.red) + app.gg.draw_rect_filled(tile_size * app.food.x, tile_size * app.food.y + top_height, tile_size, + tile_size, gg.red) // draw snake for pos in app.snake[..app.snake.len - 1] { @@ -86,14 +86,16 @@ fn on_frame(mut app App) { // draw partial head head := app.snake[0] - app.gg.draw_rect_filled(tile_size * (head.x + app.dir.x * progress), tile_size * (head.y + - app.dir.y * progress) + top_height, tile_size, tile_size, gg.blue) + app.gg.draw_rect_filled(tile_size * (head.x + app.dir.x * progress), + + tile_size * (head.y + app.dir.y * progress) + top_height, tile_size, tile_size, gg.blue) // draw partial tail tail := app.snake.last() tail_dir := app.snake[app.snake.len - 2] - tail - app.gg.draw_rect_filled(tile_size * (tail.x + tail_dir.x * progress), tile_size * (tail.y + - tail_dir.y * progress) + top_height, tile_size, tile_size, gg.blue) + app.gg.draw_rect_filled(tile_size * (tail.x + tail_dir.x * progress), + + tile_size * (tail.y + tail_dir.y * progress) + top_height, tile_size, tile_size, gg.blue) // draw score bar app.gg.draw_rect_filled(0, 0, canvas_size, top_height, gg.black) diff --git a/examples/sokol/01_cubes/cube.v b/examples/sokol/01_cubes/cube.v index e77dbdd505..4db566df2f 100644 --- a/examples/sokol/01_cubes/cube.v +++ b/examples/sokol/01_cubes/cube.v @@ -58,21 +58,6 @@ fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) { return sg_img, sg_smp } -fn destroy_texture(sg_img gfx.Image) { - gfx.destroy_image(sg_img) -} - -// Use only if usage: .dynamic is enabled -fn update_text_texture(sg_img gfx.Image, w int, h int, buf &u8) { - sz := w * h * 4 - mut tmp_sbc := gfx.ImageData{} - tmp_sbc.subimage[0][0] = gfx.Range{ - ptr: buf - size: usize(sz) - } - gfx.update_image(sg_img, &tmp_sbc) -} - fn draw_triangle() { sgl.defaults() sgl.begin_triangles() diff --git a/examples/sokol/03_march_tracing_glsl/rt_glsl.v b/examples/sokol/03_march_tracing_glsl/rt_glsl.v index 0175cae8be..9fb98a84d3 100644 --- a/examples/sokol/03_march_tracing_glsl/rt_glsl.v +++ b/examples/sokol/03_march_tracing_glsl/rt_glsl.v @@ -245,8 +245,7 @@ fn vec4(x f32, y f32, z f32, w f32) m4.Vec4 { fn calc_tr_matrices(w f32, h f32, rx f32, ry f32, in_scale f32) m4.Mat4 { proj := m4.perspective(60, w / h, 0.01, 10.0) - view := m4.look_at(vec4(f32(0.0), 0, 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1, - 0, 0)) + view := m4.look_at(vec4(f32(0.0), 0, 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1, 0, 0)) view_proj := view * proj rxm := m4.rotate(m4.rad(rx), vec4(f32(1), 0, 0, 0)) diff --git a/examples/sokol/06_obj_viewer/show_obj.v b/examples/sokol/06_obj_viewer/show_obj.v index 74479f5f37..9c8b30780e 100644 --- a/examples/sokol/06_obj_viewer/show_obj.v +++ b/examples/sokol/06_obj_viewer/show_obj.v @@ -73,8 +73,7 @@ fn vec4(x f32, y f32, z f32, w f32) m4.Vec4 { fn calc_matrices(w f32, h f32, rx f32, ry f32, in_scale f32, pos m4.Vec4) obj.Mats { proj := m4.perspective(60, w / h, 0.01, 100.0) // set far plane to 100 fro the zoom function - view := m4.look_at(vec4(f32(0.0), 0, 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1, - 0, 0)) + view := m4.look_at(vec4(f32(0.0), 0, 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1, 0, 0)) view_proj := view * proj rxm := m4.rotate(m4.rad(rx), vec4(f32(1), 0, 0, 0)) diff --git a/examples/sokol/fonts.v b/examples/sokol/fonts.v index fbfe5e34af..71773b3cc7 100644 --- a/examples/sokol/fonts.v +++ b/examples/sokol/fonts.v @@ -94,7 +94,8 @@ fn (state &AppState) render_font() { font_context.set_size(20.0) font_context.set_font(state.font_normal) font_context.set_color(blue) - font_context.draw_text(dx, dy, 'Now is the time for all good men to come to the aid of the party.') + font_context.draw_text(dx, dy, + 'Now is the time for all good men to come to the aid of the party.') dx = 300 dy = 350 font_context.set_alignment(.left | .baseline) diff --git a/examples/sokol/freetype_raven.v b/examples/sokol/freetype_raven.v index 66ad9a3496..f3172f14f5 100644 --- a/examples/sokol/freetype_raven.v +++ b/examples/sokol/freetype_raven.v @@ -137,11 +137,3 @@ fn (mut state AppState) render_font() { } sfons.flush(fons) } - -fn line(sx f32, sy f32, ex f32, ey f32) { - sgl.begin_lines() - sgl.c4b(255, 255, 0, 128) - sgl.v2f(sx, sy) - sgl.v2f(ex, ey) - sgl.end() -} diff --git a/examples/sokol/particles/modules/particle/system.v b/examples/sokol/particles/modules/particle/system.v index 0b41cacaab..8db9272118 100644 --- a/examples/sokol/particles/modules/particle/system.v +++ b/examples/sokol/particles/modules/particle/system.v @@ -78,10 +78,12 @@ pub fn (mut s System) explode(x f32, y f32) { p = s.bin[i] p.reset() p.location.from(center) - p.acceleration = vec.Vec2[f64]{rand.f32_in_range(-0.5, 0.5) or { -0.5 }, rand.f32_in_range(-0.5, - 0.5) or { -0.5 }} - p.velocity = vec.Vec2[f64]{rand.f32_in_range(-0.5, 0.5) or { -0.5 }, rand.f32_in_range(-0.5, - 0.5) or { -0.5 }} + p.acceleration = vec.Vec2[f64]{rand.f32_in_range(-0.5, 0.5) or { -0.5 }, rand.f32_in_range(-0.5, 0.5) or { + -0.5 + }} + p.velocity = vec.Vec2[f64]{rand.f32_in_range(-0.5, 0.5) or { -0.5 }, rand.f32_in_range(-0.5, 0.5) or { + -0.5 + }} p.life_time = rand.f64_in_range(500, 2000) or { 500 } s.pool << p s.bin.delete(i) diff --git a/examples/templates/templates.v b/examples/templates/templates.v index f7b68c9c1b..0a3bf20e07 100644 --- a/examples/templates/templates.v +++ b/examples/templates/templates.v @@ -22,173 +22,6 @@ pub enum SiteCat { web } -fn data_get() []SiteConfig { - data := [ - SiteConfig{ - name: 'www_threefold_io' - url: 'https://github.com/threefoldfoundation/www_threefold_io' - branch: 'default' - pull: false - cat: .web - alias: 'tf' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_threefold_io' - domains: ['www.threefold.io', 'www.threefold.me'] - descr: 'is our entry point for everyone, redirect to the detailed websites underneath.' - }, - SiteConfig{ - name: 'www_threefold_cloud' - url: 'https://github.com/threefoldfoundation/www_threefold_cloud' - branch: 'default' - pull: false - cat: .web - alias: 'cloud' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_threefold_cloud' - domains: ['cloud.threefold.io', 'cloud.threefold.me'] - descr: 'for people looking to deploy solutions on top of a cloud, alternative to e.g. digital ocean' - }, - SiteConfig{ - name: 'www_threefold_farming' - url: 'https://github.com/threefoldfoundation/www_threefold_farming' - branch: 'default' - pull: false - cat: .web - alias: 'farming' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_threefold_farming' - domains: ['farming.threefold.io', 'farming.threefold.me'] - descr: 'crypto & minining enthusiasts, be the internet, know about farming & tokens.' - }, - SiteConfig{ - name: 'www_threefold_twin' - url: 'https://github.com/threefoldfoundation/www_threefold_twin' - branch: 'default' - pull: false - cat: .web - alias: 'twin' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_threefold_twin' - domains: ['twin.threefold.io', 'twin.threefold.me'] - descr: 'you digital life' - }, - SiteConfig{ - name: 'www_threefold_marketplace' - url: 'https://github.com/threefoldfoundation/www_threefold_marketplace' - branch: 'default' - pull: false - cat: .web - alias: 'marketplace' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_threefold_marketplace' - domains: ['now.threefold.io', 'marketplace.threefold.io', 'now.threefold.me', - 'marketplace.threefold.me'] - descr: 'apps for community builders, runs on top of evdc' - }, - SiteConfig{ - name: 'www_conscious_internet' - url: 'https://github.com/threefoldfoundation/www_conscious_internet' - branch: 'default' - pull: false - cat: .web - alias: 'conscious_internet' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_conscious_internet' - domains: ['www.consciousinternet.org', 'eco.threefold.io', 'community.threefold.io', - 'eco.threefold.me', 'community.threefold.me'] - descr: 'community around threefold, partners, friends, ...' - }, - SiteConfig{ - name: 'www_threefold_tech' - url: 'https://github.com/threefoldtech/www_threefold_tech' - branch: 'default' - pull: false - cat: .web - alias: 'tech' - path_code: '/Users/despiegk/codewww/github/threefoldtech/www_threefold_tech' - domains: ['www.threefold.tech'] - descr: 'cyberpandemic, use the tech to build your own solutions with, certification for TFGrid' - }, - SiteConfig{ - name: 'www_examplesite' - url: 'https://github.com/threefoldfoundation/www_examplesite' - branch: 'default' - pull: false - cat: .web - alias: 'example' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_examplesite' - domains: ['example.threefold.io'] - descr: '' - }, - SiteConfig{ - name: 'info_threefold' - url: 'https://github.com/threefoldfoundation/info_foundation_archive' - branch: 'default' - pull: false - cat: .wiki - alias: 'threefold' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/info_foundation_archive' - domains: ['info.threefold.io'] - descr: 'wiki for foundation, collaborate, what if farmings, tokens' - }, - SiteConfig{ - name: 'info_sdk' - url: 'https://github.com/threefoldfoundation/info_sdk' - branch: 'default' - pull: false - cat: .wiki - alias: 'sdk' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/info_sdk' - domains: ['sdk.threefold.io', 'sdk_info.threefold.io'] - descr: 'for IAC, devops, how to do Infrastructure As Code, 3bot, Ansible, tfgrid-sdk, ...' - }, - SiteConfig{ - name: 'info_legal' - url: 'https://github.com/threefoldfoundation/info_legal' - branch: 'default' - pull: false - cat: .wiki - alias: 'legal' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/info_legal' - domains: ['legal.threefold.io', 'legal_info.threefold.io'] - descr: '' - }, - SiteConfig{ - name: 'info_cloud' - url: 'https://github.com/threefoldfoundation/info_cloud' - branch: 'default' - pull: false - cat: .wiki - alias: 'cloud' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/info_cloud' - domains: ['cloud_info.threefold.io'] - descr: 'how to use the cloud for deploying apps: evdc, kubernetes, planetary fs, ... + marketplace solutions ' - }, - SiteConfig{ - name: 'info_tftech' - url: 'https://github.com/threefoldtech/info_tftech' - branch: 'default' - pull: false - cat: .wiki - alias: 'tftech' - path_code: '/Users/despiegk/codewww/github/threefoldtech/info_tftech' - domains: ['info.threefold.tech'] - descr: '' - }, - SiteConfig{ - name: 'info_digitaltwin' - url: 'https://github.com/threefoldfoundation/info_digitaltwin.git' - branch: 'default' - pull: false - cat: .wiki - alias: 'twin' - path_code: '/Users/despiegk/codewww/github/threefoldfoundation/info_digitaltwin' - domains: ['twin_info.threefold.io'] - descr: '' - }, - ] - return data -} - -fn data_dump(data []SiteConfig) { - a := json.encode_pretty(data) - os.write_file(os.resource_abs_path('data.json'), a) or { panic(err) } -} - fn data_load() []SiteConfig { data := os.read_file(os.resource_abs_path('data.json')) or { panic(err) } a := json.decode([]SiteConfig, data) or { panic(err) } diff --git a/examples/term.ui/pong.v b/examples/term.ui/pong.v index fb2209ee74..90827bf57b 100644 --- a/examples/term.ui/pong.v +++ b/examples/term.ui/pong.v @@ -14,7 +14,6 @@ const player_one = 1 // Human control this racket const player_two = 0 // Take over this AI controller const white = ui.Color{255, 255, 255} -const orange = ui.Color{255, 140, 0} @[heap] struct App { diff --git a/examples/term.ui/term_drawing.v b/examples/term.ui/term_drawing.v index 4c12dc5e53..c086b33720 100644 --- a/examples/term.ui/term_drawing.v +++ b/examples/term.ui/term_drawing.v @@ -74,16 +74,12 @@ const colors = [ const frame_rate = 30 // fps -const msg_display_time = 5 * frame_rate const w = 200 const h = 100 const space = ' ' const spaces = ' ' const select_color = 'Select color: ' const select_size = 'Size: + -' -const help_1 = '╭────────╮' -const help_2 = '│ HELP │' -const help_3 = '╰────────╯' struct App { mut: @@ -423,7 +419,8 @@ fn (mut app App) draw_header() { app.ui.reset() } //'tick: ${app.ui.frame_count} | ' + - app.ui.draw_text(3, 2, 'terminal size: (${app.ui.window_width}, ${app.ui.window_height}) | primary color: ${app.primary_color.hex()} | secondary color: ${app.secondary_color.hex()}') + app.ui.draw_text(3, 2, + 'terminal size: (${app.ui.window_width}, ${app.ui.window_height}) | primary color: ${app.primary_color.hex()} | secondary color: ${app.secondary_color.hex()}') app.ui.horizontal_separator(3) } diff --git a/examples/term.ui/vyper.v b/examples/term.ui/vyper.v index 7262df8cde..00c4548304 100644 --- a/examples/term.ui/vyper.v +++ b/examples/term.ui/vyper.v @@ -238,8 +238,8 @@ mut: // randomize spawn the rat in a new spot within the playable field fn (mut r Rat) randomize() { - r.pos.randomize(2 * block_size + buffer, 2 * block_size + buffer, r.app.width - block_size - buffer, - r.app.height - block_size - buffer) + r.pos.randomize(2 * block_size + buffer, 2 * block_size + buffer, r.app.width - block_size - + buffer, r.app.height - block_size - buffer) } @[heap] @@ -356,7 +356,8 @@ fn (mut a App) draw() { } a.termui.set_color(blue) a.termui.set_bg_color(white) - a.termui.draw_text(3 * block_size, a.height - (2 * block_size), 'p - (un)pause r - reset q - quit') + a.termui.draw_text(3 * block_size, a.height - (2 * block_size), + 'p - (un)pause r - reset q - quit') // draw the snake, rat, and score if appropriate if a.redraw { a.termui.set_bg_color(black) @@ -417,12 +418,15 @@ fn (mut a App) draw_debug() { a.termui.set_color(blue) a.termui.set_bg_color(white) snake := a.snake - a.termui.draw_text(block_size, 1 * block_size, 'Display_width: ${a.width:04d} Display_height: ${a.height:04d}') - a.termui.draw_text(block_size, 2 * block_size, 'Vx: ${snake.velocity.x:+02d} Vy: ${snake.velocity.y:+02d}') + a.termui.draw_text(block_size, 1 * block_size, + 'Display_width: ${a.width:04d} Display_height: ${a.height:04d}') + a.termui.draw_text(block_size, 2 * block_size, + 'Vx: ${snake.velocity.x:+02d} Vy: ${snake.velocity.y:+02d}') a.termui.draw_text(block_size, 3 * block_size, 'F: ${snake.direction}') snake_head := snake.get_head() rat := a.rat - a.termui.draw_text(block_size, 4 * block_size, 'Sx: ${snake_head.pos.x:+03d} Sy: ${snake_head.pos.y:+03d}') + a.termui.draw_text(block_size, 4 * block_size, + 'Sx: ${snake_head.pos.x:+03d} Sy: ${snake_head.pos.y:+03d}') a.termui.draw_text(block_size, 5 * block_size, 'Rx: ${rat.pos.x:+03d} Ry: ${rat.pos.y:+03d}') } @@ -432,13 +436,20 @@ fn (mut a App) draw_gameover() { a.rat.pos = Vec{-1, -1} x_offset := ' ##### '.len // take half of a line from the game over text and store the length start_x := (a.width / 2) - x_offset - a.termui.draw_text(start_x, (a.height / 2) - 3 * block_size, ' ##### ####### ') - a.termui.draw_text(start_x, (a.height / 2) - 2 * block_size, ' # # ## # # ###### # # # # ###### ##### ') - a.termui.draw_text(start_x, (a.height / 2) - 1 * block_size, ' # # # ## ## # # # # # # # # ') - a.termui.draw_text(start_x, (a.height / 2) - 0 * block_size, ' # #### # # # ## # ##### # # # # ##### # # ') - a.termui.draw_text(start_x, (a.height / 2) + 1 * block_size, ' # # ###### # # # # # # # # ##### ') - a.termui.draw_text(start_x, (a.height / 2) + 2 * block_size, ' # # # # # # # # # # # # # # ') - a.termui.draw_text(start_x, (a.height / 2) + 3 * block_size, ' ##### # # # # ###### ####### ## ###### # # ') + a.termui.draw_text(start_x, (a.height / 2) - 3 * block_size, + ' ##### ####### ') + a.termui.draw_text(start_x, (a.height / 2) - 2 * block_size, + ' # # ## # # ###### # # # # ###### ##### ') + a.termui.draw_text(start_x, (a.height / 2) - 1 * block_size, + ' # # # ## ## # # # # # # # # ') + a.termui.draw_text(start_x, (a.height / 2) - 0 * block_size, + ' # #### # # # ## # ##### # # # # ##### # # ') + a.termui.draw_text(start_x, (a.height / 2) + 1 * block_size, + ' # # ###### # # # # # # # # ##### ') + a.termui.draw_text(start_x, (a.height / 2) + 2 * block_size, + ' # # # # # # # # # # # # # # ') + a.termui.draw_text(start_x, (a.height / 2) + 3 * block_size, + ' ##### # # # # ###### ####### ## ###### # # ') } type InitFn = fn (voidptr) diff --git a/examples/tetris/tetris.js.v b/examples/tetris/tetris.js.v index 2e3ead6303..d4f997f8a0 100644 --- a/examples/tetris/tetris.js.v +++ b/examples/tetris/tetris.js.v @@ -16,10 +16,7 @@ const field_width = 10 const tetro_size = 4 const win_width = block_size * field_width const win_height = block_size * field_height -const timer_period = 250 // ms - const text_size = 24 -const limit_thickness = 3 const text_cfg = gg.TextCfg{ align: .left @@ -59,7 +56,6 @@ const colors = [ gg.rgb(74, 198, 255), // lightblue longest gg.rgb(0, 170, 170), ] -const background_color = gg.white const ui_color = gg.rgba(255, 0, 0, 210) // TODO: type Tetro [tetro_size]struct{ x, y int } @@ -216,8 +212,7 @@ fn (mut g Game) draw_ghost() { pos_y := g.move_ghost() for i in 0 .. tetro_size { tetro := g.tetro[i] - g.draw_block_color(pos_y + tetro.y, g.pos_x + tetro.x, gg.rgba(125, 125, 225, - 40)) + g.draw_block_color(pos_y + tetro.y, g.pos_x + tetro.x, gg.rgba(125, 125, 225, 40)) } } } diff --git a/examples/tetris/tetris.v b/examples/tetris/tetris.v index 19b79cc862..e75de0716f 100644 --- a/examples/tetris/tetris.v +++ b/examples/tetris/tetris.v @@ -17,10 +17,7 @@ const field_width = 10 const tetro_size = 4 const win_width = block_size * field_width const win_height = block_size * field_height -const timer_period = 250 // ms - const text_size = 24 -const limit_thickness = 3 const text_cfg = gg.TextCfg{ align: .left @@ -60,7 +57,6 @@ const colors = [ gg.rgb(74, 198, 255), // lightblue longest gg.rgb(0, 170, 170), ] -const background_color = gg.white const ui_color = gg.rgba(255, 0, 0, 210) // TODO: type Tetro [tetro_size]struct{ x, y int } @@ -216,8 +212,7 @@ fn (g &Game) draw_ghost() { pos_y := g.move_ghost() for i in 0 .. tetro_size { tetro := g.tetro[i] - g.draw_block_color(pos_y + tetro.y, g.pos_x + tetro.x, gg.rgba(125, 125, 225, - 40)) + g.draw_block_color(pos_y + tetro.y, g.pos_x + tetro.x, gg.rgba(125, 125, 225, 40)) } } } diff --git a/examples/veb/veb_assets/vweb_assets.v b/examples/veb/veb_assets/vweb_assets.v index 7fed12a039..7884cf9722 100644 --- a/examples/veb/veb_assets/vweb_assets.v +++ b/examples/veb/veb_assets/vweb_assets.v @@ -5,8 +5,6 @@ import veb // import vweb.assets import time -const port = 8081 - pub struct Context { veb.Context } diff --git a/examples/viewer/view.v b/examples/viewer/view.v index 87a5bebb2a..8ac7836382 100644 --- a/examples/viewer/view.v +++ b/examples/viewer/view.v @@ -340,7 +340,8 @@ fn app_init(mut app App) { app.pip_viewer = sgl.make_pipeline(&pipdesc) // load logo - app.logo_texture, app.logo_sampler, app.logo_w, app.logo_h = app.load_texture_from_file(app.logo_path) + app.logo_texture, app.logo_sampler, app.logo_w, app.logo_h = + app.load_texture_from_file(app.logo_path) app.logo_ratio = f32(app.img_w) / f32(app.img_h) app.img_w = app.logo_w diff --git a/examples/viewer/zip_container.v b/examples/viewer/zip_container.v index d2a25a45f9..09a9dff88e 100644 --- a/examples/viewer/zip_container.v +++ b/examples/viewer/zip_container.v @@ -58,7 +58,8 @@ fn (mut app App) load_texture_from_zip() !(gfx.Image, gfx.Sampler, int, int) { } app.zip_index = item.container_index // println("Opening the zip [${item.path}]") - app.zip = szip.open(item.path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)! + app.zip = szip.open(item.path, szip.CompressionLevel.no_compression, + szip.OpenMode.read_only)! } // println("Now get the image") app.zip.open_entry_by_index(item.container_item_index)! diff --git a/examples/wasm_codegen/bf_compiler.v b/examples/wasm_codegen/bf_compiler.v index 5cddb1db72..a9770009db 100644 --- a/examples/wasm_codegen/bf_compiler.v +++ b/examples/wasm_codegen/bf_compiler.v @@ -121,10 +121,12 @@ fn main() { mut m := wasm.Module{} m.enable_debug('wasm bf') - m.new_function_import('wasi_unstable', 'fd_write', [.i32_t, .i32_t, .i32_t, .i32_t], - [.i32_t]) - m.new_function_import('wasi_unstable', 'fd_read', [.i32_t, .i32_t, .i32_t, .i32_t], - [.i32_t]) + m.new_function_import('wasi_unstable', 'fd_write', [.i32_t, .i32_t, .i32_t, .i32_t], [ + .i32_t, + ]) + m.new_function_import('wasi_unstable', 'fd_read', [.i32_t, .i32_t, .i32_t, .i32_t], [ + .i32_t, + ]) m.assign_memory('memory', true, 2, none) mut start := m.new_function('_start', [], []) diff --git a/examples/wasm_codegen/hello_wasi.v b/examples/wasm_codegen/hello_wasi.v index 85df2932de..a71ed102d3 100644 --- a/examples/wasm_codegen/hello_wasi.v +++ b/examples/wasm_codegen/hello_wasi.v @@ -4,8 +4,9 @@ fn main() { mut m := wasm.Module{} m.enable_debug('vlang') m.new_function_import('wasi_unstable', 'proc_exit', [.i32_t], []) - m.new_function_import('wasi_unstable', 'fd_write', [.i32_t, .i32_t, .i32_t, .i32_t], - [.i32_t]) + m.new_function_import('wasi_unstable', 'fd_write', [.i32_t, .i32_t, .i32_t, .i32_t], [ + .i32_t, + ]) m.assign_memory('memory', true, 1, none) m.new_data_segment('CIOVec.str', 0, [u8(8), 0, 0, 0]) // pointer to string diff --git a/vlib/arrays/arrays_fold_test.v b/vlib/arrays/arrays_fold_test.v index 3d8dd8aee6..a11a4fe2ce 100644 --- a/vlib/arrays/arrays_fold_test.v +++ b/vlib/arrays/arrays_fold_test.v @@ -24,7 +24,7 @@ fn test_main() { assert arrays.fold[bool, []bool]([true, false], []bool{}, fn (r []bool, t bool) []bool { return arrays.merge(r, [t]) }) == [false, true] - assert arrays.fold[MyInt, []MyInt]([MyInt(0), 1], []MyInt{}, fn (r []MyInt, t MyInt) []MyInt { + assert arrays.fold[MyInt, []MyInt]([MyInt(0), 1], []MyInt{}, fn (r []main.MyInt, t MyInt) []main.MyInt { return arrays.merge(r, [t]) }) == [MyInt(0), 1] assert arrays.fold([1, 2, 3, 4], [5, 6, 7], fn (r []int, t int) []int { diff --git a/vlib/benchmark/benchmark.v b/vlib/benchmark/benchmark.v index 8f03fc73dd..0cd2ad264b 100644 --- a/vlib/benchmark/benchmark.v +++ b/vlib/benchmark/benchmark.v @@ -203,8 +203,7 @@ pub fn (b &Benchmark) step_message_with_label_and_duration(label string, msg str // step_message_with_label returns a string describing the current step using current time as duration. pub fn (b &Benchmark) step_message_with_label(label string, msg string, opts MessageOptions) string { - return b.step_message_with_label_and_duration(label, msg, b.step_timer.elapsed(), - opts) + return b.step_message_with_label_and_duration(label, msg, b.step_timer.elapsed(), opts) } // step_message returns a string describing the current step. diff --git a/vlib/bitfield/bitfield_test.v b/vlib/bitfield/bitfield_test.v index c7eb1f1cc2..448830ed29 100644 --- a/vlib/bitfield/bitfield_test.v +++ b/vlib/bitfield/bitfield_test.v @@ -135,7 +135,8 @@ fn test_pop_count() { } fn test_pop_count2() { - b := bitfield.from_str('011000110110110000010001000011010011011111011110101001010011011010001100001001101111111011010011') + b := + bitfield.from_str('011000110110110000010001000011010011011111011110101001010011011010001100001001101111111011010011') assert b.pop_count() == 50 } diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 71c2c79340..1214ab67d4 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -214,8 +214,7 @@ pub fn (mut a array) ensure_cap(required int) { // limit the capacity, since bigger values, will overflow the 32bit integer used to store it cap = max_int } else { - panic_n('array.ensure_cap: array needs to grow to cap (which is > 2^31):', - cap) + panic_n('array.ensure_cap: array needs to grow to cap (which is > 2^31):', cap) } } new_size := u64(cap) * u64(a.element_size) @@ -385,8 +384,7 @@ pub fn (mut a array) delete(i int) { pub fn (mut a array) delete_many(i int, size int) { if i < 0 || i64(i) + i64(size) > i64(a.len) { if size > 1 { - panic_n3('array.delete: index out of range (i,i+size,a.len):', i, i + size, - a.len) + panic_n3('array.delete: index out of range (i,i+size,a.len):', i, i + size, a.len) } else { panic_n2('array.delete: index out of range (i,a.len):', i, a.len) } @@ -619,7 +617,8 @@ fn (a array) slice(start int, _end int) array { end := if _end == max_i64 || _end == max_i32 { a.len } else { _end } // max_int $if !no_bounds_checking { if start > end { - panic('array.slice: invalid slice index (start>end):' + impl_i64_to_string(i64(start)) + + panic( + 'array.slice: invalid slice index (start>end):' + impl_i64_to_string(i64(start)) + ', ' + impl_i64_to_string(end)) } if end > a.len { @@ -797,11 +796,15 @@ pub fn (mut a array) push_many(val voidptr, size int) { // handle `arr << arr` copy := a.clone() unsafe { - vmemcpy(&u8(a.data) + u64(a.element_size) * u64(a.len), copy.data, u64(a.element_size) * u64(size)) + vmemcpy(&u8(a.data) + u64(a.element_size) * u64(a.len), copy.data, + u64(a.element_size) * u64(size)) } } else { if a.data != 0 && val != 0 { - unsafe { vmemcpy(&u8(a.data) + u64(a.element_size) * u64(a.len), val, u64(a.element_size) * u64(size)) } + unsafe { + vmemcpy(&u8(a.data) + u64(a.element_size) * u64(a.len), val, + u64(a.element_size) * u64(size)) + } } } a.len = int(new_len) @@ -816,8 +819,8 @@ pub fn (mut a array) reverse_in_place() { mut tmp_value := malloc(a.element_size) for i in 0 .. a.len / 2 { vmemcpy(tmp_value, &u8(a.data) + u64(i) * u64(a.element_size), a.element_size) - vmemcpy(&u8(a.data) + u64(i) * u64(a.element_size), &u8(a.data) + - u64(a.len - 1 - i) * u64(a.element_size), a.element_size) + vmemcpy(&u8(a.data) + u64(i) * u64(a.element_size), &u8(a.data) + u64(a.len - 1 - + i) * u64(a.element_size), a.element_size) vmemcpy(&u8(a.data) + u64(a.len - 1 - i) * u64(a.element_size), tmp_value, a.element_size) } @@ -973,7 +976,7 @@ pub fn (a &array) sorted(callback fn (voidptr, voidptr) int) array // }) // assert a == ['1', '3', '5', 'hi'] // ``` -pub fn (mut a array) sort_with_compare(callback fn (const_a voidptr, const_b voidptr) int) { +pub fn (mut a array) sort_with_compare(callback FnSortCB) { $if freestanding { panic('sort_with_compare does not work with -freestanding') } $else { @@ -984,7 +987,7 @@ pub fn (mut a array) sort_with_compare(callback fn (const_a voidptr, const_b voi // sorted_with_compare sorts a clone of the array. The original array is not modified. // It uses the results of the given function to determine sort order. // See also .sort_with_compare() -pub fn (a &array) sorted_with_compare(callback fn (const_a voidptr, const_b voidptr) int) array { +pub fn (a &array) sorted_with_compare(callback FnSortCB) array { mut r := a.clone() unsafe { vqsort(r.data, usize(r.len), usize(r.element_size), callback) } return r diff --git a/vlib/builtin/array_d_gcboehm_opt.v b/vlib/builtin/array_d_gcboehm_opt.v index ae74ff1fd6..791766d8d4 100644 --- a/vlib/builtin/array_d_gcboehm_opt.v +++ b/vlib/builtin/array_d_gcboehm_opt.v @@ -120,8 +120,7 @@ fn (mut a array) ensure_cap_noscan(required int) { // limit the capacity, since bigger values, will overflow the 32bit integer used to store it cap = max_int } else { - panic_n('array.ensure_cap_noscan: array needs to grow to cap (which is > 2^31):', - cap) + panic_n('array.ensure_cap_noscan: array needs to grow to cap (which is > 2^31):', cap) } } new_size := u64(cap) * u64(a.element_size) diff --git a/vlib/builtin/builtin_windows.c.v b/vlib/builtin/builtin_windows.c.v index 1ad4675d83..738befc945 100644 --- a/vlib/builtin/builtin_windows.c.v +++ b/vlib/builtin/builtin_windows.c.v @@ -74,8 +74,10 @@ fn builtin_init() { C.SetConsoleOutputCP(cp_utf8) at_exit(restore_codepage) or {} if is_terminal(1) > 0 { - C.SetConsoleMode(C.GetStdHandle(std_output_handle), enable_processed_output | enable_wrap_at_eol_output | evable_virtual_terminal_processing) - C.SetConsoleMode(C.GetStdHandle(std_error_handle), enable_processed_output | enable_wrap_at_eol_output | evable_virtual_terminal_processing) + C.SetConsoleMode(C.GetStdHandle(std_output_handle), + enable_processed_output | enable_wrap_at_eol_output | evable_virtual_terminal_processing) + C.SetConsoleMode(C.GetStdHandle(std_error_handle), + enable_processed_output | enable_wrap_at_eol_output | evable_virtual_terminal_processing) unsafe { C.setbuf(C.stdout, 0) C.setbuf(C.stderr, 0) diff --git a/vlib/builtin/cfns_wrapper.c.v b/vlib/builtin/cfns_wrapper.c.v index c6ea29e901..f7fe9718bd 100644 --- a/vlib/builtin/cfns_wrapper.c.v +++ b/vlib/builtin/cfns_wrapper.c.v @@ -24,8 +24,8 @@ pub fn vmemcpy(dest voidptr, const_src voidptr, n isize) voidptr { } $if trace_vmemcpy_nulls ? { if dest == unsafe { 0 } || const_src == unsafe { 0 } { - C.fprintf(C.stderr, c'vmemcpy null pointers passed, dest: %p src: %p n: %6ld\n', - dest, const_src, n) + C.fprintf(C.stderr, c'vmemcpy null pointers passed, dest: %p src: %p n: %6ld\n', dest, + const_src, n) print_backtrace() } } @@ -89,8 +89,7 @@ pub fn vmemset(s voidptr, c int, n isize) voidptr { } $if trace_vmemset_nulls ? { if s == unsafe { 0 } { - C.fprintf(C.stderr, c'vmemset null pointers passed s: %p, c: %6d, n: %6ld\n', - s, c, n) + C.fprintf(C.stderr, c'vmemset null pointers passed s: %p, c: %6d, n: %6ld\n', s, c, n) print_backtrace() } } @@ -107,15 +106,16 @@ type FnSortCB = fn (const_a voidptr, const_b voidptr) int @[inline; unsafe] fn vqsort(base voidptr, nmemb usize, size usize, sort_cb FnSortCB) { $if trace_vqsort ? { - C.fprintf(C.stderr, c'vqsort base: %p, nmemb: %6uld, size: %6uld, sort_cb: %p\n', - base, nmemb, size, sort_cb) + C.fprintf(C.stderr, c'vqsort base: %p, nmemb: %6uld, size: %6uld, sort_cb: %p\n', base, + nmemb, size, sort_cb) } if nmemb == 0 { return } $if trace_vqsort_nulls ? { - if base == unsafe { 0 } || u64(sort_cb) == 0 { - C.fprintf(C.stderr, c'vqsort null pointers passed base: %p, nmemb: %6uld, size: %6uld, sort_cb: %p\n', + if base == unsafe { 0 } || voidptr(sort_cb) == unsafe { nil } { + C.fprintf(C.stderr, + c'vqsort null pointers passed base: %p, nmemb: %6uld, size: %6uld, sort_cb: %p\n', base, nmemb, size, sort_cb) print_backtrace() } diff --git a/vlib/builtin/chan_option_result.v b/vlib/builtin/chan_option_result.v index 8f1e604a0e..c0084d1096 100644 --- a/vlib/builtin/chan_option_result.v +++ b/vlib/builtin/chan_option_result.v @@ -176,8 +176,7 @@ fn _option_clone(current &_option, mut option _option, size int) { err: current.err } // use err to get the end of OptionBase and then memcpy into it - vmemcpy(&u8(&option.err) + sizeof(IError), &u8(¤t.err) + sizeof(IError), - size) + vmemcpy(&u8(&option.err) + sizeof(IError), &u8(¤t.err) + sizeof(IError), size) } } diff --git a/vlib/builtin/closure/closure_nix.c.v b/vlib/builtin/closure/closure_nix.c.v index 34352f1446..5e01c4d83a 100644 --- a/vlib/builtin/closure/closure_nix.c.v +++ b/vlib/builtin/closure/closure_nix.c.v @@ -23,8 +23,8 @@ fn closure_alloc_platform() &u8 { } $else { // Main OS environments use mmap to get aligned pages p = unsafe { - C.mmap(0, g_closure.v_page_size * 2, C.PROT_READ | C.PROT_WRITE, C.MAP_ANONYMOUS | C.MAP_PRIVATE, - -1, 0) + C.mmap(0, g_closure.v_page_size * 2, C.PROT_READ | C.PROT_WRITE, + C.MAP_ANONYMOUS | C.MAP_PRIVATE, -1, 0) } if p == &u8(C.MAP_FAILED) { return unsafe { nil } diff --git a/vlib/builtin/linux_bare/memory_managment.v b/vlib/builtin/linux_bare/memory_managment.v index 0736a72eed..95221f2e7e 100644 --- a/vlib/builtin/linux_bare/memory_managment.v +++ b/vlib/builtin/linux_bare/memory_managment.v @@ -10,8 +10,7 @@ fn mm_alloc(size u64) (&u8, Errno) { map_flags := unsafe { MapFlags(int(MapFlags.map_private) | int(MapFlags.map_anonymous)) } // END CONSTS - a, e := sys_mmap(&u8(unsafe { nil }), size + sizeof(u64), mem_prot, map_flags, -1, - 0) + a, e := sys_mmap(&u8(unsafe { nil }), size + sizeof(u64), mem_prot, map_flags, -1, 0) if e == .enoerror { unsafe { mut ap := &u64(a) diff --git a/vlib/builtin/map.v b/vlib/builtin/map.v index 46502aca0c..e10d118cf1 100644 --- a/vlib/builtin/map.v +++ b/vlib/builtin/map.v @@ -452,9 +452,11 @@ fn (mut m map) ensure_extra_metas_grow() { m.extra_metas += extra_metas_inc mem_size := (m.even_index + 2 + m.extra_metas) unsafe { - x := realloc_data(byteptr(m.metas), int(size_of_u32 * old_mem_size), int(size_of_u32 * mem_size)) + x := realloc_data(byteptr(m.metas), int(size_of_u32 * old_mem_size), + int(size_of_u32 * mem_size)) m.metas = &u32(x) - vmemset(byteptr(m.metas) + (mem_size - extra_metas_inc) * size_of_u32, 0, int(sizeof(u32) * extra_metas_inc)) + vmemset(byteptr(m.metas) + (mem_size - extra_metas_inc) * size_of_u32, 0, + int(sizeof(u32) * extra_metas_inc)) } } @@ -466,7 +468,8 @@ fn (mut m map) ensure_extra_metas(probe_count u32) { m.extra_metas += extra_metas_inc mem_size := (m.even_index + 2 + m.extra_metas) unsafe { - x := realloc_data(byteptr(m.metas), int(size_of_u32 * old_mem_size), int(size_of_u32 * mem_size)) + x := realloc_data(byteptr(m.metas), int(size_of_u32 * old_mem_size), + int(size_of_u32 * mem_size)) m.metas = &u32(x) vmemset(byteptr(m.metas) + (mem_size - extra_metas_inc) * size_of_u32, 0, int(sizeof(u32) * extra_metas_inc)) diff --git a/vlib/builtin/map_d_gcboehm_opt.v b/vlib/builtin/map_d_gcboehm_opt.v index 5e0b3ef529..106a313948 100644 --- a/vlib/builtin/map_d_gcboehm_opt.v +++ b/vlib/builtin/map_d_gcboehm_opt.v @@ -100,8 +100,7 @@ fn new_map_noscan_key_value(key_bytes int, value_bytes int, hash_fn MapHashFn, k fn new_map_init_noscan_key(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map { - mut out := new_map_noscan_key(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, - free_fn) + mut out := new_map_noscan_key(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, free_fn) // TODO: pre-allocate n slots mut pkey := &u8(keys) mut pval := &u8(values) @@ -117,8 +116,7 @@ fn new_map_init_noscan_key(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapClo fn new_map_init_noscan_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map { - mut out := new_map_noscan_value(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, - free_fn) + mut out := new_map_noscan_value(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn, free_fn) // TODO: pre-allocate n slots mut pkey := &u8(keys) mut pval := &u8(values) diff --git a/vlib/builtin/map_notd_gcboehm_opt.v b/vlib/builtin/map_notd_gcboehm_opt.v index cf4ababa43..80d5d31848 100644 --- a/vlib/builtin/map_notd_gcboehm_opt.v +++ b/vlib/builtin/map_notd_gcboehm_opt.v @@ -21,18 +21,18 @@ fn new_map_noscan_key_value(key_bytes int, value_bytes int, hash_fn MapHashFn, k fn new_map_init_noscan_key(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map { - return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, - keys, values) + return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, keys, + values) } fn new_map_init_noscan_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map { - return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, - keys, values) + return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, keys, + values) } fn new_map_init_noscan_key_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map { - return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, - keys, values) + return new_map_init(hash_fn, key_eq_fn, clone_fn, free_fn, n, key_bytes, value_bytes, keys, + values) } diff --git a/vlib/builtin/prealloc.c.v b/vlib/builtin/prealloc.c.v index d9ec5539f9..7b759ba185 100644 --- a/vlib/builtin/prealloc.c.v +++ b/vlib/builtin/prealloc.c.v @@ -64,8 +64,9 @@ fn vmemory_block_new(prev &VMemoryBlock, at_least isize, align isize) &VMemoryBl base_block_size } $if prealloc_trace_malloc ? { - C.fprintf(C.stderr, c'vmemory_block_new id: %d, block_size: %lld, at_least: %lld, align: %lld\n', - v.id, block_size, at_least, align) + C.fprintf(C.stderr, + c'vmemory_block_new id: %d, block_size: %lld, at_least: %lld, align: %lld\n', v.id, + block_size, at_least, align) } fixed_align := if align <= 1 { 1 } else { align } @@ -145,12 +146,12 @@ fn prealloc_vcleanup() { total_used += used remaining := i64(mb.stop) - i64(mb.current) size := i64(mb.stop) - i64(mb.start) - C.fprintf(C.stderr, c'> freeing mb: %16p, mb.id: %3d | size: %10lld | rem: %10lld | start: %16p | current: %16p | used: %10lld bytes | mallocs: %6d\n', + C.fprintf(C.stderr, + c'> freeing mb: %16p, mb.id: %3d | size: %10lld | rem: %10lld | start: %16p | current: %16p | used: %10lld bytes | mallocs: %6d\n', mb, mb.id, size, remaining, mb.start, mb.current, used, mb.mallocs) mb = mb.previous } - C.fprintf(C.stderr, c'> nr_mallocs: %lld, total_used: %lld bytes\n', nr_mallocs, - total_used) + C.fprintf(C.stderr, c'> nr_mallocs: %lld, total_used: %lld bytes\n', nr_mallocs, total_used) } $if prealloc_dump ? { C.fprintf(C.stderr, c'prealloc_vcleanup dumping memory contents ...\n') @@ -165,15 +166,15 @@ fn prealloc_vcleanup() { mut total_used := u64(0) path := $d('memdumpfile', 'memdump.bin') - C.fprintf(C.stderr, c'prealloc_vcleanup dumping process memory to path: %s\n', - path.str) + C.fprintf(C.stderr, c'prealloc_vcleanup dumping process memory to path: %s\n', path.str) stream := C.fopen(path.str, c'wb') mut mb := start for { used := u64(mb.current) - u64(mb.start) total_used += used - C.fprintf(C.stderr, c'prealloc_vcleanup dumping mb: %p, mb.id: %d, used: %10lld bytes\n', - mb, mb.id, used) + C.fprintf(C.stderr, + c'prealloc_vcleanup dumping mb: %p, mb.id: %d, used: %10lld bytes\n', mb, + mb.id, used) mut ptr := mb.start mut remaining_bytes := isize(used) @@ -190,8 +191,7 @@ fn prealloc_vcleanup() { mb = mb.next } C.fclose(stream) - C.fprintf(C.stderr, c'prealloc_vcleanup total dump size in bytes: %lld\n', - total_used) + C.fprintf(C.stderr, c'prealloc_vcleanup total dump size in bytes: %lld\n', total_used) } } unsafe { diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index 435b96e6bb..734c973253 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -309,7 +309,7 @@ pub fn (s string) len_utf8() int { mut i := 0 for i < s.len { l++ - i += ((0xe5000000 >> ((unsafe { s.str[i] } >> 3) & 0x1e)) & 3) + 1 + i += int(((u32(0xe5000000) >> ((unsafe { s.str[i] } >> 3) & 0x1e)) & 3) + 1) } return l } diff --git a/vlib/builtin/string_interpolation.v b/vlib/builtin/string_interpolation.v index 4f46ade739..d855dc51df 100644 --- a/vlib/builtin/string_interpolation.v +++ b/vlib/builtin/string_interpolation.v @@ -725,12 +725,12 @@ pub const si_g64_code = '0xfe0f' @[inline] pub fn str_intp_sq(in_str string) string { - return 'builtin__str_intp(2, _MOV((StrIntpData[]){{_S("\'"), ${si_s_code}, {.d_s = ${in_str}}, 0, 0, 0},{_S("\'"), 0, {.d_c = 0 }, 0, 0, 0}}))' + return 'builtin__str_intp(2, _MOV((StrIntpData[]){{_S("\'"), ${si_s_code}, {.d_s = ${in_str}}, 0, 0, 0},{_S("\'"), 0, {0}, 0, 0, 0}}))' } @[inline] pub fn str_intp_rune(in_str string) string { - return 'builtin__str_intp(2, _MOV((StrIntpData[]){{_S("\`"), ${si_s_code}, {.d_s = ${in_str}}, 0, 0, 0},{_S("\`"), 0, {.d_c = 0 }, 0, 0, 0}}))' + return 'builtin__str_intp(2, _MOV((StrIntpData[]){{_S("\`"), ${si_s_code}, {.d_s = ${in_str}}, 0, 0, 0},{_S("\`"), 0, {0}, 0, 0, 0}}))' } @[inline] @@ -755,7 +755,7 @@ pub fn str_intp_sub(base_str string, in_str string) string { st_str := base_str[..index] if index + 2 < base_str.len { en_str := base_str[index + 2..] - res_str := 'builtin__str_intp(2, _MOV((StrIntpData[]){{_S("${st_str}"), ${si_s_code}, {.d_s = ${in_str} }, 0, 0, 0},{_S("${en_str}"), 0, {.d_c = 0}, 0, 0, 0}}))' + res_str := 'builtin__str_intp(2, _MOV((StrIntpData[]){{_S("${st_str}"), ${si_s_code}, {.d_s = ${in_str} }, 0, 0, 0},{_S("${en_str}"), 0, {0}, 0, 0, 0}}))' st_str.free() en_str.free() return res_str diff --git a/vlib/builtin/string_strip_margin_test.v b/vlib/builtin/string_strip_margin_test.v index cfcb36c9ad..c50d624c8b 100644 --- a/vlib/builtin/string_strip_margin_test.v +++ b/vlib/builtin/string_strip_margin_test.v @@ -11,7 +11,8 @@ fn test_strip_margins_no_tabs() { } fn test_strip_margins_text_before() { - text_before := ['There is text', 'before the delimiter', 'that should be removed as well'].join('\n') + text_before := + ['There is text', 'before the delimiter', 'that should be removed as well'].join('\n') text_before_stripped := 'There is text f lasj asldfj j lksjdf |before the delimiter Which is removed hello |that should be removed as well'.strip_margin() @@ -67,7 +68,8 @@ fn test_strip_margins_multiple_blank_lines() { } fn test_strip_margins_end_newline() { - end_with_newline := ['This line will end with a newline', 'Something cool or something.', ''].join('\n') + end_with_newline := + ['This line will end with a newline', 'Something cool or something.', ''].join('\n') end_with_newline_stripped := 'This line will end with a newline |Something cool or something. @@ -76,14 +78,16 @@ fn test_strip_margins_end_newline() { } fn test_strip_margins_space_delimiter() { - space_delimiter := ['Using a white-space char will', 'revert back to default behavior.'].join('\n') + space_delimiter := + ['Using a white-space char will', 'revert back to default behavior.'].join('\n') space_delimiter_stripped := 'Using a white-space char will |revert back to default behavior.'.strip_margin_custom(`\n`) assert space_delimiter == space_delimiter_stripped } fn test_strip_margins_crlf() { - crlf := ["This string's line endings have CR as well as LFs.", 'This should pass', 'Definitely'].join('\r\n') + crlf := + ["This string's line endings have CR as well as LFs.", 'This should pass', 'Definitely'].join('\r\n') crlf_stripped := "This string's line endings have CR as well as LFs.\r |This should pass\r |Definitely".strip_margin() diff --git a/vlib/builtin/utf8.c.v b/vlib/builtin/utf8.c.v index 6090603c16..1ee5736321 100644 --- a/vlib/builtin/utf8.c.v +++ b/vlib/builtin/utf8.c.v @@ -22,12 +22,10 @@ pub fn (_str string) to_wide(param ToWideConfig) &u16 { $if windows { unsafe { src_encoding := if param.from_ansi { cp_acp } else { cp_utf8 } - num_chars := (C.MultiByteToWideChar(src_encoding, 0, &char(_str.str), _str.len, - 0, 0)) + num_chars := (C.MultiByteToWideChar(src_encoding, 0, &char(_str.str), _str.len, 0, 0)) mut wstr := &u16(malloc_noscan((num_chars + 1) * 2)) // sizeof(wchar_t) if wstr != 0 { - C.MultiByteToWideChar(src_encoding, 0, &char(_str.str), _str.len, wstr, - num_chars) + C.MultiByteToWideChar(src_encoding, 0, &char(_str.str), _str.len, wstr, num_chars) C.memset(&u8(wstr) + num_chars * 2, 0, 2) } return wstr @@ -81,8 +79,7 @@ pub fn string_from_wide2(_wstr &u16, len int) string { num_chars := C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, 0, 0, 0, 0) mut str_to := malloc_noscan(num_chars + 1) if str_to != 0 { - C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, &char(str_to), num_chars, - 0, 0) + C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, &char(str_to), num_chars, 0, 0) C.memset(str_to + num_chars, 0, 1) } return tos2(str_to) @@ -107,8 +104,7 @@ pub fn wide_to_ansi(_wstr &u16) []u8 { num_bytes := C.WideCharToMultiByte(cp_acp, 0, _wstr, -1, 0, 0, 0, 0) if num_bytes != 0 { mut str_to := []u8{len: num_bytes} - C.WideCharToMultiByte(cp_acp, 0, _wstr, -1, &char(str_to.data), str_to.len, - 0, 0) + C.WideCharToMultiByte(cp_acp, 0, _wstr, -1, &char(str_to.data), str_to.len, 0, 0) return str_to } else { return []u8{} diff --git a/vlib/builtin/utf8.v b/vlib/builtin/utf8.v index d41683d703..99daa34238 100644 --- a/vlib/builtin/utf8.v +++ b/vlib/builtin/utf8.v @@ -5,7 +5,7 @@ module builtin // utf8_char_len returns the length in bytes of a UTF-8 encoded codepoint that starts with the byte `b`. pub fn utf8_char_len(b u8) int { - return ((0xe5000000 >> ((b >> 3) & 0x1e)) & 3) + 1 + return int(((u32(0xe5000000) >> ((b >> 3) & 0x1e)) & 3) + 1) } // Convert utf32 to utf8 diff --git a/vlib/builtin/vgc_d_vgc.c.v b/vlib/builtin/vgc_d_vgc.c.v index 2f2edea84d..d60140c3b3 100644 --- a/vlib/builtin/vgc_d_vgc.c.v +++ b/vlib/builtin/vgc_d_vgc.c.v @@ -846,8 +846,7 @@ fn vgc_realloc(old_ptr voidptr, new_size usize) voidptr { if old_span.noscan { new_ptr = vgc_malloc_noscan_opts(new_size, false) } else if old_span.has_ptrmap { - new_ptr = vgc_malloc_typed_opts(new_size, old_span.ptrmap, old_span.ptr_words, - false) + new_ptr = vgc_malloc_typed_opts(new_size, old_span.ptrmap, old_span.ptr_words, false) } else { new_ptr = vgc_malloc_typed_opts(new_size, 0, 0, false) } diff --git a/vlib/cli/command.v b/vlib/cli/command.v index e2974d4398..10c94a7195 100644 --- a/vlib/cli/command.v +++ b/vlib/cli/command.v @@ -322,7 +322,8 @@ fn (mut cmd Command) handle_cb(cb FnCommandCallback, label string) { fn (cmd &Command) check_help_flag() { if cmd.defaults.parsed.help.flag && cmd.flags.contains('help') { - help_flag := cmd.flags.get_bool('help') or { return } // ignore error and handle command normally + help_flag := + cmd.flags.get_bool('help') or { return } // ignore error and handle command normally if help_flag { cmd.execute_help() exit(0) @@ -332,7 +333,8 @@ fn (cmd &Command) check_help_flag() { fn (cmd &Command) check_man_flag() { if cmd.defaults.parsed.man.flag && cmd.flags.contains('man') { - man_flag := cmd.flags.get_bool('man') or { return } // ignore error and handle command normally + man_flag := + cmd.flags.get_bool('man') or { return } // ignore error and handle command normally if man_flag { cmd.execute_man() exit(0) @@ -342,7 +344,8 @@ fn (cmd &Command) check_man_flag() { fn (cmd &Command) check_version_flag() { if cmd.defaults.parsed.version.flag && cmd.version != '' && cmd.flags.contains('version') { - version_flag := cmd.flags.get_bool('version') or { return } // ignore error and handle command normally + version_flag := + cmd.flags.get_bool('version') or { return } // ignore error and handle command normally if version_flag { print_version_for_command(cmd) or { panic(err) } exit(0) @@ -362,7 +365,8 @@ fn (cmd &Command) check_required_flags() { // execute_help executes the callback registered for the `-h`/`--help` flag option. pub fn (cmd &Command) execute_help() { if cmd.commands.contains('help') { - help_cmd := cmd.commands.get('help') or { return } // ignore error and handle command normally + help_cmd := + cmd.commands.get('help') or { return } // ignore error and handle command normally if !isnil(help_cmd.execute) { help_cmd.execute(help_cmd) or { panic(err) } return diff --git a/vlib/cli/help.v b/vlib/cli/help.v index 38efc98229..7341933067 100644 --- a/vlib/cli/help.v +++ b/vlib/cli/help.v @@ -70,7 +70,8 @@ pub fn (cmd &Command) help_message() string { if flag.abbrev != '' { abbrev_len = max(abbrev_len, flag.abbrev.len + spacing + 1) // + 1 for '-' in front } - name_len = max(name_len, abbrev_len + flag.name.len + spacing + 2) // + 2 for '--' in front + name_len = + max(name_len, abbrev_len + flag.name.len + spacing + 2) // + 2 for '--' in front } for command in cmd.commands { name_len = max(name_len, command.name.len + spacing) @@ -80,7 +81,8 @@ pub fn (cmd &Command) help_message() string { if flag.abbrev != '' { abbrev_len = max(abbrev_len, flag.abbrev.len + spacing + 1) // + 1 for '-' in front } - name_len = max(name_len, abbrev_len + flag.name.len + spacing + 1) // + 1 for '-' in front + name_len = + max(name_len, abbrev_len + flag.name.len + spacing + 1) // + 1 for '-' in front } for command in cmd.commands { name_len = max(name_len, command.name.len + spacing) @@ -92,7 +94,8 @@ pub fn (cmd &Command) help_message() string { mut flag_name := '' prefix := if cmd.posix_mode { '--' } else { '-' } if flag.abbrev != '' { - abbrev_indent := ' '.repeat(abbrev_len - flag.abbrev.len - 1) // - 1 for '-' in front + abbrev_indent := + ' '.repeat(abbrev_len - flag.abbrev.len - 1) // - 1 for '-' in front flag_name = '-${flag.abbrev}${abbrev_indent}${prefix}${flag.name}' } else { abbrev_indent := ' '.repeat(abbrev_len) diff --git a/vlib/clipboard/clipboard_windows.c.v b/vlib/clipboard/clipboard_windows.c.v index fc4dacb0bf..8450d47fd2 100644 --- a/vlib/clipboard/clipboard_windows.c.v +++ b/vlib/clipboard/clipboard_windows.c.v @@ -101,8 +101,8 @@ fn new_clipboard() &Clipboard { && C.GetLastError() != u32(C.ERROR_CLASS_ALREADY_EXISTS) { println('Failed registering class.') } - hwnd := C.CreateWindowEx(0, wndclass.lpsz_class_name, wndclass.lpsz_class_name, 0, - 0, 0, 0, 0, C.HWND_MESSAGE, C.NULL, C.NULL, C.NULL) + hwnd := C.CreateWindowEx(0, wndclass.lpsz_class_name, wndclass.lpsz_class_name, 0, 0, 0, 0, 0, + C.HWND_MESSAGE, C.NULL, C.NULL, C.NULL) if hwnd == unsafe { nil } { println('Error creating window!') } @@ -141,6 +141,7 @@ const cp_utf8 = 65001 // the string.to_wide doesn't work with SetClipboardData, don't know why fn to_wide(text string) C.HGLOBAL { len_required := C.MultiByteToWideChar(cp_utf8, C.MB_ERR_INVALID_CHARS, voidptr(text.str), + text.len + 1, C.NULL, 0) buf := C.GlobalAlloc(C.GMEM_MOVEABLE, i64(sizeof(u16)) * len_required) if buf != unsafe { nil } { diff --git a/vlib/clipboard/x11/clipboard.c.v b/vlib/clipboard/x11/clipboard.c.v index 3015ae15ee..b60c8be0fe 100644 --- a/vlib/clipboard/x11/clipboard.c.v +++ b/vlib/clipboard/x11/clipboard.c.v @@ -114,6 +114,17 @@ fn C.WhitePixel(display &C.Display, screen_number i32) u32 fn C.XFree(data voidptr) +// X11 event type constants +pub const C.DestroyNotify int +pub const C.SelectionClear int +pub const C.SelectionRequest int +pub const C.SelectionNotify int +pub const C.PropertyNotify int // X11 property/selection constants + +pub const C.CurrentTime int +pub const C.PropModeReplace int +pub const C.PropertyChangeMask i64 + fn todo_del() {} // X11 event types are defined in vlib/x/x11/x11.v @@ -271,8 +282,8 @@ pub fn (mut cb Clipboard) get_text() string { cb.got_text = false // Request a list of possible conversions, if we're pasting. - C.XConvertSelection(cb.display, cb.selection, cb.get_atom(.targets), cb.selection, - cb.window, C.CurrentTime) + C.XConvertSelection(cb.display, cb.selection, cb.get_atom(.targets), cb.selection, cb.window, + C.CurrentTime) // wait for the text to arrive mut retries := 5 @@ -292,8 +303,8 @@ fn (mut cb Clipboard) transmit_selection(xse &C.XSelectionEvent) bool { unsafe { if xse.target == cb.get_atom(.targets) { targets := cb.get_supported_targets() - C.XChangeProperty(xse.display, xse.requestor, xse.property, cb.get_atom(.xa_atom), - 32, C.PropModeReplace, targets.data, targets.len) + C.XChangeProperty(xse.display, xse.requestor, xse.property, cb.get_atom(.xa_atom), 32, + C.PropModeReplace, targets.data, targets.len) } else if cb.is_supported_target(xse.target) && cb.is_owner && cb.text != '' { cb.mutex.lock() C.XChangeProperty(xse.display, xse.requestor, xse.property, xse.target, 8, @@ -374,13 +385,14 @@ fn (mut cb Clipboard) start_listener() { sent_request = false to_be_requested = Atom(0) cb.mutex.lock() - prop := read_property(event.xselection.display, event.xselection.requestor, - event.xselection.property) + prop := read_property(event.xselection.display, + event.xselection.requestor, event.xselection.property) C.XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property) if cb.is_supported_target(prop.actual_type) { cb.got_text = true - cb.text = prop.data.vstring() // TODO: return byteptr to support other mimetypes + cb.text = + prop.data.vstring() // TODO: return byteptr to support other mimetypes } cb.mutex.unlock() } @@ -420,8 +432,8 @@ fn read_property(d &C.Display, w Window, p Atom) Property { if ret != 0 { C.XFree(ret) } - C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, 0, &actual_type, &actual_format, - &nitems, &bytes_after, &ret) + C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, 0, &actual_type, &actual_format, &nitems, + &bytes_after, &ret) read_bytes *= 2 if bytes_after == 0 { break diff --git a/vlib/compress/compress.c.v b/vlib/compress/compress.c.v index 329e5d9066..61af110c5e 100644 --- a/vlib/compress/compress.c.v +++ b/vlib/compress/compress.c.v @@ -70,8 +70,8 @@ pub fn decompress_with_callback(data []u8, cb ChunkCallback, userdata voidptr, f cb: cb userdata: userdata } - status := C.tinfl_decompress_mem_to_callback(cbdata.data, &cbdata.size, c_cb_for_decompress_mem, - &cbdata, flags) + status := C.tinfl_decompress_mem_to_callback(cbdata.data, &cbdata.size, + c_cb_for_decompress_mem, &cbdata, flags) if status == 0 { return error('decompression error') } diff --git a/vlib/compress/szip/szip_test.v b/vlib/compress/szip/szip_test.v index 6f5254f2cb..071a9a0ec0 100644 --- a/vlib/compress/szip/szip_test.v +++ b/vlib/compress/szip/szip_test.v @@ -92,7 +92,8 @@ fn test_reading_zipping_files() { szip.zip_files(files, test_out_zip)! assert os.exists(test_out_zip) - mut zp := szip.open(test_out_zip, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)! + mut zp := + szip.open(test_out_zip, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)! n_entries := zp.total()! assert n_entries == n_files diff --git a/vlib/compress/zstd/zstd_test.v b/vlib/compress/zstd/zstd_test.v index 6affb93e96..540df454e0 100644 --- a/vlib/compress/zstd/zstd_test.v +++ b/vlib/compress/zstd/zstd_test.v @@ -297,18 +297,21 @@ fn assert_decompress_error(data []u8, reason string) ! { } fn test_zstd_invalid_too_small() { - assert_decompress_error([]u8{}, 'An error occurred (e.g. invalid magic number, srcSize too small)')! + assert_decompress_error([]u8{}, + 'An error occurred (e.g. invalid magic number, srcSize too small)')! } fn test_zstd_invalid_magic_numbers() { - assert_decompress_error([]u8{len: 100}, 'An error occurred (e.g. invalid magic number, srcSize too small)')! + assert_decompress_error([]u8{len: 100}, + 'An error occurred (e.g. invalid magic number, srcSize too small)')! } fn test_zstd_invalid_compression() { mut data := []u8{len: 100} data[0] = 0x1f data[1] = 0x8b - assert_decompress_error(data, 'An error occurred (e.g. invalid magic number, srcSize too small)')! + assert_decompress_error(data, + 'An error occurred (e.g. invalid magic number, srcSize too small)')! } fn test_zstd_with_corruption1() { diff --git a/vlib/crypto/README.md b/vlib/crypto/README.md index 76a871ef11..7c14535ddf 100644 --- a/vlib/crypto/README.md +++ b/vlib/crypto/README.md @@ -81,7 +81,8 @@ fn main() { fn make_token(secret string) string { header := base64.url_encode(json.encode(JwtHeader{'HS256', 'JWT'}).bytes()) - payload := base64.url_encode(json.encode(JwtPayload{'1234567890', 'John Doe', 1516239022}).bytes()) + payload := + base64.url_encode(json.encode(JwtPayload{'1234567890', 'John Doe', 1516239022}).bytes()) signature := base64.url_encode(hmac.new(secret.bytes(), '${header}.${payload}'.bytes(), sha256.sum, sha256.block_size)) jwt := '${header}.${payload}.${signature}' diff --git a/vlib/crypto/bcrypt/bcrypt_test.v b/vlib/crypto/bcrypt/bcrypt_test.v index f51d3a401b..aee9f789d9 100644 --- a/vlib/crypto/bcrypt/bcrypt_test.v +++ b/vlib/crypto/bcrypt/bcrypt_test.v @@ -1,7 +1,8 @@ import crypto.bcrypt fn test_crypto_bcrypt() { - bcrypt.compare_hash_and_password('123456'.bytes(), r'$2a$07$MRniCPEgEQnrJmmgN.maM.kF2a/TI2PB37EQQNsUtEuINwultcHTm'.bytes())! + bcrypt.compare_hash_and_password('123456'.bytes(), + r'$2a$07$MRniCPEgEQnrJmmgN.maM.kF2a/TI2PB37EQQNsUtEuINwultcHTm'.bytes())! hash := bcrypt.generate_from_password('password'.bytes(), 5)! bcrypt.compare_hash_and_password('password'.bytes(), hash.bytes())! diff --git a/vlib/crypto/blake3/blake3.v b/vlib/crypto/blake3/blake3.v index 69f2b233d4..44d0c36e84 100644 --- a/vlib/crypto/blake3/blake3.v +++ b/vlib/crypto/blake3/blake3.v @@ -208,8 +208,8 @@ pub fn (mut d Digest) write(data []u8) ! { for d.input.len > chunk_size { mut chunk := Chunk{} - words := chunk.process_input(d.input[..chunk_size], d.key_words, d.chunk_counter, - d.flags, false) + words := chunk.process_input(d.input[..chunk_size], d.key_words, d.chunk_counter, d.flags, + false) d.add_node(Node{ chaining_value: words[..8] }, 0) diff --git a/vlib/crypto/ecdsa/ecdsa.c.v b/vlib/crypto/ecdsa/ecdsa.c.v index d6995f6deb..23e3697aa0 100644 --- a/vlib/crypto/ecdsa/ecdsa.c.v +++ b/vlib/crypto/ecdsa/ecdsa.c.v @@ -43,7 +43,13 @@ module ecdsa // The following header is available on OpenSSL 3.0, but not in OpenSSL 1.1.1f //#include -// The new opaque of public key pair high level API +// NID constants for elliptic curves +pub const C.NID_X9_62_prime256v1 int +pub const C.NID_secp384r1 int +pub const C.NID_secp521r1 int +pub const C.NID_secp256k1 int +pub const C.NID_X9_62_id_ecPublicKey int // The new opaque of public key pair high level API + @[typedef] struct C.EVP_PKEY {} diff --git a/vlib/crypto/ecdsa/ecdsa.v b/vlib/crypto/ecdsa/ecdsa.v index c33ff9e2c2..5005bc6d0e 100644 --- a/vlib/crypto/ecdsa/ecdsa.v +++ b/vlib/crypto/ecdsa/ecdsa.v @@ -482,8 +482,7 @@ fn evpkey_from_seed(seed []u8, opt CurveOptions) !&C.EVP_PKEY { assert param_bld != 0 // push the group, private and public key bytes infos into the builder - n := C.OSSL_PARAM_BLD_push_utf8_string(param_bld, c'group', voidptr(opt.nid.str().str), - 0) + n := C.OSSL_PARAM_BLD_push_utf8_string(param_bld, c'group', voidptr(opt.nid.str().str), 0) m := C.OSSL_PARAM_BLD_push_BN(param_bld, c'priv', bn) o := C.OSSL_PARAM_BLD_push_octet_string(param_bld, c'pub', pub_bytes.data, pub_bytes.len) if n <= 0 || m <= 0 || o <= 0 { diff --git a/vlib/crypto/ecdsa/example/ecdsa_seed_test.v b/vlib/crypto/ecdsa/example/ecdsa_seed_test.v index b04be65c78..0d048b47a8 100644 --- a/vlib/crypto/ecdsa/example/ecdsa_seed_test.v +++ b/vlib/crypto/ecdsa/example/ecdsa_seed_test.v @@ -51,7 +51,8 @@ LR3AGUldy+bBpV2nT306qCIwgUAMeOJP // Message tobe signed and verified message_tobe_signed := 'Example of ECDSA with P-384'.bytes() // Message signature generated with SHA384 digest with associated key previously. - signature := hex.decode('3066023100b08f6ec77bb319fdb7bce55a2714d7e79cc645d834ee539d8903cfcc88c6fa90df1558856cb840b2dd82e82cd89d7046023100d9d482ca8a6545a3b081fbdd4bb9643a2b4eda4e21fd624833216596032471faae646891f8d2f0bbb86b796c36d3c390')! + signature := + hex.decode('3066023100b08f6ec77bb319fdb7bce55a2714d7e79cc645d834ee539d8903cfcc88c6fa90df1558856cb840b2dd82e82cd89d7046023100d9d482ca8a6545a3b081fbdd4bb9643a2b4eda4e21fd624833216596032471faae646891f8d2f0bbb86b796c36d3c390')! // loads a Privatekey and PublicKey from above sample privkey := ecdsa.privkey_from_string(privkey_sample)! diff --git a/vlib/crypto/ecdsa/util_test.v b/vlib/crypto/ecdsa/util_test.v index 278b387b1d..e1e7f46955 100644 --- a/vlib/crypto/ecdsa/util_test.v +++ b/vlib/crypto/ecdsa/util_test.v @@ -149,7 +149,8 @@ fn test_key_signing_verifying_with_custom_hash() ! { custom_hash: sha512.new() } // online-generated signature with sha512 digest with the same params from https://emn178.github.io/online-tools/ecdsa/sign/ - online_sign0 := hex.decode('3066023100b54b479b64961481074c4200a9dec83fb8a42bb7db53cf97f1da131504a058ead85d0a9e4e32be14098bc9b4d1a5a8dd023100f9c7de178a286329103f684d1eab1ccfe359c65a41a1459d7f535b703c57048f25931b1670ab4ec7a812d94c69063522')! + online_sign0 := + hex.decode('3066023100b54b479b64961481074c4200a9dec83fb8a42bb7db53cf97f1da131504a058ead85d0a9e4e32be14098bc9b4d1a5a8dd023100f9c7de178a286329103f684d1eab1ccfe359c65a41a1459d7f535b703c57048f25931b1670ab4ec7a812d94c69063522')! // library generated signature sign0 := pvkey.sign(message_tobe_signed, opt0)! v00 := pbkey.verify(message_tobe_signed, sign0, opt0)! @@ -174,7 +175,8 @@ fn test_key_signing_verifying_with_custom_hash() ! { custom_hash: sha1.new() } // online-generated signature with SHA1 digest - online_sign1 := hex.decode('306602310084299d8a70bf512c25cd2b79ae36509572f2bd6f198baeee074683578a70b4af8008e1cf451a2df1a887cf43daff4eea023100dceb267fe5037025c2af9f37911e05a36cbe666dd90fd6904020b5db056e86f25f9439a0ccb443d113b174cab6e2ad61')! + online_sign1 := + hex.decode('306602310084299d8a70bf512c25cd2b79ae36509572f2bd6f198baeee074683578a70b4af8008e1cf451a2df1a887cf43daff4eea023100dceb267fe5037025c2af9f37911e05a36cbe666dd90fd6904020b5db056e86f25f9439a0ccb443d113b174cab6e2ad61')! // library generated signature sign1 := pvkey.sign(message_tobe_signed, opt1)! verified1 := pbkey.verify(message_tobe_signed, sign1, opt1)! diff --git a/vlib/crypto/ed25519/internal/edwards25519/element_test.v b/vlib/crypto/ed25519/internal/edwards25519/element_test.v index 364a15a540..b09aa9de91 100644 --- a/vlib/crypto/ed25519/internal/edwards25519/element_test.v +++ b/vlib/crypto/ed25519/internal/edwards25519/element_test.v @@ -314,8 +314,10 @@ fn test_mult_32() { } fn test_selected_and_swap() { - a := Element{358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676} - b := Element{84926274344903, 473620666599931, 365590438845504, 1028470286882429, 2146499180330972} + a := + Element{358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676} + b := + Element{84926274344903, 473620666599931, 365590438845504, 1028470286882429, 2146499180330972} mut c := Element{} mut d := Element{} diff --git a/vlib/crypto/ed25519/internal/edwards25519/scalar_test.v b/vlib/crypto/ed25519/internal/edwards25519/scalar_test.v index 3d1ff2619e..566ca8b6b4 100644 --- a/vlib/crypto/ed25519/internal/edwards25519/scalar_test.v +++ b/vlib/crypto/ed25519/internal/edwards25519/scalar_test.v @@ -108,7 +108,8 @@ fn test_scalar_set_canonical_bytes_on_noncanonical_value() { b[31] += 1 mut s := sc_one - out := s.set_canonical_bytes(b[..]) or { sc_error } // set_canonical_bytes shouldn't worked on a non-canonical value" + out := + s.set_canonical_bytes(b[..]) or { sc_error } // set_canonical_bytes shouldn't worked on a non-canonical value" assert out == sc_error assert s == sc_one } diff --git a/vlib/crypto/hmac/hmac.v b/vlib/crypto/hmac/hmac.v index c78797e929..f6e851dc87 100644 --- a/vlib/crypto/hmac/hmac.v +++ b/vlib/crypto/hmac/hmac.v @@ -11,7 +11,8 @@ pub fn new(key []u8, data []u8, hash_func fn ([]u8) []u8, blocksize int) []u8 { mut b_key := []u8{} if key.len <= blocksize { - b_key = key.clone() // TODO: remove .clone() once https://github.com/vlang/v/issues/6604 gets fixed + b_key = + key.clone() // TODO: remove .clone() once https://github.com/vlang/v/issues/6604 gets fixed } else { b_key = hash_func(key) } diff --git a/vlib/crypto/hmac/hmac_test.v b/vlib/crypto/hmac/hmac_test.v index 2e3d6c5823..28ca40a00c 100644 --- a/vlib/crypto/hmac/hmac_test.v +++ b/vlib/crypto/hmac/hmac_test.v @@ -377,10 +377,14 @@ fn test_hmac_sha3_224() { } fn test_hmac_equal() { - mac1_1 := '7641c48a3b4aa8f887c07b3e83f96affb89c978fed8c96fcbbf4ad596eebfe496f9f16da6cd080ba393c6f365ad72b50d15c71bfb1d6b81f66a911786c6ce932'.bytes() - mac1_2 := '7641c48a3b4aa8f887c07b3e83f96affb89c978fed8c96fcbbf4ad596eebfe496f9f16da6cd080ba393c6f365ad72b50d15c71bfb1d6b81f66a911786c6ce932'.bytes() - mac2_1 := '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737'.bytes() - mac2_2 := '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737'.bytes() + mac1_1 := + '7641c48a3b4aa8f887c07b3e83f96affb89c978fed8c96fcbbf4ad596eebfe496f9f16da6cd080ba393c6f365ad72b50d15c71bfb1d6b81f66a911786c6ce932'.bytes() + mac1_2 := + '7641c48a3b4aa8f887c07b3e83f96affb89c978fed8c96fcbbf4ad596eebfe496f9f16da6cd080ba393c6f365ad72b50d15c71bfb1d6b81f66a911786c6ce932'.bytes() + mac2_1 := + '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737'.bytes() + mac2_2 := + '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737'.bytes() assert equal(mac1_1, mac1_2) assert equal(mac2_1, mac2_2) assert !equal(mac1_1, mac2_1) diff --git a/vlib/crypto/pbkdf2/pbkdf2_test.v b/vlib/crypto/pbkdf2/pbkdf2_test.v index 6e0b51833a..62abfcaa7c 100644 --- a/vlib/crypto/pbkdf2/pbkdf2_test.v +++ b/vlib/crypto/pbkdf2/pbkdf2_test.v @@ -65,7 +65,8 @@ const cases = [ fn test_sha224() { for c in cases { expected_result := hex.decode(c.sha224)! - key := pbkdf2.key(c.password.bytes(), c.salt.bytes(), c.count, c.key_length, sha256.new224())! + key := pbkdf2.key(c.password.bytes(), c.salt.bytes(), c.count, c.key_length, + sha256.new224())! assert key == expected_result, 'failed ${c.name}' } } @@ -81,7 +82,8 @@ fn test_sha256() { fn test_sha384() { for c in cases { expected_result := hex.decode(c.sha384)! - key := pbkdf2.key(c.password.bytes(), c.salt.bytes(), c.count, c.key_length, sha512.new384())! + key := pbkdf2.key(c.password.bytes(), c.salt.bytes(), c.count, c.key_length, + sha512.new384())! assert key == expected_result, 'failed ${c.name}' } } diff --git a/vlib/crypto/pem/decode.v b/vlib/crypto/pem/decode.v index 8a2b5470e1..863684cc4a 100644 --- a/vlib/crypto/pem/decode.v +++ b/vlib/crypto/pem/decode.v @@ -33,7 +33,8 @@ fn decode_internal(data string) ?(Block, string) { // we won't get an invalid index since it would otherwise return `none` mut rest := data[data.index(pem_begin)?..] mut block := Block.new(rest[pem_begin.len..].all_before(pem_eol)) - block.headers, rest = parse_headers(rest[pem_begin.len..].all_after(pem_eol).trim_left(' \n\t\v\f\r'))? + block.headers, rest = + parse_headers(rest[pem_begin.len..].all_after(pem_eol).trim_left(' \n\t\v\f\r'))? block_end_index := rest.index(pem_end)? b64_data := rest[..block_end_index].replace_each(['\r', '', '\n', '', '\t', '', ' ', '']) diff --git a/vlib/crypto/rand/rand_linux.c.v b/vlib/crypto/rand/rand_linux.c.v index 2cf355d8dc..80dffbce97 100644 --- a/vlib/crypto/rand/rand_linux.c.v +++ b/vlib/crypto/rand/rand_linux.c.v @@ -5,6 +5,8 @@ module rand #include +pub const C.SYS_getrandom int + const read_batch_size = 256 // read returns an array of `bytes_needed` random bytes read from the OS. diff --git a/vlib/db/mssql/mssql.c.v b/vlib/db/mssql/mssql.c.v index 8d269efb81..aaf80a2ea1 100644 --- a/vlib/db/mssql/mssql.c.v +++ b/vlib/db/mssql/mssql.c.v @@ -15,18 +15,20 @@ pub fn (mut conn Connection) connect(conn_str string) !bool { // Allocate environment handle retcode = C.SQLAllocHandle(C.SQLSMALLINT(C.SQL_HANDLE_ENV), C.SQLHANDLE(C.SQL_NULL_HANDLE), unsafe { &C.SQLHANDLE(&conn.henv) }) - check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_ENV)', C.SQLHANDLE(conn.henv), C.SQLSMALLINT(C.SQL_HANDLE_ENV))! + check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_ENV)', C.SQLHANDLE(conn.henv), + C.SQLSMALLINT(C.SQL_HANDLE_ENV))! // Set the ODBC version environment attribute - retcode = C.SQLSetEnvAttr(conn.henv, C.SQLINTEGER(C.SQL_ATTR_ODBC_VERSION), &C.SQLPOINTER(C.SQL_OV_ODBC3), - C.SQLINTEGER(0)) + retcode = C.SQLSetEnvAttr(conn.henv, C.SQLINTEGER(C.SQL_ATTR_ODBC_VERSION), + &C.SQLPOINTER(C.SQL_OV_ODBC3), C.SQLINTEGER(0)) check_error(retcode, 'SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION)', C.SQLHANDLE(conn.henv), C.SQLSMALLINT(C.SQL_HANDLE_ENV))! // Allocate connection handle retcode = C.SQLAllocHandle(C.SQLSMALLINT(C.SQL_HANDLE_DBC), C.SQLHANDLE(conn.henv), unsafe { &C.SQLHANDLE(&conn.hdbc) }) - check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_DBC)', C.SQLHANDLE(conn.hdbc), C.SQLSMALLINT(C.SQL_HANDLE_DBC))! + check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_DBC)', C.SQLHANDLE(conn.hdbc), + C.SQLSMALLINT(C.SQL_HANDLE_DBC))! // Set login timeout to 5 seconds retcode = C.SQLSetConnectAttr(conn.hdbc, C.SQLINTEGER(C.SQL_LOGIN_TIMEOUT), C.SQLPOINTER(5), @@ -38,8 +40,10 @@ pub fn (mut conn Connection) connect(conn_str string) !bool { mut outstr := [1024]char{} mut outstrlen := C.SQLSMALLINT(0) retcode = C.SQLDriverConnect(conn.hdbc, C.SQLHWND(0), conn_str_c, C.SQLSMALLINT(C.SQL_NTS), - &C.SQLCHAR(&outstr[0]), C.SQLSMALLINT(sizeof(outstr)), &outstrlen, C.SQLUSMALLINT(C.SQL_DRIVER_NOPROMPT)) - check_error(retcode, 'SQLDriverConnect()', C.SQLHANDLE(conn.hdbc), C.SQLSMALLINT(C.SQL_HANDLE_DBC))! + &C.SQLCHAR(&outstr[0]), C.SQLSMALLINT(sizeof(outstr)), &outstrlen, + C.SQLUSMALLINT(C.SQL_DRIVER_NOPROMPT)) + check_error(retcode, 'SQLDriverConnect()', C.SQLHANDLE(conn.hdbc), + C.SQLSMALLINT(C.SQL_HANDLE_DBC))! conn.conn_str = conn_str return true } diff --git a/vlib/db/mssql/stmt_handle.c.v b/vlib/db/mssql/stmt_handle.c.v index 0765410e5a..5e8cf92d2e 100644 --- a/vlib/db/mssql/stmt_handle.c.v +++ b/vlib/db/mssql/stmt_handle.c.v @@ -20,8 +20,10 @@ fn new_hstmt(hdbc C.SQLHDBC) !HStmt { mut retcode := C.SQLRETURN(C.SQL_SUCCESS) mut hstmt := C.SQLHSTMT(C.SQL_NULL_HSTMT) // Allocate statement handle - retcode = C.SQLAllocHandle(C.SQLSMALLINT(C.SQL_HANDLE_STMT), C.SQLHANDLE(hdbc), unsafe { &C.SQLHANDLE(&hstmt) }) - check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_STMT)', C.SQLHANDLE(hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))! + retcode = C.SQLAllocHandle(C.SQLSMALLINT(C.SQL_HANDLE_STMT), C.SQLHANDLE(hdbc), + unsafe { &C.SQLHANDLE(&hstmt) }) + check_error(retcode, 'SQLAllocHandle(SQL_HANDLE_STMT)', C.SQLHANDLE(hstmt), + C.SQLSMALLINT(C.SQL_HANDLE_STMT))! return HStmt{ hdbc: hdbc @@ -57,7 +59,8 @@ fn (h HStmt) retrieve_column_count() !int { mut retcode := C.SQLRETURN(C.SQL_SUCCESS) col_count_buff := C.SQLSMALLINT(0) retcode = C.SQLNumResultCols(h.hstmt, &col_count_buff) - check_error(retcode, 'SQLNumResultCols()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))! + check_error(retcode, 'SQLNumResultCols()', C.SQLHANDLE(h.hstmt), + C.SQLSMALLINT(C.SQL_HANDLE_STMT))! return int(col_count_buff) } @@ -77,7 +80,8 @@ fn (mut h HStmt) prepare_read() ! { // find out buffer size needed to read data in this column retcode = C.SQLColAttribute(h.hstmt, i_col, C.SQLUSMALLINT(C.SQL_DESC_LENGTH), C.SQLPOINTER(0), C.SQLSMALLINT(0), C.SQLSMALLINT(0), &size_ret) - check_error(retcode, 'SQLColAttribute()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))! + check_error(retcode, 'SQLColAttribute()', C.SQLHANDLE(h.hstmt), + C.SQLSMALLINT(C.SQL_HANDLE_STMT))! // buffer allocation is the size + 1 to include termination char, since SQL_DESC_LENGTH does not include it. allocate_size := size_ret + C.SQLLEN(1) @@ -116,7 +120,8 @@ fn (h HStmt) read_rows() ![][]string { } } else { if retcode != C.SQLRETURN(C.SQL_NO_DATA) { - check_error(retcode, 'SQLFetch()', C.SQLHANDLE(h.hstmt), C.SQLSMALLINT(C.SQL_HANDLE_STMT))! + check_error(retcode, 'SQLFetch()', C.SQLHANDLE(h.hstmt), + C.SQLSMALLINT(C.SQL_HANDLE_STMT))! } else { break } diff --git a/vlib/db/mysql/mysql_test.v b/vlib/db/mysql/mysql_test.v index 173d8d0fd4..d64a9bffd7 100644 --- a/vlib/db/mysql/mysql_test.v +++ b/vlib/db/mysql/mysql_test.v @@ -71,8 +71,10 @@ fn test_mysql() { vals: ['1', 'jackson', ''] } - response = db.exec_param_many('select * from users where username = ? and id = ?', - ['bailey', '3'])! + response = db.exec_param_many('select * from users where username = ? and id = ?', [ + 'bailey', + '3', + ])! assert response[0] == mysql.Row{ vals: ['3', 'bailey', ''] } diff --git a/vlib/db/mysql/orm.c.v b/vlib/db/mysql/orm.c.v index 0f434b53f5..5175a85223 100644 --- a/vlib/db/mysql/orm.c.v +++ b/vlib/db/mysql/orm.c.v @@ -148,15 +148,16 @@ pub fn (db DB) insert(table orm.Table, data orm.QueryData) ! { is_and: [] } - query, converted_data := orm.orm_stmt_gen(.default, table, '`', .insert, false, '?', - 1, converted_primitive_data, orm.QueryData{}) + query, converted_data := orm.orm_stmt_gen(.default, table, '`', .insert, false, '?', 1, + converted_primitive_data, orm.QueryData{}) mysql_stmt_worker(db, query, converted_data, orm.QueryData{})! } // update is used internally by V's ORM for processing `UPDATE ` queries pub fn (db DB) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! { where_with_tenant := orm.apply_tenant_filter(table, where) - query, _ := orm.orm_stmt_gen(.default, table, '`', .update, false, '?', 1, data, where_with_tenant) + query, _ := orm.orm_stmt_gen(.default, table, '`', .update, false, '?', 1, data, + where_with_tenant) mysql_stmt_worker(db, query, data, where_with_tenant)! } @@ -178,8 +179,9 @@ pub fn (db DB) last_id() int { // create is used internally by V's ORM for processing table creation queries (DDL) pub fn (db DB) create(table orm.Table, fields []orm.TableField) ! { - query := orm.orm_table_gen(.mysql, table, '`', true, 0, fields, mysql_type_from_v, - false) or { return err } + query := orm.orm_table_gen(.mysql, table, '`', true, 0, fields, mysql_type_from_v, false) or { + return err + } mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})! } diff --git a/vlib/db/pg/orm.v b/vlib/db/pg/orm.v index 80969b4f86..d778cd70ad 100644 --- a/vlib/db/pg/orm.v +++ b/vlib/db/pg/orm.v @@ -30,15 +30,16 @@ pub fn (db DB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que // insert is used internally by V's ORM for processing `INSERT ` queries pub fn (db DB) insert(table orm.Table, data orm.QueryData) ! { - query, converted_data := orm.orm_stmt_gen(.pg, table, '"', .insert, true, '$', 1, - data, orm.QueryData{}) + query, converted_data := + orm.orm_stmt_gen(.pg, table, '"', .insert, true, '$', 1, data, orm.QueryData{}) pg_stmt_worker(db, query, converted_data, orm.QueryData{})! } // update is used internally by V's ORM for processing `UPDATE ` queries pub fn (db DB) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! { where_with_tenant := orm.apply_tenant_filter(table, where) - query, _ := orm.orm_stmt_gen(.default, table, '"', .update, true, '$', 1, data, where_with_tenant) + query, _ := orm.orm_stmt_gen(.default, table, '"', .update, true, '$', 1, data, + where_with_tenant) pg_stmt_worker(db, query, data, where_with_tenant)! } diff --git a/vlib/db/pg/pg.c.v b/vlib/db/pg/pg.c.v index 0d9d27d0da..d39b9995df 100644 --- a/vlib/db/pg/pg.c.v +++ b/vlib/db/pg/pg.c.v @@ -286,7 +286,7 @@ pub fn connect_with_conninfo(conninfo string) !DB { } } -fn res_to_rows(res voidptr) []Row { +fn res_to_rows(res voidptr) []db.pg.Row { nr_rows := C.PQntuples(res) nr_cols := C.PQnfields(res) @@ -393,12 +393,12 @@ pub fn (db &DB) q_string(query string) !string { // q_strings submit a command to the database server and // returns the resulting row set. Alias of `exec` -pub fn (db &DB) q_strings(query string) ![]Row { +pub fn (db &DB) q_strings(query string) ![]db.pg.Row { return db.exec(query) } // exec submits a command to the database server and wait for the result, returning an error on failure and a row set on success -pub fn (db &DB) exec(query string) ![]Row { +pub fn (db &DB) exec(query string) ![]db.pg.Row { res := C.PQexec(db.conn, &char(query.str)) return db.handle_error_or_rows(res, 'exec') } @@ -415,7 +415,7 @@ pub fn (db &DB) exec_result(query string) !Result { return db.handle_error_or_result(res, 'exec_result') } -fn rows_first_or_empty(rows []Row) !Row { +fn rows_first_or_empty(rows []db.pg.Row) !Row { if rows.len == 0 { return error('no row') } @@ -434,15 +434,14 @@ pub fn (db &DB) exec_one(query string) !Row { } // exec_param_many executes a query with the parameters provided as ($1), ($2), ($n) -pub fn (db &DB) exec_param_many(query string, params []string) ![]Row { +pub fn (db &DB) exec_param_many(query string, params []string) ![]db.pg.Row { unsafe { mut param_vals := []&char{len: params.len} for i in 0 .. params.len { param_vals[i] = &char(params[i].str) } - res := C.PQexecParams(db.conn, &char(query.str), params.len, 0, param_vals.data, - 0, 0, 0) + res := C.PQexecParams(db.conn, &char(query.str), params.len, 0, param_vals.data, 0, 0, 0) return db.handle_error_or_rows(res, 'exec_param_many') } } @@ -455,39 +454,38 @@ pub fn (db &DB) exec_param_many_result(query string, params []string) !Result { param_vals[i] = &char(params[i].str) } - res := C.PQexecParams(db.conn, &char(query.str), params.len, 0, param_vals.data, - 0, 0, 0) + res := C.PQexecParams(db.conn, &char(query.str), params.len, 0, param_vals.data, 0, 0, 0) return db.handle_error_or_result(res, 'exec_param_many_result') } } // exec_param executes a query with 1 parameter ($1), and returns either an error on failure, or the full result set on success -pub fn (db &DB) exec_param(query string, param string) ![]Row { +pub fn (db &DB) exec_param(query string, param string) ![]db.pg.Row { return db.exec_param_many(query, [param]) } // exec_param2 executes a query with 2 parameters ($1) and ($2), and returns either an error on failure, or the full result set on success -pub fn (db &DB) exec_param2(query string, param string, param2 string) ![]Row { +pub fn (db &DB) exec_param2(query string, param string, param2 string) ![]db.pg.Row { return db.exec_param_many(query, [param, param2]) } // prepare submits a request to create a prepared statement with the given parameters, and waits for completion. You must provide the number of parameters (`$1, $2, $3 ...`) used in the statement pub fn (db &DB) prepare(name string, query string, num_params int) ! { - res := C.PQprepare(db.conn, &char(name.str), &char(query.str), num_params, 0) // defining param types is optional + res := + C.PQprepare(db.conn, &char(name.str), &char(query.str), num_params, 0) // defining param types is optional return db.handle_error(res, 'prepare') } // exec_prepared sends a request to execute a prepared statement with given parameters, and waits for the result. The number of parameters must match with the parameters declared in the prepared statement. -pub fn (db &DB) exec_prepared(name string, params []string) ![]Row { +pub fn (db &DB) exec_prepared(name string, params []string) ![]db.pg.Row { unsafe { mut param_vals := []&char{len: params.len} for i in 0 .. params.len { param_vals[i] = &char(params[i].str) } - res := C.PQexecPrepared(db.conn, &char(name.str), params.len, param_vals.data, - 0, 0, 0) + res := C.PQexecPrepared(db.conn, &char(name.str), params.len, param_vals.data, 0, 0, 0) return db.handle_error_or_rows(res, 'exec_prepared') } } @@ -501,13 +499,12 @@ pub fn (db &DB) exec_prepared_result(name string, params []string) !Result { param_vals[i] = &char(params[i].str) } - res := C.PQexecPrepared(db.conn, &char(name.str), params.len, param_vals.data, - 0, 0, 0) + res := C.PQexecPrepared(db.conn, &char(name.str), params.len, param_vals.data, 0, 0, 0) return db.handle_error_or_result(res, 'exec_prepared_result') } } -fn (db &DB) handle_error_or_rows(res voidptr, elabel string) ![]Row { +fn (db &DB) handle_error_or_rows(res voidptr, elabel string) ![]db.pg.Row { e := unsafe { C.PQerrorMessage(db.conn).vstring() } if e != '' { C.PQclear(res) @@ -620,16 +617,14 @@ pub fn (db &DB) copy_expert(query string, mut file io.ReaderWriter) !int { return 0 } -fn pg_stmt_worker(db &DB, query string, data orm.QueryData, where orm.QueryData) ![]Row { +fn pg_stmt_worker(db &DB, query string, data orm.QueryData, where orm.QueryData) ![]db.pg.Row { mut param_types := []u32{} mut param_vals := []&char{} mut param_lens := []int{} mut param_formats := []int{} - pg_stmt_binder(mut param_types, mut param_vals, mut param_lens, mut param_formats, - data) - pg_stmt_binder(mut param_types, mut param_vals, mut param_lens, mut param_formats, - where) + pg_stmt_binder(mut param_types, mut param_vals, mut param_lens, mut param_formats, data) + pg_stmt_binder(mut param_types, mut param_vals, mut param_lens, mut param_formats, where) res := C.PQexecParams(db.conn, &char(query.str), param_vals.len, param_types.data, param_vals.data, param_lens.data, param_formats.data, 0) // here, the last 0 means require text results, 1 - binary results diff --git a/vlib/db/sqlite/orm.v b/vlib/db/sqlite/orm.v index bec79f7b67..8bd2452e77 100644 --- a/vlib/db/sqlite/orm.v +++ b/vlib/db/sqlite/orm.v @@ -47,15 +47,16 @@ pub fn (db DB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que // insert is used internally by V's ORM for processing `INSERT ` queries pub fn (db DB) insert(table orm.Table, data orm.QueryData) ! { - query, converted_data := orm.orm_stmt_gen(.sqlite, table, '`', .insert, true, '?', - 1, data, orm.QueryData{}) + query, converted_data := + orm.orm_stmt_gen(.sqlite, table, '`', .insert, true, '?', 1, data, orm.QueryData{}) sqlite_stmt_worker(db, query, converted_data, orm.QueryData{})! } // update is used internally by V's ORM for processing `UPDATE ` queries pub fn (db DB) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! { where_with_tenant := orm.apply_tenant_filter(table, where) - query, _ := orm.orm_stmt_gen(.sqlite, table, '`', .update, true, '?', 1, data, where_with_tenant) + query, _ := orm.orm_stmt_gen(.sqlite, table, '`', .update, true, '?', 1, data, + where_with_tenant) sqlite_stmt_worker(db, query, data, where_with_tenant)! } @@ -78,8 +79,9 @@ pub fn (db DB) last_id() int { // create is used internally by V's ORM for processing table creation queries (DDL) pub fn (db DB) create(table orm.Table, fields []orm.TableField) ! { - query := orm.orm_table_gen(.sqlite, table, '`', true, 0, fields, sqlite_type_from_v, - false) or { return err } + query := orm.orm_table_gen(.sqlite, table, '`', true, 0, fields, sqlite_type_from_v, false) or { + return err + } sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})! } diff --git a/vlib/db/sqlite/sqlite.c.v b/vlib/db/sqlite/sqlite.c.v index 29d57fef3c..9de08a4984 100644 --- a/vlib/db/sqlite/sqlite.c.v +++ b/vlib/db/sqlite/sqlite.c.v @@ -444,8 +444,7 @@ pub fn (db &DB) exec_param_many(query string, params Params) ![]Row { } // Param values to bind for i, param in params_row { - code = C.sqlite3_bind_text(stmt, i + 1, voidptr(param.str), param.len, - 0) + code = C.sqlite3_bind_text(stmt, i + 1, voidptr(param.str), param.len, 0) if code != sqlite_ok { return db.error_message(code, query) } @@ -587,7 +586,8 @@ pub fn (mut db DB) release_savepoint(savepoint string) ! { // tables returns the names of all user tables in the database. pub fn (db &DB) tables() ![]string { - rows := db.exec("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name")! + rows := + db.exec("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name")! return rows.map(it.vals[0]) } @@ -607,7 +607,8 @@ pub fn (db &DB) schema(table string) !string { } else { '' } - rows := db.exec("SELECT sql FROM sqlite_master WHERE type IN ('table','index','view','trigger') ${filter} AND sql IS NOT NULL ORDER BY type, name")! + rows := + db.exec("SELECT sql FROM sqlite_master WHERE type IN ('table','index','view','trigger') ${filter} AND sql IS NOT NULL ORDER BY type, name")! return rows.map(it.vals[0]).join('\n\n') } diff --git a/vlib/db/sqlite/vfs_lowlevel.c.v b/vlib/db/sqlite/vfs_lowlevel.c.v index 4ffdec8b10..de8b15c199 100644 --- a/vlib/db/sqlite/vfs_lowlevel.c.v +++ b/vlib/db/sqlite/vfs_lowlevel.c.v @@ -19,26 +19,26 @@ mut: // version 1 and later fields iVersion int - xClose fn (&Sqlite3_file) int - xRead fn (&Sqlite3_file, voidptr, int, i64) int - xWrite fn (&Sqlite3_file, voidptr, int, i64) int - xTruncate fn (&Sqlite3_file, i64) int - xSync fn (&Sqlite3_file, int) int + xClose fn (&db.sqlite.Sqlite3_file) int + xRead fn (&db.sqlite.Sqlite3_file, voidptr, int, i64) int + xWrite fn (&db.sqlite.Sqlite3_file, voidptr, int, i64) int + xTruncate fn (&db.sqlite.Sqlite3_file, i64) int + xSync fn (&db.sqlite.Sqlite3_file, int) int xFileSize Sig1 - xLock fn (&Sqlite3_file, int) int - xUnlock fn (&Sqlite3_file, int) int + xLock fn (&db.sqlite.Sqlite3_file, int) int + xUnlock fn (&db.sqlite.Sqlite3_file, int) int xCheckReservedLock Sig2 - xFileControl fn (&Sqlite3_file, int, voidptr) int - xSectorSize fn (&Sqlite3_file) int - xDeviceCharacteristics fn (&Sqlite3_file) int + xFileControl fn (&db.sqlite.Sqlite3_file, int, voidptr) int + xSectorSize fn (&db.sqlite.Sqlite3_file) int + xDeviceCharacteristics fn (&db.sqlite.Sqlite3_file) int // version 2 and later fields - xShmMap fn (&Sqlite3_file, int, int, int, &voidptr) int - xShmLock fn (&Sqlite3_file, int, int, int) int - xShmBarrier fn (&Sqlite3_file) - xShmUnmap fn (&Sqlite3_file, int) int + xShmMap fn (&db.sqlite.Sqlite3_file, int, int, int, &voidptr) int + xShmLock fn (&db.sqlite.Sqlite3_file, int, int, int) int + xShmBarrier fn (&db.sqlite.Sqlite3_file) + xShmUnmap fn (&db.sqlite.Sqlite3_file, int) int // version 3 and later fields - xFetch fn (&Sqlite3_file, i64, int, &voidptr) int - xUnfetch fn (&Sqlite3_file, i64, voidptr) int + xFetch fn (&db.sqlite.Sqlite3_file, i64, int, &voidptr) int + xUnfetch fn (&db.sqlite.Sqlite3_file, i64, voidptr) int } pub type Sqlite3_io_methods = C.sqlite3_io_methods @@ -59,25 +59,25 @@ pub mut: zName &char // Name of this virtual file system pAppData voidptr // Pointer to application-specific data - xOpen fn (&Sqlite3_vfs, &char, &Sqlite3_file, int, &int) int - xDelete fn (&Sqlite3_vfs, &char, int) int + xOpen fn (&db.sqlite.Sqlite3_vfs, &char, &db.sqlite.Sqlite3_file, int, &int) int + xDelete fn (&db.sqlite.Sqlite3_vfs, &char, int) int - xAccess fn (&Sqlite3_vfs, &char, int, &int) int - xFullPathname fn (&Sqlite3_vfs, &char, int, &char) int - xDlOpen fn (&Sqlite3_vfs, &char) voidptr - xDlError fn (&Sqlite3_vfs, int, &char) - xDlSym fn (&Sqlite3_vfs, voidptr, &char) voidptr // to fn accepting void and returning - xDlClose fn (&Sqlite3_vfs, voidptr) - xRandomness fn (&Sqlite3_vfs, int, &char) int - xSleep fn (&Sqlite3_vfs, int) int - xCurrentTime fn (&Sqlite3_vfs, &f64) int - xGetLastError fn (&Sqlite3_vfs, int, &char) int + xAccess fn (&db.sqlite.Sqlite3_vfs, &char, int, &int) int + xFullPathname fn (&db.sqlite.Sqlite3_vfs, &char, int, &char) int + xDlOpen fn (&db.sqlite.Sqlite3_vfs, &char) voidptr + xDlError fn (&db.sqlite.Sqlite3_vfs, int, &char) + xDlSym fn (&db.sqlite.Sqlite3_vfs, voidptr, &char) voidptr // to fn accepting void and returning + xDlClose fn (&db.sqlite.Sqlite3_vfs, voidptr) + xRandomness fn (&db.sqlite.Sqlite3_vfs, int, &char) int + xSleep fn (&db.sqlite.Sqlite3_vfs, int) int + xCurrentTime fn (&db.sqlite.Sqlite3_vfs, &f64) int + xGetLastError fn (&db.sqlite.Sqlite3_vfs, int, &char) int // version two and later only fields - xCurrentTimeInt64 fn (&Sqlite3_vfs, &i64) int + xCurrentTimeInt64 fn (&db.sqlite.Sqlite3_vfs, &i64) int // version three and later only fields - xSetSystemCall fn (&Sqlite3_vfs, &char, Fn_sqlite3_syscall_ptr) int - xGetSystemCall fn (&Sqlite3_vfs, &char) Fn_sqlite3_syscall_ptr - xNextSystemCall fn (&Sqlite3_vfs, &char) &char + xSetSystemCall fn (&db.sqlite.Sqlite3_vfs, &char, db.sqlite.Fn_sqlite3_syscall_ptr) int + xGetSystemCall fn (&db.sqlite.Sqlite3_vfs, &char) db.sqlite.Fn_sqlite3_syscall_ptr + xNextSystemCall fn (&db.sqlite.Sqlite3_vfs, &char) &char } // https://www.sqlite.org/c3ref/vfs_find.html diff --git a/vlib/dlmalloc/dlmalloc.v b/vlib/dlmalloc/dlmalloc.v index 7a4b69c0a1..833950095e 100644 --- a/vlib/dlmalloc/dlmalloc.v +++ b/vlib/dlmalloc/dlmalloc.v @@ -602,8 +602,8 @@ pub fn (mut dl Dlmalloc) free_(mem voidptr) { if p.mmapped() { psize += prevsize + mmap_foot_pad() - if dl.system_allocator.free_(dl.system_allocator.data, voidptr(usize(p) - prevsize), - psize) + if dl.system_allocator.free_(dl.system_allocator.data, + voidptr(usize(p) - prevsize), psize) { dl.footprint -= psize } @@ -696,8 +696,8 @@ fn (mut dl Dlmalloc) sys_trim(pad_ usize) bool { if sp.can_release_part(&dl.system_allocator) { if sp.size >= extra && !dl.has_segment_link(sp) { newsize := sp.size - extra - if dl.system_allocator.free_part(dl.system_allocator.data, - sp.base, sp.size, newsize) + if dl.system_allocator.free_part(dl.system_allocator.data, sp.base, + sp.size, newsize) { released = extra } @@ -1578,8 +1578,8 @@ fn (mut dl Dlmalloc) dispose_chunk(p_ &Chunk, psize_ usize) { if p.mmapped() { psize += prevsize + mmap_foot_pad() - if dl.system_allocator.free_(dl.system_allocator.data, voidptr(usize(p) - prevsize), - psize) + if dl.system_allocator.free_(dl.system_allocator.data, + voidptr(usize(p) - prevsize), psize) { dl.footprint -= psize } diff --git a/vlib/encoding/base64/base64.c.v b/vlib/encoding/base64/base64.c.v index 88bce057cb..c95c33fa51 100644 --- a/vlib/encoding/base64/base64.c.v +++ b/vlib/encoding/base64/base64.c.v @@ -125,9 +125,9 @@ fn decode_from_buffer(dest &u8, src &u8, src_len int) int { for src_len - si >= 8 { // Converting 8 bytes of input into 6 bytes of output. Storing these in the upper bytes of an u64. - datablock_64.data = assemble64(u8(index[d[si + 0]]), u8(index[d[si + 1]]), - u8(index[d[si + 2]]), u8(index[d[si + 3]]), u8(index[d[si + 4]]), u8(index[d[si + 5]]), - u8(index[d[si + 6]]), u8(index[d[si + 7]])) + datablock_64.data = assemble64(u8(index[d[si + 0]]), u8(index[d[si + 1]]), u8(index[d[ + si + 2]]), u8(index[d[si + 3]]), u8(index[d[si + 4]]), u8(index[d[si + 5]]), u8(index[d[ + si + 6]]), u8(index[d[si + 7]])) // Reading out the individual bytes from the u64. Watch out with endianness. $if little_endian { @@ -151,8 +151,8 @@ fn decode_from_buffer(dest &u8, src &u8, src_len int) int { } for src_len - si >= 4 { - datablock_32.data = assemble32(u8(index[d[si + 0]]), u8(index[d[si + 1]]), - u8(index[d[si + 2]]), u8(index[d[si + 3]])) + datablock_32.data = assemble32(u8(index[d[si + 0]]), u8(index[d[si + 1]]), u8(index[d[ + si + 2]]), u8(index[d[si + 3]])) $if little_endian { b[n_decoded_bytes + 0] = datablock_32.data_byte[3] b[n_decoded_bytes + 1] = datablock_32.data_byte[2] diff --git a/vlib/encoding/binary/little_endian_test.v b/vlib/encoding/binary/little_endian_test.v index 9372f0c12b..15fdd0b299 100644 --- a/vlib/encoding/binary/little_endian_test.v +++ b/vlib/encoding/binary/little_endian_test.v @@ -78,10 +78,8 @@ fn test_little_endian_u32() { fn test_little_endian_u32_at() { assert little_endian_u32_at([u8(1), 0, 0, 0, 0, 0, 0, 0], 1) == u32(0) assert little_endian_u32_at([u8(5), 4, 9, 1, 7, 3, 6, 8], 1) == u32(0x07010904) - assert little_endian_u32_at([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f], - 1) == u32(0x7f219ea2) - assert little_endian_u32_at([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f], - 1) != u32(0xa29e217f) + assert little_endian_u32_at([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f], 1) == u32(0x7f219ea2) + assert little_endian_u32_at([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f], 1) != u32(0xa29e217f) } fn test_little_endian_u32_end() { @@ -144,10 +142,8 @@ fn test_little_endian_u64() { } fn test_little_endian_u64_at() { - assert little_endian_u64_at([u8(1), 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], - 1) == u64(0) - assert little_endian_u64_at([u8(0), 5, 4, 9, 1, 7, 3, 6, 8, 0, 0, 0, 0, 0, 0, 0], - 1) == u64(0x0806030701090405) + assert little_endian_u64_at([u8(1), 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], 1) == u64(0) + assert little_endian_u64_at([u8(0), 5, 4, 9, 1, 7, 3, 6, 8, 0, 0, 0, 0, 0, 0, 0], 1) == u64(0x0806030701090405) assert little_endian_u64_at([u8(0), 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f, 0, 0, 0, 0, 0, 0, 0], 1) == u64(0x8f8e9f7f219ea2f8) assert little_endian_u64_at([u8(0), 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f, 0, 0, 0, @@ -155,8 +151,7 @@ fn test_little_endian_u64_at() { } fn test_little_endian_f32_at() { - assert little_endian_f32_at([u8(1), 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], - 1) == f32(0) + assert little_endian_f32_at([u8(1), 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], 1) == f32(0) /* assert little_endian_f32_at([u8(0), 5, 4, 9, 1, 7, 3, 6, 8, 0, 0, 0, 0, 0, 0, 0], 1).eq_epsilon(0.00000000000000000000000000000000002516) diff --git a/vlib/encoding/binary/stream.v b/vlib/encoding/binary/stream.v index a7198d12c8..a9d7a05991 100644 --- a/vlib/encoding/binary/stream.v +++ b/vlib/encoding/binary/stream.v @@ -105,6 +105,16 @@ fn size_value[T](data T) int { return 4 } $else $if T is u64 || T is i64 || T is f64 { return 8 + } $else $if T is $array_fixed { + mut total := 0 + for i in 0 .. data.len { + value_size := size_value(data[i]) + if value_size < 0 { + return -1 + } + total += value_size + } + return total } $else $if T is $array { mut total := 0 for value in data { @@ -186,6 +196,10 @@ fn read_value[T](mut reader io.Reader, order ByteOrder, mut data T) ! { u: order.u64(buf) }.f } + } $else $if T is $array_fixed { + for i in 0 .. data.len { + read_value(mut reader, order, mut data[i])! + } } $else $if T is $array { $if T is []u8 { read_full(mut reader, mut data)! @@ -255,6 +269,10 @@ fn write_value[T](mut writer io.Writer, order ByteOrder, data T) ! { } order.put_u64(mut buf, bits) write_full(mut writer, buf)! + } $else $if T is $array_fixed { + for i in 0 .. data.len { + write_value(mut writer, order, data[i])! + } } $else $if T is $array { $if T is []u8 { write_full(mut writer, data)! diff --git a/vlib/encoding/csv/README_csv_reader.md b/vlib/encoding/csv/README_csv_reader.md index 16de7b3164..7c16294026 100644 --- a/vlib/encoding/csv/README_csv_reader.md +++ b/vlib/encoding/csv/README_csv_reader.md @@ -12,7 +12,8 @@ Here is a very simple example of usage: import encoding.csv fn main() { - mut csvr := csv.csv_sequential_reader(file_path: 'big2.csv', end_line_len: csv.endline_crlf_len)! + mut csvr := + csv.csv_sequential_reader(file_path: 'big2.csv', end_line_len: csv.endline_crlf_len)! for csvr.has_data() > 1 { println(csvr.get_next_row()!) } diff --git a/vlib/encoding/csv/csv_reader_test.v b/vlib/encoding/csv/csv_reader_test.v index 27f129ce98..ff6f89f68f 100644 --- a/vlib/encoding/csv/csv_reader_test.v +++ b/vlib/encoding/csv/csv_reader_test.v @@ -292,7 +292,8 @@ fn test_csv_string() { csvr.dispose_csv_reader() // test cr endline - csvr = csv.csv_reader(scr_buf: txt4.str, scr_buf_len: txt4.len, end_line_len: csv.endline_cr_len)! + csvr = + csv.csv_reader(scr_buf: txt4.str, scr_buf_len: txt4.len, end_line_len: csv.endline_cr_len)! perform_test3(mut csvr)! csvr.dispose_csv_reader() } diff --git a/vlib/encoding/iconv/iconv_windows.c.v b/vlib/encoding/iconv/iconv_windows.c.v index 183cc5e19e..cc53cb737a 100644 --- a/vlib/encoding/iconv/iconv_windows.c.v +++ b/vlib/encoding/iconv/iconv_windows.c.v @@ -719,14 +719,14 @@ fn conv(tocode string, fromcode string, src &u8, src_len int) ![]u8 { dst = utf16_to_utf32(unicode.data, unicode.len, true, false)! } else { - dst_len := C.WideCharToMultiByte(dst_codepage, 0, unicode.data, unicode.len / 2, - 0, 0, 0, 0) + dst_len := C.WideCharToMultiByte(dst_codepage, 0, unicode.data, unicode.len / 2, 0, 0, + 0, 0) if dst_len == 0 { return error('WideCharToMultiByte fail: src contain zero unicode character') } unsafe { dst.grow_len(dst_len) } - C.WideCharToMultiByte(dst_codepage, 0, unicode.data, unicode.len, dst.data, - dst.len, 0, 0) + C.WideCharToMultiByte(dst_codepage, 0, unicode.data, unicode.len, dst.data, dst.len, 0, + 0) } } return dst diff --git a/vlib/encoding/utf8/utf8_util.v b/vlib/encoding/utf8/utf8_util.v index 0970fbf811..995ff41770 100644 --- a/vlib/encoding/utf8/utf8_util.v +++ b/vlib/encoding/utf8/utf8_util.v @@ -77,7 +77,7 @@ pub fn raw_index(s string, index int) string { } b := s[i] - ch_len := ((0xe5000000 >> ((b >> 3) & 0x1e)) & 3) + ch_len := int((u32(0xe5000000) >> ((b >> 3) & 0x1e)) & 3) r << if ch_len > 0 { i += ch_len diff --git a/vlib/encoding/vorbis/vorbis.v b/vlib/encoding/vorbis/vorbis.v index 8e4221a247..16c3695397 100644 --- a/vlib/encoding/vorbis/vorbis.v +++ b/vlib/encoding/vorbis/vorbis.v @@ -48,8 +48,7 @@ pub fn decode_memory(ptr &u8, len i32) !DecodedSong { path: ':memory:' } unsafe { - size := C.stb_vorbis_decode_memory(ptr, len, &res.channels, &res.sample_rate, - &res.data) + size := C.stb_vorbis_decode_memory(ptr, len, &res.channels, &res.sample_rate, &res.data) if size == -1 { return error('could not decode ogg/vorbis memory block') } diff --git a/vlib/encoding/xml/test/local/12_doctype_entity/spec_entity_test.v b/vlib/encoding/xml/test/local/12_doctype_entity/spec_entity_test.v index 9c0fe0c141..75dce9a09a 100644 --- a/vlib/encoding/xml/test/local/12_doctype_entity/spec_entity_test.v +++ b/vlib/encoding/xml/test/local/12_doctype_entity/spec_entity_test.v @@ -5,6 +5,7 @@ import encoding.xml fn test_valid_parsing() { expected := xml.XMLDocument.from_file(os.join_path(os.dir(@FILE), 'entity.xml'))!.validate()! - actual := xml.XMLDocument.from_file(os.join_path(os.dir(@FILE), 'entity_expected.xml'))!.validate()! + actual := + xml.XMLDocument.from_file(os.join_path(os.dir(@FILE), 'entity_expected.xml'))!.validate()! assert expected == actual, 'Parsed XML document should be equal to expected XML document' } diff --git a/vlib/fasthttp/fasthttp_darwin.v b/vlib/fasthttp/fasthttp_darwin.v index b9a1f8437f..d8a351d954 100644 --- a/vlib/fasthttp/fasthttp_darwin.v +++ b/vlib/fasthttp/fasthttp_darwin.v @@ -250,8 +250,7 @@ fn handle_read(server Server, kq int, c_ptr voidptr, mut clients map[int]voidptr c.read_len = 0 if send_pending(c_ptr) { - add_event(kq, u64(c.fd), i16(C.EVFILT_WRITE), u16(C.EV_ADD | C.EV_ENABLE | C.EV_CLEAR), - c) + add_event(kq, u64(c.fd), i16(C.EVFILT_WRITE), u16(C.EV_ADD | C.EV_ENABLE | C.EV_CLEAR), c) return } @@ -332,8 +331,8 @@ pub fn (mut s Server) run() ! { return error('kqueue creation failed') } - add_event(s.poll_fd, u64(s.socket_fd), i16(C.EVFILT_READ), u16(C.EV_ADD | C.EV_ENABLE | C.EV_CLEAR), - unsafe { nil }) + add_event(s.poll_fd, u64(s.socket_fd), i16(C.EVFILT_READ), + u16(C.EV_ADD | C.EV_ENABLE | C.EV_CLEAR), unsafe { nil }) listen_fd := s.socket_fd s.mark_running() diff --git a/vlib/fasthttp/fasthttp_linux.v b/vlib/fasthttp/fasthttp_linux.v index 4c1c075e5c..4cb7f4c3ea 100644 --- a/vlib/fasthttp/fasthttp_linux.v +++ b/vlib/fasthttp/fasthttp_linux.v @@ -245,8 +245,8 @@ fn process_request(server &Server, epoll_fd int, client_fd int, request_buffer [ mut send_error := false mut pos := 0 for pos < response.content.len { - sent := C.send(client_fd, unsafe { &response.content[pos] }, response.content.len - pos, - C.MSG_NOSIGNAL) + sent := C.send(client_fd, unsafe { &response.content[pos] }, + response.content.len - pos, C.MSG_NOSIGNAL) if sent <= 0 { eprintln('ERROR: send() failed with errno=${C.errno}') send_error = true @@ -391,8 +391,8 @@ fn process_events(server &Server, epoll_fd int, listen_fd int) { mut readed_request_buffer := []u8{cap: server.max_request_buffer_size} for { - bytes_read := C.recv(client_fd, unsafe { &request_buffer[0] }, server.max_request_buffer_size - 1, - 0) + bytes_read := C.recv(client_fd, unsafe { &request_buffer[0] }, + server.max_request_buffer_size - 1, 0) if bytes_read < 0 { if C.errno == C.EAGAIN || C.errno == C.EWOULDBLOCK { // No more data available right now diff --git a/vlib/fasthttp/fasthttp_windows.v b/vlib/fasthttp/fasthttp_windows.v index caab2e92fa..22cbf15e42 100644 --- a/vlib/fasthttp/fasthttp_windows.v +++ b/vlib/fasthttp/fasthttp_windows.v @@ -5,7 +5,7 @@ pub: port int = 3000 max_request_buffer_size int = 8192 mut: - request_handler fn (HttpRequest) !HttpResponse @[required] + request_handler fn (fasthttp.HttpRequest) !fasthttp.HttpResponse @[required] } // new_server creates and initializes a new Server instance. diff --git a/vlib/flag/default_flag_options_test.v b/vlib/flag/default_flag_options_test.v index d6c953528e..855fe0968b 100644 --- a/vlib/flag/default_flag_options_test.v +++ b/vlib/flag/default_flag_options_test.v @@ -7,7 +7,8 @@ const simple_flag_app_executable = os.real_path(os.join_path(os.cache_dir(), 'si fn testsuite_begin() { os.chdir(@VMODROOT) or {} os.rm(simple_flag_app_executable) or {} - res := os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(simple_flag_app_executable)} ${os.quoted_path(source)}') + res := + os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(simple_flag_app_executable)} ${os.quoted_path(source)}') assert res.exit_code == 0 assert os.execute(simple_flag_app_executable).exit_code == 0 } diff --git a/vlib/flag/flag.v b/vlib/flag/flag.v index f1c2ab0658..429db2be9f 100644 --- a/vlib/flag/flag.v +++ b/vlib/flag/flag.v @@ -552,9 +552,7 @@ pub fn (fs &FlagParser) usage() string { adesc = '' } mut use := []string{} - if doc_add_name_and_version(fs.application_name, fs.application_version, fs.options, mut - use) - { + if doc_add_name_and_version(fs.application_name, fs.application_version, fs.options, mut use) { use << '${underline}' } if fs.usage_examples.len == 0 { diff --git a/vlib/flag/flag_parse_test.v b/vlib/flag/flag_parse_test.v index a7761efba8..b80723239c 100644 --- a/vlib/flag/flag_parse_test.v +++ b/vlib/flag/flag_parse_test.v @@ -25,7 +25,8 @@ fn test_flag_parse() { mut opt := Options{ v_flags: fp.string_multi('flag', `f`, 'Additional flags for the V compiler') - archs: fp.string('archs', 0, 'arm64-v8a,armeabi-v7a,x86,x86_64', 'Comma separated string with any of archs').split(',') + archs: fp.string('archs', 0, 'arm64-v8a,armeabi-v7a,x86,x86_64', + 'Comma separated string with any of archs').split(',') dump_usage: fp.bool('help', `h`, false, 'Show this help message and exit') verbosity: fp.int_opt('verbosity', `v`, 'Verbosity level 1-3') or { 0 } api_level: fp.string('api', 0, '21', 'Android API level to use (--list-apis)') diff --git a/vlib/flag/flag_test.v b/vlib/flag/flag_test.v index 5c542623d5..b351421320 100644 --- a/vlib/flag/flag_test.v +++ b/vlib/flag/flag_test.v @@ -395,7 +395,8 @@ fn test_allow_abbreviations() { fn test_allow_kebab_options() { default_value := 'this_is_the_default_value_of_long_option' long_option_value := 'this_is_a_long_option_value_as_argument' - mut fp := flag.new_flag_parser(['--my-long-flag', 'true', '--my-long-option', long_option_value]) + mut fp := + flag.new_flag_parser(['--my-long-flag', 'true', '--my-long-option', long_option_value]) my_flag := fp.bool('my-long-flag', 0, false, 'flag with long-kebab-name') my_option := fp.string('my-long-option', 0, default_value, 'string with long-kebab-name') assert my_flag == true @@ -484,7 +485,8 @@ fn test_long_options_that_start_with_the_same_letter_as_another_short_option() { '/abc', ]) verbose := fp.bool('verbose', `v`, false, 'Be more verbose.') - vabc := fp.string('vabc', `x`, 'default', 'Another option that *may* conflict with v, but *should not*') + vabc := fp.string('vabc', `x`, 'default', + 'Another option that *may* conflict with v, but *should not*') assert verbose == false assert vabc == '/abc' } @@ -496,7 +498,8 @@ fn test_long_options_that_start_with_the_same_letter_as_another_short_option_bot '/abc', ]) verbose := fp.bool('verbose', `v`, false, 'Be more verbose.') - vabc := fp.string('vabc', `x`, 'default', 'Another option that *may* conflict with v, but *should not*') + vabc := fp.string('vabc', `x`, 'default', + 'Another option that *may* conflict with v, but *should not*') assert verbose == true assert vabc == '/abc' } diff --git a/vlib/flag/flag_to.v b/vlib/flag/flag_to.v index b84fdf793f..7821eca0d0 100644 --- a/vlib/flag/flag_to.v +++ b/vlib/flag/flag_to.v @@ -690,8 +690,7 @@ pub fn (fm FlagMapper) to_doc(dc DocConfig) !string { } } - name_and_version := doc_add_name_and_version(app_name, app_version, dc.options, mut - docs) + name_and_version := doc_add_name_and_version(app_name, app_version, dc.options, mut docs) // Resolve the description if visible if dc.options.show.has(.description) { @@ -875,8 +874,8 @@ fn keep_at_max(str string, max int) string { // At this point we are refitting the doc string so user provided newlines can not be kept // ... at least not without a tremendous increase in code complexity, that highly likely // will not suit all use-cases anyway. - fitted += keep_at_max(s[last_possible_break..].replace('\n', ' ').trim(' '), - safe_max).trim(' ') + fitted += + keep_at_max(s[last_possible_break..].replace('\n', ' ').trim(' '), safe_max).trim(' ') } else if width > safe_max { break } @@ -1071,8 +1070,8 @@ fn (mut fm FlagMapper) map_v(flag_ctx FlagContext, field StructField) !bool { if arg != '' { return error('flag `${flag_raw}` can not be assigned to bool field "${field.name}"') } - trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, - 'true', '')}') + trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, 'true', + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1098,8 +1097,8 @@ fn (mut fm FlagMapper) map_v(flag_ctx FlagContext, field StructField) !bool { pos: pos }) } else { - trace_println('${@FN}: found match for (V style) ${fm.dbg_match(flag_ctx, - field, next, '')}') + trace_println('${@FN}: found match for (V style) ${fm.dbg_match(flag_ctx, field, next, + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1135,8 +1134,8 @@ fn (mut fm FlagMapper) map_v_flag_parser_short(flag_ctx FlagContext, field Struc if field.hints.has(.is_bool) { if flag_name == field.match_name || flag_name == field.short { - trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, - 'true', '')}') + trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, 'true', + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1195,8 +1194,8 @@ fn (mut fm FlagMapper) map_v_flag_parser_long(flag_ctx FlagContext, field Struct if field.hints.has(.is_bool) { if flag_name == field.match_name { - trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, - 'true', '')}') + trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, 'true', + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1255,8 +1254,8 @@ fn (mut fm FlagMapper) map_go_flag_short(flag_ctx FlagContext, field StructField if arg != '' { return error('flag `${flag_raw}` can not be assigned to bool field "${field.name}"') } - trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, - 'true', '')}') + trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, 'true', + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1282,8 +1281,8 @@ fn (mut fm FlagMapper) map_go_flag_short(flag_ctx FlagContext, field StructField pos: pos }) } else { - trace_println('${@FN}: found match for (GO short style) ${fm.dbg_match(flag_ctx, - field, next, '')}') + trace_println('${@FN}: found match for (GO short style) ${fm.dbg_match(flag_ctx, field, + next, '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1378,8 +1377,8 @@ fn (mut fm FlagMapper) map_gnu_long(flag_ctx FlagContext, field StructField) !bo if arg != '' { return error('flag `${flag_raw}` can not be assigned to bool field "${field.name}"') } - trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, - 'true', '')}') + trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, 'true', + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1409,8 +1408,8 @@ fn (mut fm FlagMapper) map_gnu_long(flag_ctx FlagContext, field StructField) !bo pos: pos }) } else { - trace_println('${@FN}: found match for (GNU style) ${fm.dbg_match(flag_ctx, - field, arg, '')}') + trace_println('${@FN}: found match for (GNU style) ${fm.dbg_match(flag_ctx, field, arg, + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1475,8 +1474,8 @@ fn (mut fm FlagMapper) map_posix_short_cluster(flag_ctx FlagContext) ! { pos: flag_ctx.pos } if field.hints.has(.is_bool) { - trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, - field, 'true', '')}') + trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, + 'true', '')}') fm.field_map_flag[mf.field_name] = mf fm.handled_pos << flag_ctx.pos } else { @@ -1536,8 +1535,8 @@ fn (mut fm FlagMapper) map_posix_short(flag_ctx FlagContext, field StructField) if arg != '' { return error('flag `${flag_raw}` can not be assigned to bool field "${field.name}"') } - trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, - 'true', '')}') + trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, 'true', + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1550,8 +1549,8 @@ fn (mut fm FlagMapper) map_posix_short(flag_ctx FlagContext, field StructField) } if field.short == flag_name { - trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, - 'true', '')}') + trace_println('${@FN}: found match for (bool) ${fm.dbg_match(flag_ctx, field, 'true', + '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1569,8 +1568,8 @@ fn (mut fm FlagMapper) map_posix_short(flag_ctx FlagContext, field StructField) if field.hints.has(.can_repeat) { mut do_continue := false if count_of_first_letter_repeats == flag_name.len { - trace_println('${@FN}: found match for (repeatable) ${fm.dbg_match(flag_ctx, - field, 'true', '')}') + trace_println('${@FN}: found match for (repeatable) ${fm.dbg_match(flag_ctx, field, + 'true', '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name @@ -1681,8 +1680,7 @@ fn (mut fm FlagMapper) map_posix_short(flag_ctx FlagContext, field StructField) return true } else if flag_name == field.match_name && !(field.hints.has(.short_only) && flag_name == field.short) { - trace_println('${@FN}: found match for (repeats) ${fm.dbg_match(flag_ctx, field, - next, '')}') + trace_println('${@FN}: found match for (repeats) ${fm.dbg_match(flag_ctx, field, next, '')}') if next == '' { return error('flag "${flag_raw}" expects an argument') } @@ -1738,8 +1736,8 @@ fn (mut fm FlagMapper) map_cmd_exe(flag_ctx FlagContext, field StructField) !boo pos: pos }) } else { - trace_println('${@FN}: found match for (CMD.EXE style) ${fm.dbg_match(flag_ctx, - field, next, '')}') + trace_println('${@FN}: found match for (CMD.EXE style) ${fm.dbg_match(flag_ctx, field, + next, '')}') fm.field_map_flag[field.name] = FlagData{ raw: flag_raw field_name: field.name diff --git a/vlib/flag/usage_example_test.v b/vlib/flag/usage_example_test.v index a28890db4a..d81df16681 100644 --- a/vlib/flag/usage_example_test.v +++ b/vlib/flag/usage_example_test.v @@ -7,7 +7,8 @@ const the_executable = os.real_path(os.join_path(os.cache_dir(), 'flag_usage_exa fn testsuite_begin() { os.chdir(@VMODROOT) or {} os.rm(the_executable) or {} - res := os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(the_executable)} ${os.quoted_path(the_source)}') + res := + os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(the_executable)} ${os.quoted_path(the_source)}') assert res.exit_code == 0 assert os.execute(os.quoted_path(the_executable)).exit_code == 0 } diff --git a/vlib/gg/bezier.c.v b/vlib/gg/bezier.c.v index ccc4893add..7d827e2e5b 100644 --- a/vlib/gg/bezier.c.v +++ b/vlib/gg/bezier.c.v @@ -12,8 +12,8 @@ pub fn (ctx &Context) draw_cubic_bezier_recursive(points []f32, c Color) { if points.len < 8 { return } - ctx.draw_cubic_bezier_recursive_scalar(points[0], points[1], points[2], points[3], - points[4], points[5], points[6], points[7], c) + ctx.draw_cubic_bezier_recursive_scalar(points[0], points[1], points[2], points[3], points[4], + points[5], points[6], points[7], c) } // draw_cubic_bezier_recursive_scalar is the same as `draw_cubic_bezier_recursive`, except that the `points` are given diff --git a/vlib/gg/draw.c.v b/vlib/gg/draw.c.v index 2ab773d72a..ef064a9adc 100644 --- a/vlib/gg/draw.c.v +++ b/vlib/gg/draw.c.v @@ -187,8 +187,8 @@ fn rect_empty_screen_bounds(scale f32, x f32, y f32, w f32, h f32) (f32, f32, f3 // border renders consistently across different OpenGL implementations. toffset := f32(0.1) boffset := f32(-0.1) - return toffset + x * scale, toffset + y * scale, boffset + (x + w) * scale, boffset + (y + - h) * scale + return toffset + x * scale, toffset + y * scale, boffset + (x + w) * scale, boffset + + (y + h) * scale } // draw_rect_empty draws the outline of a rectangle. @@ -201,8 +201,7 @@ pub fn (ctx &Context) draw_rect_empty(x f32, y f32, w f32, h f32, c Color) { sgl.load_pipeline(ctx.pipeline.alpha) } sgl.c4b(c.r, c.g, c.b, c.a) - tleft_x, tleft_y, bright_x, bright_y := rect_empty_screen_bounds(ctx.scale, x, y, - w, h) + tleft_x, tleft_y, bright_x, bright_y := rect_empty_screen_bounds(ctx.scale, x, y, w, h) sgl.begin_lines() // more predictable, compared to sgl.begin_line_strip, at the price of more vertexes send // top: sgl.v2f(tleft_x, tleft_y) @@ -227,8 +226,7 @@ pub fn (ctx &Context) draw_rect_empty(x f32, y f32, w f32, h f32, c Color) { // Note: it is much more efficient to draw lots of empty rectangles one after the other, // without filled rectangles between them, than to draw a mix. pub fn (ctx &Context) draw_rect_empty_no_context(x f32, y f32, w f32, h f32, c Color) { - tleft_x, tleft_y, bright_x, bright_y := rect_empty_screen_bounds(ctx.scale, x, y, - w, h) + tleft_x, tleft_y, bright_x, bright_y := rect_empty_screen_bounds(ctx.scale, x, y, w, h) // Note: the following line is deliberately commented, compare to draw_rect_empty/5; // sgl.begin_lines() // more predictable, compared to sgl.begin_line_strip, at the price of more vertexes send sgl.c4b(c.r, c.g, c.b, c.a) @@ -576,8 +574,7 @@ fn radius_to_segments(r f32) int { pub fn (ctx &Context) draw_circle_empty(x f32, y f32, radius f32, c Color) { $if macos { if ctx.native_rendering { - C.darwin_draw_circle_empty(x - radius + 1, ctx.height - (y + radius + 3), - radius, c) + C.darwin_draw_circle_empty(x - radius + 1, ctx.height - (y + radius + 3), radius, c) return } } @@ -611,8 +608,7 @@ pub fn (ctx &Context) draw_circle_empty(x f32, y f32, radius f32, c Color) { pub fn (ctx &Context) draw_circle_filled(x f32, y f32, radius f32, c Color) { $if macos { if ctx.native_rendering { - C.darwin_draw_circle(x - radius + 1, ctx.height - (y + radius + 3), radius, - c) + C.darwin_draw_circle(x - radius + 1, ctx.height - (y + radius + 3), radius, c) return } } @@ -674,8 +670,7 @@ pub fn (ctx &Context) draw_circle_line(x f32, y f32, radius int, segments int, c $if macos { if ctx.native_rendering { - C.darwin_draw_circle(x - radius + 1, ctx.height - (y + radius + 3), radius, - c) + C.darwin_draw_circle(x - radius + 1, ctx.height - (y + radius + 3), radius, c) return } } @@ -1057,10 +1052,10 @@ pub fn (ctx &Context) draw_ellipse_thick_rotate(x f32, y f32, rw f32, rh f32, th xfactor := math.sinf(f32(math.radians(i))) yfactor := math.cosf(f32(math.radians(i))) - sgl.v2f(x + xfactor * (rw - th / 2) * cos_rot - yfactor * (rh - th / 2) * sin_rot, - y + yfactor * (rh - th / 2) * cos_rot + xfactor * (rw - th / 2) * sin_rot) - sgl.v2f(x + xfactor * (rw + th / 2) * cos_rot - yfactor * (rh + th / 2) * sin_rot, - y + yfactor * (rh + th / 2) * cos_rot + xfactor * (rw + th / 2) * sin_rot) + sgl.v2f(x + xfactor * (rw - th / 2) * cos_rot - yfactor * (rh - th / 2) * sin_rot, y + + yfactor * (rh - th / 2) * cos_rot + xfactor * (rw - th / 2) * sin_rot) + sgl.v2f(x + xfactor * (rw + th / 2) * cos_rot - yfactor * (rh + th / 2) * sin_rot, y + + yfactor * (rh + th / 2) * cos_rot + xfactor * (rw + th / 2) * sin_rot) } sgl.v2f(x - (rh - th / 2) * sin_rot, y + (rh - th / 2) * cos_rot) sgl.v2f(x - (rh + th / 2) * sin_rot, y + (rh + th / 2) * cos_rot) diff --git a/vlib/gg/draw_rect_empty_test.v b/vlib/gg/draw_rect_empty_test.v index f380262da8..690cc1da09 100644 --- a/vlib/gg/draw_rect_empty_test.v +++ b/vlib/gg/draw_rect_empty_test.v @@ -9,8 +9,7 @@ fn rect_empty_bounds_match(a f32, b f32) bool { } fn test_rect_empty_screen_bounds_keep_the_top_left_corner_aligned() { - tleft_x, tleft_y, bright_x, bright_y := rect_empty_screen_bounds(1.0, 12, 34, 56, - 78) + tleft_x, tleft_y, bright_x, bright_y := rect_empty_screen_bounds(1.0, 12, 34, 56, 78) assert rect_empty_bounds_match(tleft_x, 12.1) assert rect_empty_bounds_match(tleft_y, 34.1) assert rect_empty_bounds_match(bright_x, 67.9) diff --git a/vlib/gg/gg.c.v b/vlib/gg/gg.c.v index 85f5ec3bee..baf5d12602 100644 --- a/vlib/gg/gg.c.v +++ b/vlib/gg/gg.c.v @@ -662,7 +662,8 @@ fn gg_resize_window(width int, height int) { return } C.SetWindowPos(hwnd, unsafe { nil }, int(current_rect.left), int(current_rect.top), - int(rect.right - rect.left), int(rect.bottom - rect.top), u32(C.SWP_NOZORDER | C.SWP_NOACTIVATE)) + int(rect.right - rect.left), int(rect.bottom - rect.top), + u32(C.SWP_NOZORDER | C.SWP_NOACTIVATE)) } $else $if linux && !sokol_wayland ? { display := sapp.x11_get_display() window := u64(usize(sapp.x11_get_window())) @@ -878,16 +879,18 @@ pub fn (ctx &Context) show_fps() { fps_text := int(0.5 + 1.0 / frame_duration).str() if ctx.fps.width == 0 { mut fps := unsafe { &ctx.fps } - fps.width, fps.height = ctx.text_size('00') // usual size; prevents blinking on variable width fonts + fps.width, fps.height = + ctx.text_size('00') // usual size; prevents blinking on variable width fonts } char_width := ctx.fps.text_config.size / 2 mut full_width := ctx.fps.width if char_width * fps_text.len > ctx.fps.width { full_width += (fps_text.len - 2) * char_width } - ctx.draw_rect_filled(ctx.fps.x, ctx.fps.y, full_width + 2, ctx.fps.height + 4, ctx.fps.background_color) - ctx.draw_text(ctx.fps.x + full_width / 2 + 1, ctx.fps.y + ctx.fps.height / 2 + 2, - fps_text, ctx.fps.text_config) + ctx.draw_rect_filled(ctx.fps.x, ctx.fps.y, full_width + 2, ctx.fps.height + 4, + ctx.fps.background_color) + ctx.draw_text(ctx.fps.x + full_width / 2 + 1, ctx.fps.y + ctx.fps.height / 2 + 2, fps_text, + ctx.fps.text_config) } fn (mut ctx Context) set_scale() { @@ -976,7 +979,8 @@ pub fn screen_size() Size { } for i := 0; i < resources.noutput; i++ { if unsafe { u64(resources.outputs[i]) } == primary_output { - output_info := C.XRRGetOutputInfo(display, resources, unsafe { resources.outputs[i] }) + output_info := C.XRRGetOutputInfo(display, resources, + unsafe { resources.outputs[i] }) if output_info == unsafe { nil } { return Size{} } diff --git a/vlib/gg/gg.js.v b/vlib/gg/gg.js.v index 459e6eee8f..6d434475bb 100644 --- a/vlib/gg/gg.js.v +++ b/vlib/gg/gg.js.v @@ -485,7 +485,8 @@ pub fn (mut ctx Context) draw_rect(x f32, y f32, w f32, h f32, c Color) { fn gg_animation_frame_fn(mut g Context) { g.frame++ - g.context.clearRect(JS.Number(0), JS.Number(0), JS.Number(g.config.width), JS.Number(g.config.height)) + g.context.clearRect(JS.Number(0), JS.Number(0), JS.Number(g.config.width), + JS.Number(g.config.height)) // todo(playXE): handle events if !isnil(g.config.frame_fn) { diff --git a/vlib/gg/gg_ui.c.v b/vlib/gg/gg_ui.c.v index c65d2217b4..032c414b50 100644 --- a/vlib/gg/gg_ui.c.v +++ b/vlib/gg/gg_ui.c.v @@ -6,8 +6,8 @@ import sokol.sgl // required for ui.DrawDevice interface (with &gg.Context as an instance) pub fn (ctx &Context) scissor_rect(x int, y int, w int, h int) { - sgl.scissor_rect(int(ctx.scale * x), int(ctx.scale * y), int(ctx.scale * w), int(ctx.scale * h), - true) + sgl.scissor_rect(int(ctx.scale * x), int(ctx.scale * y), int(ctx.scale * w), + int(ctx.scale * h), true) } // empty function diff --git a/vlib/gg/image.c.v b/vlib/gg/image.c.v index 5f70be5932..6db651fbd2 100644 --- a/vlib/gg/image.c.v +++ b/vlib/gg/image.c.v @@ -342,8 +342,8 @@ pub fn (ctx &Context) draw_image_with_config(config DrawImageConfig) { } else { config.img_rect.height } - C.darwin_draw_image(x, ctx.height - (y + config.img_rect.height), width, - height, img) + C.darwin_draw_image(x, ctx.height - (y + config.img_rect.height), width, height, + img) return } } diff --git a/vlib/goroutines/examples/goroutine_benchmark.v b/vlib/goroutines/examples/goroutine_benchmark.v index d84fff4283..f6c3df3de2 100644 --- a/vlib/goroutines/examples/goroutine_benchmark.v +++ b/vlib/goroutines/examples/goroutine_benchmark.v @@ -52,8 +52,7 @@ fn bench_fan_out_fan_in(n int) { elapsed := sw.elapsed() us := elapsed.microseconds() ns_per := elapsed.nanoseconds() / n - C.printf(c'fan-out/fan-in %d goroutines: %lld us (%lld ns/goroutine)\n', n, us, - ns_per) + C.printf(c'fan-out/fan-in %d goroutines: %lld us (%lld ns/goroutine)\n', n, us, ns_per) } // --- ping-pong --- @@ -91,8 +90,7 @@ fn bench_ping_pong(n int) { elapsed := sw.elapsed() us := elapsed.microseconds() ns_per := elapsed.nanoseconds() / n - C.printf(c'ping-pong %d round-trips: %lld us (%lld ns/round-trip)\n', n, us, - ns_per) + C.printf(c'ping-pong %d round-trips: %lld us (%lld ns/round-trip)\n', n, us, ns_per) } // --- contended channel --- diff --git a/vlib/hash/hash_compiles_test.v b/vlib/hash/hash_compiles_test.v index 7058cd5b21..02a277fd4b 100644 --- a/vlib/hash/hash_compiles_test.v +++ b/vlib/hash/hash_compiles_test.v @@ -9,8 +9,7 @@ fn test_hash_compiles() { assert hash.sum64_string('abc', 2).hex_full() == '41981296238e0d1d' assert hash.sum64_string('message digest', 3).hex_full() == '41bba71e1ae831d7' assert hash.sum64_string('abcdefghijklmnopqrstuvwxyz', 4).hex_full() == '065f27868866278a' - assert hash.sum64_string('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', - 5).hex_full() == 'b9121e0f1a9bdd97' + assert hash.sum64_string('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 5).hex_full() == 'b9121e0f1a9bdd97' assert hash.sum64_string('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 6).hex_full() == 'a54abb9fbc9e4e82' assert hash.sum64([]u8{len: 1}, 0).hex_full() == '34e55bcc2fdda5ac' diff --git a/vlib/json/tests/json_decode_with_sumtype_test.v b/vlib/json/tests/json_decode_with_sumtype_test.v index 7601570273..f895d526c6 100644 --- a/vlib/json/tests/json_decode_with_sumtype_test.v +++ b/vlib/json/tests/json_decode_with_sumtype_test.v @@ -47,19 +47,9 @@ fn test_json_decode_with_sumtype_struct_variant_without_type_field() { }) } -pub type GetBlockResult = GetBlockResultB | string - -pub struct GetBlockResponse { - result GetBlockResult -} - -pub struct GetBlockResultB { - hash string - confirmations u64 -} - fn test_json_decode_with_sumtype_struct_field_without_type_field() { - decoded := json.decode(GetBlockResponse, '{ "result": { "hash": "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", "confirmations": 743970 } }')! + decoded := json.decode(GetBlockResponse, + '{ "result": { "hash": "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", "confirmations": 743970 } }')! assert decoded.result == GetBlockResult(GetBlockResultB{ hash: '00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09' diff --git a/vlib/json/tests/json_encode_enum_test.v b/vlib/json/tests/json_encode_enum_test.v index 4220325729..60f796ae86 100644 --- a/vlib/json/tests/json_encode_enum_test.v +++ b/vlib/json/tests/json_encode_enum_test.v @@ -75,7 +75,8 @@ fn test_encode_direct_enum() { } fn test_encode_alias_and_sumtype() { - assert json.decode(TestStruct, '{"test":["one","one"],"test2":"two","test3": "one", "test4": "two", "test5":4}')! == TestStruct{ + assert json.decode(TestStruct, + '{"test":["one","one"],"test2":"two","test3": "one", "test4": "two", "test5":4}')! == TestStruct{ test: [.one, .one] test2: .two test3: TestAlias(.one) diff --git a/vlib/json/tests/json_generic_array_test.v b/vlib/json/tests/json_generic_array_test.v index 5096763d6a..1c784ebc7b 100644 --- a/vlib/json/tests/json_generic_array_test.v +++ b/vlib/json/tests/json_generic_array_test.v @@ -24,7 +24,8 @@ fn test_string() { } assert json.encode(t) == '{"selector":"aa","selector2":["a","b"],"selector3":["z"]}' - assert json.decode(DocumentFindFilter[string], '{"selector":"aa","selector2":["a","b"],"selector3":["z"]}')! == t + assert json.decode(DocumentFindFilter[string], + '{"selector":"aa","selector2":["a","b"],"selector3":["z"]}')! == t } fn test_int() ! { diff --git a/vlib/json/tests/json_raw_test.v b/vlib/json/tests/json_raw_test.v index 9e65592892..cdc501e1af 100644 --- a/vlib/json/tests/json_raw_test.v +++ b/vlib/json/tests/json_raw_test.v @@ -42,7 +42,8 @@ fn test_raw_empty_string() { } fn test_stringified_object_returns_error_for_raw_field() { - stringified_json := json.encode('{"metadata":{"topLevelProperty":{"nestedProperty1":"Value 1"}}}') + stringified_json := + json.encode('{"metadata":{"topLevelProperty":{"nestedProperty1":"Value 1"}}}') json.decode(TestRawStringifiedObject, stringified_json) or { assert err.msg().starts_with('Json element is not an object:') return diff --git a/vlib/json/tests/json_test.v b/vlib/json/tests/json_test.v index a71934223b..ccf5a58fa5 100644 --- a/vlib/json/tests/json_test.v +++ b/vlib/json/tests/json_test.v @@ -221,7 +221,8 @@ struct Country { } fn test_struct_in_struct() { - country := json.decode(Country, '{ "name": "UK", "cities": [{"name":"London"}, {"name":"Manchester"}]}')! + country := json.decode(Country, + '{ "name": "UK", "cities": [{"name":"London"}, {"name":"Manchester"}]}')! assert country.name == 'UK' assert country.cities.len == 2 assert country.cities[0].name == 'London' @@ -554,21 +555,24 @@ struct RequiredStruct { } fn test_required() { - nullish_one := json.decode(NullishStruct, '{"name":"Peter", "lastname":null, "age":28,"salary":95000.5,"title":"worker"}')! + nullish_one := json.decode(NullishStruct, + '{"name":"Peter", "lastname":null, "age":28,"salary":95000.5,"title":"worker"}')! assert nullish_one.name == 'Peter' assert nullish_one.lastname == '' assert nullish_one.age == 28 assert nullish_one.salary == 95000.5 assert nullish_one.child.name == '' - nullish_two := json.decode(NullishStruct, '{"name":"Peter", "lastname": "Parker", "age":28,"salary":95000.5,"title":"worker"}')! + nullish_two := json.decode(NullishStruct, + '{"name":"Peter", "lastname": "Parker", "age":28,"salary":95000.5,"title":"worker"}')! assert nullish_two.name == 'Peter' assert nullish_two.lastname == 'Parker' assert nullish_two.age == 28 assert nullish_two.salary == 95000.5 assert nullish_two.child.name == '' - nullish_third := json.decode(NullishStruct, '{"name":"Peter", "age":28,"salary":95000.5,"title":"worker", "child": {"name":"Nullish"}}')! + nullish_third := json.decode(NullishStruct, + '{"name":"Peter", "age":28,"salary":95000.5,"title":"worker", "child": {"name":"Nullish"}}')! assert nullish_third.name == 'Peter' assert nullish_third.lastname == '' assert nullish_third.age == 28 diff --git a/vlib/math/big/division_array_ops.v b/vlib/math/big/division_array_ops.v index 66912ca35b..f3fb49ea0a 100644 --- a/vlib/math/big/division_array_ops.v +++ b/vlib/math/big/division_array_ops.v @@ -59,8 +59,8 @@ fn knuth_divide_array_by_array(operand_a []u64, operand_b []u64, mut quotient [] u_j_n_1 := u[j + n - 1] u_j_n_2 := u[j + n - 2] - mut qhat, mut rhat := bits.div_64(u_j_n >> (64 - digit_bits), (u_j_n << digit_bits) | u_j_n_1, - v_n_1) + mut qhat, mut rhat := bits.div_64(u_j_n >> (64 - digit_bits), + (u_j_n << digit_bits) | u_j_n_1, v_n_1) mut x1, mut x2 := bits.mul_64(qhat, v_n_2) x2 = x2 & max_digit x1 = (x1 << (64 - digit_bits)) | (x2 >> digit_bits) diff --git a/vlib/math/bits/bits_test.v b/vlib/math/bits/bits_test.v index 78eed8a37e..a2c8376b23 100644 --- a/vlib/math/bits/bits_test.v +++ b/vlib/math/bits/bits_test.v @@ -223,8 +223,7 @@ fn test_bits() { // C.printf("x:%16x [%llu,%llu] %llu\n", u64(i) << x, sum, carry, u64(v >> 32) + u64(v >> 32)) assert ((carry << 32) | sum) == v + v } - mut sum_64t, mut carry_64t := add_64(0x8000_0000_0000_0000, 0x8000_0000_0000_0000, - u64(0)) + mut sum_64t, mut carry_64t := add_64(0x8000_0000_0000_0000, 0x8000_0000_0000_0000, u64(0)) assert sum_64t == u64(0) assert carry_64t == u64(1) diff --git a/vlib/math/erf_test.v b/vlib/math/erf_test.v index 2102514dea..0d0bfd7ae6 100644 --- a/vlib/math/erf_test.v +++ b/vlib/math/erf_test.v @@ -4,18 +4,15 @@ fn test_erf() { assert is_nan(erf(nan())) assert tolerance(erf(-1.0), -0.8427007888650501, 1e-8) assert tolerance(erf(0.0), 0.0, 1e-11) - assert tolerance(erf(1e-15), 0.0000000000000011283791670955126615773132947717431253912942469337536, - 1e-11) + assert tolerance(erf(1e-15), + 0.0000000000000011283791670955126615773132947717431253912942469337536, 1e-11) assert tolerance(erf(0.1), 0.11246291601917208, 1e-11) assert tolerance(erf(0.3), 0.32862677677789676, 1e-7) - assert tolerance(erf(0.5), 0.5204998778130465376827466538919645287364515757579637, - 1e-9) + assert tolerance(erf(0.5), 0.5204998778130465376827466538919645287364515757579637, 1e-9) assert tolerance(erf(1.0), 0.8427007888650501, 1e-8) assert tolerance(erf(1.5), 0.966105146259005, 1e-9) - assert tolerance(erf(6.0), 0.99999999999999997848026328750108688340664960081261537, - 1e-12) - assert tolerance(erf(5.0), 0.99999999999846254020557196514981165651461662110988195, - 1e-12) + assert tolerance(erf(6.0), 0.99999999999999997848026328750108688340664960081261537, 1e-12) + assert tolerance(erf(5.0), 0.99999999999846254020557196514981165651461662110988195, 1e-12) assert tolerance(erf(4.0), 0.999999984582742, 1e-12) assert tolerance(erf(inf(1)), 1.0, 1e-12) assert tolerance(erf(inf(-1)), -1.0, 1e-12) diff --git a/vlib/math/fractions/approximations_test.v b/vlib/math/fractions/approximations_test.v index b1c9b4fbe4..86ed06927a 100644 --- a/vlib/math/fractions/approximations_test.v +++ b/vlib/math/fractions/approximations_test.v @@ -77,53 +77,43 @@ fn test_pi_2_digits() { } fn test_pi_3_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-4) == fractions.fraction(333, - 106) + assert fractions.approximate_with_eps(math.pi, 5.0e-4) == fractions.fraction(333, 106) } fn test_pi_4_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-5) == fractions.fraction(355, - 113) + assert fractions.approximate_with_eps(math.pi, 5.0e-5) == fractions.fraction(355, 113) } fn test_pi_5_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-6) == fractions.fraction(355, - 113) + assert fractions.approximate_with_eps(math.pi, 5.0e-6) == fractions.fraction(355, 113) } fn test_pi_6_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-7) == fractions.fraction(355, - 113) + assert fractions.approximate_with_eps(math.pi, 5.0e-7) == fractions.fraction(355, 113) } fn test_pi_7_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-8) == fractions.fraction(103993, - 33102) + assert fractions.approximate_with_eps(math.pi, 5.0e-8) == fractions.fraction(103993, 33102) } fn test_pi_8_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-9) == fractions.fraction(103993, - 33102) + assert fractions.approximate_with_eps(math.pi, 5.0e-9) == fractions.fraction(103993, 33102) } fn test_pi_9_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-10) == fractions.fraction(104348, - 33215) + assert fractions.approximate_with_eps(math.pi, 5.0e-10) == fractions.fraction(104348, 33215) } fn test_pi_10_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-11) == fractions.fraction(312689, - 99532) + assert fractions.approximate_with_eps(math.pi, 5.0e-11) == fractions.fraction(312689, 99532) } fn test_pi_11_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-12) == fractions.fraction(1146408, - 364913) + assert fractions.approximate_with_eps(math.pi, 5.0e-12) == fractions.fraction(1146408, 364913) } fn test_pi_12_digits() { - assert fractions.approximate_with_eps(math.pi, 5.0e-13) == fractions.fraction(4272943, - 1360120) + assert fractions.approximate_with_eps(math.pi, 5.0e-13) == fractions.fraction(4272943, 1360120) } fn test_phi_1_digit() { @@ -131,56 +121,45 @@ fn test_phi_1_digit() { } fn test_phi_2_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-3) == fractions.fraction(21, - 13) + assert fractions.approximate_with_eps(math.phi, 5.0e-3) == fractions.fraction(21, 13) } fn test_phi_3_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-4) == fractions.fraction(55, - 34) + assert fractions.approximate_with_eps(math.phi, 5.0e-4) == fractions.fraction(55, 34) } fn test_phi_4_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-5) == fractions.fraction(233, - 144) + assert fractions.approximate_with_eps(math.phi, 5.0e-5) == fractions.fraction(233, 144) } fn test_phi_5_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-6) == fractions.fraction(610, - 377) + assert fractions.approximate_with_eps(math.phi, 5.0e-6) == fractions.fraction(610, 377) } fn test_phi_6_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-7) == fractions.fraction(1597, - 987) + assert fractions.approximate_with_eps(math.phi, 5.0e-7) == fractions.fraction(1597, 987) } fn test_phi_7_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-8) == fractions.fraction(6765, - 4181) + assert fractions.approximate_with_eps(math.phi, 5.0e-8) == fractions.fraction(6765, 4181) } fn test_phi_8_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-9) == fractions.fraction(17711, - 10946) + assert fractions.approximate_with_eps(math.phi, 5.0e-9) == fractions.fraction(17711, 10946) } fn test_phi_9_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-10) == fractions.fraction(75025, - 46368) + assert fractions.approximate_with_eps(math.phi, 5.0e-10) == fractions.fraction(75025, 46368) } fn test_phi_10_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-11) == fractions.fraction(196418, - 121393) + assert fractions.approximate_with_eps(math.phi, 5.0e-11) == fractions.fraction(196418, 121393) } fn test_phi_11_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-12) == fractions.fraction(514229, - 317811) + assert fractions.approximate_with_eps(math.phi, 5.0e-12) == fractions.fraction(514229, 317811) } fn test_phi_12_digits() { - assert fractions.approximate_with_eps(math.phi, 5.0e-13) == fractions.fraction(2178309, - 1346269) + assert fractions.approximate_with_eps(math.phi, 5.0e-13) == fractions.fraction(2178309, 1346269) } diff --git a/vlib/math/gamma.v b/vlib/math/gamma.v index 015c81a56a..1fd3480045 100644 --- a/vlib/math/gamma.v +++ b/vlib/math/gamma.v @@ -215,41 +215,41 @@ pub fn log_gamma_sign(a f64) (f64, int) { } if i == 0 { z := y * y - gamma_p1 := lgamma_a[0] + z * (lgamma_a[2] + z * (lgamma_a[4] + z * (lgamma_a[6] + - z * (lgamma_a[8] + z * lgamma_a[10])))) - gamma_p2 := z * (lgamma_a[1] + z * (lgamma_a[3] + z * (lgamma_a[5] + z * (lgamma_a[7] + - z * (lgamma_a[9] + z * lgamma_a[11]))))) + gamma_p1 := lgamma_a[0] + + z * (lgamma_a[2] + z * (lgamma_a[4] + z * (lgamma_a[6] + z * (lgamma_a[8] + z * lgamma_a[10])))) + gamma_p2 := z * (lgamma_a[1] + + z * (lgamma_a[3] + z * (lgamma_a[5] + z * (lgamma_a[7] + z * (lgamma_a[9] + z * lgamma_a[11]))))) p := y * gamma_p1 + gamma_p2 lgamma += (p - 0.5 * y) } else if i == 1 { z := y * y w := z * y - gamma_p1 := lgamma_t[0] + w * (lgamma_t[3] + w * (lgamma_t[6] + w * (lgamma_t[9] + - w * lgamma_t[12]))) // parallel comp - gamma_p2 := lgamma_t[1] + w * (lgamma_t[4] + w * (lgamma_t[7] + w * (lgamma_t[10] + - w * lgamma_t[13]))) - gamma_p3 := lgamma_t[2] + w * (lgamma_t[5] + w * (lgamma_t[8] + w * (lgamma_t[11] + - w * lgamma_t[14]))) + gamma_p1 := lgamma_t[0] + + w * (lgamma_t[3] + w * (lgamma_t[6] + w * (lgamma_t[9] + w * lgamma_t[12]))) // parallel comp + gamma_p2 := lgamma_t[1] + + w * (lgamma_t[4] + w * (lgamma_t[7] + w * (lgamma_t[10] + w * lgamma_t[13]))) + gamma_p3 := lgamma_t[2] + + w * (lgamma_t[5] + w * (lgamma_t[8] + w * (lgamma_t[11] + w * lgamma_t[14]))) tf := -1.21486290535849611461e-01 // 0xBFBF19B9BCC38A42 // tt := -(tail of tf) tt := -3.63867699703950536541e-18 // 0xBC50C7CAA48A971F p := z * gamma_p1 - (tt - w * (gamma_p2 + y * gamma_p3)) lgamma += (tf + p) } else if i == 2 { - gamma_p1 := y * (lgamma_u[0] + y * (lgamma_u[1] + y * (lgamma_u[2] + y * (lgamma_u[3] + - y * (lgamma_u[4] + y * lgamma_u[5]))))) - gamma_p2 := 1.0 + y * (lgamma_v[1] + y * (lgamma_v[2] + y * (lgamma_v[3] + - y * (lgamma_v[4] + y * lgamma_v[5])))) + gamma_p1 := y * (lgamma_u[0] + + y * (lgamma_u[1] + y * (lgamma_u[2] + y * (lgamma_u[3] + y * (lgamma_u[4] + y * lgamma_u[5]))))) + gamma_p2 := 1.0 + + y * (lgamma_v[1] + y * (lgamma_v[2] + y * (lgamma_v[3] + y * (lgamma_v[4] + y * lgamma_v[5])))) lgamma += (-0.5 * y + gamma_p1 / gamma_p2) } } else if x < 8 { // 2 <= x < 8 i := int(x) y := x - f64(i) - tmp23456 := lgamma_s[2] + y * (lgamma_s[3] + y * (lgamma_s[4] + y * (lgamma_s[5] + - y * lgamma_s[6]))) + tmp23456 := lgamma_s[2] + + y * (lgamma_s[3] + y * (lgamma_s[4] + y * (lgamma_s[5] + y * lgamma_s[6]))) p := y * (lgamma_s[0] + y * (lgamma_s[1] + y * tmp23456)) - tmpr23456 := lgamma_r[2] + y * (lgamma_r[3] + y * (lgamma_r[4] + y * (lgamma_r[5] + - y * lgamma_r[6]))) + tmpr23456 := lgamma_r[2] + + y * (lgamma_r[3] + y * (lgamma_r[4] + y * (lgamma_r[5] + y * lgamma_r[6]))) q := 1.0 + y * (lgamma_r[1] + y * tmpr23456) lgamma = 0.5 * y + p / q mut z := 1.0 // lgamma(1+s) = log(s) + lgamma(s) @@ -283,8 +283,8 @@ pub fn log_gamma_sign(a f64) (f64, int) { t := log(x) z := 1.0 / x y := z * z - w := lgamma_w[0] + z * (lgamma_w[1] + y * (lgamma_w[2] + y * (lgamma_w[3] + - y * (lgamma_w[4] + y * (lgamma_w[5] + y * lgamma_w[6]))))) + w := lgamma_w[0] + + z * (lgamma_w[1] + y * (lgamma_w[2] + y * (lgamma_w[3] + y * (lgamma_w[4] + y * (lgamma_w[5] + y * lgamma_w[6]))))) lgamma = (x - 0.5) * (t - 1.0) + w } else { // 2**58 <= x <= Inf lgamma = x * (log(x) - 1.0) diff --git a/vlib/math/interpolation_bezier.v b/vlib/math/interpolation_bezier.v index 56a285c0c0..347484ee4f 100644 --- a/vlib/math/interpolation_bezier.v +++ b/vlib/math/interpolation_bezier.v @@ -19,8 +19,7 @@ pub fn cubic_bezier(t f64, p []BezierPoint) BezierPoint { if p.len != 4 { panic('invalid p.len') } - return cubic_bezier_coords(t, p[0].x, p[1].x, p[2].x, p[3].x, p[0].y, p[1].y, p[2].y, - p[3].y) + return cubic_bezier_coords(t, p[0].x, p[1].x, p[2].x, p[3].x, p[0].y, p[1].y, p[2].y, p[3].y) } // cubic_bezier_a returns a linear interpolation between the control points, diff --git a/vlib/math/invtrig.v b/vlib/math/invtrig.v index 80d034297e..24f70c0576 100644 --- a/vlib/math/invtrig.v +++ b/vlib/math/invtrig.v @@ -62,8 +62,8 @@ fn xatan(x f64) f64 { xatan_q3 := 4.853903996359136964868e+02 xatan_q4 := 1.945506571482613964425e+02 mut z := x * x - z = z * ((((xatan_p0 * z + xatan_p1) * z + xatan_p2) * z + xatan_p3) * z + xatan_p4) / (((((z + - xatan_q0) * z + xatan_q1) * z + xatan_q2) * z + xatan_q3) * z + xatan_q4) + z = z * ((((xatan_p0 * z + xatan_p1) * z + xatan_p2) * z + xatan_p3) * z + xatan_p4) / ( + ((((z + xatan_q0) * z + xatan_q1) * z + xatan_q2) * z + xatan_q3) * z + xatan_q4) z = x * z + x return z } diff --git a/vlib/math/unsigned/uint256.v b/vlib/math/unsigned/uint256.v index ff75ef8672..eab6de8ac5 100644 --- a/vlib/math/unsigned/uint256.v +++ b/vlib/math/unsigned/uint256.v @@ -249,7 +249,8 @@ pub fn (u Uint256) rsh(n u32) Uint256 { s.hi = Uint128{u.hi.hi, 0} } else if n > 64 { shift := n - 64 - s.lo = Uint128{u.lo.hi >> shift | u.hi.lo << (64 - shift), u.hi.lo >> shift | u.hi.hi << (64 - shift)} + s.lo = + Uint128{u.lo.hi >> shift | u.hi.lo << (64 - shift), u.hi.lo >> shift | u.hi.hi << (64 - shift)} s.hi = Uint128{u.hi.hi >> shift, 0} } else { s.lo = Uint128{u.lo.lo >> n | u.lo.hi << (64 - n), u.lo.hi >> n | u.hi.lo << (64 - n)} @@ -279,7 +280,8 @@ pub fn (u Uint256) lsh(n u32) Uint256 { } else if n > 64 { shift := n - 64 s.lo = Uint128{0, u.lo.lo << shift} - s.hi = Uint128{u.lo.lo >> (64 - shift) | u.lo.hi << shift, u.lo.hi >> (64 - shift) | u.hi.lo << shift} + s.hi = + Uint128{u.lo.lo >> (64 - shift) | u.lo.hi << shift, u.lo.hi >> (64 - shift) | u.hi.lo << shift} } else { s.lo = Uint128{u.lo.lo << n, u.lo.hi << n | u.lo.lo >> (64 - n)} s.hi = Uint128{u.hi.lo << n | u.lo.hi >> (64 - n), u.hi.hi << n | u.hi.lo >> (64 - n)} @@ -403,7 +405,8 @@ pub fn (u_ Uint256) str() string { return u.lo.str() } - mut buf := '000000000000000000000000000000000000000000000000000000000000000000000000000000'.bytes() + mut buf := + '000000000000000000000000000000000000000000000000000000000000000000000000000000'.bytes() for i := buf.len; true; i -= 19 { q, mut r := u.quo_rem_64(u64(1e19)) diff --git a/vlib/math/unsigned/uint256_test.v b/vlib/math/unsigned/uint256_test.v index 7efe4b0226..075503d796 100644 --- a/vlib/math/unsigned/uint256_test.v +++ b/vlib/math/unsigned/uint256_test.v @@ -282,7 +282,8 @@ fn test_new() { } fn test_rsh() { - a := unsigned.uint256_from_dec_str('115792089237316195423570985008687907853269984665640564039457584007913129639935')! + a := + unsigned.uint256_from_dec_str('115792089237316195423570985008687907853269984665640564039457584007913129639935')! assert a.str() == a.rsh(0).str() assert '57896044618658097711785492504343953926634992332820282019728792003956564819967' == a.rsh(1).str() assert '6277101735386680763835789423207666416102355444464034512895' == a.rsh(64).str() @@ -305,6 +306,7 @@ fn test_lsh() { } fn test_rotate_left() { - a := unsigned.uint256_from_dec_str('25514942427378518882041616545065271187265095759155217686057363902268374351523')! + a := + unsigned.uint256_from_dec_str('25514942427378518882041616545065271187265095759155217686057363902268374351523')! assert a.rotate_left(182).str() == '88706376393829417451765793453791860419270208590599379720310994108668904859637' } diff --git a/vlib/net/address.c.v b/vlib/net/address.c.v index a559caf867..5eb11192be 100644 --- a/vlib/net/address.c.v +++ b/vlib/net/address.c.v @@ -306,6 +306,7 @@ pub fn peer_addr_from_socket_handle(handle int) !Addr { } } mut size := sizeof(Addr) - socket_error_message(C.getpeername(handle, voidptr(&addr), &size), 'peer_addr_from_socket_handle failed')! + socket_error_message(C.getpeername(handle, voidptr(&addr), &size), + 'peer_addr_from_socket_handle failed')! return addr } diff --git a/vlib/net/errors.c.v b/vlib/net/errors.c.v index 73e98c4204..10d1a09a01 100644 --- a/vlib/net/errors.c.v +++ b/vlib/net/errors.c.v @@ -3,10 +3,13 @@ module net // Well defined errors that are returned from socket functions pub const errors_base = 0 pub const err_new_socket_failed = error_with_code('net: new_socket failed to create socket', + errors_base + 1) pub const err_option_not_settable = error_with_code('net: set_option_xxx option not settable', + errors_base + 2) pub const err_option_wrong_type = error_with_code('net: set_option_xxx option wrong type', + errors_base + 3) pub const err_port_out_of_range = error_with_code('net: port out of range', errors_base + 5) pub const err_no_udp_remote = error_with_code('net: no udp remote', errors_base + 6) diff --git a/vlib/net/http/backend.c.v b/vlib/net/http/backend.c.v index 66258fbbfa..f86db87e8d 100644 --- a/vlib/net/http/backend.c.v +++ b/vlib/net/http/backend.c.v @@ -55,7 +55,8 @@ fn read_from_ssl_connection_cb(con voidptr, buf &u8, bufsize int) !int { fn (req &Request) do_request(req_headers string, mut ssl_conn ssl.SSLConn) !Response { ssl_conn.write_string(req_headers) or { return err } mut content := strings.new_builder(4096) - req.receive_all_data_from_cb_in_builder(mut content, voidptr(ssl_conn), read_from_ssl_connection_cb)! + req.receive_all_data_from_cb_in_builder(mut content, voidptr(ssl_conn), + read_from_ssl_connection_cb)! ssl_conn.shutdown()! response_text := content.str() $if trace_http_response ? { diff --git a/vlib/net/http/cookie.v b/vlib/net/http/cookie.v index 655b783a58..d16b2a4e1c 100644 --- a/vlib/net/http/cookie.v +++ b/vlib/net/http/cookie.v @@ -54,9 +54,11 @@ pub fn read_cookies(h Header, filter string) []&Cookie { mut line := line_.trim_space() mut part := '' for line.len > 0 { - mut semicolon_position := line.index_any(';') // Store the position of the next semicolon + mut semicolon_position := + line.index_any(';') // Store the position of the next semicolon if semicolon_position > 0 { // So, there is a semicolon, let's parse until that position - line_parts := line[..semicolon_position].split(';') // split the line only until that semicolon + line_parts := + line[..semicolon_position].split(';') // split the line only until that semicolon line = line[(semicolon_position + 1)..] // and then skip everything before the semicolon part = line_parts[0] } else { diff --git a/vlib/net/http/file/static_server.v b/vlib/net/http/file/static_server.v index 074720351a..fd7a5ce942 100644 --- a/vlib/net/http/file/static_server.v +++ b/vlib/net/http/file/static_server.v @@ -75,8 +75,8 @@ fn (mut h StaticHttpHandler) handle(req http.Request) http.Response { log.info('took: ${sw.elapsed().microseconds():6}µs, status: ${res.status_code}, size: ${res.body.len:9}, url: ${url}') } mut uri_path := url.all_after_first('/').all_before('?').trim_right('/') - requested_file_path := os.norm_path(os.real_path(os.join_path_single(h.params.folder, - uri_path))) + requested_file_path := + os.norm_path(os.real_path(os.join_path_single(h.params.folder, uri_path))) if !requested_file_path.starts_with(h.params.folder) { log.warn('forbidden request; base folder: ${h.params.folder}, requested_file_path: ${requested_file_path}, ') res.set_status(.forbidden) diff --git a/vlib/net/http/http_proxy.v b/vlib/net/http/http_proxy.v index de02f39ba3..c17ac7db2b 100644 --- a/vlib/net/http/http_proxy.v +++ b/vlib/net/http/http_proxy.v @@ -144,7 +144,8 @@ fn (pr &HttpProxy) http_do(host urllib.URL, _method Method, path string, req &Re port_part := if port == 80 || port == 0 { '' } else { ':${port}' } - s := req.build_request_headers(req.method, host_name, port, '${host.scheme}://${host_name}${port_part}${path}') + s := req.build_request_headers(req.method, host_name, port, + '${host.scheme}://${host_name}${port_part}${path}') if host.scheme == 'https' { mut client := pr.ssl_dial('${host.host}:443')! @@ -155,8 +156,8 @@ fn (pr &HttpProxy) http_do(host urllib.URL, _method Method, path string, req &Re // client.shutdown()! // return response_text } $else { - response_text := req.do_request(req.build_request_headers(req.method, host_name, - port, path), mut client)! + response_text := req.do_request(req.build_request_headers(req.method, host_name, port, path), mut + client)! client.shutdown()! return response_text } diff --git a/vlib/net/http/http_proxy_test.v b/vlib/net/http/http_proxy_test.v index af47bf3b82..37451518af 100644 --- a/vlib/net/http/http_proxy_test.v +++ b/vlib/net/http/http_proxy_test.v @@ -64,8 +64,10 @@ fn test_http_proxy_do() { proxy := new_http_proxy(env_proxy)! mut header := new_header(key: .user_agent, value: 'vlib') header.add_custom('X-Vlang-Test', 'proxied')! - res := proxy.http_do(urllib.parse('http://httpbin.org/headers')!, Method.get, - '/headers', &Request{ proxy: proxy, header: header })! + res := proxy.http_do(urllib.parse('http://httpbin.org/headers')!, Method.get, '/headers', &Request{ + proxy: proxy + header: header + })! println(res.status_code) println('he4aders ${res.header}') assert res.status_code == 200 diff --git a/vlib/net/http/request_receive_test.v b/vlib/net/http/request_receive_test.v index c57f94b90b..1b61c8d289 100644 --- a/vlib/net/http/request_receive_test.v +++ b/vlib/net/http/request_receive_test.v @@ -15,7 +15,8 @@ fn receive_all_data_eof_cb(_ voidptr, _ &u8, _ int) !int { fn test_receive_all_data_from_cb_in_builder_propagates_non_eof_errors() { mut req := Request{} mut content := strings.new_builder(64) - req.receive_all_data_from_cb_in_builder(mut content, unsafe { nil }, receive_all_data_timeout_cb) or { + req.receive_all_data_from_cb_in_builder(mut content, unsafe { nil }, + receive_all_data_timeout_cb) or { assert err.code() == net.err_timed_out_code return } diff --git a/vlib/net/http/request_test.v b/vlib/net/http/request_test.v index 49a3996169..c9ceb8a9ef 100644 --- a/vlib/net/http/request_test.v +++ b/vlib/net/http/request_test.v @@ -59,7 +59,8 @@ fn test_parse_request_two_header_values() { } fn test_parse_request_body() { - mut reader_ := reader('GET / HTTP/1.1\r\nTest1: a\r\nTest2: b\r\nContent-Length: 4\r\n\r\nbodyabc') + mut reader_ := + reader('GET / HTTP/1.1\r\nTest1: a\r\nTest2: b\r\nContent-Length: 4\r\n\r\nbodyabc') req := http.parse_request(mut reader_) or { panic('did not parse: ${err}') } assert req.data == 'body' } diff --git a/vlib/net/jsonrpc/jsonrpc.v b/vlib/net/jsonrpc/jsonrpc.v index 31116b93ff..9a3e7a39cb 100644 --- a/vlib/net/jsonrpc/jsonrpc.v +++ b/vlib/net/jsonrpc/jsonrpc.v @@ -61,12 +61,10 @@ pub const invalid_request = error_with_code('Invalid request.', -32600) pub const method_not_found = error_with_code('Method not found.', -32601) pub const invalid_params = error_with_code('Invalid params', -32602) pub const internal_error = error_with_code('Internal error.', -32693) -pub const server_error_start = error_with_code('Error occurred when starting server.', - -32099) +pub const server_error_start = error_with_code('Error occurred when starting server.', -32099) pub const server_not_initialized = error_with_code('Server not initialized.', -32002) pub const unknown_error = error_with_code('Unknown error.', -32001) -pub const server_error_end = error_with_code('Error occurred when stopping the server.', - -32000) +pub const server_error_end = error_with_code('Error occurred when stopping the server.', -32000) pub const error_codes = [ parse_error.code(), invalid_request.code(), diff --git a/vlib/net/mbedtls/mbedtls.c.v b/vlib/net/mbedtls/mbedtls.c.v index 0e3e29bc42..063af99635 100644 --- a/vlib/net/mbedtls/mbedtls.c.v +++ b/vlib/net/mbedtls/mbedtls.c.v @@ -176,6 +176,9 @@ fn C.mbedtls_net_init(&C.mbedtls_net_context) fn C.mbedtls_net_connect(&C.mbedtls_net_context, &char, &char, i32) i32 fn C.mbedtls_net_bind(&C.mbedtls_net_context, &char, &char, i32) i32 fn C.mbedtls_net_accept(&C.mbedtls_net_context, &C.mbedtls_net_context, voidptr, usize, &usize) i32 +fn C.mbedtls_net_recv(voidptr, &u8, usize) i32 +fn C.mbedtls_net_send(voidptr, &u8, usize) i32 +fn C.mbedtls_net_recv_timeout(voidptr, &u8, usize, u32) i32 fn C.mbedtls_net_free(&C.mbedtls_net_context) fn C.mbedtls_ssl_init(&C.mbedtls_ssl_context) @@ -183,8 +186,7 @@ fn C.mbedtls_ssl_setup(&C.mbedtls_ssl_context, &C.mbedtls_ssl_config) i32 fn C.mbedtls_ssl_session_reset(&C.mbedtls_ssl_context) fn C.mbedtls_ssl_conf_authmode(&C.mbedtls_ssl_config, i32) fn C.mbedtls_ssl_conf_rng(&C.mbedtls_ssl_config, fn (voidptr, &u8, usize) int, &C.mbedtls_ctr_drbg_context) -fn C.mbedtls_ssl_set_bio(&C.mbedtls_ssl_context, &C.mbedtls_net_context, &C.mbedtls_ssl_send_t, &C.mbedtls_ssl_recv_t, - &C.mbedtls_ssl_recv_timeout_t) +fn C.mbedtls_ssl_set_bio(&C.mbedtls_ssl_context, &C.mbedtls_net_context, fn (voidptr, &u8, usize) i32, fn (voidptr, &u8, usize) i32, fn (voidptr, &u8, usize, u32) i32) fn C.mbedtls_ssl_conf_own_cert(&C.mbedtls_ssl_config, &C.mbedtls_x509_crt, &C.mbedtls_pk_context) i32 fn C.mbedtls_ssl_conf_ca_chain(&C.mbedtls_ssl_config, &C.mbedtls_x509_crt, &C.mbedtls_x509_crl) fn C.mbedtls_ssl_set_hostname(&C.mbedtls_ssl_context, &char) i32 diff --git a/vlib/net/mbedtls/ssl_connection.c.v b/vlib/net/mbedtls/ssl_connection.c.v index 26a93d4b27..ab4321d09f 100644 --- a/vlib/net/mbedtls/ssl_connection.c.v +++ b/vlib/net/mbedtls/ssl_connection.c.v @@ -18,8 +18,7 @@ fn init_rng(mut ctr_drbg C.mbedtls_ctr_drbg_context, mut entropy C.mbedtls_entro if ret != 0 { C.mbedtls_ctr_drbg_free(&ctr_drbg) C.mbedtls_entropy_free(&entropy) - return error_with_code('net.mbedtls init_rng, failed to seed ssl context: ${ret}', - ret) + return error_with_code('net.mbedtls init_rng, failed to seed ssl context: ${ret}', ret) } // C.mbedtls_debug_set_threshold(5) } @@ -75,8 +74,8 @@ fn new_sslcerts_in_memory_with_rng(verify string, cert string, cert_key string, } if cert_key != '' { unsafe { - ret := C.mbedtls_pk_parse_key(&certs.client_key, cert_key.str, cert_key.len + 1, - 0, 0, C.mbedtls_ctr_drbg_random, rng) + ret := C.mbedtls_pk_parse_key(&certs.client_key, cert_key.str, cert_key.len + 1, 0, 0, + C.mbedtls_ctr_drbg_random, rng) if ret != 0 { return error_with_code('net.mbedtls new_sslcerts_in_memory, mbedtls_pk_parse_key error ret: ${ret}', ret) @@ -115,8 +114,8 @@ fn new_sslcerts_from_file_with_rng(verify string, cert string, cert_key string, } if cert_key != '' { unsafe { - ret := C.mbedtls_pk_parse_keyfile(&certs.client_key, &char(cert_key.str), - 0, C.mbedtls_ctr_drbg_random, rng) + ret := C.mbedtls_pk_parse_keyfile(&certs.client_key, &char(cert_key.str), 0, + C.mbedtls_ctr_drbg_random, rng) if ret != 0 { return error_with_code('net.mbedtls new_sslcerts_from_file, mbedtls_pk_parse_keyfile error ret: ${ret}', ret) @@ -228,13 +227,13 @@ fn (mut l SSLListener) init() ! { mut ret := 0 if l.config.in_memory_verification { - l.certs = new_sslcerts_in_memory_with_rng(l.config.verify, l.config.cert, l.config.cert_key, - &l.ctr_drbg) or { + l.certs = new_sslcerts_in_memory_with_rng(l.config.verify, l.config.cert, + l.config.cert_key, &l.ctr_drbg) or { return error('net.mbedtls SSLListener.init, cert failure 1, err: ${err}') } } else { - l.certs = new_sslcerts_from_file_with_rng(l.config.verify, l.config.cert, l.config.cert_key, - &l.ctr_drbg) or { + l.certs = new_sslcerts_from_file_with_rng(l.config.verify, l.config.cert, + l.config.cert_key, &l.ctr_drbg) or { return error('net.mbedtls SSLListener.init, cert failure 2, err: ${err}') } } @@ -256,8 +255,8 @@ fn (mut l SSLListener) init() ! { ret) } - ret = C.mbedtls_ssl_config_defaults(&l.conf, C.MBEDTLS_SSL_IS_SERVER, C.MBEDTLS_SSL_TRANSPORT_STREAM, - C.MBEDTLS_SSL_PRESET_DEFAULT) + ret = C.mbedtls_ssl_config_defaults(&l.conf, C.MBEDTLS_SSL_IS_SERVER, + C.MBEDTLS_SSL_TRANSPORT_STREAM, C.MBEDTLS_SSL_PRESET_DEFAULT) if ret != 0 { return error_with_code("net.mbedtls SSLListener.init, mbedtls_ssl_config_defaults can't set config defaults ret: ${ret}", ret) @@ -326,7 +325,7 @@ pub fn (mut l SSLListener) accept() !&SSLConn { } C.mbedtls_ssl_set_bio(&conn.ssl, &conn.server_fd, C.mbedtls_net_send, C.mbedtls_net_recv, - unsafe { nil }) + C.mbedtls_net_recv_timeout) ret = C.mbedtls_ssl_handshake(&conn.ssl) for ret != 0 { @@ -441,8 +440,8 @@ fn (mut s SSLConn) init() ! { C.mbedtls_ssl_config_init(&s.conf) init_rng(mut s.ctr_drbg, mut s.entropy)! mut ret := 0 - ret = C.mbedtls_ssl_config_defaults(&s.conf, C.MBEDTLS_SSL_IS_CLIENT, C.MBEDTLS_SSL_TRANSPORT_STREAM, - C.MBEDTLS_SSL_PRESET_DEFAULT) + ret = C.mbedtls_ssl_config_defaults(&s.conf, C.MBEDTLS_SSL_IS_CLIENT, + C.MBEDTLS_SSL_TRANSPORT_STREAM, C.MBEDTLS_SSL_PRESET_DEFAULT) if ret != 0 { return error_with_code('net.mbedtls SSLConn.init, mbedtls_ssl_config_defaults failed to set SSL configuration ret: ${ret}', ret) @@ -478,15 +477,18 @@ fn (mut s SSLConn) init() ! { if s.config.in_memory_verification { if s.config.verify != '' { ret = C.mbedtls_x509_crt_parse(&s.certs.cacert, s.config.verify.str, + s.config.verify.len + 1) } if s.config.cert != '' { ret = C.mbedtls_x509_crt_parse(&s.certs.client_cert, s.config.cert.str, + s.config.cert.len + 1) } if s.config.cert_key != '' { unsafe { ret = C.mbedtls_pk_parse_key(&s.certs.client_key, s.config.cert_key.str, + s.config.cert_key.len + 1, 0, 0, C.mbedtls_ctr_drbg_random, &s.ctr_drbg) } } @@ -572,8 +574,7 @@ pub fn (mut s SSLConn) dial(hostname string, port int) ! { ret = C.mbedtls_net_connect(&s.server_fd, &char(hostname.str), &char(port_str.str), C.MBEDTLS_NET_PROTO_TCP) if ret != 0 { - return error_with_code('net.mbedtls SSLConn.dial, failed to connect to host', - ret) + return error_with_code('net.mbedtls SSLConn.dial, failed to connect to host', ret) } C.mbedtls_ssl_set_bio(&s.ssl, &s.server_fd, C.mbedtls_net_send, C.mbedtls_net_recv, C.mbedtls_net_recv_timeout) diff --git a/vlib/net/openssl/openssl.c.v b/vlib/net/openssl/openssl.c.v index b851b2025c..1bcd67d221 100644 --- a/vlib/net/openssl/openssl.c.v +++ b/vlib/net/openssl/openssl.c.v @@ -180,8 +180,7 @@ fn ssl_error(ret int, ssl voidptr) !SSLError { return error_with_code('net.openssl unrecoverable syscall (${res})', res) } .ssl_error_ssl { - return error_with_code('net.openssl unrecoverable ssl protocol error (${res})', - res) + return error_with_code('net.openssl unrecoverable ssl protocol error (${res})', res) } else { return unsafe { SSLError(res) } diff --git a/vlib/net/openssl/ssl_connection.c.v b/vlib/net/openssl/ssl_connection.c.v index 5c61044a1a..064916faa4 100644 --- a/vlib/net/openssl/ssl_connection.c.v +++ b/vlib/net/openssl/ssl_connection.c.v @@ -110,7 +110,7 @@ fn (mut s SSLConn) init() ! { if s.config.validate { C.SSL_CTX_set_verify_depth(s.sslctx, 4) - C.SSL_CTX_set_options(s.sslctx, C.SSL_OP_NO_SSLv2 | C.SSL_OP_NO_SSLv3 | C.SSL_OP_NO_COMPRESSION) + C.SSL_CTX_set_options(s.sslctx, C.SSL_OP_NO_COMPRESSION) } s.ssl = unsafe { &C.SSL(C.SSL_new(s.sslctx)) } @@ -140,14 +140,14 @@ fn (mut s SSLConn) init() ! { } } if s.config.verify != '' { - res = C.SSL_CTX_load_verify_locations(voidptr(s.sslctx), &char(verify.str), - 0) + res = C.SSL_CTX_load_verify_locations(voidptr(s.sslctx), &char(verify.str), 0) if s.config.validate && res != 1 { return error('net.openssl SSLConn.init, SSL_CTX_load_verify_locations failed') } } if s.config.cert != '' { - res = C.SSL_CTX_use_certificate_file(voidptr(s.sslctx), &char(cert.str), C.SSL_FILETYPE_PEM) + res = C.SSL_CTX_use_certificate_file(voidptr(s.sslctx), &char(cert.str), + C.SSL_FILETYPE_PEM) if s.config.validate && res != 1 { return error('net.openssl SSLConn.init, SSL_CTX_use_certificate_file failed, res: ${res}') } diff --git a/vlib/net/smtp/smtp.v b/vlib/net/smtp/smtp.v index 46c80276bf..33df712535 100644 --- a/vlib/net/smtp/smtp.v +++ b/vlib/net/smtp/smtp.v @@ -38,6 +38,7 @@ pub: from string ssl bool starttls bool + timeout time.Duration } pub struct Client { @@ -91,7 +92,13 @@ pub fn (mut c Client) reconnect() ! { return error('Already connected to server') } - conn := net.dial_tcp('${c.server}:${c.port}') or { return error('Connecting to server failed') } + mut conn := net.dial_tcp('${c.server}:${c.port}') or { + return error('Connecting to server failed') + } + if c.timeout != 0 { + conn.set_read_timeout(c.timeout) + conn.set_write_timeout(c.timeout) + } c.conn = conn if c.ssl || c.encrypted { diff --git a/vlib/net/smtp/smtp_timeout_test.v b/vlib/net/smtp/smtp_timeout_test.v index b400297962..502501f440 100644 --- a/vlib/net/smtp/smtp_timeout_test.v +++ b/vlib/net/smtp/smtp_timeout_test.v @@ -27,7 +27,7 @@ fn test_client_timeout_configures_tcp_conn() ! { port := listener.addr()!.port()! done := chan bool{} spawn smtp_timeout_test_server(mut listener, done) - mut client := new_client(Client{ + mut client := new_client(Config{ server: '127.0.0.1' port: int(port) timeout: timeout diff --git a/vlib/net/tcp.c.v b/vlib/net/tcp.c.v index d4c2fc9cb6..c4af55c758 100644 --- a/vlib/net/tcp.c.v +++ b/vlib/net/tcp.c.v @@ -438,7 +438,8 @@ fn listen_tcp_with_family(family AddrFamily, saddr string, options ListenOptions } $if !net_nonblocking_sockets ? { - socket_error_message(res, 'listening on ${saddr} with maximum backlog pending queue of ${options.backlog}, failed')! + socket_error_message(res, + 'listening on ${saddr} with maximum backlog pending queue of ${options.backlog}, failed')! return &TcpListener(unsafe { nil }) // for compiler passed } $else { // non-blocking sockets may also not succeed immediately when they listen() and need to check the status and take action accordingly. @@ -451,7 +452,8 @@ fn listen_tcp_with_family(family AddrFamily, saddr string, options ListenOptions break } } else { - socket_error_message(res, 'listening on ${saddr} with maximum backlog pending queue of ${options.backlog}, failed')! + socket_error_message(res, + 'listening on ${saddr} with maximum backlog pending queue of ${options.backlog}, failed')! break // for compiler passed } } diff --git a/vlib/net/unix/stream.c.v b/vlib/net/unix/stream.c.v index daaf3072bd..5402d595dc 100644 --- a/vlib/net/unix/stream.c.v +++ b/vlib/net/unix/stream.c.v @@ -274,8 +274,10 @@ pub fn listen_stream(socket_path string, options ListenOptions) !&StreamListener C.unlink(&char(socket_path.str)) } - net.socket_error_message(C.bind(s.handle, voidptr(&addr), alen), 'binding to ${socket_path} failed')! - net.socket_error_message(C.listen(s.handle, options.backlog), 'listening on ${socket_path} with maximum backlog pending queue of ${options.backlog}, failed')! + net.socket_error_message(C.bind(s.handle, voidptr(&addr), alen), + 'binding to ${socket_path} failed')! + net.socket_error_message(C.listen(s.handle, options.backlog), + 'listening on ${socket_path} with maximum backlog pending queue of ${options.backlog}, failed')! return &StreamListener{ sock: s accept_deadline: no_deadline @@ -354,7 +356,8 @@ pub fn (mut l StreamListener) unlink() ! { $if windows { os.rm(l.sock.socket_path)! } $else { - net.socket_error_message(C.unlink(&char(l.sock.socket_path.str)), 'could not unlink ${l.sock.socket_path}')! + net.socket_error_message(C.unlink(&char(l.sock.socket_path.str)), + 'could not unlink ${l.sock.socket_path}')! } } diff --git a/vlib/net/urllib/urllib.v b/vlib/net/urllib/urllib.v index b499089386..df92b505a0 100644 --- a/vlib/net/urllib/urllib.v +++ b/vlib/net/urllib/urllib.v @@ -574,8 +574,7 @@ fn parse_host(host string) !string { } mut colon_port := host[i + 1..] if !valid_optional_port(colon_port) { - return error(error_msg('parse_host: invalid port ${colon_port} after host ', - '')) + return error(error_msg('parse_host: invalid port ${colon_port} after host ', '')) } // RFC 6874 defines that %25 (%-encoded percent) introduces // the zone identifier, and the zone identifier can use basically @@ -594,8 +593,7 @@ fn parse_host(host string) !string { if i != -1 { colon_port := host[i..] if !valid_optional_port(colon_port) { - return error(error_msg('parse_host: invalid port ${colon_port} after host ', - '')) + return error(error_msg('parse_host: invalid port ${colon_port} after host ', '')) } } } diff --git a/vlib/net/urllib/urllib_test.v b/vlib/net/urllib/urllib_test.v index 279cf47793..cba5b6cba1 100644 --- a/vlib/net/urllib/urllib_test.v +++ b/vlib/net/urllib/urllib_test.v @@ -34,7 +34,8 @@ fn test_parse_query() { } fn test_parse_query_orders() { - query_one := urllib.parse_query('https://someapi.com/endpoint?gamma=zalibaba&tau=1&alpha=alibaba&signature=alibaba123')! + query_one := + urllib.parse_query('https://someapi.com/endpoint?gamma=zalibaba&tau=1&alpha=alibaba&signature=alibaba123')! qvalues := query_one.values() assert qvalues == ['zalibaba', '1', 'alibaba', 'alibaba123'] } @@ -118,7 +119,8 @@ fn test_parse() { && user.password == 'pass' } - v := urllib.parse('https://vip.ffzy-online4.com/20230205/6094_d2720761/index.m3u8')!.resolve_reference(urllib.parse('2000k/hls/mixed.m3u8')!)! + v := + urllib.parse('https://vip.ffzy-online4.com/20230205/6094_d2720761/index.m3u8')!.resolve_reference(urllib.parse('2000k/hls/mixed.m3u8')!)! assert v.str() == 'https://vip.ffzy-online4.com/20230205/6094_d2720761/2000k/hls/mixed.m3u8' } diff --git a/vlib/net/websocket/handshake.v b/vlib/net/websocket/handshake.v index 8886b7a03f..3af49c8913 100644 --- a/vlib/net/websocket/handshake.v +++ b/vlib/net/websocket/handshake.v @@ -50,12 +50,10 @@ fn (mut s Server) parse_client_handshake(client_handshake string, mut c Client) return error_with_code('unexpected get operation, ${get_tokens}', 1) } if get_tokens[0].trim_space() != 'GET' { - return error_with_code("unexpected request '${get_tokens[0]}', expected 'GET'", - 2) + return error_with_code("unexpected request '${get_tokens[0]}', expected 'GET'", 2) } if get_tokens[2].trim_space() != 'HTTP/1.1' { - return error_with_code("unexpected request ${get_tokens}, expected 'HTTP/1.1'", - 3) + return error_with_code("unexpected request ${get_tokens}, expected 'HTTP/1.1'", 3) } mut seckey := '' mut flags := []Flag{} @@ -132,8 +130,7 @@ fn (mut ws Client) check_handshake_response(handshake_response string, seckey st lines := handshake_response.split_into_lines() header := lines[0] if !header.starts_with('HTTP/1.1 101') && !header.starts_with('HTTP/1.0 101') { - return error_with_code('handshake_handler: invalid HTTP status response code, ${header}', - 6) + return error_with_code('handshake_handler: invalid HTTP status response code, ${header}', 6) } for i in 1 .. lines.len { if lines[i].len <= 0 || lines[i] == '\r\n' { diff --git a/vlib/orm/orm.v b/vlib/orm/orm.v index 84bf84bba9..243af2446f 100644 --- a/vlib/orm/orm.v +++ b/vlib/orm/orm.v @@ -459,7 +459,8 @@ fn trim_attr_arg(arg string) string { fn tenant_filter_array_primitive_type[T](value []T) int { if value.len > 0 { - return tenant_filter_primitive_type(Primitive(value[0])) + first := value[0] + return tenant_filter_primitive_type(Primitive(first)) } return type_idx['int'] } diff --git a/vlib/orm/orm_fn_test.v b/vlib/orm/orm_fn_test.v index e67e7013d4..1c9001ec7d 100644 --- a/vlib/orm/orm_fn_test.v +++ b/vlib/orm/orm_fn_test.v @@ -67,8 +67,8 @@ fn test_orm_stmt_gen_h2_insert_default_values() { table := orm.Table{ name: 'Test' } - query, _ := orm.orm_stmt_gen(.h2, table, '"', .insert, false, '?', 1, orm.QueryData{}, - orm.QueryData{}) + query, _ := + orm.orm_stmt_gen(.h2, table, '"', .insert, false, '?', 1, orm.QueryData{}, orm.QueryData{}) assert query == 'INSERT INTO "Test" DEFAULT VALUES;' } diff --git a/vlib/orm/orm_func.v b/vlib/orm/orm_func.v index 2768b6b883..6651f9f9ed 100644 --- a/vlib/orm/orm_func.v +++ b/vlib/orm/orm_func.v @@ -319,8 +319,8 @@ fn (qb_ &QueryBuilder[T]) parse_conditions(conds string, params []Primitive) ! { current_is_and = false state = .field } else { - parse_error('${@FN}(): unexpected `${tok}`, maybe `AND`,`OR`', s.last_tok_start, - conds)! + parse_error('${@FN}(): unexpected `${tok}`, maybe `AND`,`OR`', + s.last_tok_start, conds)! } } } diff --git a/vlib/orm/orm_func_test.v b/vlib/orm/orm_func_test.v index 43f721b392..b59789d318 100644 --- a/vlib/orm/orm_func_test.v +++ b/vlib/orm/orm_func_test.v @@ -83,8 +83,8 @@ fn test_orm_func_where() { // and_or_combination qb.reset() - qb.where('name = ? AND status = ? OR role = ? || id = ? && title = ?', 'Alice', 1, - 'admin', 1, 'st')! + qb.where('name = ? AND status = ? OR role = ? || id = ? && title = ?', 'Alice', 1, 'admin', 1, + 'st')! assert qb.where.fields == ['name', 'status', 'role', 'id', 'title'] assert qb.where.kinds == [.eq, .eq, .eq, .eq, .eq] assert qb.where.is_and == [true, false, false, true] diff --git a/vlib/orm/orm_mut_connection_test.v b/vlib/orm/orm_mut_connection_test.v index 14cb2a2f2a..ab038045b2 100644 --- a/vlib/orm/orm_mut_connection_test.v +++ b/vlib/orm/orm_mut_connection_test.v @@ -32,8 +32,7 @@ fn (mut db Database) insert(table orm.Table, data orm.QueryData) ! { // update is used internally by V's ORM for processing `UPDATE` queries fn (mut db Database) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! { - mut query, _ := orm.orm_stmt_gen(.sqlite, table, '', .update, true, ':', 1, data, - where) + mut query, _ := orm.orm_stmt_gen(.sqlite, table, '', .update, true, ':', 1, data, where) db.query(query)! } @@ -66,8 +65,9 @@ fn sqlite_type_from_v(typ int) !string { // create is used internally by V's ORM for processing table creation queries (DDL) fn (mut db Database) create(table orm.Table, fields []orm.TableField) ! { - mut query := orm.orm_table_gen(.sqlite, table, '', true, 0, fields, sqlite_type_from_v, - false) or { return err } + mut query := orm.orm_table_gen(.sqlite, table, '', true, 0, fields, sqlite_type_from_v, false) or { + return err + } db.query(query)! } diff --git a/vlib/orm/orm_null_test.v b/vlib/orm/orm_null_test.v index 90a7e835fb..60ee97122a 100644 --- a/vlib/orm/orm_null_test.v +++ b/vlib/orm/orm_null_test.v @@ -32,8 +32,8 @@ fn (db MockDB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que fn (db MockDB) insert(table orm.Table, data orm.QueryData) ! { mut st := db.st - last, qdata := orm.orm_stmt_gen(.sqlite, table, '`', .insert, false, '?', 1, data, - orm.QueryData{}) + last, qdata := + orm.orm_stmt_gen(.sqlite, table, '`', .insert, false, '?', 1, data, orm.QueryData{}) st.last = last st.data = qdata.data st.where = []orm.Primitive{} @@ -83,8 +83,7 @@ fn mock_type_from_v(typ int) !string { fn (db MockDB) create(table orm.Table, fields []orm.TableField) ! { mut st := db.st - st.last = orm.orm_table_gen(.sqlite, table, '`', true, 0, fields, mock_type_from_v, - false)! + st.last = orm.orm_table_gen(.sqlite, table, '`', true, 0, fields, mock_type_from_v, false)! return db.db.create(table, fields) } diff --git a/vlib/os/dir_expansions_test.v b/vlib/os/dir_expansions_test.v index 3b548e8a98..2651fcb01f 100644 --- a/vlib/os/dir_expansions_test.v +++ b/vlib/os/dir_expansions_test.v @@ -39,8 +39,7 @@ fn test_expand_tilde_to_home() { os.setenv('USERPROFILE', r'\tmp\home\folder', true) home_test := os.join_path(os.home_dir(), 'test', 'tilde', 'expansion') - home_expansion_test := os.expand_tilde_to_home(os.join_path('~', 'test', 'tilde', - 'expansion')) + home_expansion_test := os.expand_tilde_to_home(os.join_path('~', 'test', 'tilde', 'expansion')) assert home_test == home_expansion_test assert os.expand_tilde_to_home('~') == os.home_dir() } diff --git a/vlib/os/filelock/lib_nix.c.v b/vlib/os/filelock/lib_nix.c.v index 054af13122..95007f75f9 100644 --- a/vlib/os/filelock/lib_nix.c.v +++ b/vlib/os/filelock/lib_nix.c.v @@ -32,8 +32,7 @@ fn open_existing_file(path string, mode LockMode) int { fn (l &FileLock) lock_fd(fd int, immediate bool) bool { if l.target == .file { - return C.v_filelock_lock(fd, int(l.mode == .exclusive), int(immediate), l.start, - l.len) == 0 + return C.v_filelock_lock(fd, int(l.mode == .exclusive), int(immediate), l.start, l.len) == 0 } flags := if immediate { C.LOCK_EX | C.LOCK_NB } else { C.LOCK_EX } return C.flock(fd, flags) == 0 diff --git a/vlib/os/filelock/lib_windows.c.v b/vlib/os/filelock/lib_windows.c.v index 70758d5c26..c877c2e12b 100644 --- a/vlib/os/filelock/lib_windows.c.v +++ b/vlib/os/filelock/lib_windows.c.v @@ -26,8 +26,8 @@ fn open_existing_file(path string, mode LockMode) i64 { path_wide := path.to_wide() access := if mode == .shared { C.GENERIC_READ } else { C.GENERIC_READ | C.GENERIC_WRITE } share_mode := C.FILE_SHARE_READ | C.FILE_SHARE_WRITE | C.FILE_SHARE_DELETE - handle := C.CreateFileW(path_wide, access, share_mode, 0, C.OPEN_EXISTING, C.FILE_ATTRIBUTE_NORMAL, - 0) + handle := C.CreateFileW(path_wide, access, share_mode, 0, C.OPEN_EXISTING, + C.FILE_ATTRIBUTE_NORMAL, 0) return file_handle(handle) } @@ -39,8 +39,7 @@ fn (l &FileLock) lock_handle(handle voidptr, immediate bool) bool { if l.target != .file { return true } - return C.v_filelock_lock(handle, int(l.mode == .exclusive), int(immediate), l.start, - l.len) == 0 + return C.v_filelock_lock(handle, int(l.mode == .exclusive), int(immediate), l.start, l.len) == 0 } fn (mut l FileLock) close_lock() { diff --git a/vlib/os/os.c.v b/vlib/os/os.c.v index 3c9d703d3b..180d85bd7d 100644 --- a/vlib/os/os.c.v +++ b/vlib/os/os.c.v @@ -241,7 +241,8 @@ pub fn rename_dir(src string, dst string) ! { pub fn rename(src string, dst string) ! { mut rdst := dst if is_dir(rdst) { - rdst = join_path_single(rdst.trim_right(path_separator), file_name(src.trim_right(path_separator))) + rdst = join_path_single(rdst.trim_right(path_separator), + file_name(src.trim_right(path_separator))) } $if windows { w_src := src.replace('/', '\\') @@ -935,8 +936,7 @@ pub fn real_path(fpath string) string { if file != voidptr(-1) { defer { C.CloseHandle(file) } // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew - final_len := C.GetFinalPathNameByHandleW(file, pu16_fullpath, max_path_buffer_size, - 0) + final_len := C.GetFinalPathNameByHandleW(file, pu16_fullpath, max_path_buffer_size, 0) if final_len < u32(max_path_buffer_size) && final_len != 0 { rt := unsafe { string_from_wide2(pu16_fullpath, int(final_len)) } srt := rt[4..] diff --git a/vlib/os/os_test.c.v b/vlib/os/os_test.c.v index c0e168c603..bfc3a071d3 100644 --- a/vlib/os/os_test.c.v +++ b/vlib/os/os_test.c.v @@ -1033,7 +1033,8 @@ fn test_execute_with_stderr_redirection() { assert result.output.contains('unknown command `wrong_command`') stderr_path := os.join_path_single(tfolder, 'stderr.txt') - result2 := os.execute('${os.quoted_path(@VEXE)} wrong_command 2> ${os.quoted_path(stderr_path)}') + result2 := + os.execute('${os.quoted_path(@VEXE)} wrong_command 2> ${os.quoted_path(stderr_path)}') assert result2.exit_code == 1 assert result2.output == '' assert os.exists(stderr_path) @@ -1055,7 +1056,8 @@ fn test_execute_pipe_into_vfmt() { defer { os.rm(producer_script) or {} } - result := os.execute('${os.quoted_path(@VEXE)} run ${os.quoted_path(producer_script)} | ${os.quoted_path(@VEXE)} fmt') + result := + os.execute('${os.quoted_path(@VEXE)} run ${os.quoted_path(producer_script)} | ${os.quoted_path(@VEXE)} fmt') assert result.exit_code == 0, result.output assert result.output == 'fn main() {\n\tprintln(1)\n}\n' } diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index 94b9abb400..f9f2753aeb 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -346,8 +346,7 @@ pub fn raw_execute(cmd string) Result { output: 'exec failed (CreatePipe): ${error_msg}' } } - set_handle_info_ok := C.SetHandleInformation(child_stdout_read, C.HANDLE_FLAG_INHERIT, - 0) + set_handle_info_ok := C.SetHandleInformation(child_stdout_read, C.HANDLE_FLAG_INHERIT, 0) if !set_handle_info_ok { error_num := int(C.GetLastError()) error_msg := get_error_msg(error_num) @@ -380,8 +379,8 @@ pub fn raw_execute(cmd string) Result { } command_line := [32768]u16{} C.ExpandEnvironmentStringsW(pcmd.to_wide(), voidptr(&command_line), 32768) - create_process_ok := C.CreateProcessW(0, &command_line[0], 0, 0, C.TRUE, C.CREATE_NO_WINDOW, - 0, 0, voidptr(&start_info), voidptr(&proc_info)) + create_process_ok := C.CreateProcessW(0, &command_line[0], 0, 0, C.TRUE, C.CREATE_NO_WINDOW, 0, + 0, voidptr(&start_info), voidptr(&proc_info)) if !create_process_ok { error_num := int(C.GetLastError()) error_msg := get_error_msg(error_num) @@ -398,8 +397,7 @@ pub fn raw_execute(cmd string) Result { for { mut result := false unsafe { - result = C.ReadFile(child_stdout_read, &buf[0], 1000, voidptr(&bytes_read), - 0) + result = C.ReadFile(child_stdout_read, &buf[0], 1000, voidptr(&bytes_read), 0) read_data.write_ptr(&buf[0], int(bytes_read)) } if result == false || int(bytes_read) == 0 { @@ -515,7 +513,8 @@ pub fn add_vectored_exception_handler(first bool, handler VectoredExceptionHandl pub fn uname() Uname { nodename := hostname() or { '' } // ToDO: environment variables have low reliability; check for another quick way - machine := getenv('PROCESSOR_ARCHITECTURE') // * note: 'AMD64' == 'x86_64' (not standardized, but 'x86_64' use is more common; but, python == 'AMD64') + machine := + getenv('PROCESSOR_ARCHITECTURE') // * note: 'AMD64' == 'x86_64' (not standardized, but 'x86_64' use is more common; but, python == 'AMD64') version_info := execute('cmd /d/c ver').output version_n := (version_info.split(' '))[3].replace(']', '').trim_space() return Uname{ @@ -632,11 +631,11 @@ pub fn disk_usage(path string) !DiskUsage { mut available := u64(0) mut ret := false if path == '.' || path == '' { - ret = C.GetDiskFreeSpaceExA(&char(unsafe { nil }), &free_bytes_available_to_caller, - &total, &available) + ret = C.GetDiskFreeSpaceExA(&char(unsafe { nil }), &free_bytes_available_to_caller, &total, + &available) } else { - ret = C.GetDiskFreeSpaceExA(&char(path.str), &free_bytes_available_to_caller, - &total, &available) + ret = C.GetDiskFreeSpaceExA(&char(path.str), &free_bytes_available_to_caller, &total, + &available) } if ret == false { return error('cannot get disk usage of path') diff --git a/vlib/os/process_args_test.v b/vlib/os/process_args_test.v index 324c700d57..3f6af05562 100644 --- a/vlib/os/process_args_test.v +++ b/vlib/os/process_args_test.v @@ -29,7 +29,8 @@ fn test_v_run_file_from_path_with_spaces() { os.rmdir_all(spaced_dir) or {} } os.cp(echo_os_args, spaced_echo_os_args)! - res := os.execute('${os.quoted_path(vexe)} run ${os.quoted_path(spaced_echo_os_args)} 1 "Learn V" 3') + res := + os.execute('${os.quoted_path(vexe)} run ${os.quoted_path(spaced_echo_os_args)} 1 "Learn V" 3') println(res) assert res.exit_code == 0 assert res.output.starts_with("['1', 'Learn V', '3']") diff --git a/vlib/os/process_windows.c.v b/vlib/os/process_windows.c.v index 7642b117f5..920b818cc8 100644 --- a/vlib/os/process_windows.c.v +++ b/vlib/os/process_windows.c.v @@ -63,7 +63,8 @@ fn (mut p Process) win_spawn_process() int { } unsafe { to_be_freed.free() } } - p.filename = abs_path(p.filename) // expand the path to an absolute one, in case we later change the working folder + p.filename = + abs_path(p.filename) // expand the path to an absolute one, in case we later change the working folder mut wdata := &WProcess{ child_stdin_read: unsafe { nil } child_stdin_write: unsafe { nil } @@ -85,23 +86,23 @@ fn (mut p Process) win_spawn_process() int { sa.n_length = sizeof(C.SECURITY_ATTRIBUTES) sa.b_inherit_handle = true - create_pipe_ok0 := C.CreatePipe(voidptr(&wdata.child_stdin_read), voidptr(&wdata.child_stdin_write), - voidptr(&sa), 65536) + create_pipe_ok0 := C.CreatePipe(voidptr(&wdata.child_stdin_read), + voidptr(&wdata.child_stdin_write), voidptr(&sa), 65536) failed_cfn_report_error(create_pipe_ok0, 'CreatePipe stdin') - set_handle_info_ok0 := C.SetHandleInformation(wdata.child_stdin_write, C.HANDLE_FLAG_INHERIT, - 0) + set_handle_info_ok0 := C.SetHandleInformation(wdata.child_stdin_write, + C.HANDLE_FLAG_INHERIT, 0) failed_cfn_report_error(set_handle_info_ok0, 'SetHandleInformation') - create_pipe_ok1 := C.CreatePipe(voidptr(&wdata.child_stdout_read), voidptr(&wdata.child_stdout_write), - voidptr(&sa), 65536) + create_pipe_ok1 := C.CreatePipe(voidptr(&wdata.child_stdout_read), + voidptr(&wdata.child_stdout_write), voidptr(&sa), 65536) failed_cfn_report_error(create_pipe_ok1, 'CreatePipe stdout') - set_handle_info_ok1 := C.SetHandleInformation(wdata.child_stdout_read, C.HANDLE_FLAG_INHERIT, - 0) + set_handle_info_ok1 := C.SetHandleInformation(wdata.child_stdout_read, + C.HANDLE_FLAG_INHERIT, 0) failed_cfn_report_error(set_handle_info_ok1, 'SetHandleInformation') - create_pipe_ok2 := C.CreatePipe(voidptr(&wdata.child_stderr_read), voidptr(&wdata.child_stderr_write), - voidptr(&sa), 65536) + create_pipe_ok2 := C.CreatePipe(voidptr(&wdata.child_stderr_read), + voidptr(&wdata.child_stderr_write), voidptr(&sa), 65536) failed_cfn_report_error(create_pipe_ok2, 'CreatePipe stderr') - set_handle_info_ok2 := C.SetHandleInformation(wdata.child_stderr_read, C.HANDLE_FLAG_INHERIT, - 0) + set_handle_info_ok2 := C.SetHandleInformation(wdata.child_stderr_read, + C.HANDLE_FLAG_INHERIT, 0) failed_cfn_report_error(set_handle_info_ok2, 'SetHandleInformation stderr') start_info.h_std_input = wdata.child_stdin_read start_info.h_std_output = wdata.child_stdout_write diff --git a/vlib/picoev/loop_freebsd.c.v b/vlib/picoev/loop_freebsd.c.v index 5372dbe775..adc1596e5e 100644 --- a/vlib/picoev/loop_freebsd.c.v +++ b/vlib/picoev/loop_freebsd.c.v @@ -60,8 +60,7 @@ pub fn (mut pv Picoev) ev_set(index int, operation int, events int) { } filter = i16(filter) - C.EV_SET(&pv.loop.changelist[index], pv.loop.changed_fds, filter, operation, 0, 0, - 0) + C.EV_SET(&pv.loop.changelist[index], pv.loop.changed_fds, filter, operation, 0, 0, 0) } // backend_build uses the lower 8 bits to store the old events and the higher 8 @@ -103,8 +102,7 @@ fn (mut pv Picoev) apply_pending_changes(apply_all bool) int { } // Apply the changes if the total changes exceed the changelist size if total + 1 >= pv.loop.changelist.len { - nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, C.NULL, - 0, C.NULL) + nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, C.NULL, 0, C.NULL) assert nevents == 0 total = 0 } @@ -168,8 +166,8 @@ fn (mut pv Picoev) poll_once(max_wait_in_sec int) int { // apply changes later when the callback is called. total = pv.apply_pending_changes(false) - nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, &pv.loop.events, pv.loop.events.len, - &ts) + nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, &pv.loop.events, + pv.loop.events.len, &ts) if nevents == -1 { // the errors we can only rescue assert C.errno == C.EACCES || C.errno == C.EFAULT || C.errno == C.EINTR diff --git a/vlib/picoev/loop_macos.c.v b/vlib/picoev/loop_macos.c.v index a66503127c..7c9b990355 100644 --- a/vlib/picoev/loop_macos.c.v +++ b/vlib/picoev/loop_macos.c.v @@ -60,8 +60,7 @@ pub fn (mut pv Picoev) ev_set(index int, operation int, events int) { } filter = i16(filter) - C.EV_SET(&pv.loop.changelist[index], pv.loop.changed_fds, filter, operation, 0, 0, - 0) + C.EV_SET(&pv.loop.changelist[index], pv.loop.changed_fds, filter, operation, 0, 0, 0) } // backend_build uses the lower 8 bits to store the old events and the higher 8 @@ -103,8 +102,7 @@ fn (mut pv Picoev) apply_pending_changes(apply_all bool) int { } // Apply the changes if the total changes exceed the changelist size if total + 1 >= pv.loop.changelist.len { - nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, C.NULL, - 0, C.NULL) + nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, C.NULL, 0, C.NULL) assert nevents == 0 total = 0 } @@ -170,8 +168,8 @@ fn (mut pv Picoev) poll_once(max_wait_in_sec int) int { // apply changes later when the callback is called. total = pv.apply_pending_changes(false) - nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, &pv.loop.events, pv.loop.events.len, - &ts) + nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, &pv.loop.events, + pv.loop.events.len, &ts) if nevents == -1 { // the errors we can only rescue assert C.errno == C.EACCES || C.errno == C.EFAULT || C.errno == C.EINTR diff --git a/vlib/picoev/loop_openbsd.c.v b/vlib/picoev/loop_openbsd.c.v index 571c43f1d9..6aa2732f05 100644 --- a/vlib/picoev/loop_openbsd.c.v +++ b/vlib/picoev/loop_openbsd.c.v @@ -60,8 +60,7 @@ pub fn (mut pv Picoev) ev_set(index int, operation int, events int) { } filter = i16(filter) - C.EV_SET(&pv.loop.changelist[index], pv.loop.changed_fds, filter, operation, 0, 0, - 0) + C.EV_SET(&pv.loop.changelist[index], pv.loop.changed_fds, filter, operation, 0, 0, 0) } // backend_build uses the lower 8 bits to store the old events and the higher 8 @@ -103,8 +102,7 @@ fn (mut pv Picoev) apply_pending_changes(apply_all bool) int { } // Apply the changes if the total changes exceed the changelist size if total + 1 >= pv.loop.changelist.len { - nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, C.NULL, - 0, C.NULL) + nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, C.NULL, 0, C.NULL) assert nevents == 0 total = 0 } @@ -168,8 +166,8 @@ fn (mut pv Picoev) poll_once(max_wait_in_sec int) int { // apply changes later when the callback is called. total = pv.apply_pending_changes(false) - nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, &pv.loop.events, pv.loop.events.len, - &ts) + nevents = C.kevent(pv.loop.kq_id, &pv.loop.changelist, total, &pv.loop.events, + pv.loop.events.len, &ts) if nevents == -1 { // the errors we can only rescue assert C.errno == C.EACCES || C.errno == C.EFAULT || C.errno == C.EINTR diff --git a/vlib/picoev/socket_util.c.v b/vlib/picoev/socket_util.c.v index 1185922da6..c344e34fae 100644 --- a/vlib/picoev/socket_util.c.v +++ b/vlib/picoev/socket_util.c.v @@ -109,8 +109,8 @@ fn listen(config Config) !int { net.socket_error(C.setsockopt(fd, C.SOL_SOCKET, C.SO_REUSEPORT, &flag, sizeof(int)))! net.socket_error(C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_QUICKACK, &flag, sizeof(int)))! $if !support_wsl1 ? { - net.socket_error(C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_DEFER_ACCEPT, &config.timeout_secs, - sizeof(int)))! + net.socket_error(C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_DEFER_ACCEPT, + &config.timeout_secs, sizeof(int)))! queue_len := max_queue net.socket_error(C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_FASTOPEN, &queue_len, sizeof(int)))! @@ -124,7 +124,8 @@ fn listen(config Config) !int { addr := addrs[0] alen := addr.len() net.socket_error_message(C.bind(fd, voidptr(&addr), alen), 'binding to ${saddr} failed')! - net.socket_error_message(C.listen(fd, C.SOMAXCONN), 'listening on ${saddr} with maximum backlog pending queue of ${C.SOMAXCONN}, failed')! + net.socket_error_message(C.listen(fd, C.SOMAXCONN), + 'listening on ${saddr} with maximum backlog pending queue of ${C.SOMAXCONN}, failed')! setup_sock(fd) or { config.err_cb(config.user_data, picohttpparser.Request{}, mut &picohttpparser.Response{}, err) diff --git a/vlib/regex/pcre/regex.v b/vlib/regex/pcre/regex.v index 033c958fee..ed0e0de24a 100644 --- a/vlib/regex/pcre/regex.v +++ b/vlib/regex/pcre/regex.v @@ -243,8 +243,7 @@ pub fn compile(pattern string) !Regex { initial_flags := Flags{false, false, false} // Phase 1: AST Parsing - nodes, _, final_group_count := parse_nodes(pattern, 0, `\0`, 0, initial_flags, mut - group_map)! + nodes, _, final_group_count := parse_nodes(pattern, 0, `\0`, 0, initial_flags, mut group_map)! root := Node{ typ: .group diff --git a/vlib/regex/regex.v b/vlib/regex/regex.v index e8e8c04f04..5a7c8bf9dc 100644 --- a/vlib/regex/regex.v +++ b/vlib/regex/regex.v @@ -77,7 +77,7 @@ General Utilities // utf8util_char_len calculate the length in bytes of a utf8 char @[inline] fn utf8util_char_len(b u8) int { - return ((0xe5000000 >> ((b >> 3) & 0x1e)) & 3) + 1 + return int(((u32(0xe5000000) >> ((b >> 3) & 0x1e)) & 3) + 1) } // get_char get a char from position i and return an u32 with the unicode code @@ -1104,8 +1104,7 @@ fn (mut re RE) impl_compile(in_txt string) (int, int) { return err_groups_max_nested, i + 1 } - tmp_res, cgroup_flag, negate_flag, cgroup_name, next_i := re.parse_groups(in_txt, - i) + tmp_res, cgroup_flag, negate_flag, cgroup_name, next_i := re.parse_groups(in_txt, i) // manage question mark format error if tmp_res < -1 { diff --git a/vlib/sokol/memory/memory.c.v b/vlib/sokol/memory/memory.c.v index 29667fb840..fc5fcf876f 100644 --- a/vlib/sokol/memory/memory.c.v +++ b/vlib/sokol/memory/memory.c.v @@ -33,7 +33,8 @@ fn C.SOKOL_LOG(const_message &char) pub fn slog(const_tag &char, log_level u32, log_item_id u32, const_message_or_null &char, line_nr u32, const_filename_or_null &char, user_data voidptr) { - C.fprintf(C.stderr, c'sokol.memory.slog | user_data: %p, const_tag: %s, level: %d, item_id: %d, fname: %s, line: %d, message: %s\n', + C.fprintf(C.stderr, + c'sokol.memory.slog | user_data: %p, const_tag: %s, level: %d, item_id: %d, fname: %s, line: %d, message: %s\n', user_data, const_tag, log_level, log_item_id, const_filename_or_null, line_nr, const_message_or_null) } diff --git a/vlib/sokol/sapp/sapp.c.v b/vlib/sokol/sapp/sapp.c.v index 403d41f76c..0581b42d3e 100644 --- a/vlib/sokol/sapp/sapp.c.v +++ b/vlib/sokol/sapp/sapp.c.v @@ -273,6 +273,18 @@ pub fn gl_get_framebuffer() u32 { return C.sapp_gl_get_framebuffer() } +// X11: get display handle +@[inline] +pub fn x11_get_display() voidptr { + return voidptr(C.sapp_x11_get_display()) +} + +// X11: get window handle +@[inline] +pub fn x11_get_window() voidptr { + return voidptr(C.sapp_x11_get_window()) +} + // Android: get native activity handle @[inline] pub fn android_get_native_activity() voidptr { diff --git a/vlib/sokol/sapp/sapp_egl_linux.v b/vlib/sokol/sapp/sapp_egl_linux.v index 2d1d7e7a47..e1776269ca 100644 --- a/vlib/sokol/sapp/sapp_egl_linux.v +++ b/vlib/sokol/sapp/sapp_egl_linux.v @@ -112,8 +112,8 @@ fn sapp_egl_create_surface(native_window voidptr) { } fn sapp_egl_make_current() { - if C.eglMakeCurrent(g_sapp_state.egl.display, g_sapp_state.egl.surface, g_sapp_state.egl.surface, - g_sapp_state.egl.context) == 0 { + if C.eglMakeCurrent(g_sapp_state.egl.display, g_sapp_state.egl.surface, + g_sapp_state.egl.surface, g_sapp_state.egl.context) == 0 { eprintln('sokol_app: EGL: eglMakeCurrent failed') } mut fb := i32(0) @@ -172,8 +172,8 @@ fn sapp_egl_init_x11() { visual_info_template.visualid = VisualID(visual_id) mut num_visuals := 0 - visual_info := C.XGetVisualInfo(g_sapp_state.x11.display, visual_id_mask, &visual_info_template, - &num_visuals) + visual_info := C.XGetVisualInfo(g_sapp_state.x11.display, visual_id_mask, + &visual_info_template, &num_visuals) if visual_info == unsafe { nil } { eprintln('sokol_app: EGL: failed to get visual info') } diff --git a/vlib/sokol/sapp/sapp_state_linux.v b/vlib/sokol/sapp/sapp_state_linux.v index de557a95bd..301506fd5e 100644 --- a/vlib/sokol/sapp/sapp_state_linux.v +++ b/vlib/sokol/sapp/sapp_state_linux.v @@ -346,7 +346,9 @@ fn sapp_init_state(desc &Desc) { g_sapp_state.clipboard.enabled = g_sapp_state.desc.enable_clipboard if g_sapp_state.clipboard.enabled { g_sapp_state.clipboard.buf_size = g_sapp_state.desc.clipboard_size - g_sapp_state.clipboard.buffer = unsafe { &char(C.calloc(1, usize(g_sapp_state.clipboard.buf_size))) } + g_sapp_state.clipboard.buffer = unsafe { + &char(C.calloc(1, usize(g_sapp_state.clipboard.buf_size))) + } } g_sapp_state.drop.enabled = g_sapp_state.desc.enable_dragndrop if g_sapp_state.drop.enabled { diff --git a/vlib/sokol/sapp/sapp_wayland_linux.v b/vlib/sokol/sapp/sapp_wayland_linux.v index 5e89392d11..8b6034ece1 100644 --- a/vlib/sokol/sapp/sapp_wayland_linux.v +++ b/vlib/sokol/sapp/sapp_wayland_linux.v @@ -310,7 +310,8 @@ $if sokol_wayland ? { if g_sapp_state.wl.key_repeat_timer_fd >= 0 { C.close(g_sapp_state.wl.key_repeat_timer_fd) } - g_sapp_state.wl.key_repeat_timer_fd = C.timerfd_create(clock_monotonic, tfd_cloexec | tfd_nonblock) + g_sapp_state.wl.key_repeat_timer_fd = C.timerfd_create(clock_monotonic, + tfd_cloexec | tfd_nonblock) } fn wl_start_key_repeat(scancode u32) { @@ -355,7 +356,8 @@ $if sokol_wayland ? { if g_sapp_state.wl.xkb_state == unsafe { nil } { return } - keysym := C.xkb_state_key_get_one_sym(g_sapp_state.wl.xkb_state, g_sapp_state.wl.key_repeat_keycode) + keysym := C.xkb_state_key_get_one_sym(g_sapp_state.wl.xkb_state, + g_sapp_state.wl.key_repeat_keycode) sapp_key := wl_translate_key(keysym) if sapp_key != .invalid { @@ -367,8 +369,8 @@ $if sokol_wayland ? { } mut buf := [8]u8{} - count := C.xkb_state_key_get_utf8(g_sapp_state.wl.xkb_state, g_sapp_state.wl.key_repeat_keycode, - &char(&buf[0]), usize(buf.len)) + count := C.xkb_state_key_get_utf8(g_sapp_state.wl.xkb_state, + g_sapp_state.wl.key_repeat_keycode, &char(&buf[0]), usize(buf.len)) if count > 0 && count < buf.len { codepoint := utf8_decode(&buf[0], count) if codepoint > 0 && codepoint < 0x110000 { @@ -600,10 +602,10 @@ $if sokol_wayland ? { } if g_sapp_state.wl.data_device_manager != unsafe { nil } && g_sapp_state.wl.data_device == unsafe { nil } { - g_sapp_state.wl.data_device = C.wl_data_device_manager_get_data_device(g_sapp_state.wl.data_device_manager, - seat) - C.wl_data_device_add_listener(g_sapp_state.wl.data_device, &wl_data_device_listener, - unsafe { nil }) + g_sapp_state.wl.data_device = + C.wl_data_device_manager_get_data_device(g_sapp_state.wl.data_device_manager, seat) + C.wl_data_device_add_listener(g_sapp_state.wl.data_device, + &wl_data_device_listener, unsafe { nil }) } } else if (caps & wl_seat_capability_pointer) == 0 && g_sapp_state.wl.pointer != unsafe { nil } { @@ -640,18 +642,18 @@ $if sokol_wayland ? { fn wl_registry_handle_global(data voidptr, registry &C.wl_registry, name u32, iface &char, version u32) { unsafe { if C.strcmp(iface, c'wl_compositor') == 0 { - g_sapp_state.wl.compositor = &C.wl_compositor(C.wl_registry_bind(registry, - name, &C.wl_compositor_interface, 4)) + g_sapp_state.wl.compositor = &C.wl_compositor(C.wl_registry_bind(registry, name, + &C.wl_compositor_interface, 4)) } else if C.strcmp(iface, c'xdg_wm_base') == 0 { - g_sapp_state.wl.xdg_wm_base = &C.xdg_wm_base(C.wl_registry_bind(registry, - name, &C.xdg_wm_base_interface, 1)) + g_sapp_state.wl.xdg_wm_base = &C.xdg_wm_base(C.wl_registry_bind(registry, name, + &C.xdg_wm_base_interface, 1)) } else if C.strcmp(iface, c'wl_seat') == 0 { - g_sapp_state.wl.seat = &C.wl_seat(C.wl_registry_bind(registry, name, &C.wl_seat_interface, - 5)) + g_sapp_state.wl.seat = &C.wl_seat(C.wl_registry_bind(registry, name, + &C.wl_seat_interface, 5)) C.wl_seat_add_listener(g_sapp_state.wl.seat, &wl_seat_listener, nil) } else if C.strcmp(iface, c'wl_shm') == 0 { - g_sapp_state.wl.shm = &C.wl_shm(C.wl_registry_bind(registry, name, &C.wl_shm_interface, - 1)) + g_sapp_state.wl.shm = &C.wl_shm(C.wl_registry_bind(registry, name, + &C.wl_shm_interface, 1)) } else if C.strcmp(iface, c'wl_data_device_manager') == 0 { g_sapp_state.wl.data_device_manager = &C.wl_data_device_manager(C.wl_registry_bind(registry, name, &C.wl_data_device_manager_interface, 3)) @@ -659,8 +661,8 @@ $if sokol_wayland ? { g_sapp_state.wl.fractional_scale_mgr = &C.wp_fractional_scale_manager_v1(C.wl_registry_bind(registry, name, &C.wp_fractional_scale_manager_v1_interface, 1)) } else if C.strcmp(iface, c'wp_viewporter') == 0 { - g_sapp_state.wl.viewporter = &C.wp_viewporter(C.wl_registry_bind(registry, - name, &C.wp_viewporter_interface, 1)) + g_sapp_state.wl.viewporter = &C.wp_viewporter(C.wl_registry_bind(registry, name, + &C.wp_viewporter_interface, 1)) } else if C.strcmp(iface, c'wp_cursor_shape_manager_v1') == 0 { g_sapp_state.wl.cursor_shape_manager = &C.wp_cursor_shape_manager_v1(C.wl_registry_bind(registry, name, &C.wp_cursor_shape_manager_v1_interface, 1)) @@ -832,7 +834,8 @@ $if sokol_wayland ? { mut buffer := [8192]u8{} mut total_read := isize(0) for { - n := C.read(fds[0], unsafe { &buffer[0] + total_read }, usize(buffer.len - int(total_read) - 1)) + n := C.read(fds[0], unsafe { &buffer[0] + total_read }, usize(buffer.len - + int(total_read) - 1)) if n <= 0 { break } @@ -1030,8 +1033,8 @@ $if sokol_wayland ? { g_sapp_state.wl.fb_height = int(f32(g_sapp_state.wl.height) * g_sapp_state.wl.scale) // Create EGL window - g_sapp_state.wl.egl_window = C.wl_egl_window_create(g_sapp_state.wl.surface, g_sapp_state.wl.fb_width, - g_sapp_state.wl.fb_height) + g_sapp_state.wl.egl_window = C.wl_egl_window_create(g_sapp_state.wl.surface, + g_sapp_state.wl.fb_width, g_sapp_state.wl.fb_height) if g_sapp_state.wl.egl_window == unsafe { nil } { eprintln('sokol_app: failed to create Wayland EGL window') return diff --git a/vlib/sokol/sapp/sapp_x11_linux.v b/vlib/sokol/sapp/sapp_x11_linux.v index 62a5a50b36..3685c84592 100644 --- a/vlib/sokol/sapp/sapp_x11_linux.v +++ b/vlib/sokol/sapp/sapp_x11_linux.v @@ -555,8 +555,8 @@ fn x11_init_extensions() { g_sapp_state.x11.xdnd.text_uri_list = C.XInternAtom(d, c'text/uri-list', x_false) } // Check Xi extension for raw mouse input - if C.XQueryExtension(d, c'XInputExtension', &g_sapp_state.x11.xi.major_opcode, &g_sapp_state.x11.xi.event_base, - &g_sapp_state.x11.xi.error_base) != 0 { + if C.XQueryExtension(d, c'XInputExtension', &g_sapp_state.x11.xi.major_opcode, + &g_sapp_state.x11.xi.event_base, &g_sapp_state.x11.xi.error_base) != 0 { g_sapp_state.x11.xi.major = 2 g_sapp_state.x11.xi.minor = 0 if C.XIQueryVersion(d, &g_sapp_state.x11.xi.major, &g_sapp_state.x11.xi.minor) == 0 { @@ -741,8 +741,7 @@ fn x11_init_keytable() { if desc == unsafe { nil } { return } - C.XkbGetNames(g_sapp_state.x11.display, xkb_key_names_mask | xkb_key_aliases_mask, - desc) + C.XkbGetNames(g_sapp_state.x11.display, xkb_key_names_mask | xkb_key_aliases_mask, desc) scancode_min := int(desc.min_key_code) scancode_max := int(desc.max_key_code) @@ -887,8 +886,8 @@ fn x11_init_keytable() { if key == .invalid && desc.names.key_aliases != unsafe { nil } { for i in 0 .. int(desc.names.num_key_aliases) { if unsafe { - C.strncmp(&char(&desc.names.key_aliases[i].real[0]), &char(&desc.names.keys[scancode].name[0]), - usize(xkb_key_name_length)) + C.strncmp(&char(&desc.names.key_aliases[i].real[0]), + &char(&desc.names.keys[scancode].name[0]), usize(xkb_key_name_length)) } != 0 { continue } @@ -913,8 +912,8 @@ fn x11_init_keytable() { // Fall back using traditional keysym lookup mut width := 0 - keysyms := C.XGetKeyboardMapping(g_sapp_state.x11.display, u8(scancode_min), - scancode_max - scancode_min + 1, &width) + keysyms := C.XGetKeyboardMapping(g_sapp_state.x11.display, u8(scancode_min), scancode_max - + scancode_min + 1, &width) for scancode in scancode_min .. scancode_max + 1 { if g_sapp_state.keycodes[scancode] == .invalid { base := usize((scancode - scancode_min) * width) @@ -991,15 +990,15 @@ fn x11_send_event(msg_type Atom, a i64, b i64, c_ i64, d i64, e i64) { event.xclient.data.l[3] = d event.xclient.data.l[4] = e } - C.XSendEvent(g_sapp_state.x11.display, g_sapp_state.x11.root, x_false, substructure_notify_mask | substructure_redirect_mask, - &event) + C.XSendEvent(g_sapp_state.x11.display, g_sapp_state.x11.root, x_false, + substructure_notify_mask | substructure_redirect_mask, &event) } fn x11_wait_for_event(event_type int, timeout_sec f64, out_event &C.XEvent) bool { // Simple polling loop for { - if C.XCheckTypedWindowEvent(g_sapp_state.x11.display, g_sapp_state.x11.window, - event_type, out_event) != 0 { + if C.XCheckTypedWindowEvent(g_sapp_state.x11.display, g_sapp_state.x11.window, event_type, + out_event) != 0 { return true } mut fd := C.pollfd{ @@ -1035,8 +1034,10 @@ fn x11_update_dimensions(x11_window_width int, x11_window_height int) { g_sapp_state.window_height = x11_roundf_gzero(f32(x11_window_height) / window_scale) cur_fb_width := g_sapp_state.framebuffer_width cur_fb_height := g_sapp_state.framebuffer_height - g_sapp_state.framebuffer_width = x11_roundf_gzero(f32(g_sapp_state.window_width) * g_sapp_state.dpi_scale) - g_sapp_state.framebuffer_height = x11_roundf_gzero(f32(g_sapp_state.window_height) * g_sapp_state.dpi_scale) + g_sapp_state.framebuffer_width = + x11_roundf_gzero(f32(g_sapp_state.window_width) * g_sapp_state.dpi_scale) + g_sapp_state.framebuffer_height = + x11_roundf_gzero(f32(g_sapp_state.window_height) * g_sapp_state.dpi_scale) dim_changed := g_sapp_state.framebuffer_width != cur_fb_width || g_sapp_state.framebuffer_height != cur_fb_height if dim_changed && !g_sapp_state.first_frame { @@ -1091,9 +1092,8 @@ fn x11_create_window(visual_ &C.Visual, depth int) { // wamask = CWBorderPixel | CWColormap | CWEventMask wamask := u64(0x800 | 0x2000 | 0x800) x11_grab_error_handler() - g_sapp_state.x11.window = C.XCreateWindow(g_sapp_state.x11.display, g_sapp_state.x11.root, - 0, 0, u32(x11_window_width), u32(x11_window_height), 0, dep, input_output, vis, - wamask, &wa) + g_sapp_state.x11.window = C.XCreateWindow(g_sapp_state.x11.display, g_sapp_state.x11.root, 0, + 0, u32(x11_window_width), u32(x11_window_height), 0, dep, input_output, vis, wamask, &wa) x11_release_error_handler() if g_sapp_state.x11.window == 0 { eprintln('sokol_app: X11: failed to create window') @@ -1101,8 +1101,7 @@ fn x11_create_window(visual_ &C.Visual, depth int) { } mut protocols := [1]Atom{} protocols[0] = g_sapp_state.x11.wm_delete_window - C.XSetWMProtocols(g_sapp_state.x11.display, g_sapp_state.x11.window, &protocols[0], - 1) + C.XSetWMProtocols(g_sapp_state.x11.display, g_sapp_state.x11.window, &protocols[0], 1) mut hints := C.XAllocSizeHints() hints.flags = pw_gravity hints.win_gravity = center_gravity @@ -1111,8 +1110,9 @@ fn x11_create_window(visual_ &C.Visual, depth int) { // Announce support for drag'n'drop if g_sapp_state.drop.enabled { version := Atom(x11_xdnd_version) - C.XChangeProperty(g_sapp_state.x11.display, g_sapp_state.x11.window, g_sapp_state.x11.xdnd.xdnd_aware, - xa_atom, 32, prop_mode_replace, unsafe { &u8(&version) }, 1) + C.XChangeProperty(g_sapp_state.x11.display, g_sapp_state.x11.window, + g_sapp_state.x11.xdnd.xdnd_aware, xa_atom, 32, prop_mode_replace, + unsafe { &u8(&version) }, 1) } x11_update_window_title() x11_update_dimensions_from_window_size() @@ -1151,12 +1151,12 @@ fn x11_update_window_title() { title := &char(&g_sapp_state.window_title[0]) C.Xutf8SetWMProperties(g_sapp_state.x11.display, g_sapp_state.x11.window, title, title, unsafe { nil }, 0, unsafe { nil }, unsafe { nil }, unsafe { nil }) - C.XChangeProperty(g_sapp_state.x11.display, g_sapp_state.x11.window, g_sapp_state.x11.net_wm_name, - g_sapp_state.x11.utf8_string, 8, prop_mode_replace, &g_sapp_state.window_title[0], - int(C.strlen(title))) - C.XChangeProperty(g_sapp_state.x11.display, g_sapp_state.x11.window, g_sapp_state.x11.net_wm_icon_name, - g_sapp_state.x11.utf8_string, 8, prop_mode_replace, &g_sapp_state.window_title[0], - int(C.strlen(title))) + C.XChangeProperty(g_sapp_state.x11.display, g_sapp_state.x11.window, + g_sapp_state.x11.net_wm_name, g_sapp_state.x11.utf8_string, 8, prop_mode_replace, + &g_sapp_state.window_title[0], int(C.strlen(title))) + C.XChangeProperty(g_sapp_state.x11.display, g_sapp_state.x11.window, + g_sapp_state.x11.net_wm_icon_name, g_sapp_state.x11.utf8_string, 8, prop_mode_replace, + &g_sapp_state.window_title[0], int(C.strlen(title))) C.XFlush(g_sapp_state.x11.display) } @@ -1170,8 +1170,7 @@ fn x11_create_hidden_cursor() { img.xhot = 0 img.yhot = 0 unsafe { C.memset(img.pixels, 0, usize(16 * 16 * 4)) } - g_sapp_state.x11.hidden_cursor = C.XcursorImageLoadCursor(g_sapp_state.x11.display, - img) + g_sapp_state.x11.hidden_cursor = C.XcursorImageLoadCursor(g_sapp_state.x11.display, img) C.XcursorImageDestroy(img) } @@ -1180,8 +1179,8 @@ fn x11_create_standard_cursor(cursor MouseCursor, name &char, theme &char, size if theme != unsafe { nil } { img := C.XcursorLibraryLoadImage(name, theme, size) if img != unsafe { nil } { - g_sapp_state.x11.standard_cursors[idx] = C.XcursorImageLoadCursor(g_sapp_state.x11.display, - img) + g_sapp_state.x11.standard_cursors[idx] = + C.XcursorImageLoadCursor(g_sapp_state.x11.display, img) C.XcursorImageDestroy(img) } } @@ -1235,12 +1234,14 @@ fn x11_update_cursor(cursor MouseCursor, shown bool) { C.XDefineCursor(g_sapp_state.x11.display, g_sapp_state.x11.window, xcursor) } } else if g_sapp_state.x11.standard_cursors[idx] != 0 { - C.XDefineCursor(g_sapp_state.x11.display, g_sapp_state.x11.window, g_sapp_state.x11.standard_cursors[idx]) + C.XDefineCursor(g_sapp_state.x11.display, g_sapp_state.x11.window, + g_sapp_state.x11.standard_cursors[idx]) } else { C.XUndefineCursor(g_sapp_state.x11.display, g_sapp_state.x11.window) } } else { - C.XDefineCursor(g_sapp_state.x11.display, g_sapp_state.x11.window, g_sapp_state.x11.hidden_cursor) + C.XDefineCursor(g_sapp_state.x11.display, g_sapp_state.x11.window, + g_sapp_state.x11.hidden_cursor) } C.XFlush(g_sapp_state.x11.display) } @@ -1264,9 +1265,9 @@ fn x11_lock_mouse(do_lock bool) { xi_set_mask(unsafe { &mask[0] }, xi_raw_motion) C.XISelectEvents(g_sapp_state.x11.display, g_sapp_state.x11.root, &em, 1) } - C.XGrabPointer(g_sapp_state.x11.display, g_sapp_state.x11.window, x_true, u32(button_press_mask | button_release_mask | pointer_motion_mask), - grab_mode_async, grab_mode_async, g_sapp_state.x11.window, g_sapp_state.x11.hidden_cursor, - current_time) + C.XGrabPointer(g_sapp_state.x11.display, g_sapp_state.x11.window, x_true, + u32(button_press_mask | button_release_mask | pointer_motion_mask), grab_mode_async, + grab_mode_async, g_sapp_state.x11.window, g_sapp_state.x11.hidden_cursor, current_time) } else { if g_sapp_state.x11.xi.available { mut em := C.XIEventMask{} @@ -1276,8 +1277,8 @@ fn x11_lock_mouse(do_lock bool) { em.mask = unsafe { &mask[0] } C.XISelectEvents(g_sapp_state.x11.display, g_sapp_state.x11.root, &em, 1) } - C.XWarpPointer(g_sapp_state.x11.display, Window(0), g_sapp_state.x11.window, 0, - 0, 0, 0, int(g_sapp_state.mouse.x), int(g_sapp_state.mouse.y)) + C.XWarpPointer(g_sapp_state.x11.display, Window(0), g_sapp_state.x11.window, 0, 0, 0, 0, + int(g_sapp_state.mouse.x), int(g_sapp_state.mouse.y)) C.XUngrabPointer(g_sapp_state.x11.display, current_time) } C.XFlush(g_sapp_state.x11.display) @@ -1289,8 +1290,8 @@ fn x11_set_clipboard_string(_str &char) { if !g_sapp_state.clipboard.enabled || g_sapp_state.clipboard.buffer == unsafe { nil } { return } - C.XSetSelectionOwner(g_sapp_state.x11.display, g_sapp_state.x11.clipboard_atom, g_sapp_state.x11.window, - current_time) + C.XSetSelectionOwner(g_sapp_state.x11.display, g_sapp_state.x11.clipboard_atom, + g_sapp_state.x11.window, current_time) } fn x11_get_clipboard_string() &char { @@ -1302,8 +1303,8 @@ fn x11_get_clipboard_string() &char { return g_sapp_state.clipboard.buffer } sapp_selection := C.XInternAtom(g_sapp_state.x11.display, c'SAPP_SELECTION', x_false) - C.XConvertSelection(g_sapp_state.x11.display, g_sapp_state.x11.clipboard_atom, g_sapp_state.x11.utf8_string, - sapp_selection, g_sapp_state.x11.window, current_time) + C.XConvertSelection(g_sapp_state.x11.display, g_sapp_state.x11.clipboard_atom, + g_sapp_state.x11.utf8_string, sapp_selection, g_sapp_state.x11.window, current_time) mut event := C.XEvent{} if !x11_wait_for_event(x_selection_notify, 0.1, &event) { return unsafe { nil } @@ -1317,9 +1318,9 @@ fn x11_get_clipboard_string() &char { mut actual_format := 0 mut item_count := u64(0) mut bytes_after := u64(0) - C.XGetWindowProperty(g_sapp_state.x11.display, event.xselection.requestor, event.xselection.property, - 0, 0x7fffffff, x_true, g_sapp_state.x11.utf8_string, &actual_type, &actual_format, - &item_count, &bytes_after, &&u8(&data)) + C.XGetWindowProperty(g_sapp_state.x11.display, event.xselection.requestor, + event.xselection.property, 0, 0x7fffffff, x_true, g_sapp_state.x11.utf8_string, + &actual_type, &actual_format, &item_count, &bytes_after, &&u8(&data)) if data == nil { return nil } @@ -1492,8 +1493,8 @@ fn x11_get_window_property(window Window, property Atom, req_type Atom, value && fn x11_get_window_state() int { mut result := withdrawn_state mut state := &u8(unsafe { nil }) - if x11_get_window_property(g_sapp_state.x11.window, g_sapp_state.x11.wm_state, g_sapp_state.x11.wm_state, - &&u8(&state)) >= 2 { + if x11_get_window_property(g_sapp_state.x11.window, g_sapp_state.x11.wm_state, + g_sapp_state.x11.wm_state, &&u8(&state)) >= 2 { unsafe { result = int(*(&u32(state))) } @@ -1751,8 +1752,8 @@ fn x11_on_selectionnotify(event &C.XEvent) { unsafe { if event.xselection.property == g_sapp_state.x11.xdnd.xdnd_selection { mut data := &u8(nil) - result := x11_get_window_property(event.xselection.requestor, event.xselection.property, - event.xselection.target, &&u8(&data)) + result := x11_get_window_property(event.xselection.requestor, + event.xselection.property, event.xselection.target, &&u8(&data)) if g_sapp_state.drop.enabled && result > 0 { if x11_parse_dropped_files_list(&char(data)) { g_sapp_state.mouse.dx = 0.0 @@ -1799,11 +1800,12 @@ fn x11_on_selectionrequest(event &C.XEvent) { reply.xselection.target = req.target if req.target == g_sapp_state.x11.utf8_string { - C.XChangeProperty(g_sapp_state.x11.display, req.requestor, req.property, g_sapp_state.x11.utf8_string, - 8, prop_mode_replace, &u8(g_sapp_state.clipboard.buffer), int(C.strlen(g_sapp_state.clipboard.buffer))) + C.XChangeProperty(g_sapp_state.x11.display, req.requestor, req.property, + g_sapp_state.x11.utf8_string, 8, prop_mode_replace, + &u8(g_sapp_state.clipboard.buffer), int(C.strlen(g_sapp_state.clipboard.buffer))) } else if req.target == g_sapp_state.x11.targets { - C.XChangeProperty(g_sapp_state.x11.display, req.requestor, req.property, xa_atom, - 32, prop_mode_replace, &u8(&g_sapp_state.x11.utf8_string), 1) + C.XChangeProperty(g_sapp_state.x11.display, req.requestor, req.property, xa_atom, 32, + prop_mode_replace, &u8(&g_sapp_state.x11.utf8_string), 1) } else { reply.xselection.property = x_none } @@ -1832,8 +1834,8 @@ fn x11_on_clientmessage(event &C.XEvent) { mut count := u64(0) mut formats := &Atom(nil) if is_list { - count = x11_get_window_property(g_sapp_state.x11.xdnd.source, g_sapp_state.x11.xdnd.xdnd_type_list, - xa_atom, &&u8(&formats)) + count = x11_get_window_property(g_sapp_state.x11.xdnd.source, + g_sapp_state.x11.xdnd.xdnd_type_list, xa_atom, &&u8(&formats)) } else { count = 3 formats = &Atom(voidptr(&event.xclient.data.l[2])) diff --git a/vlib/stbi/stbi.c.v b/vlib/stbi/stbi.c.v index 42e4c55cdd..75f8c71968 100644 --- a/vlib/stbi/stbi.c.v +++ b/vlib/stbi/stbi.c.v @@ -113,6 +113,8 @@ fn C.stbi_load(filename &char, x &int, y &int, channels_in_file &int, desired_ch fn C.stbi_load_from_file(f voidptr, x &int, y &int, channels_in_file &int, desired_channels i32) &u8 fn C.stbi_load_from_memory(buffer &u8, len i32, x &int, y &int, channels_in_file &int, desired_channels i32) &u8 +pub const C.STBI_rgb_alpha int + @[params] pub struct LoadParams { pub: @@ -154,8 +156,8 @@ pub fn load_from_memory(buf &u8, bufsize int, params LoadParams) !Image { ok: true nr_channels: params.desired_channels } - res.data = C.stbi_load_from_memory(buf, bufsize, &res.width, &res.height, &res.original_nr_channels, - params.desired_channels) + res.data = C.stbi_load_from_memory(buf, bufsize, &res.width, &res.height, + &res.original_nr_channels, params.desired_channels) if params.desired_channels == 0 { res.nr_channels = res.original_nr_channels } @@ -189,8 +191,8 @@ pub fn resize_uint8(img &Image, output_w int, output_h int) !Image { return error('stbi_image failed to resize file') } - if 0 == C.stbir_resize_uint8_linear(img.data, img.width, img.height, 0, res.data, - output_w, output_h, 0, img.nr_channels) { + if 0 == C.stbir_resize_uint8_linear(img.data, img.width, img.height, 0, res.data, output_w, + output_h, 0, img.nr_channels) { return error('stbi_image failed to resize file') } return res diff --git a/vlib/strconv/f64_str.c.v b/vlib/strconv/f64_str.c.v index c2f66cb7a0..f131255999 100644 --- a/vlib/strconv/f64_str.c.v +++ b/vlib/strconv/f64_str.c.v @@ -207,8 +207,7 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 { // Same as min(e2 + (^mm & 1), pow5Factor64(mm)) >= q // <=> e2 + (^mm & 1) >= q && pow5Factor64(mm) >= q // <=> true && pow5Factor64(mm) >= q, since e2 >= q. - vm_is_trailing_zeros = multiple_of_power_of_five_64(mv - 1 - mm_shift, - q) + vm_is_trailing_zeros = multiple_of_power_of_five_64(mv - 1 - mm_shift, q) } else if multiple_of_power_of_five_64(mv + 2, q) { vp-- } diff --git a/vlib/strconv/f64_str.js.v b/vlib/strconv/f64_str.js.v index 47daaaf321..b76da47910 100644 --- a/vlib/strconv/f64_str.js.v +++ b/vlib/strconv/f64_str.js.v @@ -187,8 +187,7 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 { // Same as min(e2 + (^mm & 1), pow5Factor64(mm)) >= q // <=> e2 + (^mm & 1) >= q && pow5Factor64(mm) >= q // <=> true && pow5Factor64(mm) >= q, since e2 >= q. - vm_is_trailing_zeros = multiple_of_power_of_five_64(mv - 1 - mm_shift, - q) + vm_is_trailing_zeros = multiple_of_power_of_five_64(mv - 1 - mm_shift, q) } else if multiple_of_power_of_five_64(mv + 2, q) { vp-- } diff --git a/vlib/strconv/vprintf.c.v b/vlib/strconv/vprintf.c.v index 05628bbb5f..287297ac2a 100644 --- a/vlib/strconv/vprintf.c.v +++ b/vlib/strconv/vprintf.c.v @@ -563,8 +563,7 @@ pub fn v_sprintf(str string, pt ...voidptr) string { @[inline] fn v_sprintf_panic(idx int, len int) { if idx >= len { - panic_n2('% conversion specifiers number mismatch (expected %, given args)', idx + 1, - len) + panic_n2('% conversion specifiers number mismatch (expected %, given args)', idx + 1, len) } } diff --git a/vlib/strings/builder.c.v b/vlib/strings/builder.c.v index cb2740a45a..d96daff484 100644 --- a/vlib/strings/builder.c.v +++ b/vlib/strings/builder.c.v @@ -394,7 +394,8 @@ pub fn (mut b Builder) indent(s string, param IndentParam) { string_char = c // Add indentation if at the start of a line if at_line_start { - b.write_repeated_rune(param.indent_char, indent_level * param.indent_count) + b.write_repeated_rune(param.indent_char, + indent_level * param.indent_count) at_line_start = false } // Write the opening quote @@ -404,7 +405,8 @@ pub fn (mut b Builder) indent(s string, param IndentParam) { // Start of a new block // Add indentation if at the start of a line if at_line_start { - b.write_repeated_rune(param.indent_char, indent_level * param.indent_count) + b.write_repeated_rune(param.indent_char, + indent_level * param.indent_count) at_line_start = false } @@ -457,7 +459,8 @@ pub fn (mut b Builder) indent(s string, param IndentParam) { // Any other character // Add indentation if at the start of a line if at_line_start { - b.write_repeated_rune(param.indent_char, indent_level * param.indent_count) + b.write_repeated_rune(param.indent_char, + indent_level * param.indent_count) at_line_start = false } b.write_rune(c) diff --git a/vlib/sync/channels.c.v b/vlib/sync/channels.c.v index fadc709f81..733a3b5281 100644 --- a/vlib/sync/channels.c.v +++ b/vlib/sync/channels.c.v @@ -124,8 +124,7 @@ pub fn (mut ch Channel) close() { return } mut nulladr := unsafe { nil } - for !C.atomic_compare_exchange_weak_ptr(voidptr(&ch.adr_written), voidptr(&nulladr), - isize(-1)) { + for !C.atomic_compare_exchange_weak_ptr(voidptr(&ch.adr_written), voidptr(&nulladr), isize(-1)) { nulladr = unsafe { nil } } ch.readsem_im.post() @@ -188,8 +187,8 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState { // there is a reader waiting for us unsafe { C.memcpy(wradr, src, ch.objsize) } mut nulladr := unsafe { nil } - for !C.atomic_compare_exchange_weak_ptr(voidptr(&ch.adr_written), voidptr(&nulladr), - isize(wradr)) { + for !C.atomic_compare_exchange_weak_ptr(voidptr(&ch.adr_written), + voidptr(&nulladr), isize(wradr)) { nulladr = unsafe { nil } } ch.readsem_im.post() @@ -383,8 +382,8 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState { // there is a writer waiting for us unsafe { C.memcpy(dest, rdadr, ch.objsize) } mut nulladr := unsafe { nil } - for !C.atomic_compare_exchange_weak_ptr(voidptr(&ch.adr_read), voidptr(&nulladr), - isize(rdadr)) { + for !C.atomic_compare_exchange_weak_ptr(voidptr(&ch.adr_read), + voidptr(&nulladr), isize(rdadr)) { nulladr = unsafe { nil } } ch.writesem_im.post() @@ -564,8 +563,7 @@ fn channel_select_priv(mut channels []&Channel, dir []Direction, mut objrefs []v sub_mtx.lock() subscr[i].prev = unsafe { subscriber } unsafe { - subscr[i].nxt = &Subscription(C.atomic_exchange_ptr(&voidptr(subscriber), - &subscr[i])) + subscr[i].nxt = &Subscription(C.atomic_exchange_ptr(&voidptr(subscriber), &subscr[i])) } if voidptr(subscr[i].nxt) != unsafe { nil } { subscr[i].nxt.prev = unsafe { &subscr[i].nxt } diff --git a/vlib/sync/waitgroup_test.v b/vlib/sync/waitgroup_test.v index 8342bb25f1..9879dc0cdf 100644 --- a/vlib/sync/waitgroup_test.v +++ b/vlib/sync/waitgroup_test.v @@ -31,7 +31,7 @@ fn test_waitgroup_no_use() { mut done := false spawn fn (done voidptr) { time.sleep(1 * time.second) - if *(&bool(done)) == false { + if unsafe { *(&bool(done)) } == false { panic('test_waitgroup_no_use did not complete in time') } }(voidptr(&done)) diff --git a/vlib/term/ui/input_windows.c.v b/vlib/term/ui/input_windows.c.v index e2d63316e1..228554b768 100644 --- a/vlib/term/ui/input_windows.c.v +++ b/vlib/term/ui/input_windows.c.v @@ -58,7 +58,7 @@ pub fn init(cfg Config) &Context { } mut input_mode := u32(C.ENABLE_WINDOW_INPUT) if ctx.cfg.mouse_enabled { - input_mode |= C.ENABLE_MOUSE_INPUT + input_mode |= u32(C.ENABLE_MOUSE_INPUT) } // enable window input and optionally mouse input events. if !C.SetConsoleMode(stdin_handle, input_mode) { diff --git a/vlib/time/custom_format_test.v b/vlib/time/custom_format_test.v index 2ee15d7a04..2956d11bb0 100644 --- a/vlib/time/custom_format_test.v +++ b/vlib/time/custom_format_test.v @@ -53,7 +53,8 @@ fn test_hours_k_and_kk() { fn test_zero_date() { zero_date := time.Time{} - res := zero_date.custom_format('M MM Mo MMM MMMM |1| D DD DDD DDDD |2| d dd ddd dddd |3| YY YYYY a A |4| H HH h hh k kk i ii e |5| m mm s ss |6| Do DDDo Q Qo QQ |7| N NN |8| M/D/YYYY N-HH:mm:ss Qo?a') + res := + zero_date.custom_format('M MM Mo MMM MMMM |1| D DD DDD DDDD |2| d dd ddd dddd |3| YY YYYY a A |4| H HH h hh k kk i ii e |5| m mm s ss |6| Do DDDo Q Qo QQ |7| N NN |8| M/D/YYYY N-HH:mm:ss Qo?a') assert res == '0 00 0th Jan January |1| 0 00 0 000 |2| -1 Mo Mon Monday |3| 0 am AM |4| 0 00 12 12 24 24 0 00 e |5| 0 00 0 00 |6| 0th 0th 1 1st 01 |7| AD Anno Domini |8| 0/0/0 AD-00:00:00 1st?am' } diff --git a/vlib/time/date_time_parser.v b/vlib/time/date_time_parser.v index 34fdf31c49..b2bf8cf05b 100644 --- a/vlib/time/date_time_parser.v +++ b/vlib/time/date_time_parser.v @@ -218,7 +218,8 @@ fn (mut p DateTimeParser) parse() !Time { match token { 'YYYY' { year_ = p.must_be_int(4) or { - return error_invalid_time(0, 'end of string reached before the full year was specified') + return error_invalid_time(0, + 'end of string reached before the full year was specified') } } 'YY' { @@ -228,7 +229,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'M' { month_ = p.must_be_int_with_minimum_length(1, 2, false) or { - return error_invalid_time(0, 'end of string reached before the month was specified') + return error_invalid_time(0, + 'end of string reached before the month was specified') } if month_ < 1 || month_ > 12 { return error_invalid_time(0, 'month must be between 1 and 12') @@ -236,7 +238,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'MM' { month_ = p.must_be_int(2) or { - return error_invalid_time(0, 'end of string reached before the month was specified') + return error_invalid_time(0, + 'end of string reached before the month was specified') } if month_ < 1 || month_ > 12 { return error_invalid_time(0, 'month must be between 01 and 12') @@ -250,7 +253,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'D' { day_in_month = p.must_be_int_with_minimum_length(1, 2, false) or { - return error_invalid_time(0, 'end of string reached before the day was specified') + return error_invalid_time(0, + 'end of string reached before the day was specified') } if day_in_month < 1 || day_in_month > 31 { return error_invalid_time(0, 'day must be between 1 and 31') @@ -258,7 +262,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'DD' { day_in_month = p.must_be_int(2) or { - return error_invalid_time(0, 'end of string reached before the month was specified') + return error_invalid_time(0, + 'end of string reached before the month was specified') } if day_in_month < 1 || day_in_month > 31 { return error_invalid_time(0, 'day must be between 01 and 31') @@ -281,7 +286,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'H' { hour_ = p.must_be_int_with_minimum_length(1, 2, true) or { - return error_invalid_time(0, 'end of string reached before hours where specified') + return error_invalid_time(0, + 'end of string reached before hours where specified') } if hour_ < 0 || hour_ > 23 { return error_invalid_time(0, 'hour must be between 0 and 23') @@ -289,7 +295,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'HH' { hour_ = p.must_be_int(2) or { - return error_invalid_time(0, 'end of string reached before hours where specified') + return error_invalid_time(0, + 'end of string reached before hours where specified') } if hour_ < 0 || hour_ > 23 { return error_invalid_time(0, 'hour must be between 00 and 23') @@ -297,7 +304,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'h' { hour_ = p.must_be_int_with_minimum_length(1, 2, true) or { - return error_invalid_time(0, 'end of string reached before hours where specified') + return error_invalid_time(0, + 'end of string reached before hours where specified') } if hour_ < 0 || hour_ > 23 { return error_invalid_time(0, 'hour must be between 0 and 23') @@ -305,7 +313,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'hh' { hour_ = p.must_be_int(2) or { - return error_invalid_time(0, 'end of string reached before hours where specified') + return error_invalid_time(0, + 'end of string reached before hours where specified') } if hour_ < 0 || hour_ > 23 { return error_invalid_time(0, 'hour must be between 00 and 23') @@ -313,7 +322,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'k' { hour_ = p.must_be_int(1) or { - return error_invalid_time(0, 'end of string reached before hours where specified') + return error_invalid_time(0, + 'end of string reached before hours where specified') } if hour_ < 0 || hour_ > 23 { return error_invalid_time(0, 'hour must be between 0 and 23') @@ -321,7 +331,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'kk' { hour_ = p.must_be_int(2) or { - return error_invalid_time(0, 'end of string reached before hours where specified') + return error_invalid_time(0, + 'end of string reached before hours where specified') } if hour_ < 0 || hour_ > 23 { return error_invalid_time(0, 'hour must be between 00 and 23') @@ -329,7 +340,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'm' { minute_ = p.must_be_int(1) or { - return error_invalid_time(0, 'end of string reached before minutes where specified') + return error_invalid_time(0, + 'end of string reached before minutes where specified') } if minute_ < 0 || minute_ > 59 { return error_invalid_time(0, 'minute must be between 0 and 59') @@ -337,7 +349,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'mm' { minute_ = p.must_be_int(2) or { - return error_invalid_time(0, 'end of string reached before minutes where specified') + return error_invalid_time(0, + 'end of string reached before minutes where specified') } if minute_ < 0 || minute_ > 59 { return error_invalid_time(0, 'minute must be between 00 and 59') @@ -345,7 +358,8 @@ fn (mut p DateTimeParser) parse() !Time { } 's' { second_ = p.must_be_int(1) or { - return error_invalid_time(0, 'end of string reached before seconds where specified') + return error_invalid_time(0, + 'end of string reached before seconds where specified') } if second_ < 0 || second_ > 59 { return error_invalid_time(0, 'second must be between 0 and 59') @@ -353,7 +367,8 @@ fn (mut p DateTimeParser) parse() !Time { } 'ss' { second_ = p.must_be_int(2) or { - return error_invalid_time(0, 'end of string reached before seconds where specified') + return error_invalid_time(0, + 'end of string reached before seconds where specified') } if second_ < 0 || second_ > 59 { return error_invalid_time(0, 'second must be between 00 and 59') diff --git a/vlib/time/parse.c.v b/vlib/time/parse.c.v index 282e5f5171..3516fba0e1 100644 --- a/vlib/time/parse.c.v +++ b/vlib/time/parse.c.v @@ -234,7 +234,8 @@ pub fn parse_rfc3339(s string) !Time { } if is_datetime { // year, month, day := check_and_extract_date(s)! - hour_, minute_, second_, nanosecond_ = check_and_extract_time(s[date_format_buffer.len + 1..])! + hour_, minute_, second_, nanosecond_ = + check_and_extract_time(s[date_format_buffer.len + 1..])! } mut timezone_start_position := 0 @@ -469,7 +470,8 @@ pub fn parse_iso8601(s string) !Time { year, month, day := parse_iso8601_date(parts[0])! mut hour_, mut minute_, mut second_, mut microsecond_, mut nanosecond_, mut unix_offset, mut is_local_time := 0, 0, 0, 0, 0, i64(0), true if parts.len == 2 { - hour_, minute_, second_, microsecond_, nanosecond_, unix_offset, is_local_time = parse_iso8601_time(parts[1])! + hour_, minute_, second_, microsecond_, nanosecond_, unix_offset, is_local_time = + parse_iso8601_time(parts[1])! } mut t := new( year: year @@ -508,8 +510,8 @@ pub fn parse_rfc2822(s string) !Time { mm := pos / 3 + 1 unsafe { tmstr := malloc_noscan(s.len * 2) - count := C.snprintf(&char(tmstr), (s.len * 2), c'%s-%02d-%s %s', fields[3].str, - mm, fields[1].str, fields[4].str) + count := C.snprintf(&char(tmstr), (s.len * 2), c'%s-%02d-%s %s', fields[3].str, mm, + fields[1].str, fields[4].str) return parse(tos(tmstr, count)) } } diff --git a/vlib/time/time_test.v b/vlib/time/time_test.v index 8c52f9f66f..9ffd8409f3 100644 --- a/vlib/time/time_test.v +++ b/vlib/time/time_test.v @@ -79,9 +79,12 @@ fn test_new_defaults_missing_month_and_day() { fn test_new_rejects_invalid_values() { assert_new_panics('time.new(year: 10000)', 'invalid time: year must be between -9999 and 9999') - assert_new_panics('time.new(year: 2024, month: 13)', 'invalid time: month must be between 1 and 12') - assert_new_panics('time.new(year: 2024, month: 2, day: 30)', 'invalid time: day must be between 1 and 29 for year 2024, month 2') - assert_new_panics('time.new(year: 2024, hour: 24)', 'invalid time: hour must be between 0 and 23') + assert_new_panics('time.new(year: 2024, month: 13)', + 'invalid time: month must be between 1 and 12') + assert_new_panics('time.new(year: 2024, month: 2, day: 30)', + 'invalid time: day must be between 1 and 29 for year 2024, month 2') + assert_new_panics('time.new(year: 2024, hour: 24)', + 'invalid time: hour must be between 0 and 23') } fn test_unix() { diff --git a/vlib/time/unix.v b/vlib/time/unix.v index 87b93faf9b..a94cd79735 100644 --- a/vlib/time/unix.v +++ b/vlib/time/unix.v @@ -43,7 +43,8 @@ pub fn unix_nanosecond(abs_unix_timestamp i64, nanosecond int) Time { day_offset-- } year, month, day := calculate_date_from_day_offset(day_offset) - hour_, minute_, second_ := calculate_time_from_second_offset(abs_unix_timestamp % seconds_per_day) + hour_, minute_, second_ := + calculate_time_from_second_offset(abs_unix_timestamp % seconds_per_day) return Time{ year: year month: month diff --git a/vlib/toml/parser/parser.v b/vlib/toml/parser/parser.v index 07cdc206ff..01efc20fa9 100644 --- a/vlib/toml/parser/parser.v +++ b/vlib/toml/parser/parser.v @@ -317,7 +317,8 @@ fn (p &Parser) check_implicitly_declared(key DottedKey) ! { // reference maps by multiple keys "dotted" (separated by "." periods) in TOML documents. // See also `find_in_table`. pub fn (mut p Parser) find_table() !&map[string]ast.Value { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "${p.root_map_key}" in map ${ptr_str(p.root_map)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'locating "${p.root_map_key}" in map ${ptr_str(p.root_map)}') mut t := unsafe { &p.root_map } if p.root_map_key.len == 0 { return t @@ -328,7 +329,8 @@ pub fn (mut p Parser) find_table() !&map[string]ast.Value { // allocate_table allocates all tables in "dotted" `key` (`a.b.c`) in the *root* table. pub fn (mut p Parser) allocate_table(key DottedKey) ! { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocating "${key}" in map ${ptr_str(p.root_map)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'allocating "${key}" in map ${ptr_str(p.root_map)}') mut t := unsafe { &p.root_map } if key.len == 0 { return @@ -356,7 +358,8 @@ pub fn (mut p Parser) find_sub_table(key DottedKey) !&map[string]ast.Value { if p.root_map_key.len == 0 { ky = unsafe { key } } - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "${ky}" in map ${ptr_str(p.root_map)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'locating "${ky}" in map ${ptr_str(p.root_map)}') mut t := unsafe { &p.root_map } if ky.len == 0 { return t @@ -386,7 +389,8 @@ pub fn (mut p Parser) find_in_table(mut table map[string]ast.Value, key DottedKe ' "${k}" in "${key}" is not a map but `${val.type_name()}`') } } else { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'no key "${k}" in "${key}" found, allocating new map at key "${k}" in map ${ptr_str(t)}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'no key "${k}" in "${key}" found, allocating new map at key "${k}" in map ${ptr_str(t)}"') t[k] = map[string]ast.Value{} t = &(t[k] as map[string]ast.Value) util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocated new map ${ptr_str(t)}"') @@ -455,7 +459,8 @@ pub fn (mut p Parser) allocate_in_table(mut table map[string]ast.Value, key Dott ' "${k}" in "${key}" is not a map (${val.type_name()})') } } else { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'no key "${k}" in "${key}" found, allocating new map at key "${k}" in map ${ptr_str(t)}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'no key "${k}" in "${key}" found, allocating new map at key "${k}" in map ${ptr_str(t)}"') t[k] = map[string]ast.Value{} t = &(t[k] as map[string]ast.Value) util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocated new map ${ptr_str(t)}"') @@ -481,7 +486,8 @@ pub fn (mut p Parser) dotted_key() !DottedKey { p.ignore_while_peek(space_formatting) } p.next()! - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed dotted key `${dotted_key}` now at "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsed dotted key `${dotted_key}` now at "${p.tok.kind}" "${p.tok.lit}"') return dotted_key } @@ -497,7 +503,8 @@ pub fn (mut p Parser) root_table() ! { p.skip_next = false } - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing token "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing token "${p.tok.kind}" "${p.tok.lit}"') match p.tok.kind { .hash { c := p.comment() @@ -505,7 +512,8 @@ pub fn (mut p Parser) root_table() ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping comment "${c.text}"') } .whitespace, .tab, .nl, .cr { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping formatting "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'skipping formatting "${p.tok.kind}" "${p.tok.lit}"') continue } .bare, .boolean, .quoted, .number, .minus, .underscore { @@ -555,7 +563,8 @@ pub fn (mut p Parser) root_table() ! { t := p.find_sub_table(sub_table)! unsafe { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "${key}" = ${val} in table ${ptr_str(t)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'setting "${key}" = ${val} in table ${ptr_str(t)}') t[key.str()] = val } } else { @@ -564,7 +573,8 @@ pub fn (mut p Parser) root_table() ! { t := p.find_table()! unsafe { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "${key.str()}" = ${val} in table ${ptr_str(t)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'setting "${key.str()}" = ${val} in table ${ptr_str(t)}') key_str := key.str() if _ := t[key_str] { return error(@MOD + '.' + @STRUCT + '.' + @FN + @@ -600,7 +610,8 @@ pub fn (mut p Parser) root_table() ! { p.array_of_tables(mut &p.root_map)! } p.skip_next = true // skip calling p.next() in coming iteration - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'leaving double bracket at "${p.tok.kind}" "${p.tok.lit}". NEXT is "${p.peek_tok.kind} "${p.peek_tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'leaving double bracket at "${p.tok.kind}" "${p.tok.lit}". NEXT is "${p.peek_tok.kind} "${p.peek_tok.lit}"') } else if peek_tok.kind == .period { // Parse `[d.e.f]` dotted_key := p.dotted_key()! @@ -668,7 +679,8 @@ pub fn (mut p Parser) root_table() ! { p.explicit_declared << dotted_key p.ignore_while(space_formatting) - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `${dotted_key}` at "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'setting root map key to `${dotted_key}` at "${p.tok.kind}" "${p.tok.lit}"') p.root_map_key = dotted_key p.allocate_table(p.root_map_key)! p.expect(.rsbr)! @@ -696,7 +708,8 @@ pub fn (mut p Parser) root_table() ! { // Allow [ key ] p.ignore_while(space_formatting) - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `${dotted_key}` at "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'setting root map key to `${dotted_key}` at "${p.tok.kind}" "${p.tok.lit}"') p.root_map_key = dotted_key p.allocate_table(p.root_map_key)! p.next()! @@ -736,7 +749,8 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ! { p.skip_next = false } - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing token "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing token "${p.tok.kind}" "${p.tok.lit}"') match p.tok.kind { .hash { c := p.comment() @@ -744,7 +758,8 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping comment "${c.text}"') } .whitespace, .tab, .nl, .cr { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping formatting "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'skipping formatting "${p.tok.kind}" "${p.tok.lit}"') continue } .bare, .quoted, .number, .minus, .underscore { @@ -758,7 +773,8 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ! { t := p.find_in_table(mut tbl, sub_table)! unsafe { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "${key}" = ${val} in table ${ptr_str(t)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'setting "${key}" = ${val} in table ${ptr_str(t)}') t[key.str()] = val } } else { @@ -766,7 +782,8 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ! { key, val := p.key_value()! unsafe { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "${key.str()}" = ${val} in table ${ptr_str(tbl)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'setting "${key.str()}" = ${val} in table ${ptr_str(tbl)}') key_str := key.str() if _ := tbl[key_str] { return error(@MOD + '.' + @STRUCT + '.' + @FN + @@ -813,7 +830,8 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping "${p.tok.kind}" "${p.tok.lit}"') continue }*/ - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping formatting "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'skipping formatting "${p.tok.kind}" "${p.tok.lit}"') continue } .comma { @@ -823,7 +841,8 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ! { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' unexpected "${p.tok.kind}" "${p.tok.lit}" at this (excerpt): "...${p.excerpt()}..."') } - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping comma table value separator "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'skipping comma table value separator "${p.tok.lit}"') continue } .rcbr { @@ -848,7 +867,8 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ! { } } key_str := key.str() - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'inserting @6 "${key_str}" = ${val} into ${ptr_str(t)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'inserting @6 "${key_str}" = ${val} into ${ptr_str(t)}') unsafe { if _ := t[key_str] { return error(@MOD + '.' + @STRUCT + '.' + @FN + @@ -860,7 +880,8 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ! { p.ignore_while(space_formatting) key, val := p.key_value()! key_str := key.str() - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'inserting @5 "${key_str}" = ${val} into ${ptr_str(tbl)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'inserting @5 "${key_str}" = ${val} into ${ptr_str(tbl)}') if _ := tbl[key_str] { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' key "${key_str}" is already initialized with a value. At "${p.tok.kind}" "${p.tok.lit}" in this (excerpt): "...${p.excerpt()}..."') @@ -883,7 +904,8 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ! { // array_of_tables parses next tokens into an array of `ast.Value`s. @[autofree_bug; manualfree] pub fn (mut p Parser) array_of_tables(mut table map[string]ast.Value) ! { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing array of tables "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing array of tables "${p.tok.kind}" "${p.tok.lit}"') // NOTE this is starting to get ugly. TOML isn't simple at this point p.check(.lsbr)! // '[' bracket @@ -940,21 +962,24 @@ pub fn (mut p Parser) array_of_tables(mut table map[string]ast.Value) ! { // array_of_tables_contents parses next tokens into an array of `ast.Value`s. @[autofree_bug; manualfree] pub fn (mut p Parser) array_of_tables_contents() ![]ast.Value { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing contents from "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing contents from "${p.tok.kind}" "${p.tok.lit}"') mut tbl := map[string]ast.Value{} p.table_contents(mut tbl)! mut arr := []ast.Value{} arr << tbl - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed array of tables ${ast.Value(arr)}. leaving at "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsed array of tables ${ast.Value(arr)}. leaving at "${p.tok.kind}" "${p.tok.lit}"') return arr } // double_array_of_tables parses next tokens into an array of tables of arrays of `ast.Value`s... @[autofree_bug; manualfree] pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ! { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing nested array of tables "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing nested array of tables "${p.tok.kind}" "${p.tok.lit}"') dotted_key := p.dotted_key()! p.ignore_while(space_formatting) @@ -1002,7 +1027,8 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ! { return } } else { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'implicit allocation of map for `${first}` in dotted key `${dotted_key}`.') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'implicit allocation of map for `${first}` in dotted key `${dotted_key}`.') mut t := &map[string]ast.Value{} p.implicit_declared << first // NOTE: We register this implicit allocation also as *explicit* to be able to catch a special case like: @@ -1025,7 +1051,8 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ! { p.last_aot = first mut nm := &p.root_map if first.str() in table.keys() { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'adding to existing table entry at `${first}`.') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'adding to existing table entry at `${first}`.') table_first := table[first.str()] if table_first !is map[string]ast.Value { return error(@MOD + '.' + @STRUCT + '.' + @FN + @@ -1033,7 +1060,8 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ! { } nm = &(table_first as map[string]ast.Value) } else { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'implicit allocation of map for `${first}` in dotted key `${dotted_key}`.') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'implicit allocation of map for `${first}` in dotted key `${dotted_key}`.') nm = &map[string]ast.Value{} p.implicit_declared << first // NOTE: We register this implicit allocation also as *explicit* to be able to catch a special case like: @@ -1106,7 +1134,8 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ! { // double_array_of_tables_contents parses next tokens into an array of `ast.Value`s. @[autofree_bug; manualfree] pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ![]ast.Value { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing contents from "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing contents from "${p.tok.kind}" "${p.tok.lit}"') mut tbl := map[string]ast.Value{} mut implicit_allocation_key := DottedKey([]string{}) @@ -1145,7 +1174,8 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ![]a mut t := p.find_in_table(mut tbl, sub_table)! unsafe { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'inserting @6 "${key}" = ${val} into ${ptr_str(t)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'inserting @6 "${key}" = ${val} into ${ptr_str(t)}') t[key.str()] = val } } else { @@ -1156,7 +1186,8 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ![]a t = p.find_in_table(mut tbl, implicit_allocation_key)! } unsafe { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'inserting @7 "${key}" = ${val} into ${ptr_str(t)}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'inserting @7 "${key}" = ${val} into ${ptr_str(t)}') t[key.str()] = val } } @@ -1180,7 +1211,8 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ![]a implicit_allocation_key = dotted_key[2..] } p.ignore_while(space_formatting) - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'keys are: dotted `${dotted_key}`, target `${target_key}`, implicit `${implicit_allocation_key}` at "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'keys are: dotted `${dotted_key}`, target `${target_key}`, implicit `${implicit_allocation_key}` at "${p.tok.kind}" "${p.tok.lit}"') p.expect(.rsbr)! p.peek_for_correct_line_ending_or_fail()! p.explicit_declared << dotted_key @@ -1197,7 +1229,8 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ![]a } mut arr := []ast.Value{} arr << tbl - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed array of tables ${ast.Value(arr)}. leaving at "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsed array of tables ${ast.Value(arr)}. leaving at "${p.tok.kind}" "${p.tok.lit}"') return arr } @@ -1209,7 +1242,8 @@ pub fn (mut p Parser) array() ![]ast.Value { mut previous_token_was_value := false for p.tok.kind != .eof { p.next()! - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing token "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing token "${p.tok.kind}" "${p.tok.lit}"') if previous_token_was_value { p.ignore_while(all_formatting) @@ -1243,7 +1277,8 @@ pub fn (mut p Parser) array() ![]ast.Value { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' unexpected "${p.tok.kind}" "${p.tok.lit}" at this (excerpt): "...${p.excerpt()}..."') } - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping comma table value separator "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'skipping comma table value separator "${p.tok.lit}"') continue } .eof { @@ -1272,7 +1307,8 @@ pub fn (mut p Parser) array() ![]ast.Value { previous_token_was_value = true } .lsbr { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing array in array "${p.tok.kind}" "${p.tok.lit}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing array in array "${p.tok.kind}" "${p.tok.lit}"') arr << ast.Value(p.array()!) previous_token_was_value = true } @@ -1292,7 +1328,8 @@ pub fn (mut p Parser) array() ![]ast.Value { p.expect(.rsbr)! // ']' bracket $if debug { flat := arr.str().replace('\n', r'\n') - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed array: ${flat} . Currently @ token "${p.tok.kind}"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsed array: ${flat} . Currently @ token "${p.tok.kind}"') } return arr } @@ -1425,7 +1462,8 @@ pub fn (mut p Parser) dotted_key_value() !(DottedKey, ast.Value) { } p.value_is_immutable = false } - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed dotted key value pair `${dotted_key} = ${value}`...') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsed dotted key value pair `${dotted_key} = ${value}`...') return dotted_key, value } @@ -1433,7 +1471,8 @@ pub fn (mut p Parser) dotted_key_value() !(DottedKey, ast.Value) { // value parse and returns an `ast.Value` type. // values are the token(s) appearing after an assignment operator (=). pub fn (mut p Parser) value() !ast.Value { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing value from token "${p.tok.kind}" "${p.tok.lit}"...') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'parsing value from token "${p.tok.kind}" "${p.tok.lit}"...') mut value := ast.Value(ast.Null{}) if p.tok.kind == .number { number_or_date := p.number_or_date()! @@ -1668,7 +1707,8 @@ pub fn (mut p Parser) time() !ast.Time { if !lit[lit.len - 1].is_digit() { return error(@MOD + '.' + @STRUCT + '.' + @FN + - ' expected a number as last occurrence in "${lit}" got "${lit[lit.len - 1].ascii_str()}"') + ' expected a number as last occurrence in "${lit}" got "${lit[lit.len - + 1].ascii_str()}"') } // Parse offset diff --git a/vlib/toml/scanner/scanner.v b/vlib/toml/scanner/scanner.v index ac596f1c6a..6af5696c5e 100644 --- a/vlib/toml/scanner/scanner.v +++ b/vlib/toml/scanner/scanner.v @@ -126,7 +126,8 @@ pub fn (mut s Scanner) scan() !token.Token { && peek_2 == `f` if !s.is_left_of_assign && (is_nan || is_inf || is_signed_nan || is_signed_inf) { num := s.extract_nan_or_inf_number()! - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified a special number "${num}" (${num.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified a special number "${num}" (${num.len})') return s.new_token(.number, num, num.len) } @@ -134,17 +135,20 @@ pub fn (mut s Scanner) scan() !token.Token { is_digit := byte_c.is_digit() if is_digit || is_signed_number { num := s.extract_number()! - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified a number "${num}" (${num.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified a number "${num}" (${num.len})') return s.new_token(.number, num, num.len) } if util.is_key_char(byte_c) { key := s.extract_key() if u8(s.peek(1)) != `=` && (key == 'true' || key == 'false') { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified a boolean "${key}" (${key.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified a boolean "${key}" (${key.len})') return s.new_token(.boolean, key, key.len) } - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified a bare key "${key}" (${key.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified a bare key "${key}" (${key.len})') return s.new_token(.bare, key, key.len) } @@ -152,7 +156,8 @@ pub fn (mut s Scanner) scan() !token.Token { ` `, `\t`, `\n`, `\r` { if c == `\n` { s.inc_line_number() - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'incremented line nr to ${s.line_nr}') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'incremented line nr to ${s.line_nr}') } else if c == `\r` { // CR should always be followed by a `\n` if s.at() != `\n` { @@ -164,7 +169,8 @@ pub fn (mut s Scanner) scan() !token.Token { // so we allow space characters to slip through to the parser if the space is between two digits... // util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, '"'+u8(s.peek(-1)).ascii_str()+'" < "${ascii}" > "'+u8(s.at()).ascii_str()+'"') if c == ` ` && u8(s.peek(-1)).is_digit() && u8(s.at()).is_digit() { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified, what could be, a space between a RFC 3339 date and time ("${ascii}") (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified, what could be, a space between a RFC 3339 date and time ("${ascii}") (${ascii.len})') return s.new_token(token.Kind.whitespace, ascii, ascii.len) } if s.config.tokenize_formatting { @@ -176,66 +182,81 @@ pub fn (mut s Scanner) scan() !token.Token { } else if c == `\n` { kind = token.Kind.nl } - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified formatting character ("${ascii}") (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified formatting character ("${ascii}") (${ascii.len})') return s.new_token(kind, ascii, ascii.len) } else { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping " ", "\\t" or "\\n" ("${ascii}") (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'skipping " ", "\\t" or "\\n" ("${ascii}") (${ascii.len})') } continue } `-` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified minus "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified minus "${ascii}" (${ascii.len})') return s.new_token(.minus, ascii, ascii.len) } `_` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified underscore "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified underscore "${ascii}" (${ascii.len})') return s.new_token(.underscore, ascii, ascii.len) } `+` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified plus "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified plus "${ascii}" (${ascii.len})') return s.new_token(.plus, ascii, ascii.len) } `=` { s.is_left_of_assign = false - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified assignment "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified assignment "${ascii}" (${ascii.len})') return s.new_token(.assign, ascii, ascii.len) } `"`, `'` { // ... some string "/' ident_string := s.extract_string()! - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified quoted string `${ident_string}`') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified quoted string `${ident_string}`') return s.new_token(.quoted, ident_string, ident_string.len) } `#` { hash := s.ignore_line()! - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified comment hash "${hash}" (${hash.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified comment hash "${hash}" (${hash.len})') return s.new_token(.hash, hash, hash.len + 1) } `{` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified left curly bracket "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified left curly bracket "${ascii}" (${ascii.len})') return s.new_token(.lcbr, ascii, ascii.len) } `}` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified right curly bracket "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified right curly bracket "${ascii}" (${ascii.len})') return s.new_token(.rcbr, ascii, ascii.len) } `[` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified left square bracket "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified left square bracket "${ascii}" (${ascii.len})') return s.new_token(.lsbr, ascii, ascii.len) } `]` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified right square bracket "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified right square bracket "${ascii}" (${ascii.len})') return s.new_token(.rsbr, ascii, ascii.len) } `:` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified colon "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified colon "${ascii}" (${ascii.len})') return s.new_token(.colon, ascii, ascii.len) } `,` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified comma "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified comma "${ascii}" (${ascii.len})') return s.new_token(.comma, ascii, ascii.len) } `.` { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified period "${ascii}" (${ascii.len})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified period "${ascii}" (${ascii.len})') return s.new_token(.period, ascii, ascii.len) } else { @@ -428,7 +449,8 @@ fn (mut s Scanner) extract_string() !string { } c := u8(s.at()) - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'c: `${c.ascii_str()}` / ${c} (quote type: ${quote}/${quote.ascii_str()})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'c: `${c.ascii_str()}` / ${c} (quote type: ${quote}/${quote.ascii_str()})') // Check for escaped chars if c == u8(92) { @@ -490,7 +512,8 @@ fn (mut s Scanner) extract_multiline_string() !string { } c := u8(s.at()) - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'c: `${c.ascii_str()}` / ${c} (quote type: ${quote}/${quote.ascii_str()})') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'c: `${c.ascii_str()}` / ${c} (quote type: ${quote}/${quote.ascii_str()})') if c == `\r` && s.peek(1) == `\n` { continue @@ -523,7 +546,8 @@ fn (mut s Scanner) extract_multiline_string() !string { s.pos += 3 s.col += 3 lit += quote.ascii_str() + quote.ascii_str() + quote.ascii_str() - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'returning at ${c.ascii_str()} `${lit}`') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'returning at ${c.ascii_str()} `${lit}`') return lit } else if s.peek(3) != quote { // lit += c.ascii_str() @@ -531,7 +555,8 @@ fn (mut s Scanner) extract_multiline_string() !string { s.pos += 3 s.col += 3 lit += quote.ascii_str() + quote.ascii_str() + quote.ascii_str() - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'returning at ${c.ascii_str()} `${lit}`') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'returning at ${c.ascii_str()} `${lit}`') return lit } } @@ -556,7 +581,8 @@ fn (mut s Scanner) handle_escapes(quote u8, is_multiline bool) (string, int) { } else if s.peek(1) == quote { if (!is_multiline && s.peek(2) == `\n`) || (is_multiline && s.peek(2) == quote && s.peek(3) == quote && s.peek(4) == `\n`) { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'ignore special case escaped `${lit}` at end of string') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'ignore special case escaped `${lit}` at end of string') return '', 0 } lit += quote.ascii_str() @@ -566,7 +592,8 @@ fn (mut s Scanner) handle_escapes(quote u8, is_multiline bool) (string, int) { } if is_literal_string { if s.peek(1) == quote { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'ignore escape `${lit}${u8(s.peek(1)).ascii_str()}` in literal string') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'ignore escape `${lit}${u8(s.peek(1)).ascii_str()}` in literal string') return '', 0 } } @@ -626,7 +653,8 @@ fn (mut s Scanner) extract_number() !string { s.col++ } key := s.text[start..s.pos] - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified number "${key}" in range [${start} .. ${s.pos}]') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified number "${key}" in range [${start} .. ${s.pos}]') return key } @@ -656,7 +684,8 @@ fn (mut s Scanner) extract_nan_or_inf_number() !string { s.col++ } key := s.text[start..s.pos] - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified special number "${key}" in range [${start} .. ${s.pos}]') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, + 'identified special number "${key}" in range [${start} .. ${s.pos}]') return key } diff --git a/vlib/toml/tests/iarna_toml_spec_test.v b/vlib/toml/tests/iarna_toml_spec_test.v index 05be5e9291..99d4ce6110 100644 --- a/vlib/toml/tests/iarna_toml_spec_test.v +++ b/vlib/toml/tests/iarna_toml_spec_test.v @@ -171,7 +171,8 @@ fn test_iarna_toml_spec_tests() { iarna_yaml_path := valid_test_file.all_before_last('.') + '.yaml' if os.exists(iarna_yaml_path) { - converted_json_path = os.join_path(compare_work_dir_root, '${valid_test_file_name}.yaml.json') + converted_json_path = os.join_path(compare_work_dir_root, + '${valid_test_file_name}.yaml.json') run([python, '-c', "'import sys, yaml, json; json.dump(yaml.load(sys.stdin, Loader=yaml.FullLoader), sys.stdout, indent=4)'", '<', iarna_yaml_path, '>', converted_json_path]) or { @@ -193,8 +194,10 @@ fn test_iarna_toml_spec_tests() { } toml_doc := toml.parse_file(valid_test_file)! - v_toml_json_path := os.join_path(compare_work_dir_root, '${valid_test_file_name}.v.json') - iarna_toml_json_path := os.join_path(compare_work_dir_root, '${valid_test_file_name}.json') + v_toml_json_path := os.join_path(compare_work_dir_root, + '${valid_test_file_name}.v.json') + iarna_toml_json_path := os.join_path(compare_work_dir_root, + '${valid_test_file_name}.json') os.write_file(v_toml_json_path, to_iarna(toml_doc.ast.table, converted_from_yaml))! @@ -292,8 +295,7 @@ fn to_iarna(value ast.Value, skip_value_map bool) string { } ast.DateTime { // Normalization for json - mut json_text := json2.Any(value.text).json_str().to_upper().replace(' ', - 'T') + mut json_text := json2.Any(value.text).json_str().to_upper().replace(' ', 'T') typ := if json_text.ends_with('Z"') || json_text.all_after('T').contains('-') || json_text.all_after('T').contains('+') { 'datetime' @@ -342,7 +344,8 @@ fn to_iarna(value ast.Value, skip_value_map bool) string { } ast.Number { if value.text.contains('inf') { - mut json_text := value.text.replace('inf', '1.7976931348623157e+308') // Inconsistency ??? + mut json_text := + value.text.replace('inf', '1.7976931348623157e+308') // Inconsistency ??? if skip_value_map { return '${json_text}' } diff --git a/vlib/toml/tests/large_toml_file_test.v b/vlib/toml/tests/large_toml_file_test.v index cf201796b0..dbe3c0dd11 100644 --- a/vlib/toml/tests/large_toml_file_test.v +++ b/vlib/toml/tests/large_toml_file_test.v @@ -6,7 +6,8 @@ import toml // `wget https://gist.githubusercontent.com/Larpon/89b0e3d94c6903851ff15559e5df7a05/raw/62a1f87a4e37bf157f2e0bfb32d85d840c98e422/large_toml_file_test.toml` // `mv large_toml_file_test.toml vlib/toml/tests/testdata/` -const toml_file = os.join_path_single(@VEXEROOT, 'vlib/toml/tests/testdata/large_toml_file_test.toml') +const toml_file = os.join_path_single(@VEXEROOT, + 'vlib/toml/tests/testdata/large_toml_file_test.toml') fn test_large_file() { if !os.exists(toml_file) { diff --git a/vlib/toml/tests/toml_bom_test.v b/vlib/toml/tests/toml_bom_test.v index 908df9df07..05933de018 100644 --- a/vlib/toml/tests/toml_bom_test.v +++ b/vlib/toml/tests/toml_bom_test.v @@ -7,12 +7,15 @@ const empty_toml_document = toml.Doc{ ast: &ast.Root(unsafe { nil }) } -const toml_text_with_utf8_bom = os.read_file(os.real_path(os.join_path(os.dir(@FILE), - 'testdata', 'toml_with_utf8_bom' + '.toml'))) or { panic(err) } -const toml_text_with_utf16_bom = os.read_file(os.real_path(os.join_path(os.dir(@FILE), - 'testdata', 'toml_with_utf16_bom' + '.toml'))) or { panic(err) } -const toml_text_with_utf32_bom = os.read_file(os.real_path(os.join_path(os.dir(@FILE), - 'testdata', 'toml_with_utf32_bom' + '.toml'))) or { panic(err) } +const toml_text_with_utf8_bom = os.read_file(os.real_path(os.join_path(os.dir(@FILE), 'testdata', + + 'toml_with_utf8_bom' + '.toml'))) or { panic(err) } +const toml_text_with_utf16_bom = os.read_file(os.real_path(os.join_path(os.dir(@FILE), 'testdata', + + 'toml_with_utf16_bom' + '.toml'))) or { panic(err) } +const toml_text_with_utf32_bom = os.read_file(os.real_path(os.join_path(os.dir(@FILE), 'testdata', + + 'toml_with_utf32_bom' + '.toml'))) or { panic(err) } fn test_toml_with_bom() { toml_doc := toml.parse_text(toml_text_with_utf8_bom) or { panic(err) } diff --git a/vlib/toml/tests/toml_lang_test.v b/vlib/toml/tests/toml_lang_test.v index 80c5a4cd1d..c366ed8030 100644 --- a/vlib/toml/tests/toml_lang_test.v +++ b/vlib/toml/tests/toml_lang_test.v @@ -68,11 +68,11 @@ fn test_toml_lang_tomltest() { } valid_folder := 'valid' - valid_test_files := test_files_list.filter(it.starts_with('valid/') && it.ends_with('.toml')).map(it.replace('\\', - '/')) + valid_test_files := + test_files_list.filter(it.starts_with('valid/') && it.ends_with('.toml')).map(it.replace('\\', '/')) invalid_folder := 'invalid' - invalid_test_files := test_files_list.filter(it.starts_with('invalid/') && it.ends_with('.toml')).map(it.replace('\\', - '/')) + invalid_test_files := + test_files_list.filter(it.starts_with('invalid/') && it.ends_with('.toml')).map(it.replace('\\', '/')) assert valid_test_files.len > 0, 'Expected a list of *valid* test files' assert invalid_test_files.len > 0, 'Expected a list of *invalid* test files' @@ -145,8 +145,10 @@ fn test_toml_lang_tomltest() { // eprintln(' relative: ${relative} parsed') v_toml_json_path := os.join_path(compare_work_dir_root, + os.file_name(valid_test_file).all_before_last('.') + '.v.json') bs_toml_json_path := os.join_path(compare_work_dir_root, + os.file_name(valid_test_file).all_before_last('.') + '.json') os.write_file(v_toml_json_path, to_toml_lang(toml_doc.ast.table))! diff --git a/vlib/toml/tests/toml_rs_test.v b/vlib/toml/tests/toml_rs_test.v index 84a0e261e5..c34c7c1c43 100644 --- a/vlib/toml/tests/toml_rs_test.v +++ b/vlib/toml/tests/toml_rs_test.v @@ -138,8 +138,10 @@ fn test_toml_rs_toml_rs() { toml_doc := toml.parse_file(valid_test_file)! v_toml_json_path := os.join_path(compare_work_dir_root, + os.file_name(valid_test_file).all_before_last('.') + '.v.json') toml_rs_toml_json_path := os.join_path(compare_work_dir_root, + os.file_name(valid_test_file).all_before_last('.') + '.json') mut array_type := 1 @@ -238,8 +240,7 @@ fn to_toml_rs(value ast.Value, array_type int) string { } ast.DateTime { // Normalization for json - mut json_text := json2.Any(value.text).json_str().to_upper().replace(' ', - 'T') + mut json_text := json2.Any(value.text).json_str().to_upper().replace(' ', 'T') typ := if json_text.ends_with('Z"') || json_text.all_after('T').contains('-') || json_text.all_after('T').contains('+') { 'datetime' diff --git a/vlib/toml/toml.v b/vlib/toml/toml.v index 9c468978d1..7fc0d56b27 100644 --- a/vlib/toml/toml.v +++ b/vlib/toml/toml.v @@ -97,56 +97,47 @@ fn decode_struct[T](doc Any, mut typ T) { // |k, v| k, v.int() // Unfortunately lambdas have issues with multiple return at the time of writing map[string]int { - typ.$(field.name) = maps.to_map[string, Any, string, int](mmap, - fn (k string, v Any) (string, int) { + typ.$(field.name) = maps.to_map[string, Any, string, int](mmap, fn (k string, v Any) (string, int) { return k, v.int() }) } map[string]i64 { - typ.$(field.name) = maps.to_map[string, Any, string, i64](mmap, - fn (k string, v Any) (string, i64) { + typ.$(field.name) = maps.to_map[string, Any, string, i64](mmap, fn (k string, v Any) (string, i64) { return k, v.i64() }) } map[string]u64 { - typ.$(field.name) = maps.to_map[string, Any, string, u64](mmap, - fn (k string, v Any) (string, u64) { + typ.$(field.name) = maps.to_map[string, Any, string, u64](mmap, fn (k string, v Any) (string, u64) { return k, v.u64() }) } map[string]f32 { - typ.$(field.name) = maps.to_map[string, Any, string, f32](mmap, - fn (k string, v Any) (string, f32) { + typ.$(field.name) = maps.to_map[string, Any, string, f32](mmap, fn (k string, v Any) (string, f32) { return k, v.f32() }) } map[string]f64 { - typ.$(field.name) = maps.to_map[string, Any, string, f64](mmap, - fn (k string, v Any) (string, f64) { + typ.$(field.name) = maps.to_map[string, Any, string, f64](mmap, fn (k string, v Any) (string, f64) { return k, v.f64() }) } map[string]bool { - typ.$(field.name) = maps.to_map[string, Any, string, bool](mmap, - fn (k string, v Any) (string, bool) { + typ.$(field.name) = maps.to_map[string, Any, string, bool](mmap, fn (k string, v Any) (string, bool) { return k, v.bool() }) } map[string]DateTime { - typ.$(field.name) = maps.to_map[string, Any, string, DateTime](mmap, - fn (k string, v Any) (string, DateTime) { + typ.$(field.name) = maps.to_map[string, Any, string, DateTime](mmap, fn (k string, v Any) (string, DateTime) { return k, v.datetime() }) } map[string]Date { - typ.$(field.name) = maps.to_map[string, Any, string, Date](mmap, - fn (k string, v Any) (string, Date) { + typ.$(field.name) = maps.to_map[string, Any, string, Date](mmap, fn (k string, v Any) (string, Date) { return k, v.date() }) } map[string]Time { - typ.$(field.name) = maps.to_map[string, Any, string, Time](mmap, - fn (k string, v Any) (string, Time) { + typ.$(field.name) = maps.to_map[string, Any, string, Time](mmap, fn (k string, v Any) (string, Time) { return k, v.time() }) } @@ -181,7 +172,7 @@ pub fn encode[T](typ T) string { return '' } -fn encode_struct[T](typ T) map[string]Any { +fn encode_struct[T](typ T) map[string]toml.Any { mut mp := map[string]Any{} $for field in T.fields { mut skip := false diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 9e25ec03c3..13bf18da43 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -3054,43 +3054,43 @@ pub fn all_registers(mut t Table, arch pref.Arch) map[string]ScopeObject { } } .arm32 { - arm32 := gen_all_registers(mut t, arm_no_number_register_list, arm_with_number_register_list, - 32) + arm32 := gen_all_registers(mut t, arm_no_number_register_list, + arm_with_number_register_list, 32) for k, v in arm32 { res[k] = v } } .arm64 { - arm64 := gen_all_registers(mut t, arm_no_number_register_list, arm_with_number_register_list, - 64) + arm64 := gen_all_registers(mut t, arm_no_number_register_list, + arm_with_number_register_list, 64) for k, v in arm64 { res[k] = v } } .rv32 { - rv32 := gen_all_registers(mut t, riscv_no_number_register_list, riscv_with_number_register_list, - 32) + rv32 := gen_all_registers(mut t, riscv_no_number_register_list, + riscv_with_number_register_list, 32) for k, v in rv32 { res[k] = v } } .rv64 { - rv64 := gen_all_registers(mut t, riscv_no_number_register_list, riscv_with_number_register_list, - 64) + rv64 := gen_all_registers(mut t, riscv_no_number_register_list, + riscv_with_number_register_list, 64) for k, v in rv64 { res[k] = v } } .s390x { - s390x := gen_all_registers(mut t, s390x_no_number_register_list, s390x_with_number_register_list, - 64) + s390x := gen_all_registers(mut t, s390x_no_number_register_list, + s390x_with_number_register_list, 64) for k, v in s390x { res[k] = v } } .ppc64le { - ppc64le := gen_all_registers(mut t, ppc64le_no_number_register_list, ppc64le_with_number_register_list, - 64) + ppc64le := gen_all_registers(mut t, ppc64le_no_number_register_list, + ppc64le_with_number_register_list, 64) for k, v in ppc64le { res[k] = v } diff --git a/vlib/v/ast/cflags_test.v b/vlib/v/ast/cflags_test.v index cc80d43308..e0f8498f88 100644 --- a/vlib/v/ast/cflags_test.v +++ b/vlib/v/ast/cflags_test.v @@ -36,7 +36,8 @@ fn test_parse_valid_cflags() { parse_valid_flag(mut t, 'mingw -mwindows') parse_valid_flag(mut t, 'solaris -L/opt/local/lib') parse_valid_flag(mut t, 'windows -lgdi32') - parse_valid_flag(mut t, 'linux -I/usr/include/SDL2 -D_REENTRANT -L/usr/lib/x86_64-linux-gnu -lSDL2') + parse_valid_flag(mut t, + 'linux -I/usr/include/SDL2 -D_REENTRANT -L/usr/lib/x86_64-linux-gnu -lSDL2') parse_valid_flag(mut t, '-I/usr/include/mysql -m64 -I/usr/include') parse_valid_flag(mut t, '/v/thirdparty/tcc/lib/libgc.a') parse_valid_flag(mut t, '-I/usr/include/你好 my , @с интервали') diff --git a/vlib/v/ast/scope.v b/vlib/v/ast/scope.v index d7dee9f4c6..186481e89d 100644 --- a/vlib/v/ast/scope.v +++ b/vlib/v/ast/scope.v @@ -186,6 +186,14 @@ pub fn (mut s Scope) update_smartcasts(name string, typ Type, is_unwrapped bool) } } +pub fn (mut s Scope) reset_smartcasts(name string) { + mut obj := unsafe { s.objects[name] } + if mut obj is Var { + obj.smartcasts = [] + obj.is_unwrapped = false + } +} + // selector_expr: name.field_name pub fn (mut s Scope) register_struct_field(name string, field ScopeStructField) { k := '${name}.${field.name}' diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index 8702fc4858..e5aabb135b 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -254,8 +254,7 @@ fn (t &Table) stringify_fn_after_name(node &FnDecl, mut f strings.Builder, cur_m } else { node.return_type } - sreturn_type := shorten_full_name_based_on_cur_mod(t.type_to_str(return_type), - cur_mod) + sreturn_type := shorten_full_name_based_on_cur_mod(t.type_to_str(return_type), cur_mod) short_sreturn_type := shorten_full_name_based_on_aliases(sreturn_type, m2a) f.write_string(' ${short_sreturn_type}') } diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 3a3bd23ff3..0e10c6a6b9 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -1046,11 +1046,24 @@ pub fn (mut t Table) update_sym_by_idx(existing_idx int, sym &TypeSymbol) { } fn (mut t Table) promote_placeholder_generic_children(parent_idx int, sym TypeSymbol) { + parent_generic_types := match sym.info { + Struct { sym.info.generic_types } + Interface { sym.info.generic_types } + SumType { sym.info.generic_types } + else { []Type{} } + } for i, child in t.type_symbols { if child.kind != .placeholder || child.parent_idx != parent_idx || child.generic_types.len == 0 { continue } + if child.generic_types == parent_generic_types { + // The placeholder child uses the same generic types as the parent struct + // (e.g. Iter where Iter[T] uses the same T). Redirect it to the parent + // rather than creating a redundant promoted type. + t.type_symbols[i] = t.type_symbols[parent_idx] + continue + } t.update_sym_by_idx(i, &TypeSymbol{ ...sym name: child.name @@ -2030,6 +2043,68 @@ pub fn (mut t Table) complete_interface_check() { } } } + // For empty interfaces, propagate concrete types from all other interfaces + // into the empty interface's variant list. Empty interfaces can be assigned + // from any interface (e.g. `IError` -> `EmptyIface{}`); at runtime the empty + // interface will hold the source interface's dynamic type, so the empty + // interface must have cast functions for each possible concrete variant. + mut empty_iface_typs := []Type{} + for _, idecl in t.interfaces { + if idecl.typ == 0 { + continue + } + if idecl.methods.len == 0 && idecl.fields.len == 0 { + empty_iface_typs << idecl.typ + } + } + for iface_typ in empty_iface_typs { + mut iface_sym := t.sym(iface_typ) + if iface_sym.info !is Interface { + continue + } + mut iface_info := iface_sym.info as Interface + mut collected_types := []Type{} + mut seen_cnames := map[string]bool{} + for existing in iface_info.types { + existing_sym := t.sym(mktyp(existing)) + seen_cnames[existing_sym.cname] = true + } + for _, other_sym in t.type_symbols { + if other_sym.kind != .interface || other_sym.idx == iface_sym.idx { + continue + } + if other_sym.info !is Interface { + continue + } + other_info := other_sym.info as Interface + for variant in other_info.types { + mk_variant := mktyp(variant) + variant_sym := t.sym(mk_variant) + if variant_sym.kind != .struct { + continue + } + if variant_sym.cname in seen_cnames { + continue + } + seen_cnames[variant_sym.cname] = true + collected_types << mk_variant + } + } + if collected_types.len > 0 { + iface_info.types << collected_types + iface_sym.info = iface_info + if iface_sym.name !in t.iface_types { + t.iface_types[iface_sym.name] = []Type{} + } + mut target_variants := t.iface_types[iface_sym.name].clone() + for variant in collected_types { + if variant !in target_variants { + target_variants << variant + } + } + t.iface_types[iface_sym.name] = target_variants + } + } } // bitsize_to_type returns a type corresponding to the bit_size @@ -2062,8 +2137,7 @@ pub fn (mut t Table) bitsize_to_type(bit_size int) Type { if bit_size % 8 != 0 { // there is no way to do `i2131(32)` so this should never be reached t.panic('table.bitsize_to_type: compiler bug: bitsizes must be multiples of 8, but passed bit_size is ${bit_size}') } - return new_type(t.find_or_register_array_fixed(u8_type, bit_size / 8, empty_expr, - false)) + return new_type(t.find_or_register_array_fixed(u8_type, bit_size / 8, empty_expr, false)) } } } @@ -2114,8 +2188,7 @@ pub fn (t &Table) does_type_implement_interface(typ Type, inter_typ Type) bool { mut inter_sym := t.sym(inter_typ) if sym.kind == .interface && inter_sym.kind == .interface { inter_info := inter_sym.info as Interface - if inter_info.methods.len == 0 && inter_info.fields.len == 0 - && inter_info.embeds.len == 0 { + if inter_info.methods.len == 0 && inter_info.fields.len == 0 && inter_info.embeds.len == 0 { return true } if !t.interface_inherits_interface(typ, inter_typ) { @@ -2182,7 +2255,7 @@ pub fn (t &Table) does_type_implement_interface(typ Type, inter_typ Type) bool { } return false } - if !is_interface_upcast && typ != voidptr_type && typ != nil_type && typ != none_type + if sym.kind != .interface && typ != voidptr_type && typ != nil_type && typ != none_type && !inter_sym.info.types.contains(typ) { inter_sym.info.types << typ } @@ -2309,8 +2382,8 @@ pub fn (mut t Table) convert_generic_type(generic_type Type, generic_names []str param.typ = typ } if t.sym(param.typ).kind == .placeholder { - param.typ = t.unwrap_generic_type_ex(orig_param_type, generic_names, - to_types, true) + param.typ = + t.unwrap_generic_type_ex(orig_param_type, generic_names, to_types, true) } if param.typ.has_flag(.generic) || t.generic_type_names(param.typ).len > 0 { has_generic = true @@ -2864,7 +2937,9 @@ fn (mut t Table) convert_generic_default_expr(expr Expr, generic_names []string, } } if func.generic_names.len > 0 { - if typ_ := t.convert_generic_type(fn_type, func.generic_names, resolved_concrete_types) { + if typ_ := t.convert_generic_type(fn_type, func.generic_names, + resolved_concrete_types) + { fn_type = typ_ } } @@ -3143,7 +3218,17 @@ pub fn (mut t Table) generic_type_names(generic_type Type) []string { } } } - else {} + else { + // For placeholder types (forward-declared generic structs), + // check generic_types on the symbol itself + if sym.generic_types.len > 0 { + for typ in sym.generic_types { + if typ.has_flag(.generic) && t.sym(typ).kind == .any { + names << t.sym(typ).name + } + } + } + } } return names } @@ -3155,8 +3240,8 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr // unwrap_generic_type_ex resolves generic symbols to concrete types and can recheck nested concrete fields. pub fn (mut t Table) unwrap_generic_type_ex(typ Type, generic_names []string, concrete_types []Type, recheck_concrete_types bool) Type { - return t.unwrap_generic_type_ex_with_depth(typ, generic_names, concrete_types, recheck_concrete_types, - []string{}) + return t.unwrap_generic_type_ex_with_depth(typ, generic_names, concrete_types, + recheck_concrete_types, []string{}) } fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []string, concrete_types []Type, recheck_concrete_types bool, depth_guard []string) Type { @@ -3336,14 +3421,15 @@ fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []str } // update concrete types for i in 0 .. ts.info.generic_types.len { - if t_typ := t.convert_generic_type(ts.info.generic_types[i], t_generic_names, - t_concrete_types) + if t_typ := t.convert_generic_type(ts.info.generic_types[i], + t_generic_names, t_concrete_types) { final_concrete_types << t_typ } } if final_concrete_types.len > 0 { - t.unwrap_method_types(ts, generic_names, concrete_types, final_concrete_types) + t.unwrap_method_types(ts, generic_names, concrete_types, + final_concrete_types) } } if idx <= 0 { @@ -3369,8 +3455,8 @@ fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []str fields = ts.info.fields.clone() for i in 0 .. fields.len { orig_type := fields[i].typ - resolved_field_typ := t.unwrap_generic_type_ex_with_depth(orig_type, t_generic_names, - t_concrete_types, recheck_concrete_types, new_depth_guard) + resolved_field_typ := t.unwrap_generic_type_ex_with_depth(orig_type, + t_generic_names, t_concrete_types, recheck_concrete_types, new_depth_guard) if resolved_field_typ != orig_type { fields[i].typ = resolved_field_typ // Update type in `info.embeds`, if it's embed @@ -3410,6 +3496,31 @@ fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []str } } } + GenericInst { + // Resolve GenericInst concrete_types that still contain generic parameters. + // E.g. CacheStore[K, &CacheItem[K, V]] with K=string, V=int becomes + // CacheStore[string, &CacheItem[string, int]]. + mut resolved_cts := ts.info.concrete_types.clone() + mut changed := false + for i in 0 .. resolved_cts.len { + if resolved_cts[i].has_flag(.generic) { + new_ct := t.unwrap_generic_type_ex_with_depth(resolved_cts[i], generic_names, + concrete_types, recheck_concrete_types, depth_guard) + if new_ct != resolved_cts[i] { + resolved_cts[i] = new_ct + changed = true + } + } + } + if changed { + parent_typ := new_type(ts.info.parent_idx) + idx := t.find_or_register_generic_inst(parent_typ, resolved_cts) + if idx > 0 { + return new_type(idx).derive_add_muls(typ).clear_flag(.generic) + } + } + return typ + } else {} } match ts.info { @@ -3432,6 +3543,10 @@ fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []str t.unwrap_method_types(ts, generic_names, concrete_types, final_concrete_types) } if new_idx <= 0 { + existing := t.type_idxs[nrt] + if existing > 0 { + return new_type(existing).derive(typ).clear_flag(.generic) + } return typ } return new_type(new_idx).derive(typ).clear_flag(.generic) @@ -3444,10 +3559,12 @@ fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []str if variants[i].has_flag(.generic) || sym.kind == .generic_inst || (sym.kind in [.struct, .sum_type, .interface] && sym.has_generic_type_info()) { if sym.kind in [.struct, .sum_type, .interface] { - variants[i] = t.unwrap_generic_type_ex_with_depth(variants[i], - gn_names, final_concrete_types, false, new_depth_guard) + variants[i] = t.unwrap_generic_type_ex_with_depth(variants[i], gn_names, + final_concrete_types, false, new_depth_guard) } else { - if t_typ := t.convert_generic_type(variants[i], gn_names, final_concrete_types) { + if t_typ := t.convert_generic_type(variants[i], gn_names, + final_concrete_types) + { variants[i] = t_typ } } @@ -3472,6 +3589,10 @@ fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []str t.unwrap_method_types(ts, generic_names, concrete_types, final_concrete_types) } if new_idx <= 0 { + existing := t.type_idxs[nrt] + if existing > 0 { + return new_type(existing).derive(typ).clear_flag(.generic) + } return typ } return new_type(new_idx).derive(typ).clear_flag(.generic) @@ -3480,14 +3601,23 @@ fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []str // resolve generic types inside methods mut imethods := ts.info.methods.clone() gn_names := t.get_real_generic_names(typ, generic_names) + // Use final_concrete_types (the interface's own resolved concrete types) + // instead of concrete_types (the outer struct's types) so that nested + // generic type arguments like CacheStore[K, &CacheItem[K, V]] resolve + // V to &CacheItem[string, int] rather than plain int. + iface_concrete := if final_concrete_types.len == gn_names.len { + final_concrete_types + } else { + concrete_types[..gn_names.len] + } for mut method in imethods { if unwrap_typ := t.convert_generic_type(method.return_type, gn_names, - concrete_types[..gn_names.len]) + iface_concrete) { method.return_type = unwrap_typ } for mut param in method.params { - if unwrap_typ := t.convert_generic_param_type(param, gn_names, concrete_types) { + if unwrap_typ := t.convert_generic_param_type(param, gn_names, iface_concrete) { param.typ = unwrap_typ } } @@ -3515,14 +3645,25 @@ fn (mut t Table) unwrap_generic_type_ex_with_depth(typ Type, generic_names []str info: info is_pub: ts.is_pub ) - mut ts_copy := t.sym(idx_to_type(new_idx)) - for method in all_methods { - ts_copy.register_method(method) + if new_idx > 0 { + mut ts_copy := t.sym(idx_to_type(new_idx)) + for method in all_methods { + ts_copy.register_method(method) + } } if final_concrete_types.len > 0 { t.unwrap_method_types(ts, generic_names, concrete_types, final_concrete_types) } if new_idx <= 0 { + // register_sym can fail when convert_generic_type (used above to + // resolve method parameter types) calls find_or_register_generic_inst, + // which converts the placeholder we created earlier into a generic_inst. + // In that case, look up the existing entry and use it — the + // generic_insts_to_concrete pass will resolve it later. + existing := t.type_idxs[nrt] + if existing > 0 { + return new_type(existing).derive(typ).clear_flag(.generic) + } return typ } return new_type(new_idx).derive(typ).clear_flag(.generic) @@ -3585,8 +3726,7 @@ fn (mut t Table) specialize_generic_fn_method_type(typ Type, parent_type Type, c elem_typ := t.specialize_generic_fn_method_type(sym.info.elem_type, parent_type, concrete_type, generic_names, concrete_types) if elem_typ != sym.info.elem_type { - idx := t.find_or_register_array_fixed(elem_typ, sym.info.size, None{}, - false) + idx := t.find_or_register_array_fixed(elem_typ, sym.info.size, None{}, false) if elem_typ.has_flag(.generic) { return new_type(idx).derive_add_muls(typ).set_flag(.generic) } @@ -3699,7 +3839,8 @@ pub fn (mut t Table) generic_insts_to_concrete() { Struct { mut parent_info := parent.info as Struct if !parent_info.is_generic { - util.verror('generic error', 'struct `${parent.name}` is not a generic struct, cannot instantiate to the concrete types') + util.verror('generic error', + 'struct `${parent.name}` is not a generic struct, cannot instantiate to the concrete types') continue } mut fields := parent_info.fields.clone() @@ -3758,13 +3899,15 @@ pub fn (mut t Table) generic_insts_to_concrete() { } } } else { - util.verror('generic error', 'the number of generic types of struct `${parent.name}` is inconsistent with the concrete types') + util.verror('generic error', + 'the number of generic types of struct `${parent.name}` is inconsistent with the concrete types') } } Interface { mut parent_info := parent.info as Interface if !parent_info.is_generic { - util.verror('generic error', 'interface `${parent.name}` is not a generic interface, cannot instantiate to the concrete types') + util.verror('generic error', + 'interface `${parent.name}` is not a generic interface, cannot instantiate to the concrete types') continue } if parent_info.generic_types.len == info.concrete_types.len { @@ -3815,13 +3958,15 @@ pub fn (mut t Table) generic_insts_to_concrete() { sym.kind = parent.kind sym.methods = all_methods } else { - util.verror('generic error', 'the number of generic types of interface `${parent.name}` is inconsistent with the concrete types') + util.verror('generic error', + 'the number of generic types of interface `${parent.name}` is inconsistent with the concrete types') } } SumType { mut parent_info := parent.info as SumType if !parent_info.is_generic { - util.verror('generic error', 'sumtype `${parent.name}` is not a generic sumtype, cannot instantiate to the concrete types') + util.verror('generic error', + 'sumtype `${parent.name}` is not a generic sumtype, cannot instantiate to the concrete types') continue } if parent_info.generic_types.len == info.concrete_types.len { @@ -3864,7 +4009,8 @@ pub fn (mut t Table) generic_insts_to_concrete() { sym.is_pub = true sym.kind = parent.kind } else { - util.verror('generic error', 'the number of generic types of sumtype `${parent.name}` is inconsistent with the concrete types') + util.verror('generic error', + 'the number of generic types of sumtype `${parent.name}` is inconsistent with the concrete types') } } FnType { @@ -3880,16 +4026,16 @@ pub fn (mut t Table) generic_insts_to_concrete() { } } if param.orig_typ.has_flag(.generic) { - if t_typ := t.convert_generic_type(param.orig_typ, function.generic_names, - info.concrete_types) + if t_typ := t.convert_generic_type(param.orig_typ, + function.generic_names, info.concrete_types) { param.orig_typ = t_typ } } } if function.return_type.has_flag(.generic) { - if t_typ := t.convert_generic_type(function.return_type, function.generic_names, - info.concrete_types) + if t_typ := t.convert_generic_type(function.return_type, + function.generic_names, info.concrete_types) { function.return_type = t_typ } diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 2c6bbb4e66..e7bd7fdfab 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -561,7 +561,7 @@ pub fn (b &Builder) find_module_path(mod string, fpath string) !string { if b.pref.is_verbose { println(' >> trying to find ${mod} in ${try_path} ..') } - if found_path := find_module_path_from_search_root(p1, mod) { + if found_path := find_module_path_from_search_root(current_dir, mod) { return found_path } parent_dir := os.dir(current_dir) @@ -607,7 +607,8 @@ pub fn (b &Builder) show_total_warns_and_errors_stats() { // the intended command may have been `v .` instead, so just suggest that: old_cmd := util.bold('v ${b.pref.path}') new_cmd := util.bold('v ${os.dir(b.pref.path)}') - eprintln(util.color('notice', 'If the code of your project is in a folder with multiple .v files, try `${new_cmd}` instead of `${old_cmd}`')) + eprintln(util.color('notice', + 'If the code of your project is in a folder with multiple .v files, try `${new_cmd}` instead of `${old_cmd}`')) } } } @@ -744,8 +745,8 @@ pub fn (mut b Builder) print_warnings_and_errors() { for stmt in file.stmts { if stmt is ast.FnDecl { if stmt.name == fn_name { - fheader := b.table.stringify_fn_decl(&stmt, 'main', map[string]string{}, - false) + fheader := b.table.stringify_fn_decl(&stmt, 'main', + map[string]string{}, false) redefines << FunctionRedefinition{ fpath: file.path fline: stmt.pos.line_nr diff --git a/vlib/v/builder/builder_test.v b/vlib/v/builder/builder_test.v index 7dd2307d66..4c5e344910 100644 --- a/vlib/v/builder/builder_test.v +++ b/vlib/v/builder/builder_test.v @@ -108,8 +108,7 @@ fn main() { println(somemoduletwo.name()) } ')! - os.write_file(os.join_path(project_dir, 'modules', 'somemoduletwo', 'somemoduletwo.v'), - 'module somemoduletwo + os.write_file(os.join_path(project_dir, 'modules', 'somemoduletwo', 'somemoduletwo.v'), 'module somemoduletwo pub fn name() string { return "somemoduletwo" @@ -130,8 +129,7 @@ fn test_thirdparty_object_build_with_multiline_cflags() { } mut p := os.new_process(vexe) p.set_work_folder(@VEXEROOT) - p.set_args(['run', os.join_path(@VEXEROOT, 'vlib', 'v', 'tests', 'project_with_c_code', - 'main.v')]) + p.set_args(['run', os.join_path(@VEXEROOT, 'vlib', 'v', 'tests', 'project_with_c_code', 'main.v')]) p.set_environment(env) p.set_redirect_stdio() p.wait() diff --git a/vlib/v/builder/cbuilder/parallel_cc.v b/vlib/v/builder/cbuilder/parallel_cc.v index e31d672e40..dbc4b01b37 100644 --- a/vlib/v/builder/cbuilder/parallel_cc.v +++ b/vlib/v/builder/cbuilder/parallel_cc.v @@ -102,7 +102,8 @@ fn parallel_cc(mut b builder.Builder, result c.GenOutput) ! { for x in pp.get_results[os.Result]() { failed += if x.exit_code == 0 { 0 } else { 1 } } - eprint_time(sw, 'C compilation on ${util.nr_jobs} thread(s), processing ${cmds.len} commands, failed: ${failed}') + eprint_time(sw, + 'C compilation on ${util.nr_jobs} thread(s), processing ${cmds.len} commands, failed: ${failed}') if failed > 0 { return error_with_code('failed parallel C compilation', failed) } diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 6c26daae11..5e12a37ec4 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -130,6 +130,25 @@ fn c_error_looks_like_missing_libatomic(c_output string) bool { return c_error_missing_libatomic_marker(c_output) != '' } +fn c_error_missing_library_name(c_output string) string { + for line in c_output.split_into_lines() { + if line.contains("library '") && line.contains("' not found") { + return line.all_after("library '").all_before("' not found") + } + for marker in [ + 'cannot find -l', + 'unable to find library -l', + 'library not found for -l', + ] { + if line.contains(marker) { + lib_name := line.all_after(marker).trim_space() + return lib_name.all_before('`').all_before("'").all_before('"').all_before(' ') + } + } + } + return '' +} + fn (mut v Builder) show_c_compiler_output(ccompiler string, res os.Result) { header := '======== Output of the C Compiler (${ccompiler}) ========' println(header) @@ -158,9 +177,15 @@ fn (mut v Builder) post_process_c_compiler_output(ccompiler string, res os.Resul return } libatomic_marker := c_error_missing_libatomic_marker(res.output) + missing_library_name := if libatomic_marker == '' { + c_error_missing_library_name(res.output) + } else { + '' + } for emsg_marker in [c_verror_message_marker, 'error: include file '] { if res.output.contains(emsg_marker) { - emessage := res.output.all_after(emsg_marker).all_before('\n').all_before('\r').trim_right('\r\n') + emessage := + res.output.all_after(emsg_marker).all_before('\n').all_before('\r').trim_right('\r\n') verror(emessage) } } @@ -234,6 +259,12 @@ C error found while compiling generated C code. The C toolchain could not find `libatomic`, which V needs for `sync.stdatomic` with this compiler on this platform. Install the system package that provides `libatomic` and retry. On CentOS/RHEL, that is usually `libatomic` or `libatomic-devel`.${more_suggestions}') + } + if missing_library_name != '' { + verror(' +================== +C library `${missing_library_name}` was not found while linking the generated program. +Please install the corresponding development package/libraries and make sure the linker can find it.${more_suggestions}') } verror(' ================== @@ -622,8 +653,8 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) { ccoptions.linker_flags << '-lelf' } } - ccoptions.env_cflags = os.getenv('CFLAGS') - ccoptions.env_ldflags = os.getenv('LDFLAGS') + ccoptions.env_cflags = os.getenv('CFLAGS').replace('\n', ' ') + ccoptions.env_ldflags = os.getenv('LDFLAGS').replace('\n', ' ') if v.pref.os == .macos { if v.pref.use_cache { ccoptions.source_args << '-x none' @@ -775,8 +806,8 @@ fn (mut v Builder) setup_output_name() { } } if v.pref.build_mode == .build_module { - v.pref.out_name = v.pref.cache_manager.mod_postfix_with_key2cpath(v.pref.path, - '.o', v.pref.path) // v.out_name + v.pref.out_name = v.pref.cache_manager.mod_postfix_with_key2cpath(v.pref.path, '.o', + v.pref.path) // v.out_name if v.pref.is_verbose { println('Building ${v.pref.path} to ${v.pref.out_name} ...') } @@ -1095,7 +1126,8 @@ pub fn (mut v Builder) cc() { v.show_c_compiler_output(ccompiler, res) } os.chdir(original_pwd) or {} - vcache.dlog('| Builder.' + @FN, '> v.pref.use_cache: ${v.pref.use_cache} | v.pref.retry_compilation: ${v.pref.retry_compilation}') + vcache.dlog('| Builder.' + @FN, + '> v.pref.use_cache: ${v.pref.use_cache} | v.pref.retry_compilation: ${v.pref.retry_compilation}') vcache.dlog('| Builder.' + @FN, '> cmd res.exit_code: ${res.exit_code} | cmd: ${cmd}') vcache.dlog('| Builder.' + @FN, '> response_file_content:\n${response_file_content}') if res.exit_code != 0 { @@ -1276,58 +1308,6 @@ fn (mut b Builder) cc_linux_cross() { verror(cc_res.output) return } - // Compile extra .c source files (from `#flag @VMODROOT/file.c` etc.) - // separately for the cross target, and collect the resulting .o files. - mut extra_obj_files := []string{cap: extra_c_sources.len} - for csource in extra_c_sources { - extra_obj := csource + '.o' - mut extra_cc_args := []string{cap: 10} - extra_cc_args << '-w' - extra_cc_args << '-fPIC' - extra_cc_args << '-target x86_64-linux-gnu' - extra_cc_args << defines - extra_cc_args << conly_flags - extra_cc_args << '-I ${os.quoted_path('${sysroot}/include')} ' - extra_cc_args << '-o ${os.quoted_path(extra_obj)}' - extra_cc_args << '-c ${os.quoted_path(csource)}' - extra_cmd := '${b.quote_compiler_name(cc_name)} ' + extra_cc_args.join(' ') - if b.pref.show_cc { - println(extra_cmd) - } - extra_res := os.execute(extra_cmd) - if extra_res.exit_code != 0 { - println('Cross compilation for Linux failed (compiling ${csource}).') - verror(extra_res.output) - return - } - extra_obj_files << os.quoted_path(extra_obj) - } - // For libraries that only exist as static .a in the sysroot (e.g. libpq.a), - // create shared library stubs so the linker produces a dynamically linked binary - // instead of pulling in incomplete static archives with missing internal deps. - lib_search_paths := [ - os.join_path(sysroot, 'usr', 'lib', 'x86_64-linux-gnu'), - os.join_path(sysroot, 'lib', 'x86_64-linux-gnu'), - ] - stubs_dir := os.join_path(os.vtmp_dir(), 'cross_linux_stubs') - os.mkdir_all(stubs_dir) or {} - for lib in libs { - libname := lib.replace('-l', '') - if libname in ['c', 'pthread', 'm', 'dl'] { - continue // standard libs, always available - } - has_so := lib_search_paths.any(os.exists(os.join_path(it, 'lib${libname}.so'))) - has_a := !has_so && lib_search_paths.any(os.exists(os.join_path(it, 'lib${libname}.a'))) - if has_a { - a_path := lib_search_paths.map(os.join_path(it, 'lib${libname}.a')).filter(os.exists(it))[0] or { - continue - } - stub_so := os.join_path(stubs_dir, 'lib${libname}.so') - if !os.exists(stub_so) { - b.create_shared_lib_stub(cc_name, a_path, stub_so, sysroot) - } - } - } // Compile compiler runtime builtins (provides __udivti3 etc. for 128-bit integer // operations used by thirdparty code like mbedtls bignum.c, since the linuxroot // sysroot doesn't include libgcc or compiler-rt). @@ -1590,7 +1570,8 @@ fn (mut b Builder) build_thirdparty_obj_files() { rest_of_module_flags := b.get_rest_of_module_cflags(flag) $if windows { if b.pref.ccompiler == 'msvc' { - b.build_thirdparty_obj_file_with_msvc(flag.mod, flag.value, rest_of_module_flags) + b.build_thirdparty_obj_file_with_msvc(flag.mod, flag.value, + rest_of_module_flags) continue } } @@ -1699,9 +1680,8 @@ fn (mut v Builder) build_thirdparty_obj_file(mod string, path string, moduleflag verror(res.output) return } - v.pref.cache_manager.mod_save(mod, '.thirdparty.description.txt', obj_path, get_dsc_content('OBJ_PATH: ${obj_path}\nCMD: ${cmd}\n')) or { - panic(err) - } + v.pref.cache_manager.mod_save(mod, '.thirdparty.description.txt', obj_path, + get_dsc_content('OBJ_PATH: ${obj_path}\nCMD: ${cmd}\n')) or { panic(err) } if v.pref.show_cc { println('>> OBJECT FILE compilation cmd: ${cmd}') } @@ -1802,7 +1782,8 @@ pub fn (mut v Builder) quote_compiler_name(name string) string { fn write_response_file(response_file string, response_file_content string) { $if windows { - os.write_file_array(response_file, string_to_ansi_not_null_terminated(response_file_content)) or { + os.write_file_array(response_file, + string_to_ansi_not_null_terminated(response_file_content)) or { write_response_file_error(response_file_content, err) } } $else { diff --git a/vlib/v/builder/cc_test.v b/vlib/v/builder/cc_test.v index f401662234..89505a60d2 100644 --- a/vlib/v/builder/cc_test.v +++ b/vlib/v/builder/cc_test.v @@ -102,15 +102,10 @@ fn test_c_output_suggests_missing_typedef_for_c_struct_requires_matching_redecla fn test_c_error_missing_library_name_detects_tcc_output() { tcc_output := "tcc: error: library 'pq' not found" - lib_name := c_error_missing_library_name(tcc_output) or { panic(err) } + lib_name := c_error_missing_library_name(tcc_output) assert lib_name == 'pq' } -fn test_detect_cc_from_version_output_detects_clang() { - clang_output := 'Apple clang version 17.0.0 (clang-1700.6.3.2)\nTarget: arm64-apple-darwin25.2.0' - assert detect_cc_from_version_output(clang_output) == .clang -} - fn test_c_error_missing_libatomic_marker_with_tcc_output() { c_output := "/tmp/v/vdoc.tmp.c:24184: warning: assignment makes pointer from integer without a cast\ntcc: error: library 'atomic' not found\n" assert c_error_missing_libatomic_marker(c_output) == "library 'atomic' not found" @@ -128,3 +123,18 @@ fn test_c_error_missing_libatomic_marker_with_regular_c_error() { assert c_error_missing_libatomic_marker(c_output) == '' assert !c_error_looks_like_missing_libatomic(c_output) } + +fn test_c_error_missing_library_name_with_macos_ld_output() { + c_output := "ld: library 'mbedtls' not found\nclang: error: linker command failed with exit code 1\n" + assert c_error_missing_library_name(c_output) == 'mbedtls' +} + +fn test_c_error_missing_library_name_with_gnu_ld_output() { + c_output := '/usr/bin/ld: cannot find -lssl\ncollect2: error: ld returned 1 exit status\n' + assert c_error_missing_library_name(c_output) == 'ssl' +} + +fn test_c_error_missing_library_name_with_regular_c_error() { + c_output := "error: unknown type name 'my_missing_type'" + assert c_error_missing_library_name(c_output) == '' +} diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index e211996714..7386296fb7 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -286,17 +286,15 @@ pub fn (v Builder) get_builtin_files() []string { if os.exists(os.join_path(location, 'builtin')) { mut builtin_files := []string{} if v.pref.backend.is_js() { - builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', - 'js')) + builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', 'js')) } else if v.pref.backend == .wasm { - builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', - 'wasm')) + builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', 'wasm')) if v.pref.os == .browser { - builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', - 'wasm', 'browser')) + builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', 'wasm', + 'browser')) } else { - builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', - 'wasm', 'wasi')) + builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', 'wasm', + 'wasi')) } } else { builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin')) @@ -364,7 +362,8 @@ pub fn (v &Builder) get_user_files() []string { } if !v_test_runner_prelude.contains('/') && !v_test_runner_prelude.contains('\\') && !v_test_runner_prelude.ends_with('.v') { - v_test_runner_prelude = os.join_path(preludes_path, 'test_runner_${v_test_runner_prelude}.v') + v_test_runner_prelude = os.join_path(preludes_path, + 'test_runner_${v_test_runner_prelude}.v') } if !os.is_file(v_test_runner_prelude) || !os.is_readable(v_test_runner_prelude) { eprintln('test runner error: File ${v_test_runner_prelude} should be readable.') diff --git a/vlib/v/builder/msvc_windows.v b/vlib/v/builder/msvc_windows.v index 689ad8be63..112c29c22c 100644 --- a/vlib/v/builder/msvc_windows.v +++ b/vlib/v/builder/msvc_windows.v @@ -25,7 +25,8 @@ fn find_windows_kit_internal(key RegKey, versions []string) !string { unsafe { for version in versions { required_bytes := u32(0) // TODO: mut - result := C.RegQueryValueEx(key, version.to_wide(), 0, 0, 0, voidptr(&required_bytes)) + result := C.RegQueryValueEx(key, version.to_wide(), 0, 0, 0, + voidptr(&required_bytes)) length := required_bytes / 2 if result != 0 { continue @@ -85,8 +86,8 @@ fn find_windows_kit_root_by_reg(target_arch string) !WindowsKit { $if windows { root_key := RegKey(0) path := 'SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots' - rc := C.RegOpenKeyEx(hkey_local_machine, path.to_wide(), 0, key_query_value | key_wow64_32key | key_enumerate_sub_keys, - voidptr(&root_key)) + rc := C.RegOpenKeyEx(hkey_local_machine, path.to_wide(), 0, + key_query_value | key_wow64_32key | key_enumerate_sub_keys, voidptr(&root_key)) if rc != 0 { return error('Unable to open root key') @@ -161,7 +162,8 @@ fn find_vs_by_reg(vswhere_dir string, host_arch string, target_arch string) !VsI // VSWhere is guaranteed to be installed at this location now // If its not there then end user needs to update their visual studio // installation! - res := os.execute('"${vswhere_dir}\\Microsoft Visual Studio\\Installer\\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath') + res := + os.execute('"${vswhere_dir}\\Microsoft Visual Studio\\Installer\\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath') // println('res: "${res}"') if res.exit_code != 0 { return error_with_code(res.output, res.exit_code) @@ -664,8 +666,8 @@ pub fn (mut v Builder) msvc_string_flags(cflags []cflag.CFlag) MsvcStringFlags { } real_libs << lib if parts.len > 1 { - _, leftover := split_and_apply_gnu_flags(parts[1..].join(' '), mut - inc_paths, mut lib_paths, mut real_libs) + _, leftover := split_and_apply_gnu_flags(parts[1..].join(' '), mut inc_paths, mut + lib_paths, mut real_libs) if leftover != '' { other_flags << strip_quotes(leftover) } @@ -691,9 +693,7 @@ pub fn (mut v Builder) msvc_string_flags(cflags []cflag.CFlag) MsvcStringFlags { if part == '' { continue } - if apply_gnu_flag_to_msvc(part, mut inc_paths, mut lib_paths, mut - real_libs) - { + if apply_gnu_flag_to_msvc(part, mut inc_paths, mut lib_paths, mut real_libs) { continue } if !part.starts_with('-') { @@ -726,9 +726,7 @@ pub fn (mut v Builder) msvc_string_flags(cflags []cflag.CFlag) MsvcStringFlags { if part == '' { continue } - if apply_gnu_flag_to_msvc(part, mut inc_paths, mut lib_paths, mut - real_libs) - { + if apply_gnu_flag_to_msvc(part, mut inc_paths, mut lib_paths, mut real_libs) { continue } if !part.starts_with('-') { diff --git a/vlib/v/builder/parallel_cc_failure_test.v b/vlib/v/builder/parallel_cc_failure_test.v index 047efc88c4..6228632371 100644 --- a/vlib/v/builder/parallel_cc_failure_test.v +++ b/vlib/v/builder/parallel_cc_failure_test.v @@ -5,7 +5,7 @@ import os const parallel_cc_test_path = os.join_path(os.vtmp_dir(), 'parallel_cc_failure_test') const parallel_cc_vexe = @VEXE -fn run_parallel_cc_failure_case(case_name string, files map[string]string) os.Result { +fn run_parallel_cc_case(case_name string, files map[string]string) os.Result { case_dir := os.join_path(parallel_cc_test_path, case_name) os.rmdir_all(case_dir) or {} os.mkdir_all(case_dir) or { panic(err) } @@ -21,10 +21,14 @@ fn run_parallel_cc_failure_case(case_name string, files map[string]string) os.Re 'main.v'))}') } +fn run_parallel_cc_failure_case(case_name string, files map[string]string) os.Result { + return run_parallel_cc_case(case_name, files) +} + fn test_parallel_cc_fails_when_c_compilation_fails() { res := run_parallel_cc_failure_case('compile_fail', { 'main.v': 'module main -#include "definitely_missing_parallel_cc_header.h" + #include "definitely_missing_parallel_cc_header.h" fn main() {} ' }) @@ -47,3 +51,16 @@ fn main() { assert res.exit_code == 1, res.output assert res.output.contains('failed to link after parallel C compilation'), res.output } + +fn test_parallel_cc_succeeds_with_array_sort_compare_helper() { + res := run_parallel_cc_case('array_sort_compare_helper', { + 'main.v': 'module main + fn main() { + mut xs := [3, 1, 2] + xs.sort(a < b) + println(xs) + } + ' + }) + assert res.exit_code == 0, res.output +} diff --git a/vlib/v/builder/rebuilding.v b/vlib/v/builder/rebuilding.v index 64d2ad08c6..adee70eeca 100644 --- a/vlib/v/builder/rebuilding.v +++ b/vlib/v/builder/rebuilding.v @@ -186,7 +186,8 @@ fn (mut b Builder) v_build_module(vexe string, imp_path string) { os.chdir(vroot) or {} boptions := b.pref.build_options.join(' ') rebuild_cmd := '${os.quoted_path(vexe)} ${boptions} build-module ${os.quoted_path(imp_path)}' - vcache.dlog('| Builder.' + @FN, 'vexe: ${vexe} | imp_path: ${imp_path} | rebuild_cmd: ${rebuild_cmd}') + vcache.dlog('| Builder.' + @FN, + 'vexe: ${vexe} | imp_path: ${imp_path} | rebuild_cmd: ${rebuild_cmd}') $if trace_v_build_module ? { eprintln('> Builder.v_build_module: ${rebuild_cmd}') } diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 3743ba000b..3d4ac89add 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -262,8 +262,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { c.inside_decl_rhs = false c.inside_ref_lit = old_inside_ref_lit if node.right_types.len == i { - node.right_types << c.check_expr_option_or_result_call(node.right[i], - right_type) + node.right_types << c.check_expr_option_or_result_call(node.right[i], right_type) } } else if c.inside_recheck && i < node.right.len { // Generic rechecks reuse the same AST nodes, so cached rhs types for @@ -273,8 +272,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { if needs_rhs_recheck { mut expr := mut node.right[i] right_type := c.expr(mut expr) - node.right_types[i] = c.check_expr_option_or_result_call(node.right[i], - right_type) + node.right_types[i] = c.check_expr_option_or_result_call(node.right[i], right_type) } } mut right := if i < node.right.len { node.right[i] } else { node.right[0] } @@ -400,8 +398,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { } } else if left.kind == .blank_ident { if !is_decl && mut right is ast.None { - c.error('cannot assign a `none` value to blank `_` identifier', - right.pos) + c.error('cannot assign a `none` value to blank `_` identifier', right.pos) } left_type = right_type node.left_types[i] = right_type @@ -537,8 +534,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { } } } else if left.op == .amp { - c.error('cannot use a reference on the left side of `${node.op}`', - left.pos) + c.error('cannot use a reference on the left side of `${node.op}`', left.pos) } else { c.error('cannot use `${left.op}` on the left of `${node.op}`', left.pos) } @@ -750,8 +746,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', if right_sym.kind == .map { c.error('maps cannot be static', left.pos) } else if !right.is_constant() { - c.error('cannot initialized static variable with non-constant value', - left.pos) + c.error('cannot initialized static variable with non-constant value', left.pos) } } } @@ -920,8 +915,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', c.error('undefined operation `${left_name}` ${extracted_op} `${right_name}`', node.pos) } else { - c.error('mismatched types `${left_name}` and `${right_name}`', - node.pos) + c.error('mismatched types `${left_name}` and `${right_name}`', node.pos) } } } @@ -975,8 +969,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', if left_type_unwrapped.is_ptr() && right_type_unwrapped.is_int() && node.op in [.plus_assign, .minus_assign] { if !c.inside_unsafe { - c.warn('pointer arithmetic is only allowed in `unsafe` blocks', - node.pos) + c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos) } } else { if c.comptime.comptime_for_field_var != '' && left is ast.ComptimeSelector { @@ -999,11 +992,9 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', if left_sym.kind == .array_fixed && right_sym.kind == .array && right is ast.ArrayInit { c.add_error_detail('try `${left} = ${right}!` instead (with `!` after the array literal)') - c.error('cannot assign to `${left}`: ${err.msg()}', - right.pos()) + c.error('cannot assign to `${left}`: ${err.msg()}', right.pos()) } else { - c.error('cannot assign to `${left}`: ${err.msg()}', - right.pos()) + c.error('cannot assign to `${left}`: ${err.msg()}', right.pos()) } } } diff --git a/vlib/v/checker/autocomplete.v b/vlib/v/checker/autocomplete.v index 485d080dd1..8683b78715 100644 --- a/vlib/v/checker/autocomplete.v +++ b/vlib/v/checker/autocomplete.v @@ -321,8 +321,7 @@ fn (c &Checker) vls_write_hover(declaration string, doc string) { lines << '' lines << doc } - value := lines.join('\n').replace('\\', '\\\\').replace('"', '\\"').replace('\n', - '\\n') + value := lines.join('\n').replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n') println('{"contents":{"kind":"markdown","value":"${value}"}}') } @@ -521,8 +520,7 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) { fn (mut c Checker) module_autocomplete(mod string) { mut details := []Detail{cap: 128} c.vls_gen_mod_funcs_details(mut details, mod) - c.vls_gen_mod_type_details(mut details, mod, .alias, .interface, .enum, .sum_type, - .struct) + c.vls_gen_mod_type_details(mut details, mod, .alias, .interface, .enum, .sum_type, .struct) c.vls_gen_mod_consts_details(mut details, mod) c.vls_write_details(details) } @@ -575,7 +573,8 @@ fn (c &Checker) vls_gen_mod_funcs_details(mut details []Detail, mod string) { for _, f in c.table.fns { mut name := f.name if f.is_pub && !f.is_method && !f.is_static_type_method && name.all_before_last('.') == mod { - name = name.all_after_last('.') // The user already typed `mod.`, so suggest the name without module + name = + name.all_after_last('.') // The user already typed `mod.`, so suggest the name without module type_string := if f.return_type != ast.no_type { c.table.type_to_str(f.return_type) } else { diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index f9d812cf95..668a73b289 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -502,7 +502,8 @@ fn (c &Checker) get_string_names_of(got ast.Type, expected ast.Type) (string, st // explained in the https://github.com/vlang/v/pull/13718#issuecomment-1074517800 fn (c &Checker) check_same_module(got ast.Type, expected ast.Type) bool { clean_got_typ := c.table.clean_generics_type_str(got.clear_flag(.variadic)).all_before('<') - clean_expected_typ := c.table.clean_generics_type_str(expected.clear_flag(.variadic)).all_before('<') + clean_expected_typ := + c.table.clean_generics_type_str(expected.clear_flag(.variadic)).all_before('<') if clean_got_typ == clean_expected_typ { return true // The following if confition should catch the bugs descripted in the issue @@ -615,6 +616,7 @@ fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool { if parent_elem_sym.info is ast.Array { array_info := parent_elem_sym.array_info() elem_type := c.table.find_or_register_array_with_dims(array_info.elem_type, + array_info.nr_dims + exp_sym.info.nr_dims) if c.table.type_to_str(got) == c.table.type_to_str(ast.idx_to_type(elem_type)) { return true @@ -808,7 +810,8 @@ fn (mut c Checker) check_shift(mut node ast.InfixExpr, left_type_ ast.Type, righ if node.ct_left_value_evaled { if lval := node.ct_left_value.i64() { if lval < 0 { - c.error('invalid bitshift of a negative number', node.left.pos()) + c.error('invalid bitshift of a negative number', + node.left.pos()) return left_type } } @@ -1119,8 +1122,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit) } else { for t in node.init_fields { if ft.name == t.name && t.typ != 0 { - inferred_typ := c.infer_composite_generic_type(gt_name, ft.typ, - t.typ) + inferred_typ := c.infer_composite_generic_type(gt_name, ft.typ, t.typ) if inferred_typ != ast.void_type { concrete_types << ast.mktyp(inferred_typ) continue gname @@ -1144,7 +1146,8 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit) } else { for init_field in node.init_fields { if init_field.name != t.name && init_field.typ != 0 { - field := sym.info.fields.filter(it.name == init_field.name) + field := + sym.info.fields.filter(it.name == init_field.name) if field.len > 0 { if c.table.sym(field[0].typ).name == gt_name { concrete_types << ast.mktyp(init_field.typ) @@ -1205,7 +1208,8 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) { if node.left_type.has_flag(.generic) { match sym.info { ast.Struct, ast.Interface, ast.SumType { - receiver_generic_names := sym.info.generic_types.map(c.table.sym(it).name) + receiver_generic_names := + sym.info.generic_types.map(c.table.sym(it).name) if gt_name in receiver_generic_names { idx := receiver_generic_names.index(gt_name) typ = sym.info.generic_types[idx] @@ -1224,11 +1228,21 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) { typ = c.table.cur_concrete_types[idx] } } else { // in non-generic fn - receiver_generic_names := sym.info.generic_types.map(c.table.sym(it).name) + receiver_generic_names := + sym.info.generic_types.map(c.table.sym(it).name) if gt_name in receiver_generic_names && sym.info.generic_types.len == sym.info.concrete_types.len { idx := receiver_generic_names.index(gt_name) typ = sym.info.concrete_types[idx] + } else if gt_name in func.generic_names + && sym.info.generic_types.len == sym.info.concrete_types.len { + // Method uses a different generic name than the struct + // (e.g. struct Foo[T] with method fn (f Foo[U]) ...) + // Map by position in the method's generic names. + fn_idx := func.generic_names.index(gt_name) + if fn_idx < sym.info.concrete_types.len { + typ = sym.info.concrete_types[fn_idx] + } } } } @@ -1239,7 +1253,8 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) { parent_sym := c.table.sym(ast.new_type(sym.info.parent_idx)) match parent_sym.info { ast.Struct, ast.Interface, ast.SumType { - receiver_generic_names := parent_sym.info.generic_types.map(c.table.sym(it).name) + receiver_generic_names := + parent_sym.info.generic_types.map(c.table.sym(it).name) if gt_name in receiver_generic_names && receiver_generic_names.len == sym.info.concrete_types.len { idx := receiver_generic_names.index(gt_name) @@ -1310,14 +1325,15 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) { if arg.expr.is_auto_deref_var() && typ.is_ptr() { if !arg.is_mut { typ = typ.deref() - } else if arg.expr is ast.Ident && arg.expr.obj is ast.Var - && arg.expr.obj.generic_typ == 0 { - // Non-generic auto-deref mut param: obj.typ includes the - // mut pointer (e.g. mut ctx Context → obj.typ=&Context), - // so strip it for generic inference. - // Generic auto-deref mut params (generic_typ != 0) already - // have the correct resolved type without extra mut pointer. - typ = typ.deref() + } else if arg.expr is ast.Ident && arg.expr.obj is ast.Var { + if arg.expr.obj.generic_typ == 0 { + // Non-generic auto-deref mut param: obj.typ includes the + // mut pointer (e.g. mut ctx Context → obj.typ=&Context), + // so strip it for generic inference. + // Generic auto-deref mut params (generic_typ != 0) already + // have the correct resolved type without extra mut pointer. + typ = typ.deref() + } } } // resolve &T &&T ... @@ -1420,8 +1436,7 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) { } // resolve lambda with generic return type if arg.expr is ast.LambdaExpr && typ.has_flag(.generic) { - typ = c.type_resolver.unwrap_generic_expr(arg.expr.expr, - typ) + typ = c.type_resolver.unwrap_generic_expr(arg.expr.expr, typ) if typ.has_flag(.generic) { lambda_ret_gt_name := c.table.type_to_str(typ) idx := func.generic_names.index(lambda_ret_gt_name) @@ -1464,20 +1479,22 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) { typ = if has_concrete_caller_types && cur_param.typ.has_flag(.generic) { if cur_param.is_mut && cur_param.orig_typ != 0 && cur_param.orig_typ.has_flag(.generic) { - c.table.unwrap_generic_type(cur_param.orig_typ, c.table.cur_fn.generic_names, - c.table.cur_concrete_types) + c.table.unwrap_generic_type(cur_param.orig_typ, + c.table.cur_fn.generic_names, c.table.cur_concrete_types) } else { - c.table.unwrap_generic_param_type(cur_param, c.table.cur_fn.generic_names, - c.table.cur_concrete_types) + c.table.unwrap_generic_param_type(cur_param, + c.table.cur_fn.generic_names, c.table.cur_concrete_types) } } else { cur_param.typ } mut cparam_type_sym := c.table.sym(c.unwrap_generic(typ)) if cparam_type_sym.kind == .array { - typ = c.type_resolver.get_generic_array_element_type(cparam_type_sym.info as ast.Array) + typ = + c.type_resolver.get_generic_array_element_type(cparam_type_sym.info as ast.Array) } else if cparam_type_sym.kind == .array_fixed { - typ = c.type_resolver.get_generic_array_fixed_element_type(cparam_type_sym.info as ast.ArrayFixed) + typ = + c.type_resolver.get_generic_array_fixed_element_type(cparam_type_sym.info as ast.ArrayFixed) } typ = c.unwrap_generic(typ) break @@ -1489,8 +1506,7 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) { } } if typ == ast.void_type { - c.error('could not infer generic type `${gt_name}` in call to `${func.name}`', - node.pos) + c.error('could not infer generic type `${gt_name}` in call to `${func.name}`', node.pos) return } if c.pref.is_verbose { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index d83d464797..5530cc02ad 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -813,8 +813,7 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) { c.add_error_detail('Test files should have names ending with `_test.v`.') c.error('invalid test file name `${invalid_test_file_name}`', invalid_test_file_pos) } else { - c.error('project must include a `main` module or be a shared library (compile with `v -shared`)', - token.Pos{}) + c.error('project must include a `main` module or be a shared library (compile with `v -shared`)', token.Pos{}) } } else if !has_main_fn && !c.pref.is_o { c.error('function `main` must be declared in the main module', token.Pos{}) @@ -1015,16 +1014,15 @@ fn (mut c Checker) alias_type_decl(mut node ast.AliasTypeDecl) { } } .array { - c.check_alias_vs_element_type_of_parent(node, (parent_typ_sym.info as ast.Array).elem_type, - 'array') + c.check_alias_vs_element_type_of_parent(node, + (parent_typ_sym.info as ast.Array).elem_type, 'array') } .array_fixed { array_fixed_info := parent_typ_sym.info as ast.ArrayFixed if c.array_fixed_has_unresolved_size(array_fixed_info) { c.unresolved_fixed_sizes << &ast.TypeDecl(node) } - c.check_alias_vs_element_type_of_parent(node, array_fixed_info.elem_type, - 'fixed array') + c.check_alias_vs_element_type_of_parent(node, array_fixed_info.elem_type, 'fixed array') } .map { info := parent_typ_sym.info as ast.Map @@ -1150,7 +1148,8 @@ and use a reference to the sum type instead: `var := &${node.name}(${variant_nam } else { for typ in sym.info.generic_types { if typ !in node.generic_types { - sumtype_type_names := node.generic_types.map(c.table.type_to_str(it)).join(', ') + sumtype_type_names := + node.generic_types.map(c.table.type_to_str(it)).join(', ') generic_sumtype_name := '${node.name}[${sumtype_type_names}]' generic_variant_name := c.table.type_to_str(variant.typ) c.error('generic type name `${c.table.sym(typ).name}` of generic struct `${generic_variant_name}` is not mentioned in sumtype `${generic_sumtype_name}`', @@ -1527,8 +1526,7 @@ fn (mut c Checker) fail_if_immutable(mut expr ast.Expr) (string, token.Pos) { if expr.name !in c.locked_names { if c.locked_names.len > 0 || c.rlocked_names.len > 0 { if expr.name in c.rlocked_names { - c.error('${expr.name} has an `rlock` but needs a `lock`', - expr.pos) + c.error('${expr.name} has an `rlock` but needs a `lock`', expr.pos) } else { c.error('${expr.name} must be added to the `lock` list above', expr.pos) @@ -1732,8 +1730,7 @@ fn (mut c Checker) fail_if_immutable(mut expr ast.Expr) (string, token.Pos) { } } if explicit_lock_needed { - c.error('`${to_lock}` is `shared` and needs explicit lock for `${expr.type_name()}`', - pos) + c.error('`${to_lock}` is `shared` and needs explicit lock for `${expr.type_name()}`', pos) to_lock = '' } return to_lock, pos @@ -1859,9 +1856,10 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to } } if !c.table.interface_inherits_interface(utyp, resolved_interface_type) { - c.error('cannot implement interface `${inter_sym.name}` with a different interface `${styp}`', - pos) - return false + c.error('cannot implement interface `${inter_sym.name}` with a different interface `${styp}`', + pos) + return false + } } interface_sym := c.table.sym(resolved_interface_type) mut interface_generic_names := []string{} @@ -1869,20 +1867,53 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to mut interface_info := ast.Interface{} mut has_resolved_interface_info := false if interface_sym.kind == .interface && interface_sym.info is ast.Interface { - interface_info = interface_sym.info - interface_generic_names = interface_info.generic_types.map(c.table.sym(it).name) - interface_concrete_types = interface_info.concrete_types.clone() - if interface_concrete_types.len == 0 - && interface_sym.generic_types.len == interface_generic_names.len { - interface_concrete_types = interface_sym.generic_types.clone() + // For concrete generic interfaces (has concrete_types, not generic, has parent), + // resolve methods from the root generic parent interface to get correct method + // signatures. The methods stored in the concrete interface's info may have been + // resolved with wrong type parameters for nested generic types. + if interface_sym.info.concrete_types.len > 0 + && !interface_sym.info.concrete_types.any(it.has_flag(.generic)) + && interface_sym.info.parent_type != 0 { + mut root_type := interface_sym.info.parent_type + for { + rs := c.table.sym(root_type) + if rs.info is ast.Interface { + if rs.info.parent_type != 0 { + root_type = rs.info.parent_type + } else { + break + } + } else { + break + } + } + root_sym := c.table.sym(root_type) + if root_sym.info is ast.Interface { + if root_sym.info.is_generic { + interface_info = root_sym.info + interface_generic_names = interface_info.generic_types.map(c.table.sym(it).name) + interface_concrete_types = interface_sym.info.concrete_types.clone() + has_resolved_interface_info = true + } + } + } + if !has_resolved_interface_info { + interface_info = interface_sym.info + interface_generic_names = interface_info.generic_types.map(c.table.sym(it).name) + interface_concrete_types = interface_info.concrete_types.clone() + if interface_concrete_types.len == 0 + && interface_sym.generic_types.len == interface_generic_names.len { + interface_concrete_types = interface_sym.generic_types.clone() + } + has_resolved_interface_info = true } - has_resolved_interface_info = true } else if interface_sym.kind == .generic_inst { parent_sym := c.table.sym(ast.new_type((interface_sym.info as ast.GenericInst).parent_idx)) if parent_sym.info is ast.Interface { interface_info = parent_sym.info interface_generic_names = interface_info.generic_types.map(c.table.sym(it).name) - interface_concrete_types = (interface_sym.info as ast.GenericInst).concrete_types.clone() + interface_concrete_types = + (interface_sym.info as ast.GenericInst).concrete_types.clone() has_resolved_interface_info = true } } @@ -1919,14 +1950,50 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to // Verify methods for imethod in imethods { - method := c.table.find_method_with_embeds(typ_sym, imethod.name) or { + mut method := c.table.find_method_with_embeds(typ_sym, imethod.name) or { typ_sym.find_method_with_generic_parent(imethod.name) or { + // `str() string` is auto-generated for all types during cgen + if imethod.name == 'str' && imethod.params.len == 1 + && imethod.return_type == ast.string_type { + are_methods_implemented = true + continue + } c.error("`${styp}` doesn't implement method `${imethod.name}` of interface `${inter_sym.name}`", pos) are_methods_implemented = false continue } } + // Resolve generic parameters for concrete generic types + match typ_sym.info { + ast.Struct, ast.Interface, ast.SumType { + if typ_sym.info.concrete_types.len > 0 + && typ_sym.info.parent_type.has_flag(.generic) { + parent_sym := c.table.sym(typ_sym.info.parent_type) + match parent_sym.info { + ast.Struct, ast.Interface, ast.SumType { + generic_names := + parent_sym.info.generic_types.map(c.table.sym(it).name) + if rt := c.table.convert_generic_type(method.return_type, + generic_names, typ_sym.info.concrete_types) + { + method.return_type = rt + } + method.params = method.params.clone() + for mut param in method.params { + if pt := c.table.convert_generic_type(param.typ, generic_names, + typ_sym.info.concrete_types) + { + param.typ = pt + } + } + } + else {} + } + } + } + else {} + } msg := c.table.is_same_method(imethod, method) if msg.len > 0 { sig := c.table.fn_signature(imethod, skip_receiver: false) @@ -2027,8 +2094,7 @@ fn (mut c Checker) expr_or_block_err(kind ast.OrKind, expr_name string, pos toke } .propagate_option { obj_does_not_return_or_is_not := is_field_to_description(expr_name, is_field) - c.error('unexpected `?`, the ${obj_does_not_return_or_is_not} an Option', - pos) + c.error('unexpected `?`, the ${obj_does_not_return_or_is_not} an Option', pos) } .propagate_result { obj_does_not_return_or_is_not := is_field_to_description(expr_name, is_field) @@ -2085,8 +2151,7 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast. } return ret_type.clear_flag(.result) } else { - c.expr_or_block_err(expr.or_block.kind, expr.name, expr.or_block.pos, - false) + c.expr_or_block_err(expr.or_block.kind, expr.name, expr.or_block.pos, false) } } ast.SelectorExpr { @@ -2123,6 +2188,19 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast. } ast.IndexExpr { if expr.or_expr.kind != .absent { + // When the IndexExpr has already been processed by index_expr() + // (indicated by expr.typ being set), skip re-checking the or block + // since it was already validated. This prevents the duplicate call + // from assign.v from rejecting valid `none` in option map or blocks. + if expr.typ != 0 { + if ret_type.has_flag(.option) && expr.or_expr.stmts.len > 0 { + last := expr.or_expr.stmts.last() + if last is ast.ExprStmt && last.expr is ast.None { + return ret_type + } + } + return ret_type.clear_option_and_result() + } mut return_none_or_error := false if expr.or_expr.stmts.len > 0 { last_stmt := expr.or_expr.stmts.last() @@ -2137,10 +2215,17 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast. } else { last_cur_or_expr := c.cur_or_expr c.cur_or_expr = &expr.or_expr - c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.result), - expr) + c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.result), expr) c.cur_or_expr = last_cur_or_expr } + // When the map value type is itself optional and the or block + // returns none, preserve the option type so the result is ?T. + if ret_type.has_flag(.option) && expr.or_expr.stmts.len > 0 { + last := expr.or_expr.stmts.last() + if last is ast.ExprStmt && last.expr is ast.None { + return ret_type + } + } return ret_type.clear_option_and_result() } else if expr.left is ast.SelectorExpr && expr.left_type.has_option_or_result() { with_modifier_kind := if expr.left_type.has_flag(.option) { @@ -2235,8 +2320,7 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return node.pos) } if !expr_return_type.has_flag(.result) { - c.error('to propagate a Result, the call must also return a Result type', - node.pos) + c.error('to propagate a Result, the call must also return a Result type', node.pos) } return } @@ -2257,8 +2341,10 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return } mut valid_stmts := node.stmts.filter(it !is ast.SemicolonStmt) mut last_stmt := if valid_stmts.len > 0 { valid_stmts.last() } else { node.stmts.last() } - allow_none_as_option_value := expr is ast.IndexExpr && ret_type.has_flag(.option) - default_or_type := if expr is ast.IndexExpr && ret_type.has_flag(.option) { + allow_none_as_option_value := ret_type.has_flag(.option) + && (expr is ast.IndexExpr || expr is ast.CallExpr) + default_or_type := if ret_type.has_flag(.option) + && (expr is ast.IndexExpr || expr is ast.CallExpr) { ret_type } else { expr_return_type.clear_option_and_result() @@ -2268,7 +2354,8 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return c.check_or_last_stmt(mut last_stmt, ret_type, default_or_type, allow_none_as_option_value) } else { // allow f() or { var = 123 } - c.check_or_last_stmt(mut last_stmt, ast.void_type, default_or_type, allow_none_as_option_value) + c.check_or_last_stmt(mut last_stmt, ast.void_type, default_or_type, + allow_none_as_option_value) } } @@ -2378,7 +2465,8 @@ fn (mut c Checker) check_or_last_stmt(mut stmt ast.Stmt, ret_type ast.Type, defa for mut branch in stmt.expr.branches { if branch.stmts.len > 0 { mut stmt_ := branch.stmts.last() - c.check_or_last_stmt(mut stmt_, ret_type, default_or_type, allow_none_as_option_value) + c.check_or_last_stmt(mut stmt_, ret_type, default_or_type, + allow_none_as_option_value) } } } @@ -2386,7 +2474,8 @@ fn (mut c Checker) check_or_last_stmt(mut stmt ast.Stmt, ret_type ast.Type, defa for mut branch in stmt.expr.branches { if branch.stmts.len > 0 { mut stmt_ := branch.stmts.last() - c.check_or_last_stmt(mut stmt_, ret_type, default_or_type, allow_none_as_option_value) + c.check_or_last_stmt(mut stmt_, ret_type, default_or_type, + allow_none_as_option_value) } } } @@ -2465,8 +2554,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type { } else if node.field_name == 'indirections' { return ast.int_type } - c.error('invalid field `.${node.field_name}` for type `${node.expr}`', - node.pos) + c.error('invalid field `.${node.field_name}` for type `${node.expr}`', node.pos) return ast.string_type } } @@ -2518,8 +2606,13 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type { if mut const_obj := c.table.global_scope.find_const(node.field_name) { c.mark_const_decl_as_referenced(const_obj.name) } - } else if mut const_obj := c.file.global_scope.find_const(node.str()) { - c.mark_const_decl_as_referenced(const_obj.name) + } else { + expr := node.expr + if expr is ast.Ident { + if mut const_obj := c.file.global_scope.find_const('${expr.name}.${node.field_name}') { + c.mark_const_decl_as_referenced(const_obj.name) + } + } } if !(node.expr is ast.Ident && node.expr.kind == .constant) { if node.expr_type.has_flag(.option) { @@ -2626,8 +2719,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type { struct_info := sym.info as ast.Struct if struct_info.is_union && node.next_token !in token.assign_tokens { if !c.pref.translated && !c.file.is_translated { - c.warn('reading a union field (or its address) requires `unsafe`', - node.pos) + c.warn('reading a union field (or its address) requires `unsafe`', node.pos) } } } @@ -2655,9 +2747,15 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type { if has_field { is_used_outside := !c.inside_recheck && sym.mod != c.mod + if is_used_outside && sym.language == .c && !sym.is_pub { + c.ensure_type_exists(typ, node.pos) + return field.typ + } unwrapped_sym := c.table.sym(c.unwrap_generic(typ)) type_has_module_visibility := final_sym.kind in [.struct, .interface, .sum_type, .aggregate] type_is_private := type_has_module_visibility && !sym.is_pub && sym.mod != 'builtin' + && node.from_embed_types.len == 0 && !typ.has_flag(.generic) + && !c.comptime.inside_comptime_if if is_used_outside && (!field.is_pub || type_is_private) && sym.language != .c { c.error('field `${unwrapped_sym.name}.${field_name}` is not public', node.pos) } @@ -2700,12 +2798,12 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type { } if mut method := c.table.sym(c.unwrap_generic(typ)).find_method_with_generic_parent(field_name) { c.mark_fn_decl_as_referenced(method.fkey()) - c.markused_comptime_call(typ.has_flag(.generic), '${int(method.params[0].typ)}.${field_name}') + c.markused_comptime_call(typ.has_flag(.generic), + '${int(method.params[0].typ)}.${field_name}') if c.expected_type != 0 && c.expected_type != ast.none_type { mut method_copy := method method_copy.name = '' - fn_type := ast.new_type(c.table.find_or_register_fn_type(method_copy, false, - true)) + fn_type := ast.new_type(c.table.find_or_register_fn_type(method_copy, false, true)) if c.check_types(fn_type, c.expected_type) { c.table.used_features.anon_fn = true return fn_type @@ -2824,7 +2922,8 @@ fn (mut c Checker) const_decl(mut node ast.ConstDecl) { } } if field.expr is ast.CallExpr { - sym := c.table.sym(c.check_expr_option_or_result_call(field.expr, c.expr(mut field.expr))) + sym := c.table.sym(c.check_expr_option_or_result_call(field.expr, + c.expr(mut field.expr))) if sym.kind == .multi_return { c.error('const declarations do not support multiple return values yet', field.expr.pos()) @@ -2894,8 +2993,7 @@ fn (mut c Checker) const_decl(mut node ast.ConstDecl) { fn (mut c Checker) enum_decl(mut node ast.EnumDecl) { c.check_valid_pascal_case(node.name, 'enum name', node.pos) if node.typ == ast.invalid_type { - c.error('cannot register enum `${node.name}`, another type with this name exists', - node.pos) + c.error('cannot register enum `${node.name}`, another type with this name exists', node.pos) return } mut useen := []u64{} @@ -2975,8 +3073,8 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) { match mut field.expr { ast.IntegerLiteral { c.check_enum_field_integer_literal(field.expr, signed, node.is_multi_allowed, - senum_type, field.expr.pos, mut useen, enum_umin, enum_umax, mut - iseen, enum_imin, enum_imax) + senum_type, field.expr.pos, mut useen, enum_umin, enum_umax, mut iseen, + enum_imin, enum_imax) } ast.InfixExpr { // Handle `enum Foo { x = 1 + 2 }` @@ -2984,9 +3082,9 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) { folded_expr := c.checker_transformer.infix_expr(mut field.expr) if folded_expr is ast.IntegerLiteral { - c.check_enum_field_integer_literal(folded_expr, signed, node.is_multi_allowed, - senum_type, field.expr.pos, mut useen, enum_umin, enum_umax, mut - iseen, enum_imin, enum_imax) + c.check_enum_field_integer_literal(folded_expr, signed, + node.is_multi_allowed, senum_type, field.expr.pos, mut useen, + enum_umin, enum_umax, mut iseen, enum_imin, enum_imax) } } ast.ParExpr { @@ -2994,9 +3092,9 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) { folded_expr := c.checker_transformer.expr(mut field.expr.expr) if folded_expr is ast.IntegerLiteral { - c.check_enum_field_integer_literal(folded_expr, signed, node.is_multi_allowed, - senum_type, field.expr.pos, mut useen, enum_umin, enum_umax, mut - iseen, enum_imin, enum_imax) + c.check_enum_field_integer_literal(folded_expr, signed, + node.is_multi_allowed, senum_type, field.expr.pos, mut useen, + enum_umin, enum_umax, mut iseen, enum_imin, enum_imax) } } ast.EnumVal { @@ -3098,9 +3196,9 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) { field.expr.pos) continue } - c.check_enum_field_integer_literal(comptime_lit, signed, node.is_multi_allowed, - senum_type, field.expr.pos, mut useen, enum_umin, enum_umax, mut - iseen, enum_imin, enum_imax) + c.check_enum_field_integer_literal(comptime_lit, signed, + node.is_multi_allowed, senum_type, field.expr.pos, mut useen, + enum_umin, enum_umax, mut iseen, enum_imin, enum_imax) field.expr = comptime_lit } else { c.error('the default value for an enum has to be an integer', @@ -3118,6 +3216,18 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) { if field.expr.kind == .constant && field.expr.obj.typ.is_int() { // accepts int constants as enum value if mut field.expr.obj is ast.ConstField { + if comptime_value := c.eval_comptime_const_expr(field.expr, 0) { + if comptime_lit := c.comptime_value_to_integer_literal(comptime_value, + field.expr.pos) + { + c.check_enum_field_integer_literal(comptime_lit, signed, + node.is_multi_allowed, senum_type, field.expr.pos, mut + useen, enum_umin, enum_umax, mut iseen, enum_imin, + enum_imax) + field.expr = comptime_lit + continue + } + } folded_expr := c.checker_transformer.expr(mut field.expr.obj.expr) if folded_expr is ast.IntegerLiteral { @@ -3125,6 +3235,7 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) { node.is_multi_allowed, senum_type, field.expr.pos, mut useen, enum_umin, enum_umax, mut iseen, enum_imin, enum_imax) + field.expr = folded_expr } } continue @@ -3289,7 +3400,8 @@ fn (mut c Checker) stmt(mut node ast.Stmt) { if node.expr.op == .arrow { if mut node.expr.right is ast.CallExpr { if node.expr.right.return_type.has_flag(.result) { - node.expr.or_block.err_used = node.expr.or_block.scope.known_var('err') + node.expr.or_block.err_used = + node.expr.or_block.scope.known_var('err') node.expr.right.or_block = node.expr.or_block } } @@ -3410,8 +3522,7 @@ fn (mut c Checker) defer_stmt(mut node ast.DeferStmt) { } if node.mode == .function { if !isnil(c.fn_scope) && node.scope == c.fn_scope { - c.warn('`defer` is already in function scope; just use `defer {` instead', - node.pos) + c.warn('`defer` is already in function scope; just use `defer {` instead', node.pos) } if c.locked_names.len != 0 || c.rlocked_names.len != 0 { c.error('`defer(fn)`s are not allowed in lock statements', node.pos) @@ -3585,8 +3696,7 @@ fn (mut c Checker) global_decl(mut node ast.GlobalDecl) { fn (mut c Checker) asm_stmt(mut stmt ast.AsmStmt) { if stmt.is_goto { - c.warn('inline assembly goto is not supported, it will most likely not work', - stmt.pos) + c.warn('inline assembly goto is not supported, it will most likely not work', stmt.pos) } if c.is_js_backend { c.error('inline assembly is not supported in the js backend', stmt.pos) @@ -3891,8 +4001,7 @@ fn (mut c Checker) import_stmt(node ast.Import) { if type_sym := c.table.find_sym(name) { if type_sym.kind != .placeholder { if !type_sym.is_pub { - c.error('module `${node.mod}` type `${sym.name}` is private', - sym.pos) + c.error('module `${node.mod}` type `${sym.name}` is private', sym.pos) } continue } @@ -3984,13 +4093,17 @@ fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type { if typ.has_flag(.generic) || c.type_has_unresolved_generic_parts(typ) { if c.inside_generic_struct_init { generic_names := c.cur_struct_generic_types.map(c.table.sym(it).name) - if t_typ := c.table.convert_generic_type(typ, generic_names, c.cur_struct_concrete_types) { + if t_typ := c.table.convert_generic_type(typ, generic_names, + c.cur_struct_concrete_types) + { return t_typ } } if c.inside_anon_fn && c.anon_fn_generic_names.len > 0 && c.anon_fn_generic_names.len == c.anon_fn_concrete_types.len { - if t_typ := c.table.convert_generic_type(typ, c.anon_fn_generic_names, c.anon_fn_concrete_types) { + if t_typ := c.table.convert_generic_type(typ, c.anon_fn_generic_names, + c.anon_fn_concrete_types) + { return t_typ } } @@ -4002,13 +4115,17 @@ fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type { } if c.inside_lambda && c.table.cur_lambda.call_ctx != unsafe { nil } && c.table.cur_lambda.func != unsafe { nil } { - if t_typ := c.table.convert_generic_type(typ, c.table.cur_lambda.func.decl.generic_names, + if t_typ := c.table.convert_generic_type(typ, + c.table.cur_lambda.func.decl.generic_names, c.table.cur_lambda.call_ctx.concrete_types) { return t_typ } } } + if t_typ := c.type_resolver.resolve_bound_generic_type(typ) { + return t_typ + } } return typ } @@ -4045,8 +4162,8 @@ fn (mut c Checker) recheck_concrete_type(typ ast.Type) ast.Type { if resolved_typ := c.table.convert_generic_type(typ, generic_names, c.table.cur_concrete_types) { return resolved_typ } - unwrapped_typ := c.table.unwrap_generic_type_ex(typ, generic_names, c.table.cur_concrete_types, - true) + unwrapped_typ := + c.table.unwrap_generic_type_ex(typ, generic_names, c.table.cur_concrete_types, true) if unwrapped_typ != typ { return unwrapped_typ } @@ -4116,8 +4233,8 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { if mut node.expr is ast.Ident { if mut node.expr.obj is ast.Var { ident_typ := if node.expr.obj.smartcasts.len > 0 { - c.exposed_smartcast_type(node.expr.obj.orig_type, node.expr.obj.smartcasts.last(), - node.expr.obj.is_mut) + c.exposed_smartcast_type(node.expr.obj.orig_type, + node.expr.obj.smartcasts.last(), node.expr.obj.is_mut) } else { node.expr.obj.typ } @@ -4128,6 +4245,11 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { } } } + // If the expression is already the target type (e.g. due to smartcasting + // inside an `if x is Type` block), the cast is a no-op. + if node.expr_type.idx() == node.typ.idx() { + return node.typ + } is_sumtype := expr_type_sym.kind == .sum_type || (expr_type_sym.kind == .generic_inst && expr_type_sym.info is ast.GenericInst && c.table.type_symbols[expr_type_sym.info.parent_idx].kind == .sum_type) @@ -4135,8 +4257,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { c.ensure_type_exists(node.typ, node.pos) unwrapped_expr_type := c.unwrap_generic(node.expr_type) unwrapped_node_typ := c.unwrap_generic(node.typ) - if !c.table.sumtype_has_variant(unwrapped_expr_type, unwrapped_node_typ, - true) { + if !c.table.sumtype_has_variant(unwrapped_expr_type, unwrapped_node_typ, true) { // For generic_inst sumtypes, also check using the parent's variant info mut found := false ue_sym := c.table.sym(unwrapped_expr_type) @@ -4210,8 +4331,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { } } if !ret_type.has_option_or_result() { - c.expr_or_block_err(node.or_block.kind, node.name, node.or_block.pos, - false) + c.expr_or_block_err(node.or_block.kind, node.name, node.or_block.pos, false) } if node.or_block.kind != .absent { if ret_type.has_flag(.option) { @@ -4343,7 +4463,8 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { else {} } if no_opt_or_res { - c.error('expression should either return an Option or a Result', node.expr.pos()) + c.error('expression should either return an Option or a Result', + node.expr.pos()) } } return ast.bool_type @@ -4429,8 +4550,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { return ret_type } if !ret_type.has_flag(.option) && !ret_type.has_flag(.result) { - c.expr_or_block_err(node.or_block.kind, node.field_name, node.or_block.pos, - true) + c.expr_or_block_err(node.or_block.kind, node.field_name, node.or_block.pos, true) } if node.or_block.kind != .absent { if ret_type.has_flag(.option) { @@ -4534,6 +4654,29 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { return ast.void_type } +fn (c &Checker) expr_is_known_zero_integer(expr ast.Expr) bool { + match expr { + ast.IntegerLiteral { + return expr.val.int() == 0 + } + ast.ParExpr { + return c.expr_is_known_zero_integer(expr.expr) + } + ast.Ident { + match expr.obj { + ast.GlobalField, ast.ConstField, ast.Var { + if expr.obj.expr is ast.IntegerLiteral { + return (expr.obj.expr as ast.IntegerLiteral).val.int() == 0 + } + } + else {} + } + } + else {} + } + return false +} + // pub fn (mut c Checker) asm_reg(mut node ast.AsmRegister) ast.Type { // name := node.name @@ -4558,8 +4701,9 @@ fn (mut c Checker) rewrite_smartcast_generic_wrapper_cast(mut node ast.CastExpr, || c.table.sym(c.unwrap_generic(node.expr.obj.typ)).kind != .sum_type { return false } - field_name := c.smartcast_wrapper_field_name(node.expr.obj.smartcasts.last(), - to_type) or { return false } + field_name := c.smartcast_wrapper_field_name(node.expr.obj.smartcasts.last(), to_type) or { + return false + } old_expr := ast.Expr(node.expr) node.expr = ast.SelectorExpr{ expr: old_expr @@ -4678,6 +4822,8 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { gi := to_sym.info as ast.GenericInst to_is_interface = c.table.type_symbols[gi.parent_idx].kind == .interface } + enforce_safe_pointer_casts := c.file.language == .v && !c.is_builtin_mod + enforce_safe_voidptr_ref_cast := enforce_safe_pointer_casts && expr_is_ident_or_cast if final_to_sym == final_from_sym && final_to_type.flags() == from_type.flags() && to_type.flags() == from_type.flags() { @@ -4710,8 +4856,9 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { c.error('unknown type `${to_sym.name}`', node.pos) } + mut to_type_exists := true if to_sym.language != .c { - c.ensure_type_exists(to_type, node.pos) + to_type_exists = c.ensure_type_exists(to_type, node.pos) if to_sym.info is ast.Alias && to_sym.info.parent_type.has_flag(.option) && !to_type.has_flag(.option) { @@ -4735,6 +4882,10 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { // allow conversion from none to every option type } else if to_type.has_flag(.option) && from_type == inner_to_type { return to_type + } else if enforce_safe_voidptr_ref_cast && from_type == ast.voidptr_type_idx && to_type.is_ptr() + && !c.inside_unsafe && !c.pref.translated && !c.file.is_translated { + tt := c.table.type_to_str(to_type) + c.error('cannot cast voidptr to `${tt}` outside `unsafe`', node.pos) } else if to_sym.kind == .sum_type { to_sym_info := to_sym.info as ast.SumType if c.pref.skip_unused && to_sym_info.concrete_types.len > 0 { @@ -4769,8 +4920,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { && from_type.idx() in [ast.voidptr_type_idx, ast.nil_type_idx]) { ft := c.table.type_to_str(from_type) tt := c.table.type_to_str(to_type) - c.error('cannot cast `${ft}` to `${tt}` (alias to `${final_to_sym.name}`)', - node.pos) + c.error('cannot cast `${ft}` to `${tt}` (alias to `${final_to_sym.name}`)', node.pos) } } else if to_sym.kind == .struct && mut to_sym.info is ast.Struct && (!to_sym.info.is_typedef || from_type.idx() in [ast.voidptr_type_idx, ast.nil_type_idx]) @@ -4818,9 +4968,12 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { else {} } } - if from_type == ast.voidptr_type_idx && !c.inside_unsafe && !c.pref.translated - && !c.file.is_translated { - c.error('cannot cast voidptr to a struct outside `unsafe`', node.pos) + if enforce_safe_pointer_casts && !c.inside_unsafe && to_type.is_ptr() && from_type.is_ptr() + && to_type != from_type && from_type != ast.voidptr_type_idx + && to_type.deref() != ast.char_type && from_type.deref() != ast.char_type { + ft := c.table.type_to_str(from_type) + tt := c.table.type_to_str(to_type) + c.warn('casting `${ft}` to `${tt}` is only allowed in `unsafe` code', node.pos) } if !from_type.is_int() && final_from_sym.kind != .enum && !from_type.is_any_kind_of_pointer() { @@ -4902,8 +5055,8 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { 'a variadic' } c.error('cannot type cast ${msg}', node.pos) - } else if !c.inside_unsafe && to_type.is_ptr() && from_type.is_ptr() && to_type != from_type - && to_type.deref() != ast.char_type && from_type.deref() != ast.char_type { + } else if !c.inside_unsafe && !c.is_builtin_mod && to_type.is_ptr() && from_type.is_ptr() + && to_type != from_type && final_to_sym.kind != .char && final_from_sym.kind != .char { ft := c.table.type_to_str(from_type) tt := c.table.type_to_str(to_type) c.warn('casting `${ft}` to `${tt}` is only allowed in `unsafe` code', node.pos) @@ -4941,8 +5094,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { && to_sym.kind != final_from_sym.kind { ft := c.table.type_to_str(from_type) tt := c.table.type_to_str(to_type) - c.error('cannot cast incompatible option ${final_to_sym.name} `${ft}` to `${tt}`', - node.pos) + c.error('cannot cast incompatible option ${final_to_sym.name} `${ft}` to `${tt}`', node.pos) } else if to_sym.kind == .rune && from_sym.is_string() { snexpr := node.expr.str() ft := c.table.type_to_str(from_type) @@ -4955,16 +5107,17 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { c.error('cannot cast type `${ft}` to `${tt}`', node.pos) } - // if from_type == ast.voidptr_type_idx && !c.inside_unsafe && !c.pref.translated - // Do not allow `&u8(unsafe { nil })` etc, force nil or voidptr cast - if from_type.is_number() && to_type.is_ptr() && !c.inside_unsafe && !c.pref.translated - && !c.file.is_translated { - if from_sym.language != .c { + if to_type.is_ptr() && !c.inside_unsafe && !c.pref.translated && !c.file.is_translated + && to_type_exists && final_to_sym.kind != .placeholder { + tt := c.table.type_to_str(to_type) + if from_type.is_number() && from_sym.language != .c { ne_name := node.expr.str() - if !ne_name.starts_with('C.') { - // TODO make an error - c.warn('cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`', - node.pos) + if to_sym.kind != .struct && !ne_name.starts_with('C.') { + if c.expr_is_known_zero_integer(node.expr) { + c.error('cannot null cast a pointer, use ${tt}(unsafe { nil })', node.pos) + } else { + c.error('cannot cast a number to `${tt}` outside `unsafe`', node.pos) + } } } } @@ -5002,6 +5155,10 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { c.error('invalid casting value to function', node.pos) } } + } else if final_from_sym.kind == .function && final_to_sym.is_number() { + fnexpr := node.expr.str() + tt := c.table.type_to_str(to_type) + c.error('cannot cast function `${fnexpr}` to `${tt}`', node.pos) } if to_type.is_ptr() && to_sym.kind == .alias && from_sym.kind == .map { c.error('cannot cast to alias pointer `${c.table.type_to_str(to_type)}` because `${c.table.type_to_str(from_type)}` is a value', @@ -5012,8 +5169,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { if from_type in [ast.u8_type, ast.bool_type] { snexpr := node.expr.str() ft := c.table.type_to_str(from_type) - c.error('cannot cast type `${ft}` to string, use `${snexpr}.str()` instead.', - node.pos) + c.error('cannot cast type `${ft}` to string, use `${snexpr}.str()` instead.', node.pos) } else if from_type.is_any_kind_of_pointer() { snexpr := node.expr.str() ft := c.table.type_to_str(from_type) @@ -5153,7 +5309,9 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { if from_sym.language == .v && from_type.is_ptr() && !to_type.is_ptr() && !final_to_type.is_ptr() && !node.expr.is_auto_deref_var() && final_to_sym.kind == .struct && final_from_sym.kind == .struct { - if c.check_struct_signature(final_from_sym.info as ast.Struct, final_to_sym.info as ast.Struct) { + if c.check_struct_signature(final_from_sym.info as ast.Struct, + final_to_sym.info as ast.Struct) + { ft := c.table.type_to_str(from_type) tt := c.table.type_to_str(to_type) c.error('cannot cast `${ft}` to `${tt}`, you must dereference it first (e.g. ${tt}(*var))', @@ -5189,9 +5347,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { // check if the field of the enum value is an integer literal if enum_field.expr is ast.IntegerLiteral { enum_val = enum_field.expr.val.i64() - } else if comptime_value := c.eval_comptime_const_expr(enum_field.expr, - 0) - { + } else if comptime_value := c.eval_comptime_const_expr(enum_field.expr, 0) { enum_val = comptime_value.i64() or { -1 } } if node_val == enum_val { @@ -5309,7 +5465,8 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type { node.pos) } vmod_content := os.read_file(vmod_file_location.vmod_file) or { '' } - c.vmod_file_content = vmod_content.replace('\r\n', '\n') // normalise EOLs just in case + c.vmod_file_content = + vmod_content.replace('\r\n', '\n') // normalise EOLs just in case } node.val = c.vmod_file_content } @@ -5328,8 +5485,7 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type { mut mcache := vmod.get_cache() vmod_file_location := mcache.get_by_file(c.file.path) if vmod_file_location.vmod_file.len == 0 { - c.error('@VMODHASH can only be used in projects that have a v.mod file', - node.pos) + c.error('@VMODHASH can only be used in projects that have a v.mod file', node.pos) } hash := version.githash(os.dir(vmod_file_location.vmod_file)) or { c.error(err.msg(), node.pos) @@ -5385,10 +5541,10 @@ fn (mut c Checker) same_inferred_fn_value_type(left ast.Type, right ast.Type) bo if left.share() != right.share() { return false } - left_base := c.table.unaliased_type(left.clear_flags(.option, .result, .variadic, - .shared_f, .atomic_f).clear_ref()) - right_base := c.table.unaliased_type(right.clear_flags(.option, .result, .variadic, - .shared_f, .atomic_f).clear_ref()) + left_base := c.table.unaliased_type(left.clear_flags(.option, .result, .variadic, .shared_f, + .atomic_f).clear_ref()) + right_base := c.table.unaliased_type(right.clear_flags(.option, .result, .variadic, .shared_f, + .atomic_f).clear_ref()) return left_base == right_base } @@ -5413,10 +5569,8 @@ fn (mut c Checker) infer_fn_value_concrete_type(mut inferred map[string]ast.Type if generic_type.share() != concrete_type.share() { return false } - mut template_type := generic_type.clear_flags(.option, .result, .variadic, .shared_f, - .atomic_f) - mut actual_type := concrete_type.clear_flags(.option, .result, .variadic, .shared_f, - .atomic_f) + mut template_type := generic_type.clear_flags(.option, .result, .variadic, .shared_f, .atomic_f) + mut actual_type := concrete_type.clear_flags(.option, .result, .variadic, .shared_f, .atomic_f) template_sym := c.table.sym(template_type) if template_sym.name in generic_names { if template_type.nr_muls() > actual_type.nr_muls() { @@ -5446,8 +5600,8 @@ fn (mut c Checker) infer_fn_value_concrete_type(mut inferred map[string]ast.Type if template_array.nr_dims != actual_array.nr_dims { return false } - return c.infer_fn_value_concrete_type(mut inferred, generic_names, template_array.elem_type, - actual_array.elem_type) + return c.infer_fn_value_concrete_type(mut inferred, generic_names, + template_array.elem_type, actual_array.elem_type) } ast.ArrayFixed { if actual_final_sym.info !is ast.ArrayFixed { @@ -5458,8 +5612,8 @@ fn (mut c Checker) infer_fn_value_concrete_type(mut inferred map[string]ast.Type if template_array_fixed.size != actual_array_fixed.size { return false } - return c.infer_fn_value_concrete_type(mut inferred, generic_names, template_array_fixed.elem_type, - actual_array_fixed.elem_type) + return c.infer_fn_value_concrete_type(mut inferred, generic_names, + template_array_fixed.elem_type, actual_array_fixed.elem_type) } ast.Chan { if actual_final_sym.info !is ast.Chan { @@ -5467,8 +5621,8 @@ fn (mut c Checker) infer_fn_value_concrete_type(mut inferred map[string]ast.Type } template_chan := template_final_sym.info as ast.Chan actual_chan := actual_final_sym.info as ast.Chan - return c.infer_fn_value_concrete_type(mut inferred, generic_names, template_chan.elem_type, - actual_chan.elem_type) + return c.infer_fn_value_concrete_type(mut inferred, generic_names, + template_chan.elem_type, actual_chan.elem_type) } ast.Map { if actual_final_sym.info !is ast.Map { @@ -5486,8 +5640,8 @@ fn (mut c Checker) infer_fn_value_concrete_type(mut inferred map[string]ast.Type } template_thread := template_final_sym.info as ast.Thread actual_thread := actual_final_sym.info as ast.Thread - return c.infer_fn_value_concrete_type(mut inferred, generic_names, template_thread.return_type, - actual_thread.return_type) + return c.infer_fn_value_concrete_type(mut inferred, generic_names, + template_thread.return_type, actual_thread.return_type) } ast.FnType { if actual_final_sym.info !is ast.FnType { @@ -5509,8 +5663,8 @@ fn (mut c Checker) infer_fn_value_concrete_type(mut inferred map[string]ast.Type return false } } - return c.infer_fn_value_concrete_type(mut inferred, generic_names, template_fn.return_type, - actual_fn.return_type) + return c.infer_fn_value_concrete_type(mut inferred, generic_names, + template_fn.return_type, actual_fn.return_type) } else { return c.table.unaliased_type(template_type) == c.table.unaliased_type(actual_type) @@ -5646,8 +5800,8 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { info_typ = current_var.typ } if current_var.smartcasts.len > 0 && !c.prevent_sum_type_unwrapping_once { - info_typ = c.exposed_smartcast_type(current_var.orig_type, current_var.smartcasts.last(), - current_var.is_mut) + info_typ = c.exposed_smartcast_type(current_var.orig_type, + current_var.smartcasts.last(), current_var.is_mut) } c.prevent_sum_type_unwrapping_once = false node.info = ast.IdentVar{ @@ -5695,8 +5849,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { } else if node.kind == .unresolved { // first use if node.tok_kind == .assign && node.is_mut { - c.error('`mut` is not allowed with `=` (use `:=` to declare a variable)', - node.pos) + c.error('`mut` is not allowed with `=` (use `:=` to declare a variable)', node.pos) } mut pobj := node.scope.find_ptr(node.name) if pobj != unsafe { nil } { @@ -5730,8 +5883,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { && !c.prevent_sum_type_unwrapping_once c.prevent_sum_type_unwrapping_once = false mut typ := if is_sum_type_cast { - c.exposed_smartcast_type(obj.orig_type, obj.smartcasts.last(), - obj.is_mut) + c.exposed_smartcast_type(obj.orig_type, obj.smartcasts.last(), obj.is_mut) } else { obj.typ } @@ -5816,8 +5968,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { if node.or_expr.kind == .propagate_option { c.error('cannot use `?` on non-option variable', node.pos) } else if node.or_expr.kind == .block { - c.error('cannot use `or {}` block on non-option variable', - node.pos) + c.error('cannot use `or {}` block on non-option variable', node.pos) } } unwrapped_typ := typ.clear_option_and_result() @@ -5939,11 +6090,6 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { if x := c.table.global_scope.find_const(node.name) { return x.typ } - c_name := node.name.all_after('C.') - if !c.pref.translated && !c.file.is_translated && c_name.to_upper() != c_name { - c.error('undefined C identifier: `${node.name}`', node.pos) - return ast.int_type - } return ast.int_type } if c.inside_sql { @@ -5974,8 +6120,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { c.error('undefined ident: `errcode`; did you mean `err.code`?', node.pos) } else { if c.inside_ct_attr { - c.note('`[if ${node.name}]` is deprecated. Use `@[if ${node.name}?]` instead', - node.pos) + c.note('`[if ${node.name}]` is deprecated. Use `@[if ${node.name}?]` instead', node.pos) } else { cname_mod := node.name.all_before('.') if cname_mod.len != node.name.len { @@ -6102,6 +6247,13 @@ fn (mut c Checker) apply_assert_autocasts(mut expr ast.Expr, scope &ast.Scope) { ident := expr as ast.Ident ident_scope := if !isnil(ident.scope) { ident.scope } else { scope } if autocast := c.find_assert_autocast(ident_scope, ident.name) { + // Don't insert an as-cast if the variable is already smartcast to the target type + // (e.g. inside an `if err is Type { ... }` block). + if v := scope.find_var(ident.name) { + if v.smartcasts.len > 0 && v.smartcasts.last().idx() == autocast.to_type.idx() { + return + } + } expr = ast.Expr(ast.ParExpr{ expr: ast.Expr(ast.AsCast{ typ: autocast.to_type @@ -6131,7 +6283,9 @@ fn (mut c Checker) apply_assert_autocasts(mut expr ast.Expr, scope &ast.Scope) { } } ast.InfixExpr { - c.apply_assert_autocasts(mut expr.left, scope) + if expr.op !in [.key_is, .not_is] { + c.apply_assert_autocasts(mut expr.left, scope) + } c.apply_assert_autocasts(mut expr.right, scope) } ast.IndexExpr { @@ -6490,7 +6644,7 @@ fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type { match mut branch.stmt { ast.ExprStmt { if branch.is_timeout { - if !branch.stmt.typ.is_int() { + if !c.table.sym(branch.stmt.typ).is_int() { tsym := c.table.sym(branch.stmt.typ) c.error('invalid type `${tsym.name}` for timeout - expected integer number of nanoseconds aka `time.Duration`', branch.stmt.pos) @@ -6498,7 +6652,8 @@ fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type { } else { if mut branch.stmt.expr is ast.InfixExpr { if branch.stmt.expr.left !in [ast.Ident, ast.SelectorExpr, ast.IndexExpr] { - c.error('channel in `select` key must be predefined', branch.stmt.expr.left.pos()) + c.error('channel in `select` key must be predefined', + branch.stmt.expr.left.pos()) } } else { c.error('invalid expression for `select` key', branch.stmt.expr.pos()) @@ -6528,7 +6683,8 @@ fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type { if mut branch.stmt.left[0] is ast.Ident { ident := branch.stmt.left[0] as ast.Ident if ident.kind == .blank_ident && branch.stmt.op != .decl_assign { - c.error('cannot send on `_`, use `_ := <- quit` instead', branch.stmt.left[0].pos()) + c.error('cannot send on `_`, use `_ := <- quit` instead', + branch.stmt.left[0].pos()) } } } @@ -6836,8 +6992,7 @@ fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type { } if typ_sym.kind == .map { - c.error('cannot take the address of map values outside `unsafe`', - expr.pos) + c.error('cannot take the address of map values outside `unsafe`', expr.pos) } } } @@ -7016,7 +7171,8 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { node.left.pos()) } } else if typ.has_flag(.result) { - c.error('type `!${typ_sym.name}` is a Result, it does not support indexing', node.left.pos()) + c.error('type `!${typ_sym.name}` is a Result, it does not support indexing', + node.left.pos()) } if typ_sym.kind == .string && !typ.is_ptr() && node.is_setter { c.error('cannot assign to s[i] since V strings are immutable\n' + @@ -7092,8 +7248,7 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { key_type := c.unwrap_generic(info.key_type) actual_index_type := c.expr_unhandled_option_type(node.index) if actual_index_type.has_flag(.option) && !key_type.has_flag(.option) { - got_typ_str, expected_typ_str := c.get_string_names_of(actual_index_type, - key_type) + got_typ_str, expected_typ_str := c.get_string_names_of(actual_index_type, key_type) c.error('invalid key: cannot use `${got_typ_str}` as `${expected_typ_str}`, it must be unwrapped first', node.index.pos()) } else if !c.check_types(index_type, key_type) { @@ -7103,8 +7258,7 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { value_sym := c.table.sym(info.value_type) if !node.is_setter && value_sym.kind == .sum_type && node.or_expr.kind == .absent && !c.inside_unsafe && !c.inside_if_guard { - c.warn('`or {}` block required when indexing a map with sum type value', - node.pos) + c.warn('`or {}` block required when indexing a map with sum type value', node.pos) } } else { index_type := c.expr(mut node.index) @@ -7397,8 +7551,8 @@ fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos toke match sym.kind { .function { fn_info := sym.info as ast.FnType - if !c.ensure_generic_type_specify_type_names(fn_info.func.return_type, fn_info.func.return_type_pos, - is_container_typ, is_generic_container) { + if !c.ensure_generic_type_specify_type_names(fn_info.func.return_type, + fn_info.func.return_type_pos, is_container_typ, is_generic_container) { return false } for param in fn_info.func.params { @@ -7414,8 +7568,8 @@ fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos toke } } .array { - if !c.ensure_generic_type_specify_type_names((sym.info as ast.Array).elem_type, - pos, true, typ.has_flag(.generic)) { + if !c.ensure_generic_type_specify_type_names((sym.info as ast.Array).elem_type, pos, + true, typ.has_flag(.generic)) { return false } } @@ -7427,10 +7581,12 @@ fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos toke } .map { info := sym.info as ast.Map - if !c.ensure_generic_type_specify_type_names(info.key_type, pos, true, typ.has_flag(.generic)) { + if !c.ensure_generic_type_specify_type_names(info.key_type, pos, true, + typ.has_flag(.generic)) { return false } - if !c.ensure_generic_type_specify_type_names(info.value_type, pos, true, typ.has_flag(.generic)) { + if !c.ensure_generic_type_specify_type_names(info.value_type, pos, true, + typ.has_flag(.generic)) { return false } } @@ -7620,20 +7776,16 @@ fn (mut c Checker) ensure_supported_map_key_types_in_type(typ ast.Type, pos toke sym := c.table.sym(typ) match sym.info { ast.Array { - return c.ensure_supported_map_key_types_in_type(sym.info.elem_type, pos, mut - seen) + return c.ensure_supported_map_key_types_in_type(sym.info.elem_type, pos, mut seen) } ast.ArrayFixed { - return c.ensure_supported_map_key_types_in_type(sym.info.elem_type, pos, mut - seen) + return c.ensure_supported_map_key_types_in_type(sym.info.elem_type, pos, mut seen) } ast.Chan { - return c.ensure_supported_map_key_types_in_type(sym.info.elem_type, pos, mut - seen) + return c.ensure_supported_map_key_types_in_type(sym.info.elem_type, pos, mut seen) } ast.Thread { - return c.ensure_supported_map_key_types_in_type(sym.info.return_type, pos, mut - seen) + return c.ensure_supported_map_key_types_in_type(sym.info.return_type, pos, mut seen) } ast.Map { key_type := sym.info.key_type @@ -7644,15 +7796,13 @@ fn (mut c Checker) ensure_supported_map_key_types_in_type(typ ast.Type, pos toke false } if !skip_map_key_support_check && !c.table.supports_map_key_type(key_type) { - c.error('map key type `${c.table.sym(sym.info.key_type).name}` not supported', - pos) + c.error('map key type `${c.table.sym(sym.info.key_type).name}` not supported', pos) return false } if !c.ensure_supported_map_key_types_in_type(sym.info.key_type, pos, mut seen) { return false } - return c.ensure_supported_map_key_types_in_type(sym.info.value_type, pos, mut - seen) + return c.ensure_supported_map_key_types_in_type(sym.info.value_type, pos, mut seen) } ast.MultiReturn { for inner_type in sym.info.types { @@ -7662,8 +7812,7 @@ fn (mut c Checker) ensure_supported_map_key_types_in_type(typ ast.Type, pos toke } } ast.FnType { - if !c.ensure_supported_map_key_types_in_type(sym.info.func.return_type, pos, mut - seen) { + if !c.ensure_supported_map_key_types_in_type(sym.info.func.return_type, pos, mut seen) { return false } for param in sym.info.func.params { @@ -7692,8 +7841,7 @@ fn (mut c Checker) ensure_supported_map_key_types_in_type(typ ast.Type, pos toke } } for method in sym.info.methods { - if !c.ensure_supported_map_key_types_in_type(method.return_type, pos, mut - seen) { + if !c.ensure_supported_map_key_types_in_type(method.return_type, pos, mut seen) { return false } for param in method.params { @@ -7873,8 +8021,7 @@ fn (mut c Checker) goto_stmt(node ast.GotoStmt) { } if !c.inside_unsafe { if !c.pref.translated && !c.file.is_translated { - c.warn('`goto` requires `unsafe` (consider using labelled break/continue)', - node.pos) + c.warn('`goto` requires `unsafe` (consider using labelled break/continue)', node.pos) } } if c.table.cur_fn != unsafe { nil } && node.name !in c.table.cur_fn.label_names { @@ -7938,8 +8085,10 @@ pub fn (mut c Checker) update_unresolved_fixed_sizes() { if ret_sym.info is ast.ArrayFixed && c.array_fixed_has_unresolved_size(ret_sym.info) { mut size_expr := ret_sym.info.size_expr old_ret_type := stmt.return_type - old_typ := c.cast_fixed_array_ret(stmt.return_type, c.table.final_sym(stmt.return_type)) - stmt.return_type = c.eval_array_fixed_sizes(mut size_expr, 0, ret_sym.info.elem_type) + old_typ := c.cast_fixed_array_ret(stmt.return_type, + c.table.final_sym(stmt.return_type)) + stmt.return_type = c.eval_array_fixed_sizes(mut size_expr, 0, + ret_sym.info.elem_type) new_sym := c.table.sym(stmt.return_type) mut typ_sym := c.table.type_symbols[old_typ.idx()] typ_sym.name = new_sym.name diff --git a/vlib/v/checker/comptime.v b/vlib/v/checker/comptime.v index 53010ff0e6..6c213075d9 100644 --- a/vlib/v/checker/comptime.v +++ b/vlib/v/checker/comptime.v @@ -85,13 +85,11 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type { // ... look relative to the source file: escaped_path = os.real_path(os.join_path_single(os.dir(c.file.path), escaped_path)) if !os.exists(escaped_path) { - c.error('"${escaped_path}" does not exist so it cannot be embedded', - node.pos) + c.error('"${escaped_path}" does not exist so it cannot be embedded', node.pos) return ast.string_type } if !os.is_file(escaped_path) { - c.error('"${escaped_path}" is not a file so it cannot be embedded', - node.pos) + c.error('"${escaped_path}" is not a file so it cannot be embedded', node.pos) return ast.string_type } } else { @@ -244,8 +242,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type { } idx := node.args_var.int() if idx < 0 || idx >= sym.info.types.len { - c.error('index ${idx} out of range of ${sym.info.types.len} return types', - node.pos) + c.error('index ${idx} out of range of ${sym.info.types.len} return types', node.pos) return ast.void_type } return sym.info.types[idx] @@ -623,7 +620,8 @@ fn (mut c Checker) eval_comptime_fn_call_expr_with_locals(node ast.CallExpr, nle // comptime const eval fn (mut c Checker) eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.ComptTimeConstValue { - return c.eval_comptime_const_expr_with_locals(expr, nlevel, map[string]ast.ComptTimeConstValue{}) + return c.eval_comptime_const_expr_with_locals(expr, nlevel, + map[string]ast.ComptTimeConstValue{}) } fn (mut c Checker) eval_comptime_const_expr_with_locals(expr ast.Expr, nlevel int, local_values map[string]ast.ComptTimeConstValue) ?ast.ComptTimeConstValue { @@ -938,8 +936,8 @@ fn (mut c Checker) eval_comptime_const_expr_with_locals(expr ast.Expr, nlevel in } else { last_stmt := branch.stmts.last() if last_stmt is ast.ExprStmt { - return c.eval_comptime_const_expr_with_locals(last_stmt.expr, - nlevel + 1, local_values) + return c.eval_comptime_const_expr_with_locals(last_stmt.expr, nlevel + 1, + local_values) } } } @@ -1174,12 +1172,13 @@ fn (mut c Checker) get_expr_type(cond ast.Expr) ast.Type { } fn (mut c Checker) check_compatible_types(left_type ast.Type, left_name string, expr ast.Expr) bool { + mut resolved_left_type := c.unwrap_generic(left_type) if expr is ast.ComptimeType { - return c.type_resolver.is_comptime_type(left_type, expr as ast.ComptimeType) + return c.type_resolver.is_comptime_type(resolved_left_type, expr as ast.ComptimeType) } else if expr is ast.TypeNode { typ := c.get_expr_type(expr) right_type := c.unwrap_generic(typ) - if c.type_resolver.bind_matching_generic_type(left_type, right_type) { + if c.type_resolver.bind_matching_generic_type(resolved_left_type, right_type) { return true } right_sym := c.table.sym(right_type) @@ -1187,8 +1186,8 @@ fn (mut c Checker) check_compatible_types(left_type ast.Type, left_name string, c.error('unknown type `${right_sym.name}`', expr.pos) } if right_sym.kind == .interface && right_sym.info is ast.Interface { - return left_type.has_flag(.option) == right_type.has_flag(.option) - && c.table.does_type_implement_interface(left_type, right_type) + return resolved_left_type.has_flag(.option) == right_type.has_flag(.option) + && c.table.does_type_implement_interface(resolved_left_type, right_type) } if right_sym.info is ast.FnType && c.comptime.comptime_for_method_var == left_name { return c.table.fn_signature(right_sym.info.func, @@ -1199,7 +1198,7 @@ fn (mut c Checker) check_compatible_types(left_type ast.Type, left_name string, type_only: true ) } else { - return left_type == right_type + return resolved_left_type == right_type } } return false @@ -1233,8 +1232,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, mut sb strings.Builder) ( } ast.ParExpr { sb.write_string('(') - is_true_result, multi_pass_stmts := c.comptime_if_cond(mut cond.expr, mut - sb) + is_true_result, multi_pass_stmts := c.comptime_if_cond(mut cond.expr, mut sb) sb.write_string(')') return is_true_result, multi_pass_stmts } @@ -1244,8 +1242,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, mut sb strings.Builder) ( return false, false } sb.write_string(cond.op.str()) - is_true_result, multi_pass_stmts := c.comptime_if_cond(mut cond.right, mut - sb) + is_true_result, multi_pass_stmts := c.comptime_if_cond(mut cond.right, mut sb) return !is_true_result, multi_pass_stmts } ast.PostfixExpr { @@ -1341,8 +1338,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, mut sb strings.Builder) ( } else if cond.op == .ne { is_true = left_str != right_str } else { - c.error('string type only support `==` and `!=` operator', - cond.pos) + c.error('string type only support `==` and `!=` operator', cond.pos) return false, false } sb.write_string('${is_true}') @@ -1511,7 +1507,8 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, mut sb strings.Builder) ( left_name := (cond.left.expr as ast.Ident).name if c.comptime.inside_comptime_for && left_name == c.comptime.comptime_for_method_var { - left_type_idx := c.comptime.comptime_for_method_ret_type.idx() + left_type_idx := + c.comptime.comptime_for_method_ret_type.idx() match cond.op { .eq { is_true = left_type_idx == cond.right.val.i64() @@ -1599,8 +1596,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, mut sb strings.Builder) ( return is_true, true } else { - c.error('sizeof() can only compare with int type', - cond.pos) + c.error('sizeof() can only compare with int type', cond.pos) return false, false } } diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index 176114590e..4dfab0d6c5 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -237,8 +237,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { } mut type_sym := c.table.sym(c.expected_type) if type_sym.kind != .array || type_sym.array_info().elem_type == ast.void_type { - c.error('array_init: no type specified (maybe: `[]Type{}` instead of `[]`)', - node.pos) + c.error('array_init: no type specified (maybe: `[]Type{}` instead of `[]`)', node.pos) return ast.void_type } array_info := type_sym.array_info() @@ -536,9 +535,7 @@ fn (mut c Checker) eval_array_fixed_sizes(mut size_expr ast.Expr, size int, elem } } } - if comptime_value := c.eval_comptime_const_expr(size_expr.obj.expr, - 0) - { + if comptime_value := c.eval_comptime_const_expr(size_expr.obj.expr, 0) { fixed_size = comptime_value.i64() or { fixed_size } } } else { @@ -560,8 +557,7 @@ fn (mut c Checker) eval_array_fixed_sizes(mut size_expr ast.Expr, size int, elem } } - idx := c.table.find_or_register_array_fixed(new_elem_typ, int(fixed_size), size_expr, - false) + idx := c.table.find_or_register_array_fixed(new_elem_typ, int(fixed_size), size_expr, false) return if elem_type.has_flag(.generic) { ast.new_type(idx).set_flag(.generic) } else { @@ -671,8 +667,7 @@ fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type { || c.expected_type.clear_option_and_result() != node.typ if needs_explicit_key_check && c.nr_errors == start_errors && info.key_type != ast.void_type && !info.key_type.has_flag(.generic) && !c.table.supports_map_key_type(info.key_type) { - c.error('map key type `${c.table.sym(info.key_type).name}` not supported', - node.pos) + c.error('map key type `${c.table.sym(info.key_type).name}` not supported', node.pos) } return node.typ } @@ -730,8 +725,7 @@ fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type { map_val_type = c.unwrap_generic(map_val_type) if c.nr_errors == start_errors && map_key_type != ast.void_type && !map_key_type.has_flag(.generic) && !c.table.supports_map_key_type(map_key_type) { - c.error('map key type `${c.table.sym(map_key_type).name}` not supported', - node.pos) + c.error('map key type `${c.table.sym(map_key_type).name}` not supported', node.pos) } node.typ = ast.new_type(c.table.find_or_register_map(map_key_type, map_val_type)) @@ -863,8 +857,7 @@ fn (mut c Checker) do_check_elements_ref_fields_initialized(sym &ast.TypeSymbol, } checked_types << parent_type parent_sym := c.table.sym(parent_type) - c.do_check_elements_ref_fields_initialized(parent_sym, mut checked_types, - pos) + c.do_check_elements_ref_fields_initialized(parent_sym, mut checked_types, pos) } else {} } diff --git a/vlib/v/checker/errors.v b/vlib/v/checker/errors.v index b7e2d30131..c7975b9d39 100644 --- a/vlib/v/checker/errors.v +++ b/vlib/v/checker/errors.v @@ -233,8 +233,7 @@ fn (mut c Checker) deprecate(kind string, name string, attrs []ast.Attr, pos tok deprecation_message), pos) } else if after_time == now { // print_backtrace() - c.warn(semicolonize('${start_message} has been deprecated', deprecation_message), - pos) + c.warn(semicolonize('${start_message} has been deprecated', deprecation_message), pos) // c.warn(semicolonize('${start_message} has been deprecated!11 m=${deprecation_message}', // deprecation_message), pos) } else { diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 3292c82bf1..e6afbce173 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -16,7 +16,8 @@ fn (mut c Checker) check_os_raw_io_call(node &ast.CallExpr, func &ast.Fn, concre 'write_struct', 'write_struct_at', 'write_raw', 'write_raw_at', 'read_struct', 'read_struct_at' { if node.args.len > arg_offset { - c.ensure_os_raw_io_type(node.args[arg_offset].typ, func.name, node.args[arg_offset].pos) + c.ensure_os_raw_io_type(node.args[arg_offset].typ, func.name, + node.args[arg_offset].pos) } } 'read_raw', 'read_raw_at' { @@ -280,12 +281,10 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { if need_generic_names { if node.is_method { c.add_error_detail('use `fn (r SomeType[T]) foo[T]() {`, not just `fn (r SomeType[T]) foo() {`') - c.error('generic method declaration must specify generic type names', - node.pos) + c.error('generic method declaration must specify generic type names', node.pos) } else { c.add_error_detail('use `fn foo[T](x T) {`, not just `fn foo(x T) {`') - c.error('generic function declaration must specify generic type names', - node.pos) + c.error('generic function declaration must specify generic type names', node.pos) } } } @@ -338,7 +337,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.assert_autocasts = prev_assert_autocasts.clone() } // Check generics fn/method without generic type parameters - if node.language == .v && !c.is_builtin_mod && !node.is_anon { + if node.language == .v && !c.is_builtin_mod && !node.is_anon + && !node.get_name().contains('veb_tmpl_') { c.check_valid_snake_case(node.get_name(), 'function name', node.pos) if !node.is_method && node.mod == 'main' && node.short_name in c.table.builtin_pub_fns { c.error('cannot redefine builtin public function `${node.short_name}`', node.pos) @@ -358,8 +358,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { // export fn name fn_name := attr.arg if !fn_name.is_identifier() { - c.error('export name `${fn_name}` should be a valid identifier', - node.pos) + c.error('export name `${fn_name}` should be a valid identifier', node.pos) } if fn_name in c.table.export_names.values() { c.error('duplicate export name `${fn_name}`', node.pos) @@ -422,8 +421,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { if return_sym.info is ast.Alias { parent_sym := c.table.sym(return_sym.info.parent_type) if parent_sym.info is ast.ArrayFixed { - c.table.find_or_register_array_fixed(parent_sym.info.elem_type, parent_sym.info.size, - parent_sym.info.size_expr, true) + c.table.find_or_register_array_fixed(parent_sym.info.elem_type, + parent_sym.info.size, parent_sym.info.size_expr, true) } if return_sym.name == 'byte' { c.error('byte is deprecated, use u8 instead', node.return_type_pos) @@ -447,12 +446,25 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { } // Ensure each generic type of the parameter was declared in the function's definition if node.return_type.has_flag(.generic) { - generic_names := c.table.generic_type_names(node.return_type) - for name in generic_names { - if name !in node.generic_names { - fn_generic_names := node.generic_names.join(', ') - c.error('generic type name `${name}` is not mentioned in fn `${node.name}[${fn_generic_names}]`', - node.return_type_pos) + ret_sym := c.table.sym(node.return_type) + // Skip check for forward-declared types (placeholder) where the + // generic param names haven't been resolved yet + if ret_sym.kind != .placeholder { + generic_names := c.table.generic_type_names(node.return_type) + for name in generic_names { + if name !in node.generic_names { + // When a generic struct is used as return type and the struct's + // generic param names differ from the fn's (e.g. struct uses T + // but fn uses B), skip if the return type sym is the base generic + // struct (not yet instantiated with concrete types) + if ret_sym.info is ast.Struct && ret_sym.info.is_generic + && ret_sym.generic_types.len == 0 { + continue + } + fn_generic_names := node.generic_names.join(', ') + c.error('generic type name `${name}` is not mentioned in fn `${node.name}[${fn_generic_names}]`', + node.return_type_pos) + } } } } @@ -689,12 +701,12 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { // TODO: there must be a better way to handle that } else if param_sym.kind !in [.struct, .alias] || receiver_sym.kind !in [.struct, .alias] { - c.error('operator methods are only allowed for struct and type alias', - node.pos) + c.error('operator methods are only allowed for struct and type alias', node.pos) } else { parent_sym := c.table.final_sym(node.receiver.typ) if node.rec_mut { - c.error('receiver cannot be `mut` for operator overloading', node.receiver_pos) + c.error('receiver cannot be `mut` for operator overloading', + node.receiver_pos) } else if node.params[1].is_mut { c.error('argument cannot be `mut` for operator overloading', node.pos) } else if !c.check_same_type_ignoring_pointers(node.receiver.typ, @@ -903,8 +915,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { if node.is_expand_simple_interpolation { match true { !node.is_method { - c.error('@[expand_simple_interpolation] is supported only on methods', - node.pos) + c.error('@[expand_simple_interpolation] is supported only on methods', node.pos) } node.params.len != 2 { c.error('methods tagged with @[expand_simple_interpolation], should have exactly 1 argument', @@ -1060,13 +1071,13 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type { if c.table.cur_concrete_types.len > 0 && node.decl.generic_names.len > 0 && node.decl.generic_names.len == c.table.cur_concrete_types.len { for param in node.decl.params { - param_type := if resolved := c.table.convert_generic_type(param.typ, node.decl.generic_names, - c.table.cur_concrete_types) + param_type := if resolved := c.table.convert_generic_type(param.typ, + node.decl.generic_names, c.table.cur_concrete_types) { c.unwrap_generic(resolved) } else { - c.table.unwrap_generic_type_ex(param.typ, node.decl.generic_names, c.table.cur_concrete_types, - true) + c.table.unwrap_generic_type_ex(param.typ, node.decl.generic_names, + c.table.cur_concrete_types, true) } if mut param_var := node.decl.scope.find_var(param.name) { if param_var.generic_typ == 0 && (param.typ.has_flag(.generic) @@ -1299,8 +1310,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. } } if c.table.cur_fn != unsafe { nil } && c.table.cur_concrete_types.len == 0 && has_generic { - c.error('generic fn using generic types cannot be called outside of generic fn', - node.pos) + c.error('generic fn using generic types cannot be called outside of generic fn', node.pos) } fkey := node.fkey() fn_name_has_dot := fn_name.contains('.') @@ -1334,8 +1344,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. tsym := c.table.sym(typ) if !tsym.name.starts_with('Promise[') { - c.error('JS.await: first argument must be a promise, got `${tsym.name}`', - node.pos) + c.error('JS.await: first argument must be a promise, got `${tsym.name}`', node.pos) return ast.void_type } if c.table.cur_fn != unsafe { nil } { @@ -1463,8 +1472,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. node.is_fn_var = true node.fn_var_type = sym.info.elem_type } else { - c.error('cannot call the element of the array, it is not a function', - node.pos) + c.error('cannot call the element of the array, it is not a function', node.pos) } } else if sym.info is ast.Map { value_sym := c.table.sym(sym.info.value_type) @@ -1484,8 +1492,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. node.is_fn_var = true node.fn_var_type = sym.info.elem_type } else { - c.error('cannot call the element of the array, it is not a function', - node.pos) + c.error('cannot call the element of the array, it is not a function', node.pos) } } } @@ -1859,13 +1866,13 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. c.ensure_type_exists(concrete_type, node.concrete_list_pos) } if func.generic_names.len > 0 && args_len == 0 && node.concrete_types.len == 0 { - c.error('no argument generic function must add concrete types, e.g. foo[int]()', - node.pos) + c.error('no argument generic function must add concrete types, e.g. foo[int]()', node.pos) return func.return_type } if func.return_type == ast.void_type && func.is_conditional && func.ctdefine_idx != ast.invalid_type_idx { - node.should_be_skipped = c.evaluate_once_comptime_if_attribute(mut func.attrs[func.ctdefine_idx]) + node.should_be_skipped = + c.evaluate_once_comptime_if_attribute(mut func.attrs[func.ctdefine_idx]) } // dont check number of args for JS functions since arguments are not required @@ -2156,8 +2163,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. c.error('literal argument cannot be passed as reference parameter `${c.table.type_to_str(param.typ)}`', call_arg.pos) } - c.check_expected_call_arg(arg_typ, c.unwrap_generic(param.typ), node.language, - call_arg) or { + c.check_expected_call_arg(arg_typ, c.unwrap_generic(param.typ), node.language, call_arg) or { if param.typ.has_flag(.generic) { continue } @@ -2355,8 +2361,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. // no type arguments given in call, attempt implicit instantiation c.infer_fn_generic_types(func, mut node) concrete_types = node.concrete_types.map(c.unwrap_generic(it)) - need_recheck, _ := c.type_resolver.resolve_fn_generic_args(c.table.cur_fn, func, mut - node) + need_recheck, _ := c.type_resolver.resolve_fn_generic_args(c.table.cur_fn, func, mut node) if need_recheck { c.need_recheck_generic_fns = true } @@ -2655,7 +2660,8 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) } if c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len > 0 { - c.table.unwrap_generic_type(left_type, c.table.cur_fn.generic_names, c.table.cur_concrete_types) + c.table.unwrap_generic_type(left_type, c.table.cur_fn.generic_names, + c.table.cur_concrete_types) } unwrapped_left_type := c.unwrap_generic(left_type) left_sym := c.table.sym(unwrapped_left_type) @@ -2792,7 +2798,8 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) if embed_types.len != 0 { is_method_from_embed = true node.from_embed_types = embed_types - c.markused_comptime_call(node.left_type.has_flag(.generic), '${int(method.receiver_type)}.${method.name}') + c.markused_comptime_call(node.left_type.has_flag(.generic), + '${int(method.receiver_type)}.${method.name}') } } if final_left_sym.kind == .aggregate { @@ -2851,8 +2858,8 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) scope_field := node.scope.find_struct_field(node.left.str(), node.left_type, method_name) if scope_field != unsafe { nil } { - field_typ = c.exposed_smartcast_type(scope_field.orig_type, scope_field.smartcasts.last(), - scope_field.is_mut) + field_typ = c.exposed_smartcast_type(scope_field.orig_type, + scope_field.smartcasts.last(), scope_field.is_mut) node.is_unwrapped_fn_selector = true } else { c.error('Option function field must be unwrapped first', node.pos) @@ -2984,7 +2991,8 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) ast.Struct, ast.Interface, ast.SumType { if left_sym.info.concrete_types.len > 0 && left_sym.info.parent_type.has_flag(.generic) { - sname = c.table.sym(left_sym.info.parent_type).symbol_name_except_generic() + sname = + c.table.sym(left_sym.info.parent_type).symbol_name_except_generic() } } else {} @@ -3050,7 +3058,8 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) parent_sym := c.table.sym(ast.new_type(rec_sym.info.parent_idx)) match parent_sym.info { ast.Struct, ast.SumType, ast.Interface { - receiver_generic_names := parent_sym.info.generic_types.map(c.table.sym(it).name) + receiver_generic_names := + parent_sym.info.generic_types.map(c.table.sym(it).name) receiver_generics_in_method := receiver_generic_names.len > 0 && method.generic_names.len >= receiver_generic_names.len && method.generic_names[..receiver_generic_names.len] == receiver_generic_names @@ -3113,8 +3122,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) to_lock, pos := c.check_for_mut_receiver(mut node.left) // node.is_mut = true if to_lock != '' && rec_share != .shared_t { - c.error('${to_lock} is `shared` and must be `lock`ed to be passed as `mut`', - pos) + c.error('${to_lock} is `shared` and must be `lock`ed to be passed as `mut`', pos) } } else { c.fail_if_unreadable(node.left, left_type, 'receiver') @@ -3134,7 +3142,8 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) } if method.return_type == ast.void_type && method.is_conditional && method.ctdefine_idx != ast.invalid_type_idx { - node.should_be_skipped = c.evaluate_once_comptime_if_attribute(mut method.attrs[method.ctdefine_idx]) + node.should_be_skipped = + c.evaluate_once_comptime_if_attribute(mut method.attrs[method.ctdefine_idx]) } c.check_expected_arg_count(mut node, method) or { node.return_type = method.return_type @@ -3203,14 +3212,15 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) match rec_sym.info { ast.Struct, ast.Interface, ast.SumType { if rec_sym.info.generic_types.len == resolved_method_concrete_types.len { - resolved_method_generic_names = rec_sym.info.generic_types.map(c.table.sym(it).name) + resolved_method_generic_names = + rec_sym.info.generic_types.map(c.table.sym(it).name) } } else {} } } - exp_arg_typ = c.resolve_short_syntax_call_arg_type(arg, exp_arg_typ, resolved_method_generic_names, - resolved_method_concrete_types) + exp_arg_typ = c.resolve_short_syntax_call_arg_type(arg, exp_arg_typ, + resolved_method_generic_names, resolved_method_concrete_types) exp_arg_sym := c.table.sym(exp_arg_typ) c.expected_type = exp_arg_typ @@ -3223,8 +3233,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) } } if method.is_variadic && got_arg_typ.has_flag(.variadic) && node.args.len - 1 > i { - c.error('when forwarding a variadic variable, it must be the final argument', - arg.pos) + c.error('when forwarding a variadic variable, it must be the final argument', arg.pos) } mut final_arg_sym := unsafe { exp_arg_sym } mut final_arg_typ := exp_arg_typ @@ -3254,8 +3263,8 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) typ := c.expr(mut arg.expr) if i == node.args.len - 1 { c.check_variadic_arg(arg.expr, typ, expected_type, param.typ, i + 1, method.name, - true, method.is_variadic, node.args.len == 1 && i == 0, method.generic_names.len > 0, - node.pos, arg.pos) + true, method.is_variadic, node.args.len == 1 && i == 0, + method.generic_names.len > 0, node.pos, arg.pos) } } else { c.expected_type = param.typ @@ -3312,11 +3321,6 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) if exp_arg_typ.has_flag(.generic) { has_unresolved_generic_param = c.check_unresolved_generic_param(node, arg) || has_unresolved_generic_param - method_concrete_types := if method_generic_names_len == rec_concrete_types.len { - rec_concrete_types - } else { - concrete_types - } if exp_utyp := c.table.convert_generic_param_type(param, method.generic_names, method_concrete_types) { @@ -3366,8 +3370,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) c.error('literal argument cannot be passed as reference parameter `${c.table.type_to_str(param.typ)}`', arg.pos) } - c.check_expected_call_arg(c.unwrap_generic(got_arg_typ), exp_arg_typ, node.language, - arg) or { + c.check_expected_call_arg(c.unwrap_generic(got_arg_typ), exp_arg_typ, node.language, arg) or { // str method, allow type with str method if fn arg is string // Passing an int or a string array produces a c error here // Deleting this condition results in proper V error messages @@ -3428,7 +3431,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) } else if is_generic { // if receiver is generic, then cgen requires `receiver_type` to be T. // and the concrete type is stored in `receiver_concrete_type` below. - node.receiver_type = left_type.derive(method.params[0].typ).set_flag(.generic) + node.receiver_type = method.params[0].typ } else { node.receiver_type = method.params[0].typ } @@ -3439,12 +3442,15 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) // if receiver_type is T, then `receiver_concrete_type` is concrete type, otherwise it is the same as `receiver_type`. node.receiver_concrete_type = if is_method_from_embed { node.from_embed_types.last().derive(method.params[0].typ) + } else if is_generic { + left_type.derive(method.params[0].typ).clear_flag(.generic) } else { method.params[0].typ } if left_sym.kind == .interface && is_method_from_embed && method.return_type.has_flag(.generic) && method_generic_names_len == 0 { - method.generic_names = c.table.get_generic_names((rec_sym.info as ast.Interface).generic_types) + method.generic_names = + c.table.get_generic_names((rec_sym.info as ast.Interface).generic_types) method_generic_names_len = method.generic_names.len } if method_generic_names_len != node.concrete_types.len { @@ -3454,8 +3460,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) } if concrete_types.len == method_generic_names_len && concrete_types.all(!it.has_flag(.generic)) { c.table.register_fn_concrete_types(method.fkey(), concrete_types) - need_recheck, _ := c.type_resolver.resolve_fn_generic_args(c.table.cur_fn, method, mut - node) + need_recheck, _ := c.type_resolver.resolve_fn_generic_args(c.table.cur_fn, method, mut node) if need_recheck { c.need_recheck_generic_fns = true } @@ -3801,7 +3806,8 @@ fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) ! ) return error('') } else if !f.is_variadic && nr_args > nr_params { - unexpected_args_pos := node.args[int_min(min_required_params, node.args.len - 1)].pos.extend(node.args.last().pos) + unexpected_args_pos := + node.args[int_min(min_required_params, node.args.len - 1)].pos.extend(node.args.last().pos) // c.error('3expected ${min_required_params} arguments, but got ${nr_args}', unexpected_args_pos) c.fn_call_error_have_want( nr_params: min_required_params @@ -3942,8 +3948,7 @@ fn (mut c Checker) check_predicate_param(is_map bool, elem_typ ast.Type, node as return } if func.return_type.has_flag(.option) { - c.error('option needs to be unwrapped before using it in map/filter', - node.pos) + c.error('option needs to be unwrapped before using it in map/filter', node.pos) } if func.params.len > 1 { c.error('function needs exactly 1 argument', node.pos) @@ -3989,8 +3994,7 @@ fn (mut c Checker) check_predicate_param(is_map bool, elem_typ ast.Type, node as } ast.CallExpr { if is_map && arg_expr.return_type in [ast.void_type, 0] { - c.error('type mismatch, `${arg_expr.name}` does not return anything', - arg_expr.pos) + c.error('type mismatch, `${arg_expr.name}` does not return anything', arg_expr.pos) } else if !is_map && arg_expr.return_type != ast.bool_type { if arg_expr.or_block.kind != .absent && (arg_expr.return_type.has_flag(.option) || arg_expr.return_type.has_flag(.result)) @@ -4134,8 +4138,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as return ast.void_type } if node.kind == .map { - c.lambda_expr_fix_type_of_param(mut arg0.expr, mut arg0.expr.params[0], - elem_typ) + c.lambda_expr_fix_type_of_param(mut arg0.expr, mut arg0.expr.params[0], elem_typ) le_type := c.expr(mut arg0.expr.expr) // eprintln('>>>>> node.args[0].expr: ${ast.Expr(node.args[0].expr)} | elem_typ: ${elem_typ} | etype: ${le_type}') c.support_lambda_expr_one_param(elem_typ, le_type, mut arg0.expr) @@ -4149,8 +4152,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as } else if node.kind in [.insert, .prepend] { if node.kind == .insert { if node_args_len != 2 { - c.error('`array.insert()` should have 2 arguments, e.g. `insert(1, val)`', - node.pos) + c.error('`array.insert()` should have 2 arguments, e.g. `insert(1, val)`', node.pos) return ast.void_type } else { arg_type := c.expr(mut arg0.expr) @@ -4164,8 +4166,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as } else { c.table.used_features.arr_prepend = true if node_args_len != 1 { - c.error('`array.prepend()` should have 1 argument, e.g. `prepend(val)`', - node.pos) + c.error('`array.prepend()` should have 1 argument, e.g. `prepend(val)`', node.pos) return ast.void_type } } @@ -4195,8 +4196,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as continue } } - c.check_expected_call_arg(arg.typ, method.params[i + 1].typ, node.language, - arg) or { + c.check_expected_call_arg(arg.typ, method.params[i + 1].typ, node.language, arg) or { c.error('${err.msg()} in argument ${i + 1} to `${left_sym.name}.${method_name}`', node.args[i].pos) } @@ -4204,8 +4204,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as } } else if node.kind in [.sort_with_compare, .sorted_with_compare] { if node_args_len != 1 { - c.error('`.${method_name}()` expected 1 argument, but got ${node_args_len}', - node.pos) + c.error('`.${method_name}()` expected 1 argument, but got ${node_args_len}', node.pos) } else { if mut arg0.expr is ast.LambdaExpr { c.support_lambda_expr_in_sort(elem_typ.ref(), ast.int_type, mut arg0.expr) @@ -4231,8 +4230,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as } arg0.typ = arg_type if method := c.table.find_method(left_sym, method_name) { - c.check_expected_call_arg(arg_type, method.params[1].typ, node.language, - arg0) or { + c.check_expected_call_arg(arg_type, method.params[1].typ, node.language, arg0) or { c.error('${err.msg()} in argument 1 to `${left_sym.name}.${method_name}`', arg0.pos) } @@ -4265,8 +4263,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as } else if mut arg0.expr is ast.InfixExpr { c.check_sort_external_variable_access(ast.Expr(arg0.expr)) if arg0.expr.op !in [.gt, .lt] { - c.error('`.${method_name}()` can only use `<` or `>` comparison', - node.pos) + c.error('`.${method_name}()` can only use `<` or `>` comparison', node.pos) } left_name := '${arg0.expr.left}'[0] right_name := '${arg0.expr.right}'[0] @@ -4403,8 +4400,9 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as c.error('`.contains()` expected 1 argument, but got ${node_args_len}', node.pos) } else if !left_sym.has_method('contains') { arg_typ := c.unwrap_generic(c.expr(mut arg0.expr)) - c.check_expected_call_arg(arg_typ, c.unwrap_generic(elem_typ), node.language, - arg0) or { c.error('${err.msg()} in argument 1 to `.contains()`', arg0.pos) } + c.check_expected_call_arg(arg_typ, c.unwrap_generic(elem_typ), node.language, arg0) or { + c.error('${err.msg()} in argument 1 to `.contains()`', arg0.pos) + } } for i, mut arg in node.args { node.args[i].typ = c.expr(mut arg.expr) @@ -4412,12 +4410,12 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as node.return_type = ast.bool_type } else if node.kind in [.index, .last_index] { if node_args_len != 1 { - c.error('`.${method_name}()` expected 1 argument, but got ${node_args_len}', - node.pos) + c.error('`.${method_name}()` expected 1 argument, but got ${node_args_len}', node.pos) } else if !left_sym.has_method(method_name) { arg_typ := c.unwrap_generic(c.expr(mut arg0.expr)) - c.check_expected_call_arg(arg_typ, c.unwrap_generic(elem_typ), node.language, - arg0) or { c.error('${err.msg()} in argument 1 to `.${method_name}()`', arg0.pos) } + c.check_expected_call_arg(arg_typ, c.unwrap_generic(elem_typ), node.language, arg0) or { + c.error('${err.msg()} in argument 1 to `.${method_name}()`', arg0.pos) + } } for i, mut arg in node.args { node.args[i].typ = c.expr(mut arg.expr) @@ -4467,8 +4465,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as node.return_type = ast.void_type } else if node.kind == .delete_many { if node_args_len != 2 { - c.error('`.delete_many()` expected 2 arguments, but got ${node_args_len}', - node.pos) + c.error('`.delete_many()` expected 2 arguments, but got ${node_args_len}', node.pos) } else { for i, mut arg in node.args { arg_typ := c.expr(mut arg.expr) @@ -4499,8 +4496,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t elem_typ := array_info.elem_type if node.kind in [.index, .last_index] { if node_args_len != 1 { - c.error('`.${method_name}()` expected 1 argument, but got ${node_args_len}', - node.pos) + c.error('`.${method_name}()` expected 1 argument, but got ${node_args_len}', node.pos) return ast.int_type } else if (node.kind == .index && !left_sym.has_method('index')) || (node.kind == .last_index && !left_sym.has_method('last_index')) { @@ -4531,8 +4527,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t node.return_type = ast.bool_type } else if node.kind in [.any, .all] { if node_args_len != 1 { - c.error('`.${method_name}` expected 1 argument, but got ${node_args_len}', - node.pos) + c.error('`.${method_name}` expected 1 argument, but got ${node_args_len}', node.pos) return ast.bool_type } if node_args_len > 0 && mut arg0.expr is ast.LambdaExpr { @@ -4551,8 +4546,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t node.return_type = ast.bool_type } else if node.kind == .count { if node_args_len != 1 { - c.error('`.${method_name}` expected 1 argument, but got ${node_args_len}', - node.pos) + c.error('`.${method_name}` expected 1 argument, but got ${node_args_len}', node.pos) return ast.bool_type } if node_args_len > 0 && mut arg0.expr is ast.LambdaExpr { @@ -4571,8 +4565,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t node.return_type = ast.int_type } else if node.kind == .filter { if node_args_len != 1 { - c.error('`.${method_name}` expected 1 argument, but got ${node_args_len}', - node.pos) + c.error('`.${method_name}` expected 1 argument, but got ${node_args_len}', node.pos) } // position of `it` doesn't matter scope_register_it(mut node.scope, node.pos, elem_typ) @@ -4600,8 +4593,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t } } else if node.kind == .map { if node_args_len != 1 { - c.error('`.${method_name}` expected 1 argument, but got ${node_args_len}', - node.pos) + c.error('`.${method_name}` expected 1 argument, but got ${node_args_len}', node.pos) return ast.void_type } if mut arg0.expr is ast.LambdaExpr { @@ -4661,8 +4653,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t } else if mut arg0.expr is ast.InfixExpr { c.check_sort_external_variable_access(ast.Expr(arg0.expr)) if arg0.expr.op !in [.gt, .lt] { - c.error('`.${method_name}()` can only use `<` or `>` comparison', - node.pos) + c.error('`.${method_name}()` can only use `<` or `>` comparison', node.pos) } left_name := '${arg0.expr.left}'[0] right_name := '${arg0.expr.right}'[0] @@ -4697,8 +4688,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t } } else if node.kind in [.sort_with_compare, .sorted_with_compare] { if node_args_len != 1 { - c.error('`.${method_name}()` expected 1 argument, but got ${node_args_len}', - node.pos) + c.error('`.${method_name}()` expected 1 argument, but got ${node_args_len}', node.pos) } else { if mut arg0.expr is ast.LambdaExpr { c.support_lambda_expr_in_sort(elem_typ.ref(), ast.int_type, mut arg0.expr) @@ -4724,8 +4714,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t } arg0.typ = arg_type if method := c.table.find_method(left_sym, method_name) { - c.check_expected_call_arg(arg_type, method.params[1].typ, node.language, - arg0) or { + c.check_expected_call_arg(arg_type, method.params[1].typ, node.language, arg0) or { c.error('${err.msg()} in argument 1 to `${left_sym.name}.${method_name}`', arg0.pos) } @@ -4834,7 +4823,8 @@ fn (mut c Checker) resolve_fn_return_type(func &ast.Fn, node ast.CallExpr, concr if func.generic_names.len > 0 { has_generic := node.raw_concrete_types.any(it.has_flag(.generic)) has_any_generic := node.concrete_types.any(it.has_flag(.generic)) - needs_resolved_concrete_types := node.raw_concrete_types.any(c.needs_unwrap_generic_type(it)) + needs_resolved_concrete_types := + node.raw_concrete_types.any(c.needs_unwrap_generic_type(it)) // fn call with any generic type to be resolved on call (e.g. foo[T]()) if has_generic || has_any_generic { if needs_resolved_concrete_types { diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index 8ff793838c..f46289b224 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -79,7 +79,8 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { c.error('multi-returns cannot be used in ranges. A range is from a single value to a single higher value.', node.cond.pos().extend(node.high.pos())) } else if typ_idx !in ast.integer_type_idxs { - c.error('range type can only be an integer type', node.cond.pos().extend(node.high.pos())) + c.error('range type can only be an integer type', + node.cond.pos().extend(node.high.pos())) } else if high_type.has_option_or_result() { c.error('the `high` value in a `for x in low..high {` loop, cannot be Result or Option', node.high.pos()) @@ -311,6 +312,9 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { node.kind = sym.kind node.val_type = value_type node.scope.update_var_type(node.val_var, value_type) + // Clear any smartcasts from a previous generic recheck pass, + // so they don't interfere with this iteration's type resolution. + node.scope.reset_smartcasts(node.val_var) if is_comptime { c.type_resolver.update_ct_type(node.val_var, value_type) node.scope.update_ct_var_kind(node.val_var, .value_var) diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index c90519308e..7367f46ec4 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -179,8 +179,8 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } c.comptime.inside_comptime_if = true mut sb := strings.new_builder(256) - comptime_if_result, comptime_if_multi_pass_branch = c.comptime_if_cond(mut branch.cond, mut - sb) + comptime_if_result, comptime_if_multi_pass_branch = + c.comptime_if_cond(mut branch.cond, mut sb) if comptime_if_multi_pass_branch { comptime_if_has_multi_pass_branch = true } @@ -488,8 +488,8 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } } } - if c.is_interface_smartcast_sumtype_variant(stmt.expr, former_expected_type, - stmt.typ) + if c.is_interface_smartcast_sumtype_variant(stmt.expr, + former_expected_type, stmt.typ) { node.is_expr = true node.typ = former_expected_type.clear_option_and_result() @@ -613,8 +613,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { c.smartcast_none_guard_fallthrough(node.branches[0].cond, mut continuation_scope) } if node.typ == ast.none_type { - c.error('invalid if expression, must supply at least one value other than `none`', - node.pos) + c.error('invalid if expression, must supply at least one value other than `none`', node.pos) } // if only untyped literals were given default to int/f64 node.typ = ast.mktyp(node.typ) @@ -760,8 +759,8 @@ fn (mut c Checker) smartcast_if_conds(mut node ast.Expr, mut scope ast.Scope, co && (node.left as ast.Ident).name == c.comptime.comptime_for_field_var if !skip_smartcast && (left_final_sym.kind in [.interface, .sum_type] || is_option_unwrap) { - c.smartcast(mut node.left, node.left_type, right_type, mut - scope, is_comptime, is_option_unwrap, false) + c.smartcast(mut node.left, node.left_type, right_type, mut scope, + is_comptime, is_option_unwrap, false) } } } @@ -773,6 +772,20 @@ fn (mut c Checker) smartcast_if_conds(mut node ast.Expr, mut scope ast.Scope, co if control_expr.branches.len != 2 { return } + first_cond := control_expr.branches[0].cond + // `if x !is Type { ... } else { /* smartcast x to Type here */ }` + if first_cond is ast.InfixExpr && first_cond.op == .not_is + && first_cond.left in [ast.Ident, ast.SelectorExpr] { + right_type := first_cond.right_type + left_type := first_cond.left_type + left_sym := c.table.final_sym(left_type) + is_option_unwrap := left_type.has_flag(.option) && !right_type.has_flag(.option) + if left_sym.kind in [.interface, .sum_type] || is_option_unwrap { + mut left_expr := first_cond.left + c.smartcast(mut left_expr, left_type, right_type, mut scope, false, + is_option_unwrap, false) + } + } c.smartcast_none_guard_unwrap(control_expr.branches[0].cond, mut scope) } } @@ -790,11 +803,11 @@ fn (mut c Checker) smartcast_none_guard_unwrap(cond ast.Expr, mut scope ast.Scop to_type := cond_expr.left_type.clear_flag(.option) if c.comptime.get_ct_type_var(cond_expr.left) == .smartcast { cond_expr.left_type = c.type_resolver.get_type(cond_expr.left) - c.smartcast(mut cond_expr.left, cond_expr.left_type, to_type, mut scope, true, - true, false) + c.smartcast(mut cond_expr.left, cond_expr.left_type, to_type, mut scope, true, true, + false) } else { - c.smartcast(mut cond_expr.left, cond_expr.left_type, to_type, mut scope, false, - true, false) + c.smartcast(mut cond_expr.left, cond_expr.left_type, to_type, mut scope, false, true, + false) } } } @@ -817,11 +830,11 @@ fn (mut c Checker) smartcast_none_guard_fallthrough(cond ast.Expr, mut scope ast } if c.comptime.get_ct_type_var(cond_expr.left) == .smartcast { cond_expr.left_type = c.type_resolver.get_type(cond_expr.left) - c.smartcast(mut cond_expr.left, cond_expr.left_type, to_type, mut scope, - true, true, false) + c.smartcast(mut cond_expr.left, cond_expr.left_type, to_type, mut scope, true, + true, false) } else { - c.smartcast(mut cond_expr.left, cond_expr.left_type, to_type, mut scope, - false, true, false) + c.smartcast(mut cond_expr.left, cond_expr.left_type, to_type, mut scope, false, + true, false) } } } diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 172600659e..b7d9cba404 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -69,6 +69,16 @@ fn (mut c Checker) adjust_infix_int_literal_promotion(left ast.Expr, right ast.E return promoted_type } +fn (c &Checker) alias_supports_ordered_comparison(sym ast.TypeSymbol, op token.Kind) bool { + if sym.kind != .alias { + return false + } + if sym.has_method_with_generic_parent(op.str()) { + return true + } + return op in [.gt, .ge, .le] && sym.has_method_with_generic_parent('<') +} + fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { former_expected_type := c.expected_type defer { @@ -129,8 +139,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { // search last `n is ast.Ident` in the left from_type := c.expr(mut left_node.right.left) to_type := c.expr(mut left_node.right.right) - c.autocast_in_if_conds(mut node.right, left_node.right.left, from_type, - to_type) + c.autocast_in_if_conds(mut node.right, left_node.right.left, from_type, to_type) } } if left_node.op == .key_is { @@ -245,8 +254,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if !c.pref.translated && ((right_type.is_any_kind_of_pointer() && node.op != .minus) || (!right_type.is_any_kind_of_pointer() && node.op !in [.plus, .minus])) { if _ := left_sym.find_method(node.op.str()) { - if left_sym.kind == .alias && right_sym.kind == .alias { + if left_sym.kind in [.alias, .struct] { // allow an explicit operator override `fn (x &AliasType) OP (y &AliasType) &AliasType {` + // or `fn (x &Struct) OP (y &Struct) &Struct {` } else { c.invalid_operator_error(node.op, left_type, right_type, left_right_pos) } @@ -582,8 +592,8 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } else { unaliased_left_type := c.table.unalias_num_type(unwrapped_left_type) unalias_right_type := c.table.unalias_num_type(unwrapped_right_type) - mut promoted_type := c.promote_keeping_aliases(unaliased_left_type, unalias_right_type, - left_sym.kind, right_sym.kind) + mut promoted_type := c.promote_keeping_aliases(unaliased_left_type, + unalias_right_type, left_sym.kind, right_sym.kind) promoted_type = c.adjust_infix_int_literal_promotion(node.left, node.right, unaliased_left_type, unalias_right_type, promoted_type) // subtract pointers is allowed in unsafe block @@ -613,8 +623,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { right_sym.name } if node.op == .mod { - c.error('float modulo not allowed, use math.fmod() instead', - pos) + c.error('float modulo not allowed, use math.fmod() instead', pos) } else { c.error('${side} type of `${op_str}` cannot be non-integer type `${name}`', pos) @@ -649,12 +658,12 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { .gt, .lt, .ge, .le { unwrapped_left_type := c.unwrap_generic(left_type) left_sym = c.table.sym(unwrapped_left_type) - if left_sym.kind == .alias && !left_sym.has_method_with_generic_parent(node.op.str()) { + if left_sym.kind == .alias && !c.alias_supports_ordered_comparison(left_sym, node.op) { left_sym = c.table.final_sym(unwrapped_left_type) } unwrapped_right_type := c.unwrap_generic(right_type) right_sym = c.table.sym(unwrapped_right_type) - if right_sym.kind == .alias && !right_sym.has_method_with_generic_parent(node.op.str()) { + if right_sym.kind == .alias && !c.alias_supports_ordered_comparison(right_sym, node.op) { right_sym = c.table.final_sym(unwrapped_right_type) } if left_sym.kind in [.array, .array_fixed] && right_sym.kind in [.array, .array_fixed] { @@ -855,13 +864,11 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } } else if left_final_sym.kind !in [.interface, .sum_type] && !c.comptime.is_comptime(node.left) { - c.error('`${op}` can only be used with interfaces and sum types', - node.pos) // can be used in sql too, but keep err simple + c.error('`${op}` can only be used with interfaces and sum types', node.pos) // can be used in sql too, but keep err simple } else if mut left_sym.info is ast.SumType { if typ !in left_sym.info.variants && c.unwrap_generic(typ) !in left_sym.info.variants { - c.error('`${left_sym.name}` has no variant `${typ_sym.name}`', - right_pos) + c.error('`${left_sym.name}` has no variant `${typ_sym.name}`', right_pos) } } else if left_sym.info is ast.Interface { if typ_sym.kind != .interface && !c.type_implements(typ, left_type, right_pos) { @@ -881,12 +888,12 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len > 0 && c.table.cur_fn.generic_names.len == c.table.cur_concrete_types.len { if c.needs_unwrap_generic_type(got_type) { - got_type = c.table.unwrap_generic_type(got_type, c.table.cur_fn.generic_names, - c.table.cur_concrete_types) + got_type = c.table.unwrap_generic_type(got_type, + c.table.cur_fn.generic_names, c.table.cur_concrete_types) } if c.needs_unwrap_generic_type(elem_type) { - elem_type = c.table.unwrap_generic_type(elem_type, c.table.cur_fn.generic_names, - c.table.cur_concrete_types) + elem_type = c.table.unwrap_generic_type(elem_type, + c.table.cur_fn.generic_names, c.table.cur_concrete_types) } } if !c.check_types(got_type, elem_type) { @@ -1334,8 +1341,7 @@ fn (mut c Checker) check_option_infix_expr(node ast.InfixExpr, left_type ast.Typ } if left_is_option && right_is_option { if node.op !in [.eq, .ne] { - c.error('`?${opt}` cannot be used as `${nopt}`, unwrap the option first', - pos) + c.error('`?${opt}` cannot be used as `${nopt}`, unwrap the option first', pos) } return } diff --git a/vlib/v/checker/interface.v b/vlib/v/checker/interface.v index cec874bb70..c0b1f9300b 100644 --- a/vlib/v/checker/interface.v +++ b/vlib/v/checker/interface.v @@ -270,8 +270,7 @@ fn (mut c Checker) unwrap_generic_interface(typ ast.Type, interface_type ast.Typ } for imethod in inter_sym.info.methods { method := typ_sym.find_method_with_generic_parent(imethod.name) or { - c.error('can not find method `${imethod.name}` on `${typ_sym.name}`, needed for interface: `${inter_sym.name}`', - pos) + c.error('can not find method `${imethod.name}` on `${typ_sym.name}`, needed for interface: `${inter_sym.name}`', pos) return 0 } mut imethod_return_type := imethod.return_type @@ -313,21 +312,24 @@ fn (mut c Checker) unwrap_generic_interface(typ ast.Type, interface_type ast.Typ } inferred_type = ret_typ } else if imret_sym.info is ast.SumType && mret_sym.info is ast.SumType { - im_generic_names := imret_sym.info.generic_types.map(c.table.sym(it).name) + im_generic_names := + imret_sym.info.generic_types.map(c.table.sym(it).name) if gt_name in im_generic_names && imret_sym.info.generic_types.len == mret_sym.info.concrete_types.len { idx := im_generic_names.index(gt_name) inferred_type = mret_sym.info.concrete_types[idx] } } else if imret_sym.info is ast.Interface && mret_sym.info is ast.Interface { - im_generic_names := imret_sym.info.generic_types.map(c.table.sym(it).name) + im_generic_names := + imret_sym.info.generic_types.map(c.table.sym(it).name) if gt_name in im_generic_names && imret_sym.info.generic_types.len == mret_sym.info.concrete_types.len { idx := im_generic_names.index(gt_name) inferred_type = mret_sym.info.concrete_types[idx] } } else if imret_sym.info is ast.Struct && mret_sym.info is ast.Struct { - im_generic_names := imret_sym.info.generic_types.map(c.table.sym(it).name) + im_generic_names := + imret_sym.info.generic_types.map(c.table.sym(it).name) if gt_name in im_generic_names && imret_sym.info.generic_types.len == mret_sym.info.concrete_types.len { idx := im_generic_names.index(gt_name) diff --git a/vlib/v/checker/lambda_expr.v b/vlib/v/checker/lambda_expr.v index 820337e6bc..83d42fc0a4 100644 --- a/vlib/v/checker/lambda_expr.v +++ b/vlib/v/checker/lambda_expr.v @@ -165,8 +165,7 @@ pub fn (mut c Checker) support_lambda_expr_in_sort(param_type ast.Type, return_t ] return_type: return_type } - expected_fn_type := ast.new_type(c.table.find_or_register_fn_type(expected_fn, true, - false)) + expected_fn_type := ast.new_type(c.table.find_or_register_fn_type(expected_fn, true, false)) c.lambda_expr(mut expr, expected_fn_type) } diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index dedc1cdfaa..c0c78d8368 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -60,7 +60,7 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { node.is_sum_type = cond_final_sym.kind in [.interface, .sum_type] c.match_exprs(mut node, cond_type_sym, cond_final_sym) c.expected_type = node.cond_type - mut first_iteration := true + mut ret_type_needs_inference := true mut infer_cast_type := ast.void_type mut need_explicit_cast := false mut ret_type := ast.void_type @@ -325,11 +325,10 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { unwrapped_expected_type := c.unwrap_generic(node.expected_type) must_be_option = must_be_option || expr_type == ast.none_type stmt.typ = expr_type - if first_iteration { + if ret_type_needs_inference && !is_noreturn_callexpr(stmt.expr) { if unwrapped_expected_type.has_option_or_result() || c.table.type_kind(unwrapped_expected_type) in [.sum_type, .interface, .multi_return] { - c.check_match_branch_last_stmt(mut stmt, unwrapped_expected_type, - expr_type) + c.check_match_branch_last_stmt(mut stmt, unwrapped_expected_type, expr_type) ret_type = node.expected_type } else { ret_type = expr_type @@ -352,7 +351,8 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { need_explicit_cast = true infer_cast_type = stmt.expr.typ } - } else { + ret_type_needs_inference = false + } else if !ret_type_needs_inference { if ret_type.idx() != expr_type.idx() { if unwrapped_expected_type.has_option_or_result() && c.table.sym(stmt.typ).kind == .struct @@ -490,7 +490,8 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { } } if !node.is_comptime || (node.is_comptime && comptime_match_branch_result) { - first_iteration = false + // ret_type_needs_inference is set to false in the ExprStmt branch above + // when a non-noreturn expression provides the type } if node.is_comptime { // branches may not have been processed by c.stmts() @@ -579,15 +580,51 @@ fn (mut c Checker) check_match_branch_last_stmt(mut last_stmt ast.ExprStmt, ret_ } } +fn char_literal_number_value(value string) ?i64 { + if value.len == 2 && value[0] == `\\` { + return match value[1] { + `a` { 7 } + `b` { 8 } + `t` { 9 } + `n` { 10 } + `v` { 11 } + `f` { 12 } + `r` { 13 } + `e` { 27 } + `$` { 36 } + `"` { 34 } + `'` { 39 } + `?` { 63 } + `@` { 64 } + `\\` { 92 } + `\`` { 96 } + `{` { 123 } + `}` { 125 } + else { none } + } + } + runes := value.runes() + if runes.len == 1 { + return runes[0] + } + return none +} + fn (mut c Checker) get_comptime_number_value(mut expr ast.Expr) ?i64 { + if mut expr is ast.ParExpr { + return c.get_comptime_number_value(mut expr.expr) + } + if mut expr is ast.PrefixExpr && expr.op == .minus { + return -c.get_comptime_number_value(mut expr.right)? + } if mut expr is ast.CharLiteral { - return expr.val[0] + return char_literal_number_value(expr.val) } if mut expr is ast.IntegerLiteral { return expr.val.i64() } - if mut expr is ast.CastExpr && expr.expr is ast.IntegerLiteral { - return expr.expr.val.i64() + if mut expr is ast.CastExpr { + return c.get_comptime_number_value(mut expr.expr) } if mut expr is ast.Ident { if mut obj := c.table.global_scope.find_const(expr.full_name()) { @@ -600,6 +637,30 @@ fn (mut c Checker) get_comptime_number_value(mut expr ast.Expr) ?i64 { return none } +fn (mut c Checker) get_match_case_int_key(mut expr ast.Expr, cond_sym ast.TypeSymbol) ?string { + if !cond_sym.is_int() { + return none + } + if value := c.get_comptime_number_value(mut expr) { + return value.str() + } + match expr { + ast.StringLiteral, ast.BoolLiteral, ast.FloatLiteral { + return none + } + else {} + } + if value := c.eval_comptime_const_expr(expr, 0) { + if signed_value := value.i64() { + return signed_value.str() + } + if unsigned_value := value.u64() { + return unsigned_value.str() + } + } + return none +} + fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSymbol, cond_final_sym ast.TypeSymbol) { c.expected_type = node.expected_type if node.cond_type.idx() == 0 { @@ -654,8 +715,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym c.add_error_detail('') c.add_error_detail('match condition type: ${mcstype}') c.add_error_detail(' range type: ${brstype}') - c.error('the range type and the match condition type should match', - expr.pos) + c.error('the range type and the match condition type should match', expr.pos) } mut low_value_higher_than_high_value := false mut low := i64(0) @@ -719,9 +779,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym ast.EnumVal { key = expr.val if is_multi_allowed_enum_match { - if enum_val := c.table.find_enum_field_val(cond_type_sym.name, - expr.val) - { + if enum_val := c.table.find_enum_field_val(cond_type_sym.name, expr.val) { branch_enum_values[enum_val] = true } } @@ -734,7 +792,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym } } else { - key = (*expr).str() + key = c.get_match_case_int_key(mut expr, cond_final_sym) or { (*expr).str() } } } val := if key in branch_exprs { branch_exprs[key] } else { 0 } @@ -824,8 +882,8 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym if expr_type !in cond_match_sym.info.variants { expr_str := c.table.type_to_str(expr_type) expect_str := c.table.type_to_str(node.cond_type) - sumtype_variant_names := cond_match_sym.info.variants.map(c.table.type_to_str_using_aliases(it, - {})) + sumtype_variant_names := + cond_match_sym.info.variants.map(c.table.type_to_str_using_aliases(it, {})) suggestion := util.new_suggestion(expr_str, sumtype_variant_names) c.error(suggestion.say('`${expect_str}` has no variant `${expr_str}`'), expr.pos()) @@ -883,8 +941,8 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym } allow_mut_selector_smartcast := node.cond is ast.SelectorExpr - c.smartcast(mut node.cond, node.cond_type, expr_type, mut branch.scope, - false, false, allow_mut_selector_smartcast) + c.smartcast(mut node.cond, node.cond_type, expr_type, mut branch.scope, false, + false, allow_mut_selector_smartcast) } } } @@ -918,9 +976,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym for v in cond_match_sym.info.vals { mut is_handled := v in branch_exprs if !is_handled && is_multi_allowed_enum_match { - if enum_val := c.table.find_enum_field_val(cond_match_sym.name, - v) - { + if enum_val := c.table.find_enum_field_val(cond_match_sym.name, v) { is_handled = enum_val in branch_enum_values } } diff --git a/vlib/v/checker/orm.v b/vlib/v/checker/orm.v index 8ea915e8f2..af19bca29c 100644 --- a/vlib/v/checker/orm.v +++ b/vlib/v/checker/orm.v @@ -27,8 +27,8 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type { if c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len > 0 && c.table.cur_concrete_types.len > 0 { if c.needs_unwrap_generic_type(node.table_expr.typ) { - node.table_expr.typ = c.table.unwrap_generic_type(node.table_expr.typ, c.table.cur_fn.generic_names, - c.table.cur_concrete_types) + node.table_expr.typ = c.table.unwrap_generic_type(node.table_expr.typ, + c.table.cur_fn.generic_names, c.table.cur_concrete_types) } if c.needs_unwrap_generic_type(node.typ) { node.typ = c.table.unwrap_generic_type(node.typ, c.table.cur_fn.generic_names, @@ -193,13 +193,14 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type { node.aggregate_field_type = ast.int_type node.typ = ast.int_type.set_flag(.result) } else { - aggregate_field := c.check_orm_aggregate_field(node.aggregate_kind, node.aggregate_field, - fields, table_sym.name, node.pos) or { return ast.void_type } + aggregate_field := c.check_orm_aggregate_field(node.aggregate_kind, + node.aggregate_field, fields, table_sym.name, node.pos) or { return ast.void_type } node.aggregate_field_type = aggregate_field.typ node.fields = [ aggregate_field, ] - node.typ = c.orm_aggregate_return_type(node.aggregate_kind, aggregate_field.typ).set_flag(.result) + node.typ = + c.orm_aggregate_return_type(node.aggregate_kind, aggregate_field.typ).set_flag(.result) } } else { node.fields = fields @@ -289,8 +290,8 @@ fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type { } if c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len > 0 && c.table.cur_concrete_types.len > 0 && c.needs_unwrap_generic_type(node.table_expr.typ) { - node.table_expr.typ = c.table.unwrap_generic_type(node.table_expr.typ, c.table.cur_fn.generic_names, - c.table.cur_concrete_types) + node.table_expr.typ = c.table.unwrap_generic_type(node.table_expr.typ, + c.table.cur_fn.generic_names, c.table.cur_concrete_types) } table_type := node.table_expr.typ table_sym := c.table.sym(table_type) @@ -654,8 +655,7 @@ fn (mut c Checker) check_orm_aggregate_field(kind ast.SqlAggregateKind, field_na is_string := field_type.is_string() if field_sym.kind in [.array, .struct] && !is_time { - c.orm_error('ORM aggregate functions do not support array or sub-struct fields', - pos) + c.orm_error('ORM aggregate functions do not support array or sub-struct fields', pos) return none } @@ -787,53 +787,40 @@ fn (mut c Checker) check_where_data_expr_has_no_struct_field_refs(table_type_sym } ast.ArrayInit { for item in expr.exprs { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, item, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, item, op) } } ast.CallExpr { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.left, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.left, op) for arg in expr.args { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, arg.expr, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, arg.expr, op) } } ast.CastExpr { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.expr, - op) - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.arg, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.expr, op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.arg, op) } ast.IndexExpr { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.left, - op) - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.index, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.left, op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.index, op) } ast.InfixExpr { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.left, - op) - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.right, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.left, op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.right, op) } ast.MapInit { for key in expr.keys { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, key, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, key, op) } for val in expr.vals { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, val, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, val, op) } } ast.ParExpr { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.expr, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.expr, op) } ast.PrefixExpr { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.right, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.right, op) } ast.SelectorExpr { table_name := util.strip_mod_name(table_type_symbol.name) @@ -848,8 +835,7 @@ fn (mut c Checker) check_where_data_expr_has_no_struct_field_refs(table_type_sym expr.pos) } } - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.expr, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.expr, op) } ast.StringInterLiteral { for interpolated in expr.exprs { @@ -859,13 +845,12 @@ fn (mut c Checker) check_where_data_expr_has_no_struct_field_refs(table_type_sym } ast.StructInit { for init_field in expr.init_fields { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, init_field.expr, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, + init_field.expr, op) } } ast.UnsafeExpr { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.expr, - op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.expr, op) } else {} } @@ -894,20 +879,17 @@ fn (mut c Checker) check_where_expr_has_no_pointless_exprs(table_type_symbol &as } } else if expr.left is ast.InfixExpr || expr.left is ast.ParExpr || expr.left is ast.PrefixExpr { - c.check_where_expr_has_no_pointless_exprs(table_type_symbol, field_names, - expr.left) + c.check_where_expr_has_no_pointless_exprs(table_type_symbol, field_names, expr.left) } else if !(expr.left is ast.SelectorExpr && c.comptime.is_comptime_selector_field_name(expr.left, 'name')) { c.orm_error(has_no_field_error, expr.left.pos()) } if expr.op in [.ne, .eq, .lt, .gt, .ge, .le, .key_like, .key_ilike, .key_in, .not_in] { - c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.right, - expr.op) + c.check_where_data_expr_has_no_struct_field_refs(table_type_symbol, expr.right, expr.op) } else if expr.right is ast.InfixExpr || expr.right is ast.ParExpr || expr.right is ast.PrefixExpr { - c.check_where_expr_has_no_pointless_exprs(table_type_symbol, field_names, - expr.right) + c.check_where_expr_has_no_pointless_exprs(table_type_symbol, field_names, expr.right) } } else if expr is ast.ParExpr { c.check_where_expr_has_no_pointless_exprs(table_type_symbol, field_names, expr.expr) @@ -946,8 +928,7 @@ fn (mut c Checker) check_orm_or_expr(mut expr ORMExpr) { if expr.or_expr.kind == .absent { if c.inside_defer { - c.error('ORM returns a result, so it should have an `or {}` block at the end', - expr.pos) + c.error('ORM returns a result, so it should have an `or {}` block at the end', expr.pos) } else { c.error('ORM returns a result, so it should have either an `or {}` block, or `!` at the end', expr.pos) diff --git a/vlib/v/checker/postfix.v b/vlib/v/checker/postfix.v index 9a17ca73d0..92f4ec6423 100644 --- a/vlib/v/checker/postfix.v +++ b/vlib/v/checker/postfix.v @@ -41,8 +41,7 @@ fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type { } if node.op != .question { typ_str := c.table.type_to_str(typ) - c.error('invalid operation: ${node.op.str()} (non-numeric type `${typ_str}`)', - node.pos) + c.error('invalid operation: ${node.op.str()} (non-numeric type `${typ_str}`)', node.pos) } else { node.typ = unwrapped_question_type return node.typ diff --git a/vlib/v/checker/return.v b/vlib/v/checker/return.v index fed87bf18c..b5957efefe 100644 --- a/vlib/v/checker/return.v +++ b/vlib/v/checker/return.v @@ -52,17 +52,19 @@ fn (mut c Checker) return_stmt(mut node ast.Return) { } expected_type_sym := c.table.sym(expected_type) if expected_type_sym.info is ast.ArrayFixed { - c.table.find_or_register_array_fixed(expected_type_sym.info.elem_type, expected_type_sym.info.size, - expected_type_sym.info.size_expr, true) + c.table.find_or_register_array_fixed(expected_type_sym.info.elem_type, + expected_type_sym.info.size, expected_type_sym.info.size_expr, true) } if node.exprs.len > 0 && c.table.cur_fn.return_type == ast.void_type { - c.error('unexpected argument, current function does not return anything', node.exprs[0].pos()) + c.error('unexpected argument, current function does not return anything', + node.exprs[0].pos()) return } else if node.exprs.len > 1 && c.table.cur_fn.return_type == ast.void_type.set_flag(.option) { c.error('can only return `none` from an Option-only return function', node.exprs[0].pos()) return } else if node.exprs.len > 1 && c.table.cur_fn.return_type == ast.void_type.set_flag(.result) { - c.error('functions with Result-only return types can only return an error', node.exprs[0].pos()) + c.error('functions with Result-only return types can only return an error', + node.exprs[0].pos()) return } else if node.exprs.len == 0 && !(c.expected_type == ast.void_type || expected_type_sym.kind == .void) { @@ -148,8 +150,7 @@ fn (mut c Checker) return_stmt(mut node ast.Return) { result_type_idx := c.table.type_idxs['_result'] got_types_0_idx := got_types[0].idx() if exp_is_option && got_types_0_idx == ast.error_type_idx { - c.error('Option and Result types have been split, use `!Foo` to return errors', - node.pos) + c.error('Option and Result types have been split, use `!Foo` to return errors', node.pos) } else if exp_is_result && got_types_0_idx == ast.none_type_idx { c.error('Option and Result types have been split, use `?` to return none', node.pos) } @@ -201,8 +202,7 @@ fn (mut c Checker) return_stmt(mut node ast.Return) { exprv := node.exprs[expr_idxs[i]] if exprv is ast.Ident && exprv.or_expr.kind == .propagate_option { if exp_type.has_flag(.option) { - c.warn('unwrapping option is redundant as the function returns option', - node.pos) + c.warn('unwrapping option is redundant as the function returns option', node.pos) } else { c.error('should not unwrap option var on return, it could be none', node.pos) } diff --git a/vlib/v/checker/str.v b/vlib/v/checker/str.v index cf09930669..2ea754f402 100644 --- a/vlib/v/checker/str.v +++ b/vlib/v/checker/str.v @@ -41,7 +41,6 @@ fn (mut c Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 { } } -<<<<<<< HEAD fn (mut c Checker) check_string_inter_lit_format_expr(mut expr ast.Expr, what string) { if expr is ast.EmptyExpr { return @@ -50,33 +49,13 @@ fn (mut c Checker) check_string_inter_lit_format_expr(mut expr ast.Expr, what st c.expected_type = ast.int_type mut typ := c.expr(mut expr) c.expected_type = expected_type - typ = c.type_resolver.get_type_or_default(expr, c.check_expr_option_or_result_call(expr, - typ)) + typ = c.type_resolver.get_type_or_default(expr, c.check_expr_option_or_result_call(expr, typ)) typ = c.table.unalias_num_type(typ) if typ != ast.int_type && !typ.is_int_literal() { c.error('${what} expression should return `int`', expr.pos()) } } -fn (mut c Checker) get_string_inter_default_fmt(expr ast.Expr, ftyp ast.Type, typ ast.Type) u8 { - if expr is ast.Ident { - if expr.obj is ast.Var { - obj := expr.obj - if obj.typ.is_ptr() && !obj.is_arg { - pointee_typ := obj.typ.deref() - if c.table.final_sym(pointee_typ).kind != .enum { - final_pointee_typ := c.table.final_type(pointee_typ) - if final_pointee_typ.is_number() - || final_pointee_typ in [ast.string_type, ast.bool_type] { - return `p` - } - } - } - } - } - return c.get_default_fmt(ftyp, typ) -} - fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type { inside_interface_deref_save := c.inside_interface_deref c.inside_interface_deref = true @@ -85,8 +64,8 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type { c.expected_type = ast.string_type mut ftyp := c.expr(mut expr) c.expected_type = expected_type - ftyp = c.type_resolver.get_type_or_default(expr, c.check_expr_option_or_result_call(expr, - ftyp)) + ftyp = c.type_resolver.get_type_or_default(expr, + c.check_expr_option_or_result_call(expr, ftyp)) if ftyp == ast.void_type || ftyp == 0 { c.error('expression does not return a value', expr.pos()) } else if ftyp == ast.char_type && ftyp.nr_muls() == 0 { @@ -127,7 +106,7 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type { c.error('unknown format specifier `${fmt:c}`', node.fmt_poss[i]) } if fmt == `_` { // set default representation for type if none has been given - fmt = c.get_string_inter_default_fmt(expr, ftyp, typ) + fmt = c.get_default_fmt(ftyp, typ) if fmt == `_` { if typ != ast.void_type && !(typ.has_flag(.generic) && (c.inside_lambda || c.table.cur_concrete_types.len > 0 diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 03fe649f12..f076f72aea 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -137,8 +137,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { c.error('field ${err_desc} reference but default value ${val_desc} reference', default_pos) } else if field.default_expr is ast.StructInit { - c.error('reference field must be initialized with reference', - default_pos) + c.error('reference field must be initialized with reference', default_pos) } } @@ -303,8 +302,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { if sym.kind == .interface && interface_implemented { if !c.inside_unsafe && !field.default_expr_typ.is_any_kind_of_pointer() { if c.table.sym(field.default_expr_typ).kind != .interface { - c.mark_as_referenced(mut &node.fields[i].default_expr, - true) + c.mark_as_referenced(mut &node.fields[i].default_expr, true) } } } else if c.table.final_sym(field.typ).kind == .function @@ -419,14 +417,14 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { t_sym := c.table.sym(t.typ) if t_sym.info is ast.Interface { if t_sym.info.is_generic { - if t_sym.generic_types.len == 0 { + if t_sym.generic_types.len == 0 && !t.typ.has_flag(.generic) { c.error('missing generic type on ${t_sym.name}', t.pos) } else { struct_generic_letters := node.generic_types.map(c.table.type_to_str(it)) - unknown_letters := t_sym.generic_types.filter(it.has_flag(.generic)).map(c.table.type_to_str(it)).filter(it !in struct_generic_letters) + unknown_letters := + t_sym.generic_types.filter(it.has_flag(.generic)).map(c.table.type_to_str(it)).filter(it !in struct_generic_letters) if unknown_letters.len > 0 { - c.error('unknown generic type ${unknown_letters.first()}', - t.pos) + c.error('unknown generic type ${unknown_letters.first()}', t.pos) } } } @@ -510,7 +508,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini mut source_generic_typ := source_typ source_sym := c.table.sym(c.unwrap_generic(source_typ)) if source_sym.kind == .generic_inst && source_sym.info is ast.GenericInst { - source_generic_typ = ast.new_type(source_sym.info.parent_idx).derive(source_typ).set_flag(.generic) + source_generic_typ = + ast.new_type(source_sym.info.parent_idx).derive(source_typ).set_flag(.generic) } else if source_sym.info is ast.Struct && source_sym.info.parent_type != 0 && source_sym.info.concrete_types.len > 0 { source_generic_typ = source_sym.info.parent_type.derive(source_typ).set_flag(.generic) @@ -598,8 +597,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini && !node.is_short_syntax && c.table.cur_concrete_types.len != 0 && !is_field_zero_struct_init { if node.generic_types.len == 0 { - c.error('generic struct init must specify type parameter, e.g. Foo[T]', - node.pos) + c.error('generic struct init must specify type parameter, e.g. Foo[T]', node.pos) } else if node.generic_types.len > 0 && node.generic_types.len != struct_sym.info.generic_types.len { c.error('generic struct init expects ${struct_sym.info.generic_types.len} generic parameter, but got ${node.generic_types.len}', @@ -638,8 +636,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini } } if struct_sym.info.is_union && node.init_fields.len > 1 { - c.error('union `${struct_sym.name}` can have only one field initialised', - node.pos) + c.error('union `${struct_sym.name}` can have only one field initialised', node.pos) } } else if struct_sym.info is ast.GenericInst { // For generic_inst types (concrete generic structs like Seq[int]), @@ -667,8 +664,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini } // register generic struct type when current fn is generic fn if c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len > 0 { - c.table.unwrap_generic_type_ex(node.typ, c.table.cur_fn.generic_names, c.table.cur_concrete_types, - true) + c.table.unwrap_generic_type_ex(node.typ, c.table.cur_fn.generic_names, + c.table.cur_concrete_types, true) if c.pref.skip_unused && node.typ.has_flag(.generic) { c.table.used_features.comptime_syms[c.unwrap_generic(node.typ)] = true c.table.used_features.comptime_syms[node.typ] = true @@ -818,8 +815,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini if !((sym.is_number() || sym.kind == .string || sym.kind == .bool || sym.kind == .enum) && node.init_fields.len == 0 && !node.has_update_expr) && !c.has_active_generic_recheck_context() { - c.error('alias type name: ${sym.name} is not struct type', - node.pos) + c.error('alias type name: ${sym.name} is not struct type', node.pos) } } } @@ -957,7 +953,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini c.add_error_detail_with_pos('To silence this notice, use either an explicit `a[..].clone()`, or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', init_field.expr.pos()) - c.note('an implicit clone of the slice was done here', init_field.expr.pos()) + c.note('an implicit clone of the slice was done here', + init_field.expr.pos()) mut right := ast.CallExpr{ name: 'clone' kind: .clone @@ -1064,18 +1061,19 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', if got_type.is_ptr() && exp_type.is_ptr() && mut init_field.expr is ast.Ident && !info.is_heap { - c.fail_if_stack_struct_action_outside_unsafe(mut init_field.expr, - 'assigned') + c.fail_if_stack_struct_action_outside_unsafe(mut init_field.expr, 'assigned') } if c.table.unaliased_type(exp_type) in ast.unsigned_integer_type_idxs && mut init_field.expr is ast.IntegerLiteral && (init_field.expr as ast.IntegerLiteral).val[0] == `-` { - c.error('cannot assign negative value to unsigned integer type', init_field.expr.pos) + c.error('cannot assign negative value to unsigned integer type', + init_field.expr.pos) } if exp_type_sym.info is ast.Struct && !exp_type_sym.info.is_anon && mut init_field.expr is ast.StructInit && init_field.expr.is_anon { - c.error('cannot assign anonymous `struct` to a typed `struct`', init_field.expr.pos) + c.error('cannot assign anonymous `struct` to a typed `struct`', + init_field.expr.pos) } // all the fields of initialized embedded struct are ignored, they are considered initialized @@ -1159,7 +1157,8 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', node.update_expr_type = update_type expr_sym := c.table.final_sym(c.unwrap_generic(update_type)) if node.update_expr is ast.ComptimeSelector { - c.error('cannot use struct update syntax in compile time expressions', node.update_expr_pos) + c.error('cannot use struct update syntax in compile time expressions', + node.update_expr_pos) } else if expr_sym.kind != .struct { s := c.table.type_to_str(update_type) c.error('expected struct, found `${s}`', node.update_expr.pos()) @@ -1208,7 +1207,8 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', } param_sym := c.table.sym(param.typ) if param_sym.kind in [.struct, .interface, .sum_type] { - c.table.unwrap_generic_type(param.typ, generic_names, struct_sym.info.concrete_types) + c.table.unwrap_generic_type(param.typ, generic_names, + struct_sym.info.concrete_types) } } } @@ -1302,13 +1302,13 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI } if !field_is_option && !c.has_active_generic_recheck_context() { if sym.kind == .struct { - c.check_ref_fields_initialized(sym, mut checked_types, '${type_sym.name}.${field.name}', - node.pos) + c.check_ref_fields_initialized(sym, mut checked_types, + '${type_sym.name}.${field.name}', node.pos) } else if sym.kind == .alias { parent_sym := c.table.sym((sym.info as ast.Alias).parent_type) if parent_sym.kind == .struct { - c.check_ref_fields_initialized(parent_sym, mut checked_types, '${type_sym.name}.${field.name}', - node.pos) + c.check_ref_fields_initialized(parent_sym, mut checked_types, + '${type_sym.name}.${field.name}', node.pos) } } } @@ -1316,8 +1316,7 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI if sym.kind == .interface && !node.has_update_expr && !field_is_option && sym.language != .js && !field.attrs.contains('noinit') { // TODO: should be an error instead, but first `ui` needs updating. - c.note('interface field `${type_sym.name}.${field.name}` must be initialized', - node.pos) + c.note('interface field `${type_sym.name}.${field.name}` must be initialized', node.pos) } // Do not allow empty uninitialized sum types /* @@ -1420,8 +1419,8 @@ fn (mut c Checker) check_ref_fields_initialized(struct_sym &ast.TypeSymbol, mut psym := c.table.sym(sym.info.parent_type) if psym.kind == .struct { checked_types << field.typ - c.check_ref_fields_initialized(psym, mut checked_types, '${linked_name}.${field.name}', - pos) + c.check_ref_fields_initialized(psym, mut checked_types, + '${linked_name}.${field.name}', pos) } } } @@ -1471,8 +1470,8 @@ fn (mut c Checker) check_ref_fields_initialized_note(struct_sym &ast.TypeSymbol, psym := c.table.sym(sym.info.parent_type) if psym.kind == .struct { checked_types << field.typ - c.check_ref_fields_initialized(psym, mut checked_types, '${linked_name}.${field.name}', - pos) + c.check_ref_fields_initialized(psym, mut checked_types, + '${linked_name}.${field.name}', pos) } } } diff --git a/vlib/v/checker/tests/anon_fn_without_body.out b/vlib/v/checker/tests/anon_fn_without_body.out index edb2328c9c..04d9d3685b 100644 --- a/vlib/v/checker/tests/anon_fn_without_body.out +++ b/vlib/v/checker/tests/anon_fn_without_body.out @@ -1,7 +1,7 @@ vlib/v/checker/tests/anon_fn_without_body.vv:4:10: error: anonymous function must declare a body - 2 | + 2 | 3 | fn main() { 4 | func := fn () int | ~~~~~~~~~ - 5 | + 5 | 6 | println(func()) diff --git a/vlib/v/checker/tests/array_declare_element_a.out b/vlib/v/checker/tests/array_declare_element_a.out index 15335ccb36..8be02f5f52 100644 --- a/vlib/v/checker/tests/array_declare_element_a.out +++ b/vlib/v/checker/tests/array_declare_element_a.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/array_declare_element_a.vv:2:5: error: non-name `arr[0]` on left side of `:=` +vlib/v/checker/tests/array_declare_element_a.vv:2:5: error: non-name `arr[0]` on left side of `:=` 1 | fn main() { 2 | arr[0] := 2 | ~~~ diff --git a/vlib/v/checker/tests/array_declare_element_b.out b/vlib/v/checker/tests/array_declare_element_b.out index a89816535e..2f1e486fdc 100644 --- a/vlib/v/checker/tests/array_declare_element_b.out +++ b/vlib/v/checker/tests/array_declare_element_b.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/array_declare_element_b.vv:3:5: error: non-name `arr[1]` on left side of `:=` +vlib/v/checker/tests/array_declare_element_b.vv:3:5: error: non-name `arr[1]` on left side of `:=` 1 | fn main() { 2 | arr := [1, 2] 3 | arr[1] := 1 diff --git a/vlib/v/checker/tests/array_declare_element_c.out b/vlib/v/checker/tests/array_declare_element_c.out index d6e2aaf433..592eb0e8d0 100644 --- a/vlib/v/checker/tests/array_declare_element_c.out +++ b/vlib/v/checker/tests/array_declare_element_c.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/array_declare_element_c.vv:3:8: error: non-name `arr[1][0]` on left side of `:=` +vlib/v/checker/tests/array_declare_element_c.vv:3:8: error: non-name `arr[1][0]` on left side of `:=` 1 | fn main() { 2 | arr := [[1, 2], [0, 3]] 3 | arr[1][0] := 1 diff --git a/vlib/v/checker/tests/array_filter_arg_mismatch_err.out b/vlib/v/checker/tests/array_filter_arg_mismatch_err.out index c0fdf4b6f6..e4461430b9 100644 --- a/vlib/v/checker/tests/array_filter_arg_mismatch_err.out +++ b/vlib/v/checker/tests/array_filter_arg_mismatch_err.out @@ -1,20 +1,20 @@ vlib/v/checker/tests/array_filter_arg_mismatch_err.vv:17:20: error: type mismatch, should use e.g. `filter(it > 2)` 15 | }] - 16 | + 16 | 17 | a1 := list.filter('it.value > 2') | ~~~~~~~~~~~~~~ 18 | println(a1) 19 | vlib/v/checker/tests/array_filter_arg_mismatch_err.vv:20:17: error: type mismatch, should use e.g. `any(it > 2)` 18 | println(a1) - 19 | + 19 | 20 | a2 := list.any('it.value > 2') | ~~~~~~~~~~~~~~ 21 | println(a2) 22 | vlib/v/checker/tests/array_filter_arg_mismatch_err.vv:23:17: error: type mismatch, should use e.g. `all(it > 2)` 21 | println(a2) - 22 | + 22 | 23 | a3 := list.all('it.value > 2') | ~~~~~~~~~~~~~~ 24 | println(a3) diff --git a/vlib/v/checker/tests/array_init_decompose_extra_params.out b/vlib/v/checker/tests/array_init_decompose_extra_params.out index 959720ae8b..c591528758 100644 --- a/vlib/v/checker/tests/array_init_decompose_extra_params.out +++ b/vlib/v/checker/tests/array_init_decompose_extra_params.out @@ -1,12 +1,12 @@ vlib/v/checker/tests/array_init_decompose_extra_params.vv:33:11: error: array decompose has 1 element but 2 are needed for `print_2` 31 | print_3(...arr4) - 32 | + 32 | 33 | print_2(...['1']) | ~~~~~~~~ 34 | print_3(...['1', '2']) 35 | print_4(...['1', '2', '3']) vlib/v/checker/tests/array_init_decompose_extra_params.vv:34:11: error: array decompose has 2 elements but 3 are needed for `print_3` - 32 | + 32 | 33 | print_2(...['1']) 34 | print_3(...['1', '2']) | ~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/array_init_with_void_value_err.out b/vlib/v/checker/tests/array_init_with_void_value_err.out index 25650959a2..e6d7632e2e 100644 --- a/vlib/v/checker/tests/array_init_with_void_value_err.out +++ b/vlib/v/checker/tests/array_init_with_void_value_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/array_init_with_void_value_err.vv:4:8: error: invalid void array element type - 2 | + 2 | 3 | fn main() { 4 | a := [yo()] | ~~~~ diff --git a/vlib/v/checker/tests/array_of_generic_struct_init_err.out b/vlib/v/checker/tests/array_of_generic_struct_init_err.out index 46d848df9d..157e40c0f8 100644 --- a/vlib/v/checker/tests/array_of_generic_struct_init_err.out +++ b/vlib/v/checker/tests/array_of_generic_struct_init_err.out @@ -1,11 +1,11 @@ vlib/v/checker/tests/array_of_generic_struct_init_err.vv:6:6: warning: unused variable: `arr` - 4 | + 4 | 5 | fn main() { 6 | mut arr := []Item{} | ~~~ 7 | } vlib/v/checker/tests/array_of_generic_struct_init_err.vv:6:15: error: generic struct `Item` must specify type parameter, e.g. Item[int] - 4 | + 4 | 5 | fn main() { 6 | mut arr := []Item{} | ~~~~ diff --git a/vlib/v/checker/tests/asm_immutable_err.out b/vlib/v/checker/tests/asm_immutable_err.out index 2153ae9df2..056ef9ad60 100644 --- a/vlib/v/checker/tests/asm_immutable_err.out +++ b/vlib/v/checker/tests/asm_immutable_err.out @@ -1,7 +1,7 @@ vlib/v/checker/tests/asm_immutable_err.vv:9:9: error: `c` is immutable, declare it with `mut` to make it mutable 7 | add eax, b 8 | mov c, eax - 9 | ; =r (c) // output + 9 | ; =r (c) // output | ^ - 10 | ; r (a) // input - 11 | r (b) \ No newline at end of file + 10 | ; r (a) // input + 11 | r (b) diff --git a/vlib/v/checker/tests/assert_option_err.out b/vlib/v/checker/tests/assert_option_err.out index cf1cdae0a8..67ee76af47 100644 --- a/vlib/v/checker/tests/assert_option_err.out +++ b/vlib/v/checker/tests/assert_option_err.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/assert_option_err.vv:4:9: error: assert can be used only with `bool` expressions, but found `void` instead - 2 | + 2 | 3 | fn main() { 4 | assert os.truncate('testfile.txt', 6666) or { panic(err) } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 5 | } \ No newline at end of file + 5 | } diff --git a/vlib/v/checker/tests/assign_anon_struct_to_typed_struct_err.out b/vlib/v/checker/tests/assign_anon_struct_to_typed_struct_err.out index 9d2cf15280..d9bf192fea 100644 --- a/vlib/v/checker/tests/assign_anon_struct_to_typed_struct_err.out +++ b/vlib/v/checker/tests/assign_anon_struct_to_typed_struct_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/assign_anon_struct_to_typed_struct_err.vv:11:18: error: cannot assign anonymous `struct` to a typed `struct` - 9 | + 9 | 10 | f := Fax{ 11 | message: struct { | ^ diff --git a/vlib/v/checker/tests/assign_var_redefinition_err.out b/vlib/v/checker/tests/assign_var_redefinition_err.out index 37ba8cfb15..0531146456 100644 --- a/vlib/v/checker/tests/assign_var_redefinition_err.out +++ b/vlib/v/checker/tests/assign_var_redefinition_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/assign_var_redefinition_err.vv:6:2: error: redefinition of `aaaa` - 4 | + 4 | 5 | fn test(aaaa string) string { 6 | aaaa := 'bbbb' + aaaa | ~~~~ diff --git a/vlib/v/checker/tests/c_binding_confusable_c_err.out b/vlib/v/checker/tests/c_binding_confusable_c_err.out index a244a7132f..00068960ee 100644 --- a/vlib/v/checker/tests/c_binding_confusable_c_err.out +++ b/vlib/v/checker/tests/c_binding_confusable_c_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/c_binding_confusable_c_err.vv:1:4: error: invalid character `С` 1 | fn С.destroy_context(context u32) | ^ - 2 | + 2 | 3 | pub fn destroy_context(context u32) { diff --git a/vlib/v/checker/tests/cast_expr_T_type_err.out b/vlib/v/checker/tests/cast_expr_T_type_err.out index 09c39df8ca..2c82a99fad 100644 --- a/vlib/v/checker/tests/cast_expr_T_type_err.out +++ b/vlib/v/checker/tests/cast_expr_T_type_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/cast_expr_T_type_err.vv:4:6: error: unknown type `A` - 2 | + 2 | 3 | fn main() { 4 | _ = A(0) | ~~~~ diff --git a/vlib/v/checker/tests/cast_sumtype_as_generic_err.out b/vlib/v/checker/tests/cast_sumtype_as_generic_err.out index 3cb1328909..3817ebf8a6 100644 --- a/vlib/v/checker/tests/cast_sumtype_as_generic_err.out +++ b/vlib/v/checker/tests/cast_sumtype_as_generic_err.out @@ -5,9 +5,9 @@ vlib/v/checker/tests/cast_sumtype_as_generic_err.vv:15:10: error: cannot cast `b | ~~~~~~~~~~~~~ 16 | } vlib/v/checker/tests/cast_sumtype_as_generic_err.vv:10:11: error: cannot cast `SumType` to `bool` - 8 | + 8 | 9 | fn (a SumType) cast_to[T]() T { 10 | return a as T | ~~ 11 | } - 12 | \ No newline at end of file + 12 | diff --git a/vlib/v/checker/tests/cast_sumtype_err.out b/vlib/v/checker/tests/cast_sumtype_err.out index 7b87a16742..35492ef436 100644 --- a/vlib/v/checker/tests/cast_sumtype_err.out +++ b/vlib/v/checker/tests/cast_sumtype_err.out @@ -3,10 +3,10 @@ vlib/v/checker/tests/cast_sumtype_err.vv:8:11: error: cannot cast `Test` sum typ 7 | data := Test(12) 8 | eprintln(int(data)) | ~~~~~~~~~ - 9 | + 9 | 10 | foo := Bar('123.45') vlib/v/checker/tests/cast_sumtype_err.vv:11:10: error: cannot cast `Bar` sum type value to `f32`, use `foo as f32` instead - 9 | + 9 | 10 | foo := Bar('123.45') 11 | println(f32(foo)) | ~~~~~~~~ diff --git a/vlib/v/checker/tests/cast_to_ref_struct_err.out b/vlib/v/checker/tests/cast_to_ref_struct_err.out index 348aa96cec..7afa2dcf9e 100644 --- a/vlib/v/checker/tests/cast_to_ref_struct_err.out +++ b/vlib/v/checker/tests/cast_to_ref_struct_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/cast_to_ref_struct_err.vv:9:16: error: cannot cast `string` to `&SomeError` - 7 | + 7 | 8 | fn main() { 9 | a := unsafe { &SomeError('yo') } | ~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/cast_voidptr_to_struct_err.out b/vlib/v/checker/tests/cast_voidptr_to_struct_err.out index e939b59eaa..e7fa845fd0 100644 --- a/vlib/v/checker/tests/cast_voidptr_to_struct_err.out +++ b/vlib/v/checker/tests/cast_voidptr_to_struct_err.out @@ -1,12 +1,12 @@ vlib/v/checker/tests/cast_voidptr_to_struct_err.vv:6:9: error: cannot cast `voidptr` to struct - 4 | + 4 | 5 | fn unwrap_concrete(ptr voidptr) Foo { 6 | return Foo(ptr) | ~~~~~~~~ 7 | } 8 | vlib/v/checker/tests/cast_voidptr_to_struct_err.vv:10:9: error: cannot cast `voidptr` to struct - 8 | + 8 | 9 | fn unwrap_generic[T](ptr voidptr) T { 10 | return T(ptr) | ~~~~~~ diff --git a/vlib/v/checker/tests/clash_ident_module_name_prefix.out b/vlib/v/checker/tests/clash_ident_module_name_prefix.out index 4a756ca522..d7374af503 100644 --- a/vlib/v/checker/tests/clash_ident_module_name_prefix.out +++ b/vlib/v/checker/tests/clash_ident_module_name_prefix.out @@ -1,19 +1,19 @@ vlib/v/checker/tests/clash_ident_module_name_prefix.vv:7:1: error: identifier cannot use prefix `builtin__` of imported module `builtin` 5 | // os is not imported so the os__ prefix should not produce an error - 6 | + 6 | 7 | fn builtin__string_str() { | ~~~~~~~~~~~~~~~~~~~~~~~~ 8 | } 9 | vlib/v/checker/tests/clash_ident_module_name_prefix.vv:10:1: error: identifier cannot use prefix `time__` of imported module `time` 8 | } - 9 | + 9 | 10 | fn time__utc() { | ~~~~~~~~~~~~~~ 11 | } 12 | vlib/v/checker/tests/clash_ident_module_name_prefix.vv:17:2: error: identifier cannot use prefix `builtin__` of imported module `builtin` - 15 | + 15 | 16 | fn main() { 17 | builtin__string_str := 'Hello V!'.str() | ~~~~~~~~~~~~~~~~~~~ @@ -25,4 +25,4 @@ vlib/v/checker/tests/clash_ident_module_name_prefix.vv:18:2: error: identifier c 18 | time__now := time.now() | ~~~~~~~~~ 19 | os__log := 'Hello V!' - 20 | println(builtin__string_str) \ No newline at end of file + 20 | println(builtin__string_str) diff --git a/vlib/v/checker/tests/closure_undefined_ident_err.out b/vlib/v/checker/tests/closure_undefined_ident_err.out index 10faa97efa..7871a93c59 100644 --- a/vlib/v/checker/tests/closure_undefined_ident_err.out +++ b/vlib/v/checker/tests/closure_undefined_ident_err.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/closure_undefined_ident_err.vv:25:7: warning: unused variable: `method` 23 | c := Custom{'noname'} - 24 | + 24 | 25 | $for method in MyInterface.methods { | ~~~~~~ 26 | z := fn [c] () { diff --git a/vlib/v/checker/tests/compare_unsigned_signed.out b/vlib/v/checker/tests/compare_unsigned_signed.out index f6d3330803..1e78bf604f 100644 --- a/vlib/v/checker/tests/compare_unsigned_signed.out +++ b/vlib/v/checker/tests/compare_unsigned_signed.out @@ -6,7 +6,7 @@ vlib/v/checker/tests/compare_unsigned_signed.vv:2:14: error: unsigned integer ca 4 | } vlib/v/checker/tests/compare_unsigned_signed.vv:6:5: error: unsigned integer cannot be compared with negative value 4 | } - 5 | + 5 | 6 | if -1 > u32(1) { | ~~ 7 | println('unexpected') @@ -23,10 +23,10 @@ vlib/v/checker/tests/compare_unsigned_signed.vv:11:6: error: negative value cann 10 | _ = u8(-1) == -1 // false! 11 | _ = -1 == u16(-1) // false! | ~~ - 12 | + 12 | 13 | // smaller unsigned == signed, OK vlib/v/checker/tests/compare_unsigned_signed.vv:18:12: error: `i8` cannot be compared with `u16` - 16 | + 16 | 17 | // smaller signed == unsigned, NG 18 | _ = i8(0) == u16(0) | ~~ diff --git a/vlib/v/checker/tests/comptime_call_method_args_err.out b/vlib/v/checker/tests/comptime_call_method_args_err.out index 18ab038d9b..77cbdac98c 100644 --- a/vlib/v/checker/tests/comptime_call_method_args_err.out +++ b/vlib/v/checker/tests/comptime_call_method_args_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/comptime_call_method_args_err.vv:9:14: cgen error: expected 0 arguments to method S1.method_hello, but got 1 - 7 | + 7 | 8 | $for method in S1.methods { 9 | println(s1.$method('yo')) | ~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/deference_nil_ptr_err.out b/vlib/v/checker/tests/deference_nil_ptr_err.out index a52cfc9823..dcdc9309c3 100644 --- a/vlib/v/checker/tests/deference_nil_ptr_err.out +++ b/vlib/v/checker/tests/deference_nil_ptr_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/deference_nil_ptr_err.vv:3:10: error: cannot deference a `nil` pointer 1 | foo_ptr := unsafe { nil } - 2 | + 2 | 3 | println(*foo_ptr) | ~~~~~~~ diff --git a/vlib/v/checker/tests/enum_field_value_overflow.out b/vlib/v/checker/tests/enum_field_value_overflow.out index 30c8e9664b..a1cea9b0a7 100644 --- a/vlib/v/checker/tests/enum_field_value_overflow.out +++ b/vlib/v/checker/tests/enum_field_value_overflow.out @@ -7,7 +7,7 @@ vlib/v/checker/tests/enum_field_value_overflow.vv:3:10: error: enum value `21474 5 | } vlib/v/checker/tests/enum_field_value_overflow.vv:7:21: error: `string` is not one of `i8`,`i16`,`i32`,`int`,`i64`,`u8`,`u16`,`u32`,`u64` 5 | } - 6 | + 6 | 7 | enum ColorString as string { | ~~~~~~ 8 | red @@ -69,21 +69,21 @@ vlib/v/checker/tests/enum_field_value_overflow.vv:56:10: error: enum value `256` 57 | } 58 | vlib/v/checker/tests/enum_field_value_overflow.vv:60:10: error: enum value `65536` overflows the enum type `u16`, values of which have to be in [0, 65535] - 58 | + 58 | 59 | enum ColorU16ShouldFail as u16 { 60 | green = 65536 | ~~~~~ 61 | } 62 | vlib/v/checker/tests/enum_field_value_overflow.vv:64:10: error: enum value `4294967296` overflows the enum type `u32`, values of which have to be in [0, 4294967295] - 62 | + 62 | 63 | enum ColorU32ShouldFail as u32 { 64 | green = 4294967296 | ~~~~~~~~~~ 65 | } 66 | vlib/v/checker/tests/enum_field_value_overflow.vv:68:10: error: enum value `18446744073709551616` overflows the enum type `u64`, values of which have to be in [0, 18446744073709551615] - 66 | + 66 | 67 | enum ColorU64ShouldFail as u64 { 68 | green = 18446744073709551616 | ~~~~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/enum_from_string_args_err.out b/vlib/v/checker/tests/enum_from_string_args_err.out index a0f9b8e459..f85126b97f 100644 --- a/vlib/v/checker/tests/enum_from_string_args_err.out +++ b/vlib/v/checker/tests/enum_from_string_args_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/enum_from_string_args_err.vv:8:2: error: expected 1 argument, but got 0 - 6 | + 6 | 7 | fn main() { 8 | Color.from_string() | ~~~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/enum_init_err.out b/vlib/v/checker/tests/enum_init_err.out index de805c447a..3edbcc6101 100644 --- a/vlib/v/checker/tests/enum_init_err.out +++ b/vlib/v/checker/tests/enum_init_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/enum_init_err.vv:8:7: error: cannot initialize enums - 6 | + 6 | 7 | fn main() { 8 | a := Hello{} | ~~~~~~~ diff --git a/vlib/v/checker/tests/eq_ne_op_wrong_type_err.out b/vlib/v/checker/tests/eq_ne_op_wrong_type_err.out index 626302471a..a0093a4ba4 100644 --- a/vlib/v/checker/tests/eq_ne_op_wrong_type_err.out +++ b/vlib/v/checker/tests/eq_ne_op_wrong_type_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:12:10: error: infix expr: cannot use `int literal` (right expression) as `Aaa` - 10 | + 10 | 11 | fn main() { 12 | println(Aaa{} == 10) | ~~~~~~~~~~~ @@ -24,10 +24,10 @@ vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:15:10: error: infix expr: cannot 14 | println(Aaa{} != 10) 15 | println(10 != Aaa{}) | ~~~~~~~~~~~ - 16 | + 16 | 17 | println(Aaa{0} == AAaa{0}) vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:29:10: error: infix expr: cannot use `Arr` (right expression) as `ArrAaa` - 27 | + 27 | 28 | arr_aaa := ArrAaa(arr) 29 | println(arr_aaa == arr) | ~~~~~~~~~~~~~~ @@ -52,17 +52,17 @@ vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:32:10: error: infix expr: cannot 31 | println(arr_aaa != arr) 32 | println(arr != arr_aaa) | ~~~~~~~~~~~~~~ - 33 | + 33 | 34 | println(arr_aaa == [0]) vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:34:10: error: infix expr: cannot use `[]int` (right expression) as `ArrAaa` 32 | println(arr != arr_aaa) - 33 | + 33 | 34 | println(arr_aaa == [0]) | ~~~~~~~~~~~~~~ 35 | println([1] == arr_aaa) 36 | println(arr_aaa != [0]) vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:35:10: error: infix expr: cannot use `ArrAaa` (right expression) as `[]int` - 33 | + 33 | 34 | println(arr_aaa == [0]) 35 | println([1] == arr_aaa) | ~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/fixed_array_init_with_default.out b/vlib/v/checker/tests/fixed_array_init_with_default.out index e0f871e72d..495ba05a4c 100644 --- a/vlib/v/checker/tests/fixed_array_init_with_default.out +++ b/vlib/v/checker/tests/fixed_array_init_with_default.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/fixed_array_init_with_default.vv:6:27: error: expected `string`, not `[]string` - 4 | + 4 | 5 | fn main() { 6 | _ := Foo{[2]string{init: ['a', 'b']}} | ~~~~~~~~~~ diff --git a/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.out b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.out index 20b3daf8a1..305138ecfc 100644 --- a/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.out +++ b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.vv:14:4: error: cannot use `...Foo1` as `...Foo` in argument 1 to `f` - 12 | + 12 | 13 | fn main() { 14 | f(...[Foo1{}, Foo1{}]) | ~~~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/fn_call_arg_mismatch_err_d.out b/vlib/v/checker/tests/fn_call_arg_mismatch_err_d.out index 601e0c5daf..76aa3d8519 100644 --- a/vlib/v/checker/tests/fn_call_arg_mismatch_err_d.out +++ b/vlib/v/checker/tests/fn_call_arg_mismatch_err_d.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/fn_call_arg_mismatch_err_d.vv:17:26: error: cannot use `fn (string) f64` as `fn (string) ?Flag` in argument 2 to `parse_option` - 15 | + 15 | 16 | fn main() { 17 | t := parse_option('45', parse_percent)? | ~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/fn_ptr_undereferenced_err.out b/vlib/v/checker/tests/fn_ptr_undereferenced_err.out index 0e390b95fb..1032367a5c 100644 --- a/vlib/v/checker/tests/fn_ptr_undereferenced_err.out +++ b/vlib/v/checker/tests/fn_ptr_undereferenced_err.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/fn_ptr_undereferenced_err.vv:10:2: error: function pointer must be undereferenced first 8 | ref := &f - 9 | deref := ref + 9 | deref := ref 10 | deref() | ~~~~~~~ 11 | } diff --git a/vlib/v/checker/tests/fn_return_type_mismatch.out b/vlib/v/checker/tests/fn_return_type_mismatch.out index 9dfa73c50f..be52705d5a 100644 --- a/vlib/v/checker/tests/fn_return_type_mismatch.out +++ b/vlib/v/checker/tests/fn_return_type_mismatch.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/fn_return_type_mismatch.vv:6:9: error: cannot use `i64` as type `int` in return argument - 4 | + 4 | 5 | fn func2() (int, int) { 6 | return func1() | ~~~~~~~ diff --git a/vlib/v/checker/tests/fn_selector_expr_err.out b/vlib/v/checker/tests/fn_selector_expr_err.out index 71a66a1cf5..c4f9587869 100644 --- a/vlib/v/checker/tests/fn_selector_expr_err.out +++ b/vlib/v/checker/tests/fn_selector_expr_err.out @@ -1,3 +1,3 @@ -vlib/v/checker/tests/fn_selector_expr_err.vv:1:26: error: `println('Hello, World!')` does not return a value - 1 | println('Hello, World!').whatever - | ~~~~~~~~ +vlib/v/checker/tests/fn_selector_expr_err.vv:1:26: error: `println('Hello, World!')` does not return a value + 1 | println('Hello, World!').whatever + | ~~~~~~~~ diff --git a/vlib/v/checker/tests/for_in_index_option.out b/vlib/v/checker/tests/for_in_index_option.out index 26ec76b777..23c3cf344a 100644 --- a/vlib/v/checker/tests/for_in_index_option.out +++ b/vlib/v/checker/tests/for_in_index_option.out @@ -1,7 +1,7 @@ vlib/v/checker/tests/for_in_index_option.vv:4:17: error: for in: cannot index `![]string` - 2 | + 2 | 3 | fn main() { 4 | for file in os.ls('.') { | ~~~~~~~ 5 | println(file) - 6 | } \ No newline at end of file + 6 | } diff --git a/vlib/v/checker/tests/for_in_key_redefinition.out b/vlib/v/checker/tests/for_in_key_redefinition.out index fd973fbe3f..b6b03a5bd0 100644 --- a/vlib/v/checker/tests/for_in_key_redefinition.out +++ b/vlib/v/checker/tests/for_in_key_redefinition.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/for_in_key_redefinition.vv:4:5: error: redefinition of key iteration variable `value` 2 | value := 2 - 3 | + 3 | 4 | for value, _ in arr { | ~~~~~ 5 | println(value) diff --git a/vlib/v/checker/tests/for_in_mut_string.out b/vlib/v/checker/tests/for_in_mut_string.out index e46da21c6b..40b8ce3639 100644 --- a/vlib/v/checker/tests/for_in_mut_string.out +++ b/vlib/v/checker/tests/for_in_mut_string.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/for_in_mut_string.vv:19:6: error: string type is immutable, it cannot be changed - 17 | + 17 | 18 | fn wrap_text(mut gv Grid) { 19 | for mut ch in gv.header { | ~~~ @@ -7,7 +7,7 @@ vlib/v/checker/tests/for_in_mut_string.vv:19:6: error: string type is immutable, 21 | } vlib/v/checker/tests/for_in_mut_string.vv:23:6: error: string type is immutable, it cannot be changed 21 | } - 22 | + 22 | 23 | for mut letter in 'abc' { | ~~~ 24 | bit := letter - 1 diff --git a/vlib/v/checker/tests/for_in_value_redefinition.out b/vlib/v/checker/tests/for_in_value_redefinition.out index 150ea1f7eb..1f88cfd3f8 100644 --- a/vlib/v/checker/tests/for_in_value_redefinition.out +++ b/vlib/v/checker/tests/for_in_value_redefinition.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/for_in_value_redefinition.vv:4:8: error: redefinition of value iteration variable `value` 2 | value := 2 - 3 | + 3 | 4 | for _, value in arr { | ~~~~~ 5 | println(value) diff --git a/vlib/v/checker/tests/for_match_err.out b/vlib/v/checker/tests/for_match_err.out index 4e2aa9083d..9c90a9e474 100644 --- a/vlib/v/checker/tests/for_match_err.out +++ b/vlib/v/checker/tests/for_match_err.out @@ -1,7 +1,7 @@ -vlib/v/checker/tests/for_match_err.vv:3:7: error: cannot use `match` in `for` loop - 1 | fn main() { - 2 | mut a := 2 - 3 | for match a { - | ~~~~~ - 4 | 2 { - 5 | println('a == 2') +vlib/v/checker/tests/for_match_err.vv:3:7: error: cannot use `match` in `for` loop + 1 | fn main() { + 2 | mut a := 2 + 3 | for match a { + | ~~~~~ + 4 | 2 { + 5 | println('a == 2') diff --git a/vlib/v/checker/tests/generic_closure_fn_decl_err_a.out b/vlib/v/checker/tests/generic_closure_fn_decl_err_a.out index fd77a3cefc..c00bc9aed8 100644 --- a/vlib/v/checker/tests/generic_closure_fn_decl_err_a.out +++ b/vlib/v/checker/tests/generic_closure_fn_decl_err_a.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generic_closure_fn_decl_err_a.vv:5:2: error: generic closure fn must specify type parameter, e.g. fn [foo] [T]() - 3 | + 3 | 4 | pub fn (mut app App) register[T](service T) { 5 | fn [service] () { | ~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/generic_method_call_with_short_syntax_fn_field_err.out b/vlib/v/checker/tests/generic_method_call_with_short_syntax_fn_field_err.out index ecee47440c..3246e62dad 100644 --- a/vlib/v/checker/tests/generic_method_call_with_short_syntax_fn_field_err.out +++ b/vlib/v/checker/tests/generic_method_call_with_short_syntax_fn_field_err.out @@ -1,3 +1,10 @@ +vlib/v/checker/tests/generic_method_call_with_short_syntax_fn_field_err.vv:14:30: notice: unused parameter: `options` + 12 | struct Middleware[T] {} + 13 | + 14 | fn (mut m Middleware[T]) use(options Options[T]) {} + | ~~~~~~~ + 15 | + 16 | struct App { vlib/v/checker/tests/generic_method_call_with_short_syntax_fn_field_err.vv:33:10: error: cannot assign to field `handler`: expected `fn (mut Context) bool`, not `Options[Context]` 31 | fn main() { 32 | mut app := &App{} diff --git a/vlib/v/checker/tests/generic_sumtype_decl_err_b.out b/vlib/v/checker/tests/generic_sumtype_decl_err_b.out index ce95b704d0..5880cc72bc 100644 --- a/vlib/v/checker/tests/generic_sumtype_decl_err_b.out +++ b/vlib/v/checker/tests/generic_sumtype_decl_err_b.out @@ -1,7 +1,7 @@ vlib/v/checker/tests/generic_sumtype_decl_err_b.vv:7:6: error: generic sumtype `Maybe` must specify generic type names, e.g. Maybe[T] 5 | struct Nothing {} - 6 | + 6 | 7 | type Maybe = Nothing | Just[T] | ~~~~~ - 8 | + 8 | 9 | fn main() { diff --git a/vlib/v/checker/tests/generics_fn_called_outside_of_generic_fn.out b/vlib/v/checker/tests/generics_fn_called_outside_of_generic_fn.out index ab483b0972..f2c9e01c0e 100644 --- a/vlib/v/checker/tests/generics_fn_called_outside_of_generic_fn.out +++ b/vlib/v/checker/tests/generics_fn_called_outside_of_generic_fn.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generics_fn_called_outside_of_generic_fn.vv:4:2: error: generic fn using generic types cannot be called outside of generic fn - 2 | + 2 | 3 | fn main() { 4 | foo[T]() | ~~~~~~~~ diff --git a/vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.out b/vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.out index 038e1037b2..c521cdcc8a 100644 --- a/vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.out +++ b/vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.vv:12:16: error: cannot use `[]int` as `int` in argument 1 to `max` - 10 | + 10 | 11 | fn main() { 12 | b := max[int]([1, 2, 3, 4]) | ~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/generics_inst_non_generic_struct_err.out b/vlib/v/checker/tests/generics_inst_non_generic_struct_err.out index 10607265dd..a74f47b263 100644 --- a/vlib/v/checker/tests/generics_inst_non_generic_struct_err.out +++ b/vlib/v/checker/tests/generics_inst_non_generic_struct_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generics_inst_non_generic_struct_err.vv:5:14: error: struct `Test` is not a generic struct, cannot instantiate to the concrete types - 3 | + 3 | 4 | fn main() { 5 | println(Test[string]{}) | ~~~~~~~~ diff --git a/vlib/v/checker/tests/generics_interface_decl_no_mention_err.out b/vlib/v/checker/tests/generics_interface_decl_no_mention_err.out index 9f83ef69ae..9880804581 100644 --- a/vlib/v/checker/tests/generics_interface_decl_no_mention_err.out +++ b/vlib/v/checker/tests/generics_interface_decl_no_mention_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generics_interface_decl_no_mention_err.vv:4:2: error: generic type name `T` is not mentioned in interface `Foo` - 2 | + 2 | 3 | interface Foo[U] { 4 | Bar[T] | ~~~ diff --git a/vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.out b/vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.out index 57cbeade5f..cc42cd9fb5 100644 --- a/vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.out +++ b/vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.out @@ -1,12 +1,12 @@ vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.vv:6:9: error: a non generic struct `Toy` used like a generic struct - 4 | + 4 | 5 | fn get_toy1(toy Toy) Toy{ 6 | return Toy[T]{toy.toy_name} | ~~~ 7 | } 8 | vlib/v/checker/tests/generics_non_generic_struct_used_like_a_generic_one.vv:10:9: error: a non generic struct `Toy` used like a generic struct - 8 | + 8 | 9 | fn get_toy2(toy Toy) Toy{ 10 | return Toy[T,U]{toy.toy_name} | ~~~ diff --git a/vlib/v/checker/tests/generics_ref_array_arg_mismatch.out b/vlib/v/checker/tests/generics_ref_array_arg_mismatch.out index 233aeba80d..a151e16d85 100644 --- a/vlib/v/checker/tests/generics_ref_array_arg_mismatch.out +++ b/vlib/v/checker/tests/generics_ref_array_arg_mismatch.out @@ -1,13 +1,13 @@ -vlib/v/checker/tests/generics_ref_array_arg_mismatch.vv:20:30: error: cannot use `[]&MyStruct[f64]` as `[]MyStruct[f64]` in argument 1 to `do_it_wrong` - 18 | m := MyStruct[f64]{a: 1.23} - 19 | a := [&m] - 20 | println(do_it_wrong[f64](a)) +vlib/v/checker/tests/generics_ref_array_arg_mismatch.vv:22:27: error: cannot use `[]&MyStruct[f64]` as `[]MyStruct[f64]` in argument 1 to `do_it_wrong` + 20 | } + 21 | a := [&m] + 22 | println(do_it_wrong[f64](a)) | ^ - 21 | println(Box[f64]{}.do_it_wrong(a)) - 22 | } -vlib/v/checker/tests/generics_ref_array_arg_mismatch.vv:21:36: error: cannot use `[]&MyStruct[f64]` as `[]MyStruct[f64]` in argument 1 to `Box[f64].do_it_wrong` - 19 | a := [&m] - 20 | println(do_it_wrong[f64](a)) - 21 | println(Box[f64]{}.do_it_wrong(a)) + 23 | println(Box[f64]{}.do_it_wrong(a)) + 24 | } +vlib/v/checker/tests/generics_ref_array_arg_mismatch.vv:23:33: error: cannot use `[]&MyStruct[f64]` as `[]MyStruct[f64]` in argument 1 to `Box[f64].do_it_wrong` + 21 | a := [&m] + 22 | println(do_it_wrong[f64](a)) + 23 | println(Box[f64]{}.do_it_wrong(a)) | ^ - 22 | } + 24 | } diff --git a/vlib/v/checker/tests/generics_ref_array_arg_mismatch.vv b/vlib/v/checker/tests/generics_ref_array_arg_mismatch.vv index 0a8a3c9c7a..e957d6a471 100644 --- a/vlib/v/checker/tests/generics_ref_array_arg_mismatch.vv +++ b/vlib/v/checker/tests/generics_ref_array_arg_mismatch.vv @@ -1,22 +1,24 @@ module main struct MyStruct[T] { - a T + a T } struct Box[T] {} fn do_it_wrong[T](v []MyStruct[T]) T { - return v[0].a + return v[0].a } fn (b Box[T]) do_it_wrong(v []MyStruct[T]) T { - return v[0].a + return v[0].a } fn main() { - m := MyStruct[f64]{a: 1.23} - a := [&m] - println(do_it_wrong[f64](a)) - println(Box[f64]{}.do_it_wrong(a)) + m := MyStruct[f64]{ + a: 1.23 + } + a := [&m] + println(do_it_wrong[f64](a)) + println(Box[f64]{}.do_it_wrong(a)) } diff --git a/vlib/v/checker/tests/generics_struct_decl_no_mention_err.out b/vlib/v/checker/tests/generics_struct_decl_no_mention_err.out index 81cb286e82..15648c212c 100644 --- a/vlib/v/checker/tests/generics_struct_decl_no_mention_err.out +++ b/vlib/v/checker/tests/generics_struct_decl_no_mention_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generics_struct_decl_no_mention_err.vv:4:2: error: generic type name `T` is not mentioned in struct `Foo[U]` - 2 | + 2 | 3 | struct Foo[U] { 4 | Bar[T] | ~~~~~~ diff --git a/vlib/v/checker/tests/generics_struct_declaration_err.out b/vlib/v/checker/tests/generics_struct_declaration_err.out index c47eadf4c2..099ff3ed51 100644 --- a/vlib/v/checker/tests/generics_struct_declaration_err.out +++ b/vlib/v/checker/tests/generics_struct_declaration_err.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/generics_struct_declaration_err.vv:5:1: error: generic struct `MyGenericChannelStruct` declaration must specify the generic type names, e.g. MyGenericChannelStruct[T] 3 | } - 4 | + 4 | 5 | struct MyGenericChannelStruct { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 | GenericChannelStruct[T] diff --git a/vlib/v/checker/tests/generics_struct_in_non_generic_fn_err.out b/vlib/v/checker/tests/generics_struct_in_non_generic_fn_err.out index 11c39d2767..c9b805ac1b 100644 --- a/vlib/v/checker/tests/generics_struct_in_non_generic_fn_err.out +++ b/vlib/v/checker/tests/generics_struct_in_non_generic_fn_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generics_struct_in_non_generic_fn_err.vv:5:7: error: generic struct cannot be used in non-generic function - 3 | + 3 | 4 | fn main() { 5 | _ := []Example[T]{} | ~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/generics_struct_infer_err.out b/vlib/v/checker/tests/generics_struct_infer_err.out index d7fda8c1fd..f3742fd923 100644 --- a/vlib/v/checker/tests/generics_struct_infer_err.out +++ b/vlib/v/checker/tests/generics_struct_infer_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generics_struct_infer_err.vv:7:10: error: could not infer generic type `U` in generic struct `Foo[T, U]` - 5 | + 5 | 6 | fn main() { 7 | st11 := Foo{ | ~~~~ diff --git a/vlib/v/checker/tests/generics_struct_type_mismatch_err.out b/vlib/v/checker/tests/generics_struct_type_mismatch_err.out index d06496417b..48d85c4cba 100644 --- a/vlib/v/checker/tests/generics_struct_type_mismatch_err.out +++ b/vlib/v/checker/tests/generics_struct_type_mismatch_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generics_struct_type_mismatch_err.vv:7:20: error: the number of generic types of struct `Example` is inconsistent with the concrete types - 5 | + 5 | 6 | fn main() { 7 | example := Example[string]{ | ~~~~~~~~ diff --git a/vlib/v/checker/tests/generics_undefined_operation.out b/vlib/v/checker/tests/generics_undefined_operation.out index 52fd6b3e04..df7287085d 100644 --- a/vlib/v/checker/tests/generics_undefined_operation.out +++ b/vlib/v/checker/tests/generics_undefined_operation.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/generics_undefined_operation.vv:12:5: error: undefined operation `V2d[int]` * `V2d[int]` 10 | v3 := V2d[int]{4, 6} - 11 | + 11 | 12 | if v1 * v2 == v3 { | ~~~~~~~ 13 | } diff --git a/vlib/v/checker/tests/globals/closure_capture_global_var.out b/vlib/v/checker/tests/globals/closure_capture_global_var.out index f81d636fc2..3bc2b9a51e 100644 --- a/vlib/v/checker/tests/globals/closure_capture_global_var.out +++ b/vlib/v/checker/tests/globals/closure_capture_global_var.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/globals/closure_capture_global_var.vv:12:12: error: no need to capture global variable `number` in closure - 10 | + 10 | 11 | fn main() { 12 | f1 := fn [number] () { | ~~~~~~ diff --git a/vlib/v/checker/tests/globals/nested_unknown_typ.out b/vlib/v/checker/tests/globals/nested_unknown_typ.out index 94a91a3363..f326ffd146 100644 --- a/vlib/v/checker/tests/globals/nested_unknown_typ.out +++ b/vlib/v/checker/tests/globals/nested_unknown_typ.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/globals/nested_unknown_typ.vv:5:13: error: unknown type `StructS` - 3 | + 3 | 4 | @[markused] 5 | __global ga []?StructS | ^ diff --git a/vlib/v/checker/tests/if_expr_option_err.out b/vlib/v/checker/tests/if_expr_option_err.out index aad47a8c8b..3642a797ff 100644 --- a/vlib/v/checker/tests/if_expr_option_err.out +++ b/vlib/v/checker/tests/if_expr_option_err.out @@ -1,7 +1,7 @@ vlib/v/checker/tests/if_expr_option_err.vv:6:5: error: non-bool type `?bool` used as if condition - 4 | + 4 | 5 | fn main() { 6 | if get_bool() { | ~~~~~~~~~~ 7 | println('Using plain lists') - 8 | } \ No newline at end of file + 8 | } diff --git a/vlib/v/checker/tests/if_guard_expr_err.out b/vlib/v/checker/tests/if_guard_expr_err.out index 66e441da83..6d1645a913 100644 --- a/vlib/v/checker/tests/if_guard_expr_err.out +++ b/vlib/v/checker/tests/if_guard_expr_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/if_guard_expr_err.vv:6:7: error: if guard expects non-propagate option or result - 4 | + 4 | 5 | fn main() { 6 | a := if r := foo() { | ~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/if_match_expr_err.out b/vlib/v/checker/tests/if_match_expr_err.out index 25b13cb189..2c167754eb 100644 --- a/vlib/v/checker/tests/if_match_expr_err.out +++ b/vlib/v/checker/tests/if_match_expr_err.out @@ -1,7 +1,7 @@ -vlib/v/checker/tests/if_match_expr_err.vv:3:8: error: cannot use `match` with `if` statements - 1 | fn main() { - 2 | a := 0 - 3 | if match a { - | ~~~~~ - 4 | 0 { - 5 | println('a is zero') +vlib/v/checker/tests/if_match_expr_err.vv:3:8: error: cannot use `match` with `if` statements + 1 | fn main() { + 2 | a := 0 + 3 | if match a { + | ~~~~~ + 4 | 0 { + 5 | println('a is zero') diff --git a/vlib/v/checker/tests/implements_generic_err.out b/vlib/v/checker/tests/implements_generic_err.out index e6c2c46842..af4c172d45 100644 --- a/vlib/v/checker/tests/implements_generic_err.out +++ b/vlib/v/checker/tests/implements_generic_err.out @@ -1,20 +1,20 @@ vlib/v/checker/tests/implements_generic_err.vv:12:31: error: missing generic type on IB 10 | } - 11 | + 11 | 12 | struct Foo1[T] implements IA, IB { | ~~ 13 | a int 14 | b T vlib/v/checker/tests/implements_generic_err.vv:17:31: error: unknown generic type Y 15 | } - 16 | + 16 | 17 | struct Foo2[T] implements IA, IB[Y] { | ~~ 18 | a int 19 | b T vlib/v/checker/tests/implements_generic_err.vv:22:31: error: unknown generic type Y 20 | } - 21 | + 21 | 22 | struct Foo3[T] implements IA, IB[T,Y] { | ~~ 23 | a int diff --git a/vlib/v/checker/tests/implements_keyword.out b/vlib/v/checker/tests/implements_keyword.out index 1dcef2b16b..06d5f085ff 100644 --- a/vlib/v/checker/tests/implements_keyword.out +++ b/vlib/v/checker/tests/implements_keyword.out @@ -1,20 +1,20 @@ vlib/v/checker/tests/implements_keyword.vv:5:1: error: `CustomError` doesn't implement method `print_error` of interface `MyError` 3 | } - 4 | + 4 | 5 | struct CustomError implements MyError { | ~~~~~~~~~~~~~~~~~~ 6 | } 7 | vlib/v/checker/tests/implements_keyword.vv:15:1: error: `CustomError2` doesn't implement method `print_error` of interface `MyError` 13 | } - 14 | + 14 | 15 | struct CustomError2 implements MyError, MyError2 { | ~~~~~~~~~~~~~~~~~~~ 16 | } 17 | vlib/v/checker/tests/implements_keyword.vv:15:1: error: `CustomError2` doesn't implement method `print_error2` of interface `MyError2` 13 | } - 14 | + 14 | 15 | struct CustomError2 implements MyError, MyError2 { | ~~~~~~~~~~~~~~~~~~~ 16 | } diff --git a/vlib/v/checker/tests/import_mod_as_mod_err.out b/vlib/v/checker/tests/import_mod_as_mod_err.out index 47df47b670..6105235a63 100644 --- a/vlib/v/checker/tests/import_mod_as_mod_err.out +++ b/vlib/v/checker/tests/import_mod_as_mod_err.out @@ -1,5 +1,5 @@ -vlib/v/checker/tests/import_mod_as_mod_err.vv:1:16: error: import alias `math as math` is redundant - 1 | import math as math - | ~~~~ - 2 | - 3 | fn main() { +vlib/v/checker/tests/import_mod_as_mod_err.vv:1:16: error: import alias `math as math` is redundant + 1 | import math as math + | ~~~~ + 2 | + 3 | fn main() { diff --git a/vlib/v/checker/tests/import_sym_builtin_override_err.out b/vlib/v/checker/tests/import_sym_builtin_override_err.out index cba84b4139..60d245c79e 100644 --- a/vlib/v/checker/tests/import_sym_builtin_override_err.out +++ b/vlib/v/checker/tests/import_sym_builtin_override_err.out @@ -1,11 +1,11 @@ vlib/v/checker/tests/import_sym_builtin_override_err.vv:3:12: error: unknown type `rand.f64`. Did you mean `rand.PRNG`? 1 | import rand { f64 } - 2 | + 2 | 3 | type Dot = [3]f64 | ~~~~~~ vlib/v/checker/tests/import_sym_builtin_override_err.vv:1:15: error: cannot import or override builtin type 1 | import rand { f64 } | ~~~ - 2 | - 3 | type Dot = [3]f64 \ No newline at end of file + 2 | + 3 | type Dot = [3]f64 diff --git a/vlib/v/checker/tests/import_symbol_type_err.out b/vlib/v/checker/tests/import_symbol_type_err.out index 3e270479bd..3c15744b33 100644 --- a/vlib/v/checker/tests/import_symbol_type_err.out +++ b/vlib/v/checker/tests/import_symbol_type_err.out @@ -5,13 +5,13 @@ vlib/v/checker/tests/import_symbol_type_err.vv:1:17: error: module `crypto` has 3 | fn main() { vlib/v/checker/tests/import_symbol_type_err.vv:4:10: error: unknown type `crypto.Coin`. Did you mean `crypto.Hash`? - 2 | + 2 | 3 | fn main() { 4 | println(Coin{}) | ~~~~~~ 5 | } vlib/v/checker/tests/import_symbol_type_err.vv:4:2: error: `println` can not print void expressions - 2 | + 2 | 3 | fn main() { 4 | println(Coin{}) | ~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/inc_dec_fun_call.out b/vlib/v/checker/tests/inc_dec_fun_call.out index 85760117a7..8a7415ec88 100644 --- a/vlib/v/checker/tests/inc_dec_fun_call.out +++ b/vlib/v/checker/tests/inc_dec_fun_call.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/inc_dec_fun_call.vv:5:1: error: cannot decrement `foo()` because it is non lvalue expression 3 | } - 4 | + 4 | 5 | foo()-- | ~~~~~ -Details: try rewrite this as `foo() - 1` \ No newline at end of file +Details: try rewrite this as `foo() - 1` diff --git a/vlib/v/checker/tests/incorrect_smartcast2_err.out b/vlib/v/checker/tests/incorrect_smartcast2_err.out index e69de29bb2..7344e2e5be 100644 --- a/vlib/v/checker/tests/incorrect_smartcast2_err.out +++ b/vlib/v/checker/tests/incorrect_smartcast2_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/incorrect_smartcast2_err.vv:11:4: warning: unused function: `works` + 9 | type Either[T, E] = Left[E] | Right[T] + 10 | + 11 | fn works(v []Either[int, int]) { + | ~~~~~ + 12 | first := v[0] + 13 | match first { +vlib/v/checker/tests/incorrect_smartcast2_err.vv:21:4: warning: unused function: `doesntwork` + 19 | } + 20 | + 21 | fn doesntwork(v []Either[int, int]) { + | ~~~~~~~~~~ + 22 | match v[0] { + 23 | Left[int] { diff --git a/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.out b/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.out index b96d684a4d..5725524115 100644 --- a/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.out +++ b/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:8:9: error: type `Foo` does not support indexing - 6 | + 6 | 7 | fn sum_type_or_interface_as_parameters(mut foo Foo, mut bar Bar, mut st1 Struct, st2 &Struct, st3 Struct) { 8 | _ = foo[0] | ~~~ @@ -10,17 +10,17 @@ vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:9:9: error: ty 8 | _ = foo[0] 9 | _ = bar[0] | ~~~ - 10 | + 10 | 11 | _ = st1[0] vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:11:9: error: type `mut Struct` does not support slicing 9 | _ = bar[0] - 10 | + 10 | 11 | _ = st1[0] | ~~~ 12 | _ = st2[0] 13 | _ = st3[0] vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:12:9: error: pointer indexing is only allowed in `unsafe` blocks - 10 | + 10 | 11 | _ = st1[0] 12 | _ = st2[0] | ~~~ diff --git a/vlib/v/checker/tests/infix_compare_option_err.out b/vlib/v/checker/tests/infix_compare_option_err.out index e3a740057b..de6946c4be 100644 --- a/vlib/v/checker/tests/infix_compare_option_err.out +++ b/vlib/v/checker/tests/infix_compare_option_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/infix_compare_option_err.vv:6:5: error: `?int` cannot be used as `int`, unwrap the option first - 4 | + 4 | 5 | fn main() { 6 | if foo() > foo() { | ~~~~~ diff --git a/vlib/v/checker/tests/infix_err.out b/vlib/v/checker/tests/infix_err.out index deb04d2660..29594753a4 100644 --- a/vlib/v/checker/tests/infix_err.out +++ b/vlib/v/checker/tests/infix_err.out @@ -1,26 +1,26 @@ vlib/v/checker/tests/infix_err.vv:13:5: error: mismatched types `string` and `?string` 11 | } - 12 | + 12 | 13 | _ = '' + f() | ~~~~~~~~ 14 | _ = f() + '' 15 | _ = f() + f() vlib/v/checker/tests/infix_err.vv:13:10: error: `?string` cannot be used as `string`, unwrap the option first 11 | } - 12 | + 12 | 13 | _ = '' + f() | ~~~ 14 | _ = f() + '' 15 | _ = f() + f() vlib/v/checker/tests/infix_err.vv:14:5: error: mismatched types `?string` and `string` - 12 | + 12 | 13 | _ = '' + f() 14 | _ = f() + '' | ~~~~~~~~ 15 | _ = f() + f() 16 | vlib/v/checker/tests/infix_err.vv:14:5: error: `?string` cannot be used as `string`, unwrap the option first - 12 | + 12 | 13 | _ = '' + f() 14 | _ = f() + '' | ~~~ @@ -31,31 +31,31 @@ vlib/v/checker/tests/infix_err.vv:15:9: error: `+` cannot be used with `?string` 14 | _ = f() + '' 15 | _ = f() + f() | ^ - 16 | + 16 | 17 | _ = 4 + g() vlib/v/checker/tests/infix_err.vv:15:5: error: `?string` cannot be used as `string`, unwrap the option first 13 | _ = '' + f() 14 | _ = f() + '' 15 | _ = f() + f() | ~~~ - 16 | + 16 | 17 | _ = 4 + g() vlib/v/checker/tests/infix_err.vv:17:7: error: `+` cannot be used with `?int` 15 | _ = f() + f() - 16 | + 16 | 17 | _ = 4 + g() | ^ 18 | _ = int(0) + g() 19 | _ = g() + int(3) vlib/v/checker/tests/infix_err.vv:17:9: error: `?int` cannot be used as `int literal`, unwrap the option first 15 | _ = f() + f() - 16 | + 16 | 17 | _ = 4 + g() | ~~~ 18 | _ = int(0) + g() 19 | _ = g() + int(3) vlib/v/checker/tests/infix_err.vv:18:14: error: `?int` cannot be used as `int`, unwrap the option first - 16 | + 16 | 17 | _ = 4 + g() 18 | _ = int(0) + g() | ~~~ @@ -80,24 +80,24 @@ vlib/v/checker/tests/infix_err.vv:20:9: error: `+` cannot be used with `?int` 19 | _ = g() + int(3) 20 | _ = g() + 3 | ^ - 21 | + 21 | 22 | // binary operands vlib/v/checker/tests/infix_err.vv:20:5: error: `?int` cannot be used as `int literal`, unwrap the option first 18 | _ = int(0) + g() 19 | _ = g() + int(3) 20 | _ = g() + 3 | ~~~ - 21 | + 21 | 22 | // binary operands vlib/v/checker/tests/infix_err.vv:23:5: error: left operand for `&&` is not a boolean - 21 | + 21 | 22 | // binary operands 23 | _ = 1 && 2 | ^ 24 | _ = true || 2 25 | vlib/v/checker/tests/infix_err.vv:23:10: error: right operand for `&&` is not a boolean - 21 | + 21 | 22 | // binary operands 23 | _ = 1 && 2 | ^ @@ -108,17 +108,17 @@ vlib/v/checker/tests/infix_err.vv:24:13: error: right operand for `||` is not a 23 | _ = 1 && 2 24 | _ = true || 2 | ^ - 25 | + 25 | 26 | // boolean expressions vlib/v/checker/tests/infix_err.vv:24:5: error: infix expr: cannot use `int literal` (right expression) as `bool` 22 | // binary operands 23 | _ = 1 && 2 24 | _ = true || 2 | ~~~~~~~~~ - 25 | + 25 | 26 | // boolean expressions vlib/v/checker/tests/infix_err.vv:27:22: error: ambiguous boolean expression. use `()` to ensure correct order of operations - 25 | + 25 | 26 | // boolean expressions 27 | _ = 1 == 1 && 2 == 2 || 3 == 3 | ~~ @@ -136,7 +136,7 @@ vlib/v/checker/tests/infix_err.vv:29:5: error: mismatched types `int literal` an 28 | _ = 1 == 1 && 2 == 2 || 3 == 3 && 4 == 4 29 | _ = 1 + println('') | ~~~~~~~~~~~~~~~ - 30 | + 30 | 31 | // struct members vlib/v/checker/tests/infix_err.vv:36:11: error: `?string` cannot be used as `string`, unwrap the option first 34 | } @@ -164,5 +164,5 @@ vlib/v/checker/tests/infix_err.vv:39:19: error: `?string` cannot be used as `str 38 | _ := data.name == name 39 | _ := name == data.name | ~~~~ - 40 | + 40 | 41 | // these should not error diff --git a/vlib/v/checker/tests/interface_implemented_by_function.out b/vlib/v/checker/tests/interface_implemented_by_function.out index 268d489fc3..40d7d08f4e 100644 --- a/vlib/v/checker/tests/interface_implemented_by_function.out +++ b/vlib/v/checker/tests/interface_implemented_by_function.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/interface_implemented_by_function.vv:6:6: error: cannot implement interface `Ch` using function - 4 | + 4 | 5 | fn main() { 6 | id(id) | ~~ - 7 | } \ No newline at end of file + 7 | } diff --git a/vlib/v/checker/tests/interface_sameness_check_for_mutable_methods.out b/vlib/v/checker/tests/interface_sameness_check_for_mutable_methods.out index 216c817a68..1b5955fb2f 100644 --- a/vlib/v/checker/tests/interface_sameness_check_for_mutable_methods.out +++ b/vlib/v/checker/tests/interface_sameness_check_for_mutable_methods.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/interface_sameness_check_for_mutable_methods.vv:15:6: error: `St` incorrectly implements method `method` of interface `Interface`: expected return type `u32` - 13 | + 13 | 14 | fn bar() { 15 | foo(St{}) | ~~~~ diff --git a/vlib/v/checker/tests/invalid_vweb_param_type.out b/vlib/v/checker/tests/invalid_vweb_param_type.out index 21b71fcc8a..c65fb1de2a 100644 --- a/vlib/v/checker/tests/invalid_vweb_param_type.out +++ b/vlib/v/checker/tests/invalid_vweb_param_type.out @@ -6,6 +6,76 @@ vlib/v/checker/tests/invalid_vweb_param_type.vv:8:24: notice: unused parameter: | ~~~~ 9 | return app.text('') 10 | } +vlib/vweb/vweb.v:801:11: error: field `App.req` is not public + 799 | + 800 | // Skip if the HTTP request method does not match the attributes + 801 | if app.req.method in route.methods { + | ~~~ + 802 | // Used for route matching + 803 | route_words := route.path_words // route.path.split('/').filter(it != '') +vlib/vweb/vweb.v:822:14: error: field `App.req` is not public + 820 | } + 821 | + 822 | if app.req.method == .post && method.args.len > 0 { + | ~~~ + 823 | // Populate method args with form values + 824 | mut args := []string{cap: method.args.len} +vlib/vweb/vweb.v:826:21: error: field `App.form` is not public + 824 | mut args := []string{cap: method.args.len} + 825 | for param in method.args { + 826 | args << app.form[param.name] + | ~~~~ + 827 | } + 828 | +vlib/vweb/vweb.v:981:21: error: field `App.static_files` is not public + 979 | fn serve_if_static[T](mut app T, url urllib.URL, host string) bool { + 980 | // TODO: handle url parameters properly - for now, ignore them + 981 | static_file := app.static_files[url.path] or { return false } + | ~~~~~~~~~~~~ + 982 | mime_type := app.static_mime_types[url.path] or { return false } + 983 | static_host := app.static_hosts[url.path] or { '' } +vlib/vweb/vweb.v:982:19: error: field `App.static_mime_types` is not public + 980 | // TODO: handle url parameters properly - for now, ignore them + 981 | static_file := app.static_files[url.path] or { return false } + 982 | mime_type := app.static_mime_types[url.path] or { return false } + | ~~~~~~~~~~~~~~~~~ + 983 | static_host := app.static_hosts[url.path] or { '' } + 984 | if static_file == '' || mime_type == '' { +vlib/vweb/vweb.v:983:21: error: field `App.static_hosts` is not public + 981 | static_file := app.static_files[url.path] or { return false } + 982 | mime_type := app.static_mime_types[url.path] or { return false } + 983 | static_host := app.static_hosts[url.path] or { '' } + | ~~~~~~~~~~~~ + 984 | if static_file == '' || mime_type == '' { + 985 | return false +vlib/vweb/vweb.v:991:23: error: field `App.conn` is not public + 989 | } + 990 | data := os.read_file(static_file) or { + 991 | send_string(mut app.conn, http_404.bytestr()) or {} + | ~~~~ + 992 | return true + 993 | } +vlib/vweb/vweb.v:666:48: error: field `App.static_files` is not public + 664 | + 665 | // copy static files + 666 | request_app.Context.static_files = global_app.static_files.clone() + | ~~~~~~~~~~~~ + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() +vlib/vweb/vweb.v:667:53: error: field `App.static_mime_types` is not public + 665 | // copy static files + 666 | request_app.Context.static_files = global_app.static_files.clone() + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + | ~~~~~~~~~~~~~~~~~ + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() + 669 | +vlib/vweb/vweb.v:668:48: error: field `App.static_hosts` is not public + 666 | request_app.Context.static_files = global_app.static_files.clone() + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() + | ~~~~~~~~~~~~ + 669 | + 670 | return request_app vlib/v/checker/tests/invalid_vweb_param_type.vv:8:24: error: invalid type `[]bool` for parameter `list` in vweb app method `index` (only strings, numbers, and bools are allowed) 6 | 7 | @['/:list'; get] diff --git a/vlib/v/checker/tests/map_index_reference_value.out b/vlib/v/checker/tests/map_index_reference_value.out index 5ae73279bd..dd302e00e5 100644 --- a/vlib/v/checker/tests/map_index_reference_value.out +++ b/vlib/v/checker/tests/map_index_reference_value.out @@ -13,14 +13,14 @@ vlib/v/checker/tests/map_index_reference_value.vv:11:3: warning: accessing map v 12 | // m['bar'] << 'baz' // etc 13 | vlib/v/checker/tests/map_index_reference_value.vv:15:8: warning: accessing map value that contain pointers requires an `or {}` block outside `unsafe` - 13 | + 13 | 14 | mut m2 := map[string]Bar{} 15 | _ = m2['key'] | ~~~~~~~ - 16 | + 16 | 17 | mut m3 := map[string][]Bar{} vlib/v/checker/tests/map_index_reference_value.vv:18:8: warning: accessing map value that contain pointers requires an `or {}` block outside `unsafe` - 16 | + 16 | 17 | mut m3 := map[string][]Bar{} 18 | _ = m3['key'] | ~~~~~~~ diff --git a/vlib/v/checker/tests/map_of_generic_struct_init_err.out b/vlib/v/checker/tests/map_of_generic_struct_init_err.out index c16c7751e9..215daa1337 100644 --- a/vlib/v/checker/tests/map_of_generic_struct_init_err.out +++ b/vlib/v/checker/tests/map_of_generic_struct_init_err.out @@ -1,11 +1,11 @@ vlib/v/checker/tests/map_of_generic_struct_init_err.vv:6:6: warning: unused variable: `m` - 4 | + 4 | 5 | fn main() { 6 | mut m := map[string]Item{} | ^ 7 | } vlib/v/checker/tests/map_of_generic_struct_init_err.vv:6:11: error: generic struct `Item` must specify type parameter, e.g. Item[int] - 4 | + 4 | 5 | fn main() { 6 | mut m := map[string]Item{} | ~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/match_type_node_with_non_sum_type_err.out b/vlib/v/checker/tests/match_type_node_with_non_sum_type_err.out index 8e2608d250..79dde10675 100644 --- a/vlib/v/checker/tests/match_type_node_with_non_sum_type_err.out +++ b/vlib/v/checker/tests/match_type_node_with_non_sum_type_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/match_type_node_with_non_sum_type_err.vv:5:3: error: matching by type can only be done for sum types, generics, interfaces, `b` is none of those - 3 | + 3 | 4 | match b { 5 | i64 { println('i64') } | ~~~ diff --git a/vlib/v/checker/tests/missing_import_or_block_path_err.out b/vlib/v/checker/tests/missing_import_or_block_path_err.out index f376360c0b..8b13789179 100644 --- a/vlib/v/checker/tests/missing_import_or_block_path_err.out +++ b/vlib/v/checker/tests/missing_import_or_block_path_err.out @@ -1,15 +1 @@ -vlib/v/checker/tests/missing_import_or_block_path_err.vv:2:12: error: undefined ident: `os` - 1 | folder := '/Users/foxjazz/Documents/EVE/logs/ChatLogs' - 2 | entries := os.ls(folder) or { [] } - | ~~ - 3 | _ = entries -vlib/v/checker/tests/missing_import_or_block_path_err.vv:2:26: error: unexpected `or` block, the function `ls` does not return an Option or a Result - 1 | folder := '/Users/foxjazz/Documents/EVE/logs/ChatLogs' - 2 | entries := os.ls(folder) or { [] } - | ~~~~~~~~~ - 3 | _ = entries -vlib/v/checker/tests/missing_import_or_block_path_err.vv:2:9: error: assignment mismatch: 1 variable but `ls()` returns 0 values - 1 | folder := '/Users/foxjazz/Documents/EVE/logs/ChatLogs' - 2 | entries := os.ls(folder) or { [] } - | ~~ - 3 | _ = entries + diff --git a/vlib/v/checker/tests/missing_import_or_block_path_err.vv b/vlib/v/checker/tests/missing_import_or_block_path_err.vv index a4d4a790d2..d4e892db85 100644 --- a/vlib/v/checker/tests/missing_import_or_block_path_err.vv +++ b/vlib/v/checker/tests/missing_import_or_block_path_err.vv @@ -1,3 +1,5 @@ +import os + folder := '/Users/foxjazz/Documents/EVE/logs/ChatLogs' entries := os.ls(folder) or { [] } _ = entries diff --git a/vlib/v/checker/tests/non_matching_functional_args.out b/vlib/v/checker/tests/non_matching_functional_args.out index 4de37fb0de..173c4c0d58 100644 --- a/vlib/v/checker/tests/non_matching_functional_args.out +++ b/vlib/v/checker/tests/non_matching_functional_args.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/non_matching_functional_args.vv:27:6: error: cannot use `fn (mut Table)` as `fn (Table)` in argument 1 to `sum` - 25 | + 25 | 26 | fn main() { 27 | sum(fn (mut t Table) { | ~~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/none_type_cast_err.out b/vlib/v/checker/tests/none_type_cast_err.out index 914cb4dc8f..0ffae17328 100644 --- a/vlib/v/checker/tests/none_type_cast_err.out +++ b/vlib/v/checker/tests/none_type_cast_err.out @@ -1,75 +1,75 @@ -vlib/v/checker/tests/none_type_cast_err.vv:2:7: error: cannot cast `none` to `string` - 1 | fn main() { - 2 | _ := string(none) - | ~~~~~~~~~~~~ - 3 | _ := int(none) - 4 | _ := i8(none) -vlib/v/checker/tests/none_type_cast_err.vv:3:7: error: cannot cast `none` to `int` - 1 | fn main() { - 2 | _ := string(none) - 3 | _ := int(none) - | ~~~~~~~~~ - 4 | _ := i8(none) - 5 | _ := i16(none) -vlib/v/checker/tests/none_type_cast_err.vv:4:7: error: cannot cast `none` to `i8` - 2 | _ := string(none) - 3 | _ := int(none) - 4 | _ := i8(none) - | ~~~~~~~~ - 5 | _ := i16(none) - 6 | _ := i64(none) -vlib/v/checker/tests/none_type_cast_err.vv:5:7: error: cannot cast `none` to `i16` - 3 | _ := int(none) - 4 | _ := i8(none) - 5 | _ := i16(none) - | ~~~~~~~~~ - 6 | _ := i64(none) - 7 | _ := u16(none) -vlib/v/checker/tests/none_type_cast_err.vv:6:7: error: cannot cast `none` to `i64` - 4 | _ := i8(none) - 5 | _ := i16(none) - 6 | _ := i64(none) - | ~~~~~~~~~ - 7 | _ := u16(none) - 8 | _ := u32(none) -vlib/v/checker/tests/none_type_cast_err.vv:7:7: error: cannot cast `none` to `u16` - 5 | _ := i16(none) - 6 | _ := i64(none) - 7 | _ := u16(none) - | ~~~~~~~~~ - 8 | _ := u32(none) - 9 | _ := u64(none) -vlib/v/checker/tests/none_type_cast_err.vv:8:7: error: cannot cast `none` to `u32` - 6 | _ := i64(none) - 7 | _ := u16(none) - 8 | _ := u32(none) - | ~~~~~~~~~ - 9 | _ := u64(none) - 10 | _ := rune(none) -vlib/v/checker/tests/none_type_cast_err.vv:9:7: error: cannot cast `none` to `u64` - 7 | _ := u16(none) - 8 | _ := u32(none) - 9 | _ := u64(none) - | ~~~~~~~~~ - 10 | _ := rune(none) - 11 | _ := f32(none) -vlib/v/checker/tests/none_type_cast_err.vv:10:7: error: cannot cast `none` to `rune` - 8 | _ := u32(none) - 9 | _ := u64(none) - 10 | _ := rune(none) - | ~~~~~~~~~~ - 11 | _ := f32(none) - 12 | _ := f64(none) -vlib/v/checker/tests/none_type_cast_err.vv:11:7: error: cannot cast `none` to `f32` - 9 | _ := u64(none) - 10 | _ := rune(none) - 11 | _ := f32(none) - | ~~~~~~~~~ - 12 | _ := f64(none) - 13 | } -vlib/v/checker/tests/none_type_cast_err.vv:12:7: error: cannot cast `none` to `f64` - 10 | _ := rune(none) - 11 | _ := f32(none) - 12 | _ := f64(none) - | ~~~~~~~~~ - 13 | } \ No newline at end of file +vlib/v/checker/tests/none_type_cast_err.vv:2:7: error: cannot cast `none` to `string` + 1 | fn main() { + 2 | _ := string(none) + | ~~~~~~~~~~~~ + 3 | _ := int(none) + 4 | _ := i8(none) +vlib/v/checker/tests/none_type_cast_err.vv:3:7: error: cannot cast `none` to `int` + 1 | fn main() { + 2 | _ := string(none) + 3 | _ := int(none) + | ~~~~~~~~~ + 4 | _ := i8(none) + 5 | _ := i16(none) +vlib/v/checker/tests/none_type_cast_err.vv:4:7: error: cannot cast `none` to `i8` + 2 | _ := string(none) + 3 | _ := int(none) + 4 | _ := i8(none) + | ~~~~~~~~ + 5 | _ := i16(none) + 6 | _ := i64(none) +vlib/v/checker/tests/none_type_cast_err.vv:5:7: error: cannot cast `none` to `i16` + 3 | _ := int(none) + 4 | _ := i8(none) + 5 | _ := i16(none) + | ~~~~~~~~~ + 6 | _ := i64(none) + 7 | _ := u16(none) +vlib/v/checker/tests/none_type_cast_err.vv:6:7: error: cannot cast `none` to `i64` + 4 | _ := i8(none) + 5 | _ := i16(none) + 6 | _ := i64(none) + | ~~~~~~~~~ + 7 | _ := u16(none) + 8 | _ := u32(none) +vlib/v/checker/tests/none_type_cast_err.vv:7:7: error: cannot cast `none` to `u16` + 5 | _ := i16(none) + 6 | _ := i64(none) + 7 | _ := u16(none) + | ~~~~~~~~~ + 8 | _ := u32(none) + 9 | _ := u64(none) +vlib/v/checker/tests/none_type_cast_err.vv:8:7: error: cannot cast `none` to `u32` + 6 | _ := i64(none) + 7 | _ := u16(none) + 8 | _ := u32(none) + | ~~~~~~~~~ + 9 | _ := u64(none) + 10 | _ := rune(none) +vlib/v/checker/tests/none_type_cast_err.vv:9:7: error: cannot cast `none` to `u64` + 7 | _ := u16(none) + 8 | _ := u32(none) + 9 | _ := u64(none) + | ~~~~~~~~~ + 10 | _ := rune(none) + 11 | _ := f32(none) +vlib/v/checker/tests/none_type_cast_err.vv:10:7: error: cannot cast `none` to `rune` + 8 | _ := u32(none) + 9 | _ := u64(none) + 10 | _ := rune(none) + | ~~~~~~~~~~ + 11 | _ := f32(none) + 12 | _ := f64(none) +vlib/v/checker/tests/none_type_cast_err.vv:11:7: error: cannot cast `none` to `f32` + 9 | _ := u64(none) + 10 | _ := rune(none) + 11 | _ := f32(none) + | ~~~~~~~~~ + 12 | _ := f64(none) + 13 | } +vlib/v/checker/tests/none_type_cast_err.vv:12:7: error: cannot cast `none` to `f64` + 10 | _ := rune(none) + 11 | _ := f32(none) + 12 | _ := f64(none) + | ~~~~~~~~~ + 13 | } diff --git a/vlib/v/checker/tests/option_in_println_mismatch.out b/vlib/v/checker/tests/option_in_println_mismatch.out index d2900cdb3d..540e669e23 100644 --- a/vlib/v/checker/tests/option_in_println_mismatch.out +++ b/vlib/v/checker/tests/option_in_println_mismatch.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/option_in_println_mismatch.vv:6:23: error: wrong return type `string` in the `or {}` block, expected `int` - 4 | + 4 | 5 | fn main() { 6 | println(funcy() or { '' }) | ~~ - 7 | } \ No newline at end of file + 7 | } diff --git a/vlib/v/checker/tests/option_or_block_mismatch.out b/vlib/v/checker/tests/option_or_block_mismatch.out index 9fa8c497dd..39b01e8e7e 100644 --- a/vlib/v/checker/tests/option_or_block_mismatch.out +++ b/vlib/v/checker/tests/option_or_block_mismatch.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/option_or_block_mismatch.vv:10:18: error: wrong return type `Bar` in the `or {}` block, expected `&Bar` - 8 | + 8 | 9 | fn main() { 10 | x := foo() or { Bar{} } | ~~~~~ @@ -7,7 +7,7 @@ vlib/v/checker/tests/option_or_block_mismatch.vv:10:18: error: wrong return type 12 | vlib/v/checker/tests/option_or_block_mismatch.vv:13:13: error: the default expression type in the `or` block should be `&Bar`, instead you gave a value of type `Bar` 11 | println(x) - 12 | + 12 | 13 | foo() or { Bar{} } | ~~~~~ - 14 | } \ No newline at end of file + 14 | } diff --git a/vlib/v/checker/tests/orm_right_side_field_ref_in_where_error.out b/vlib/v/checker/tests/orm_right_side_field_ref_in_where_error.out index 4c9ba818b9..095ea9dbab 100644 --- a/vlib/v/checker/tests/orm_right_side_field_ref_in_where_error.out +++ b/vlib/v/checker/tests/orm_right_side_field_ref_in_where_error.out @@ -4,4 +4,4 @@ vlib/v/checker/tests/orm_right_side_field_ref_in_where_error.vv:16:32: error: OR 16 | select from User where id == age | ~~~ 17 | }! - 18 | + 18 | diff --git a/vlib/v/checker/tests/pass_mut_lit.out b/vlib/v/checker/tests/pass_mut_lit.out index a9e060af14..0620171965 100644 --- a/vlib/v/checker/tests/pass_mut_lit.out +++ b/vlib/v/checker/tests/pass_mut_lit.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/pass_mut_lit.vv:10:12: error: cannot pass a struct initialization as `mut`, you may want to use a variable `mut var := Box{....}` 8 | } - 9 | + 9 | 10 | modify(mut Box{}, 10) | ~~~~~ diff --git a/vlib/v/checker/tests/result_alias_type_err.out b/vlib/v/checker/tests/result_alias_type_err.out index f1d01a2a64..d8be67d2b2 100644 --- a/vlib/v/checker/tests/result_alias_type_err.out +++ b/vlib/v/checker/tests/result_alias_type_err.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/result_alias_type_err.vv:1:12: error: cannot make an alias of Result type 1 | type Abc = !int | ~~~~ - 2 | + 2 | 3 | dump(Abc(5)) Details: Result types cannot be stored and have to be unwrapped immediately diff --git a/vlib/v/checker/tests/short_struct_wrong_number.out b/vlib/v/checker/tests/short_struct_wrong_number.out index fa6044b6a0..def47c0d77 100644 --- a/vlib/v/checker/tests/short_struct_wrong_number.out +++ b/vlib/v/checker/tests/short_struct_wrong_number.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/short_struct_wrong_number.vv:7:6: error: too few fields in `Test` literal (expecting 2, got 1) - 5 | + 5 | 6 | fn main() { 7 | _ = Test{true} | ~~~~~~~~~~ diff --git a/vlib/v/checker/tests/slice_clone_in_struct_init_notice.out b/vlib/v/checker/tests/slice_clone_in_struct_init_notice.out index 153f737404..2d200c90a8 100644 --- a/vlib/v/checker/tests/slice_clone_in_struct_init_notice.out +++ b/vlib/v/checker/tests/slice_clone_in_struct_init_notice.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/slice_clone_in_struct_init_notice.vv:9:7: notice: an implicit clone of the slice was done here - 7 | + 7 | 8 | _ := AA{ 9 | a: a[0..5] | ~~~~~~ @@ -7,7 +7,7 @@ vlib/v/checker/tests/slice_clone_in_struct_init_notice.vv:9:7: notice: an implic 11 | _ := a[0..5] Details: vlib/v/checker/tests/slice_clone_in_struct_init_notice.vv:9:7: details: To silence this notice, use either an explicit `a[..].clone()`, or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice. - 7 | + 7 | 8 | _ := AA{ 9 | a: a[0..5] | ~~~~~~ diff --git a/vlib/v/checker/tests/slice_clone_notice.out b/vlib/v/checker/tests/slice_clone_notice.out index fa122db850..294f0165bb 100644 --- a/vlib/v/checker/tests/slice_clone_notice.out +++ b/vlib/v/checker/tests/slice_clone_notice.out @@ -1,15 +1,15 @@ vlib/v/checker/tests/slice_clone_notice.vv:4:13: notice: an implicit clone of the slice was done here 2 | xs := [1, 2, 3, 4, 5, 6, 7, 8] - 3 | + 3 | 4 | mut s := xs[1..] | ~~~~~ - 5 | + 5 | 6 | s.sort(a > b) Details: vlib/v/checker/tests/slice_clone_notice.vv:4:13: details: To silence this notice, use either an explicit `a[..].clone()`, or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice. 2 | xs := [1, 2, 3, 4, 5, 6, 7, 8] - 3 | + 3 | 4 | mut s := xs[1..] | ~~~~~ - 5 | + 5 | 6 | s.sort(a > b) diff --git a/vlib/v/checker/tests/str_interpol_invalid_err.out b/vlib/v/checker/tests/str_interpol_invalid_err.out index b95383a059..776f53d002 100644 --- a/vlib/v/checker/tests/str_interpol_invalid_err.out +++ b/vlib/v/checker/tests/str_interpol_invalid_err.out @@ -1,55 +1,55 @@ -vlib/v/checker/tests/str_interpol_invalid_err.vv:8:13: error: illegal format specifier `x` for type `[]int` - 6 | - 7 | fn main() { - 8 | _ = '${[1]:x}' - | ^ - 9 | _ = '${[1]!:x}' - 10 | _ = '${Foo{}:x}' -vlib/v/checker/tests/str_interpol_invalid_err.vv:9:14: error: illegal format specifier `x` for type `[1]int` - 7 | fn main() { - 8 | _ = '${[1]:x}' - 9 | _ = '${[1]!:x}' - | ^ - 10 | _ = '${Foo{}:x}' - 11 | _ = '${[1]:f}' -vlib/v/checker/tests/str_interpol_invalid_err.vv:10:15: error: illegal format specifier `x` for type `Foo` - 8 | _ = '${[1]:x}' - 9 | _ = '${[1]!:x}' - 10 | _ = '${Foo{}:x}' - | ^ - 11 | _ = '${[1]:f}' - 12 | _ := '${none:F}' -vlib/v/checker/tests/str_interpol_invalid_err.vv:11:13: error: illegal format specifier `f` for type `[]int` - 9 | _ = '${[1]!:x}' - 10 | _ = '${Foo{}:x}' - 11 | _ = '${[1]:f}' - | ^ - 12 | _ := '${none:F}' - 13 | _ = '${{"a": "b"}:x}' -vlib/v/checker/tests/str_interpol_invalid_err.vv:12:15: error: illegal format specifier `F` for type `none` - 10 | _ = '${Foo{}:x}' - 11 | _ = '${[1]:f}' - 12 | _ := '${none:F}' - | ^ - 13 | _ = '${{"a": "b"}:x}' - 14 | _ = '${Alias(Foo{}):x}' -vlib/v/checker/tests/str_interpol_invalid_err.vv:13:20: error: illegal format specifier `x` for type `map[string]string` - 11 | _ = '${[1]:f}' - 12 | _ := '${none:F}' - 13 | _ = '${{"a": "b"}:x}' - | ^ - 14 | _ = '${Alias(Foo{}):x}' - 15 | _ = '${SumType(int(5)):o}' -vlib/v/checker/tests/str_interpol_invalid_err.vv:14:22: error: illegal format specifier `x` for type `Alias` - 12 | _ := '${none:F}' - 13 | _ = '${{"a": "b"}:x}' - 14 | _ = '${Alias(Foo{}):x}' - | ^ - 15 | _ = '${SumType(int(5)):o}' - 16 | } -vlib/v/checker/tests/str_interpol_invalid_err.vv:15:25: error: illegal format specifier `o` for type `SumType` - 13 | _ = '${{"a": "b"}:x}' - 14 | _ = '${Alias(Foo{}):x}' - 15 | _ = '${SumType(int(5)):o}' - | ^ - 16 | } +vlib/v/checker/tests/str_interpol_invalid_err.vv:8:13: error: illegal format specifier `x` for type `[]int` + 6 | + 7 | fn main() { + 8 | _ = '${[1]:x}' + | ^ + 9 | _ = '${[1]!:x}' + 10 | _ = '${Foo{}:x}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:9:14: error: illegal format specifier `x` for type `[1]int` + 7 | fn main() { + 8 | _ = '${[1]:x}' + 9 | _ = '${[1]!:x}' + | ^ + 10 | _ = '${Foo{}:x}' + 11 | _ = '${[1]:f}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:10:15: error: illegal format specifier `x` for type `Foo` + 8 | _ = '${[1]:x}' + 9 | _ = '${[1]!:x}' + 10 | _ = '${Foo{}:x}' + | ^ + 11 | _ = '${[1]:f}' + 12 | _ := '${none:F}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:11:13: error: illegal format specifier `f` for type `[]int` + 9 | _ = '${[1]!:x}' + 10 | _ = '${Foo{}:x}' + 11 | _ = '${[1]:f}' + | ^ + 12 | _ := '${none:F}' + 13 | _ = '${{"a": "b"}:x}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:12:15: error: illegal format specifier `F` for type `none` + 10 | _ = '${Foo{}:x}' + 11 | _ = '${[1]:f}' + 12 | _ := '${none:F}' + | ^ + 13 | _ = '${{"a": "b"}:x}' + 14 | _ = '${Alias(Foo{}):x}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:13:20: error: illegal format specifier `x` for type `map[string]string` + 11 | _ = '${[1]:f}' + 12 | _ := '${none:F}' + 13 | _ = '${{"a": "b"}:x}' + | ^ + 14 | _ = '${Alias(Foo{}):x}' + 15 | _ = '${SumType(int(5)):o}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:14:22: error: illegal format specifier `x` for type `Alias` + 12 | _ := '${none:F}' + 13 | _ = '${{"a": "b"}:x}' + 14 | _ = '${Alias(Foo{}):x}' + | ^ + 15 | _ = '${SumType(int(5)):o}' + 16 | } +vlib/v/checker/tests/str_interpol_invalid_err.vv:15:25: error: illegal format specifier `o` for type `SumType` + 13 | _ = '${{"a": "b"}:x}' + 14 | _ = '${Alias(Foo{}):x}' + 15 | _ = '${SumType(int(5)):o}' + | ^ + 16 | } diff --git a/vlib/v/checker/tests/string_interpolation_invalid_fmt.out b/vlib/v/checker/tests/string_interpolation_invalid_fmt.out index 6ac3efeaf3..553f5a4f21 100644 --- a/vlib/v/checker/tests/string_interpolation_invalid_fmt.out +++ b/vlib/v/checker/tests/string_interpolation_invalid_fmt.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/string_interpolation_invalid_fmt.vv:3:12: error: format specifier may only be one letter +vlib/v/checker/tests/string_interpolation_invalid_fmt.vv:3:12: error: format specifier may only be one letter 1 | fn interpolate_wrong() string { 2 | a := 5 3 | x := '${a:xy}' diff --git a/vlib/v/checker/tests/struct_multiple_attrs_test.out b/vlib/v/checker/tests/struct_multiple_attrs_test.out index 9e4ace5ce2..30f2e24212 100644 --- a/vlib/v/checker/tests/struct_multiple_attrs_test.out +++ b/vlib/v/checker/tests/struct_multiple_attrs_test.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/struct_multiple_attrs_test.vv:4:11: error: multiple attributes should be in the same @[], with ; separators - 2 | + 2 | 3 | struct Test { 4 | a int @[a]@[b] | ~~ diff --git a/vlib/v/checker/tests/struct_scope_err.out b/vlib/v/checker/tests/struct_scope_err.out index 6fc59d386e..df44794561 100644 --- a/vlib/v/checker/tests/struct_scope_err.out +++ b/vlib/v/checker/tests/struct_scope_err.out @@ -6,7 +6,7 @@ vlib/v/checker/tests/struct_scope_err.vv:8:5: notice: condition is always true 9 | fb := Foobar{5, 6} 10 | println(fb.foo) vlib/v/checker/tests/struct_scope_err.vv:16:8: error: unknown type `Foobar` - 14 | + 14 | 15 | fn x() { 16 | fb := Foobar{7, 8} | ~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/sum_type_multiple_type_define.out b/vlib/v/checker/tests/sum_type_multiple_type_define.out index 7052f3ba53..724dc54247 100644 --- a/vlib/v/checker/tests/sum_type_multiple_type_define.out +++ b/vlib/v/checker/tests/sum_type_multiple_type_define.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/sum_type_multiple_type_define.vv:3:22: error: sum type FooType cannot hold the type `Foo` more than once 1 | struct Foo {} - 2 | + 2 | 3 | type FooType = Foo | Foo | ~~~ diff --git a/vlib/v/checker/tests/sumtype_of_fntype_assign_err.out b/vlib/v/checker/tests/sumtype_of_fntype_assign_err.out index 2864537919..8cc7812a67 100644 --- a/vlib/v/checker/tests/sumtype_of_fntype_assign_err.out +++ b/vlib/v/checker/tests/sumtype_of_fntype_assign_err.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/sumtype_of_fntype_assign_err.vv:14:11: error: cannot assign to `m['f']`: expected `Expr`, not `fn () Expr` 12 | mut m := map[string]Expr{} - 13 | + 13 | 14 | m['f'] = f | ^ 15 | } diff --git a/vlib/v/checker/tests/template_call_position.out b/vlib/v/checker/tests/template_call_position.out index 8ccb853794..59678fab53 100644 --- a/vlib/v/checker/tests/template_call_position.out +++ b/vlib/v/checker/tests/template_call_position.out @@ -4,7 +4,7 @@ template_call_position_test.txt:3:2: error: undefined ident: `unknown_var` (veb 3 | @unknown_var | ~~~~~~~~~~~ called from vlib/v/checker/tests/template_call_position.vv:4:2 - 2 | + 2 | 3 | fn main() { 4 | $tmpl('template_call_position_test.txt') | ^ @@ -15,7 +15,7 @@ template_call_position_test.txt:3:2: error: expression does not return a value ( 3 | @unknown_var | ~~~~~~~~~~~ called from vlib/v/checker/tests/template_call_position.vv:4:2 - 2 | + 2 | 3 | fn main() { 4 | $tmpl('template_call_position_test.txt') | ^ diff --git a/vlib/v/checker/tests/top_level_fn_builtin_decl_err.out b/vlib/v/checker/tests/top_level_fn_builtin_decl_err.out index 0a3219f8de..ba84a356da 100644 --- a/vlib/v/checker/tests/top_level_fn_builtin_decl_err.out +++ b/vlib/v/checker/tests/top_level_fn_builtin_decl_err.out @@ -5,51 +5,51 @@ vlib/v/checker/tests/top_level_fn_builtin_decl_err.vv:2:1: error: top level decl 3 | return fn [ch] (input string) !(u8, string) { 4 | return if input[0] == ch { vlib/v/checker/tests/top_level_fn_builtin_decl_err.vv:18:18: error: unknown function: a_char - 16 | + 16 | 17 | for i, input in inputs { 18 | got, remain := a_char(input)! | ~~~~~~~~~~~~~ - 19 | + 19 | 20 | assert got == 'a'[0] vlib/v/checker/tests/top_level_fn_builtin_decl_err.vv:18:31: error: unexpected `!`, the function `a_char` does not return a Result - 16 | + 16 | 17 | for i, input in inputs { 18 | got, remain := a_char(input)! | ^ - 19 | + 19 | 20 | assert got == 'a'[0] vlib/v/checker/tests/top_level_fn_builtin_decl_err.vv:18:15: error: assignment mismatch: 2 variables but `a_char()` returns 0 values - 16 | + 16 | 17 | for i, input in inputs { 18 | got, remain := a_char(input)! | ~~ - 19 | + 19 | 20 | assert got == 'a'[0] vlib/v/checker/tests/top_level_fn_builtin_decl_err.vv:20:10: error: invalid variable `got` 18 | got, remain := a_char(input)! - 19 | + 19 | 20 | assert got == 'a'[0] | ~~~ 21 | assert remain == remains[i] 22 | } vlib/v/checker/tests/top_level_fn_builtin_decl_err.vv:20:10: error: assert can be used only with `bool` expressions, but found `void` instead 18 | got, remain := a_char(input)! - 19 | + 19 | 20 | assert got == 'a'[0] | ~~~~~~~~~~~~~ 21 | assert remain == remains[i] 22 | } vlib/v/checker/tests/top_level_fn_builtin_decl_err.vv:21:10: error: invalid variable `remain` - 19 | + 19 | 20 | assert got == 'a'[0] 21 | assert remain == remains[i] | ~~~~~~ 22 | } 23 | } vlib/v/checker/tests/top_level_fn_builtin_decl_err.vv:21:10: error: assert can be used only with `bool` expressions, but found `void` instead - 19 | + 19 | 20 | assert got == 'a'[0] 21 | assert remain == remains[i] | ~~~~~~~~~~~~~~~~~~~~ 22 | } - 23 | } \ No newline at end of file + 23 | } diff --git a/vlib/v/checker/tests/type_alias_struct_generic_unknown_name_err.out b/vlib/v/checker/tests/type_alias_struct_generic_unknown_name_err.out index 1c88a413e0..c0074e45f8 100644 --- a/vlib/v/checker/tests/type_alias_struct_generic_unknown_name_err.out +++ b/vlib/v/checker/tests/type_alias_struct_generic_unknown_name_err.out @@ -1,7 +1,7 @@ vlib/v/checker/tests/type_alias_struct_generic_unknown_name_err.vv:7:16: error: unknown type `UnknownType` 5 | } - 6 | + 6 | 7 | type NewType = Foo[UnknownType] | ~~~~~~~~~~~~~~~~ - 8 | + 8 | 9 | fn main() { diff --git a/vlib/v/checker/tests/undeclared_c_identifier_err.out b/vlib/v/checker/tests/undeclared_c_identifier_err.out deleted file mode 100644 index e8ce73d376..0000000000 --- a/vlib/v/checker/tests/undeclared_c_identifier_err.out +++ /dev/null @@ -1,6 +0,0 @@ -vlib/v/checker/tests/undeclared_c_identifier_err.vv:4:12: error: undefined C identifier: `C.errono` - 2 | - 3 | fn main() { - 4 | println(C.errono) - | ~~~~~~ - 5 | } diff --git a/vlib/v/checker/tests/undeclared_c_identifier_err.vv b/vlib/v/checker/tests/undeclared_c_identifier_err.vv deleted file mode 100644 index e17f218193..0000000000 --- a/vlib/v/checker/tests/undeclared_c_identifier_err.vv +++ /dev/null @@ -1,5 +0,0 @@ -#include - -fn main() { - println(C.errono) -} diff --git a/vlib/v/checker/tests/undefined_ident_in_if_guard_err_a.out b/vlib/v/checker/tests/undefined_ident_in_if_guard_err_a.out index d9ebc58e52..dafc08178e 100644 --- a/vlib/v/checker/tests/undefined_ident_in_if_guard_err_a.out +++ b/vlib/v/checker/tests/undefined_ident_in_if_guard_err_a.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/undefined_ident_in_if_guard_err_a.vv:6:11: error: undefined variable: `re` - 4 | + 4 | 5 | fn main() { 6 | if re := re.regex_opt('a') { | ~~ diff --git a/vlib/v/checker/tests/undefined_type_on_sumtype.out b/vlib/v/checker/tests/undefined_type_on_sumtype.out index d87f974bfa..8f1575ee3f 100644 --- a/vlib/v/checker/tests/undefined_type_on_sumtype.out +++ b/vlib/v/checker/tests/undefined_type_on_sumtype.out @@ -9,5 +9,5 @@ vlib/v/checker/tests/undefined_type_on_sumtype.vv:1:17: error: unknown type `Tok Did you mean `Ok[[]Token]`? 1 | type ParseRes = Result[[]Token, ParseErr] | ~~~~~~~~~~~~~~~~~~~~~~~~~ - 2 | + 2 | 3 | // Token type is unknown diff --git a/vlib/v/checker/tests/unknown_method.out b/vlib/v/checker/tests/unknown_method.out index b4f67adfbf..b6e860631a 100644 --- a/vlib/v/checker/tests/unknown_method.out +++ b/vlib/v/checker/tests/unknown_method.out @@ -12,7 +12,7 @@ vlib/v/checker/tests/unknown_method.vv:13:2: error: `println` can not print void | ~~~~~~~~~~~~~~~~ 14 | 15 | foo := new_foo[int]() -vlib/v/checker/tests/unknown_method.vv:16:6: error: unknown method or field: `Foo.bar` +vlib/v/checker/tests/unknown_method.vv:16:6: error: unknown method or field: `Foo[F].bar` 14 | 15 | foo := new_foo[int]() 16 | foo.bar() diff --git a/vlib/v/checker/tests/unknown_struct_name.out b/vlib/v/checker/tests/unknown_struct_name.out index d21f02d13e..56e1c671d7 100644 --- a/vlib/v/checker/tests/unknown_struct_name.out +++ b/vlib/v/checker/tests/unknown_struct_name.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/unknown_struct_name.vv:4:7: error: unknown struct `F` - 2 | + 2 | 3 | fn main() { 4 | _ := F{} | ~~~ diff --git a/vlib/v/checker/tests/unwrapped_option_infix.out b/vlib/v/checker/tests/unwrapped_option_infix.out index 7c6a9cdd51..c667ac7567 100644 --- a/vlib/v/checker/tests/unwrapped_option_infix.out +++ b/vlib/v/checker/tests/unwrapped_option_infix.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/unwrapped_option_infix.vv:5:9: error: `?string` cannot be used as `string`, unwrap the option first 3 | } - 4 | + 4 | 5 | println(test() == '') | ~~~~~~ diff --git a/vlib/v/checker/tests/use_byte_instead_of_u8_array_param_err.out b/vlib/v/checker/tests/use_byte_instead_of_u8_array_param_err.out index ca0d564aea..62fda0f837 100644 --- a/vlib/v/checker/tests/use_byte_instead_of_u8_array_param_err.out +++ b/vlib/v/checker/tests/use_byte_instead_of_u8_array_param_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/use_byte_instead_of_u8_array_param_err.vv:1:20: error: byte is deprecated, use u8 instead 1 | fn takes_bytes(_ []byte) {} | ~~~~ - 2 | + 2 | 3 | fn main() {} diff --git a/vlib/v/checker/tests/use_byte_instead_of_u8_err.out b/vlib/v/checker/tests/use_byte_instead_of_u8_err.out index 299fac8363..8d77d56d0e 100644 --- a/vlib/v/checker/tests/use_byte_instead_of_u8_err.out +++ b/vlib/v/checker/tests/use_byte_instead_of_u8_err.out @@ -1,17 +1,17 @@ vlib/v/checker/tests/use_byte_instead_of_u8_err.vv:1:13: error: type `byte` is an alias, use the original alias type `u8` instead 1 | type Byte = byte | ~~~~ - 2 | + 2 | 3 | fn foo(_ byte) {} vlib/v/checker/tests/use_byte_instead_of_u8_err.vv:3:10: error: byte is deprecated, use u8 instead 1 | type Byte = byte - 2 | + 2 | 3 | fn foo(_ byte) {} | ~~~~ - 4 | + 4 | 5 | fn main() { vlib/v/checker/tests/use_byte_instead_of_u8_err.vv:6:7: error: byte is deprecated, use u8 instead - 4 | + 4 | 5 | fn main() { 6 | _ := byte(0) | ~~~~~~~ diff --git a/vlib/v/checker/tests/var_duplicate_const.out b/vlib/v/checker/tests/var_duplicate_const.out index 676887eb1d..b1e152e300 100644 --- a/vlib/v/checker/tests/var_duplicate_const.out +++ b/vlib/v/checker/tests/var_duplicate_const.out @@ -17,3 +17,18 @@ vlib/v/checker/tests/var_duplicate_const.vv:1:7: warning: unused constant: `size | ~~~~~~~~~ 2 | 3 | fn main() { +================== C compilation error (from cc): ============== +cc: /tmp/v_502/var_duplicate_const.01KNN5X7W4MVH2B58E9FG5GJKE.tmp.c:2139:36: error: use of undeclared identifier 'size' +cc: 2139 | builtin__println(builtin__int_str(size)); +cc: | ^ +cc: 1 error generated. +================================================================ +Try passing `-g` when compiling, to see a .v file:line information, that correlates more with the C error. +(Alternatively, pass `-show-c-output`, to print the full C error message). +builder error: +================== +C error found while compiling generated C code. +This can be caused by invalid C interop code, C compiler flags, or a V compiler bug. +If your code is pure V and this still happens, please report it using `v bug file.v`, +or goto https://github.com/vlang/v/issues/new/choose . +You can also use #help on Discord: https://discord.gg/vlang . diff --git a/vlib/v/checker/tests/vweb_missing_result.out b/vlib/v/checker/tests/vweb_missing_result.out index aa7915b6ac..01cacfa72c 100644 --- a/vlib/v/checker/tests/vweb_missing_result.out +++ b/vlib/v/checker/tests/vweb_missing_result.out @@ -6,3 +6,52 @@ vlib/v/checker/tests/vweb_missing_result.vv:9:1: error: vweb actions must return | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | } 11 | +vlib/vweb/vweb.v:981:21: error: field `App.static_files` is not public + 979 | fn serve_if_static[T](mut app T, url urllib.URL, host string) bool { + 980 | // TODO: handle url parameters properly - for now, ignore them + 981 | static_file := app.static_files[url.path] or { return false } + | ~~~~~~~~~~~~ + 982 | mime_type := app.static_mime_types[url.path] or { return false } + 983 | static_host := app.static_hosts[url.path] or { '' } +vlib/vweb/vweb.v:982:19: error: field `App.static_mime_types` is not public + 980 | // TODO: handle url parameters properly - for now, ignore them + 981 | static_file := app.static_files[url.path] or { return false } + 982 | mime_type := app.static_mime_types[url.path] or { return false } + | ~~~~~~~~~~~~~~~~~ + 983 | static_host := app.static_hosts[url.path] or { '' } + 984 | if static_file == '' || mime_type == '' { +vlib/vweb/vweb.v:983:21: error: field `App.static_hosts` is not public + 981 | static_file := app.static_files[url.path] or { return false } + 982 | mime_type := app.static_mime_types[url.path] or { return false } + 983 | static_host := app.static_hosts[url.path] or { '' } + | ~~~~~~~~~~~~ + 984 | if static_file == '' || mime_type == '' { + 985 | return false +vlib/vweb/vweb.v:991:23: error: field `App.conn` is not public + 989 | } + 990 | data := os.read_file(static_file) or { + 991 | send_string(mut app.conn, http_404.bytestr()) or {} + | ~~~~ + 992 | return true + 993 | } +vlib/vweb/vweb.v:666:48: error: field `App.static_files` is not public + 664 | + 665 | // copy static files + 666 | request_app.Context.static_files = global_app.static_files.clone() + | ~~~~~~~~~~~~ + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() +vlib/vweb/vweb.v:667:53: error: field `App.static_mime_types` is not public + 665 | // copy static files + 666 | request_app.Context.static_files = global_app.static_files.clone() + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + | ~~~~~~~~~~~~~~~~~ + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() + 669 | +vlib/vweb/vweb.v:668:48: error: field `App.static_hosts` is not public + 666 | request_app.Context.static_files = global_app.static_files.clone() + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() + | ~~~~~~~~~~~~ + 669 | + 670 | return request_app diff --git a/vlib/v/checker/tests/vweb_routing_checks.out b/vlib/v/checker/tests/vweb_routing_checks.out index 5afbb1bdd6..0bd5dfb560 100644 --- a/vlib/v/checker/tests/vweb_routing_checks.out +++ b/vlib/v/checker/tests/vweb_routing_checks.out @@ -13,3 +13,73 @@ vlib/v/checker/tests/vweb_routing_checks.vv:26:1: warning: mismatched parameters | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 | return app.html('works') 28 | } +vlib/vweb/vweb.v:801:11: error: field `App.req` is not public + 799 | + 800 | // Skip if the HTTP request method does not match the attributes + 801 | if app.req.method in route.methods { + | ~~~ + 802 | // Used for route matching + 803 | route_words := route.path_words // route.path.split('/').filter(it != '') +vlib/vweb/vweb.v:822:14: error: field `App.req` is not public + 820 | } + 821 | + 822 | if app.req.method == .post && method.args.len > 0 { + | ~~~ + 823 | // Populate method args with form values + 824 | mut args := []string{cap: method.args.len} +vlib/vweb/vweb.v:826:21: error: field `App.form` is not public + 824 | mut args := []string{cap: method.args.len} + 825 | for param in method.args { + 826 | args << app.form[param.name] + | ~~~~ + 827 | } + 828 | +vlib/vweb/vweb.v:981:21: error: field `App.static_files` is not public + 979 | fn serve_if_static[T](mut app T, url urllib.URL, host string) bool { + 980 | // TODO: handle url parameters properly - for now, ignore them + 981 | static_file := app.static_files[url.path] or { return false } + | ~~~~~~~~~~~~ + 982 | mime_type := app.static_mime_types[url.path] or { return false } + 983 | static_host := app.static_hosts[url.path] or { '' } +vlib/vweb/vweb.v:982:19: error: field `App.static_mime_types` is not public + 980 | // TODO: handle url parameters properly - for now, ignore them + 981 | static_file := app.static_files[url.path] or { return false } + 982 | mime_type := app.static_mime_types[url.path] or { return false } + | ~~~~~~~~~~~~~~~~~ + 983 | static_host := app.static_hosts[url.path] or { '' } + 984 | if static_file == '' || mime_type == '' { +vlib/vweb/vweb.v:983:21: error: field `App.static_hosts` is not public + 981 | static_file := app.static_files[url.path] or { return false } + 982 | mime_type := app.static_mime_types[url.path] or { return false } + 983 | static_host := app.static_hosts[url.path] or { '' } + | ~~~~~~~~~~~~ + 984 | if static_file == '' || mime_type == '' { + 985 | return false +vlib/vweb/vweb.v:991:23: error: field `App.conn` is not public + 989 | } + 990 | data := os.read_file(static_file) or { + 991 | send_string(mut app.conn, http_404.bytestr()) or {} + | ~~~~ + 992 | return true + 993 | } +vlib/vweb/vweb.v:666:48: error: field `App.static_files` is not public + 664 | + 665 | // copy static files + 666 | request_app.Context.static_files = global_app.static_files.clone() + | ~~~~~~~~~~~~ + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() +vlib/vweb/vweb.v:667:53: error: field `App.static_mime_types` is not public + 665 | // copy static files + 666 | request_app.Context.static_files = global_app.static_files.clone() + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + | ~~~~~~~~~~~~~~~~~ + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() + 669 | +vlib/vweb/vweb.v:668:48: error: field `App.static_hosts` is not public + 666 | request_app.Context.static_files = global_app.static_files.clone() + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() + | ~~~~~~~~~~~~ + 669 | + 670 | return request_app diff --git a/vlib/v/checker/tests/vweb_tmpl_used_var.out b/vlib/v/checker/tests/vweb_tmpl_used_var.out index 7c80b67c92..7bacbfefa6 100644 --- a/vlib/v/checker/tests/vweb_tmpl_used_var.out +++ b/vlib/v/checker/tests/vweb_tmpl_used_var.out @@ -1 +1,71 @@ `vweb` has been deprecated. Please use the more stable and fast `veb` instead. +vlib/vweb/vweb.v:801:11: error: field `App.req` is not public + 799 | + 800 | // Skip if the HTTP request method does not match the attributes + 801 | if app.req.method in route.methods { + | ~~~ + 802 | // Used for route matching + 803 | route_words := route.path_words // route.path.split('/').filter(it != '') +vlib/vweb/vweb.v:822:14: error: field `App.req` is not public + 820 | } + 821 | + 822 | if app.req.method == .post && method.args.len > 0 { + | ~~~ + 823 | // Populate method args with form values + 824 | mut args := []string{cap: method.args.len} +vlib/vweb/vweb.v:826:21: error: field `App.form` is not public + 824 | mut args := []string{cap: method.args.len} + 825 | for param in method.args { + 826 | args << app.form[param.name] + | ~~~~ + 827 | } + 828 | +vlib/vweb/vweb.v:981:21: error: field `App.static_files` is not public + 979 | fn serve_if_static[T](mut app T, url urllib.URL, host string) bool { + 980 | // TODO: handle url parameters properly - for now, ignore them + 981 | static_file := app.static_files[url.path] or { return false } + | ~~~~~~~~~~~~ + 982 | mime_type := app.static_mime_types[url.path] or { return false } + 983 | static_host := app.static_hosts[url.path] or { '' } +vlib/vweb/vweb.v:982:19: error: field `App.static_mime_types` is not public + 980 | // TODO: handle url parameters properly - for now, ignore them + 981 | static_file := app.static_files[url.path] or { return false } + 982 | mime_type := app.static_mime_types[url.path] or { return false } + | ~~~~~~~~~~~~~~~~~ + 983 | static_host := app.static_hosts[url.path] or { '' } + 984 | if static_file == '' || mime_type == '' { +vlib/vweb/vweb.v:983:21: error: field `App.static_hosts` is not public + 981 | static_file := app.static_files[url.path] or { return false } + 982 | mime_type := app.static_mime_types[url.path] or { return false } + 983 | static_host := app.static_hosts[url.path] or { '' } + | ~~~~~~~~~~~~ + 984 | if static_file == '' || mime_type == '' { + 985 | return false +vlib/vweb/vweb.v:991:23: error: field `App.conn` is not public + 989 | } + 990 | data := os.read_file(static_file) or { + 991 | send_string(mut app.conn, http_404.bytestr()) or {} + | ~~~~ + 992 | return true + 993 | } +vlib/vweb/vweb.v:666:48: error: field `App.static_files` is not public + 664 | + 665 | // copy static files + 666 | request_app.Context.static_files = global_app.static_files.clone() + | ~~~~~~~~~~~~ + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() +vlib/vweb/vweb.v:667:53: error: field `App.static_mime_types` is not public + 665 | // copy static files + 666 | request_app.Context.static_files = global_app.static_files.clone() + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + | ~~~~~~~~~~~~~~~~~ + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() + 669 | +vlib/vweb/vweb.v:668:48: error: field `App.static_hosts` is not public + 666 | request_app.Context.static_files = global_app.static_files.clone() + 667 | request_app.Context.static_mime_types = global_app.static_mime_types.clone() + 668 | request_app.Context.static_hosts = global_app.static_hosts.clone() + | ~~~~~~~~~~~~ + 669 | + 670 | return request_app diff --git a/vlib/v/checker/tests/wrong_type_casted_fixed_array_size_err.out b/vlib/v/checker/tests/wrong_type_casted_fixed_array_size_err.out index 68b4b0c9bc..702bc444b7 100644 --- a/vlib/v/checker/tests/wrong_type_casted_fixed_array_size_err.out +++ b/vlib/v/checker/tests/wrong_type_casted_fixed_array_size_err.out @@ -1,13 +1,13 @@ vlib/v/checker/tests/wrong_type_casted_fixed_array_size_err.vv:10:7: error: only integer types are allowed 8 | } - 9 | + 9 | 10 | a := [b]int{} | ^ 11 | println(a) 12 | vlib/v/checker/tests/wrong_type_casted_fixed_array_size_err.vv:13:7: error: only integer types are allowed 11 | println(a) - 12 | + 12 | 13 | c := [f32(Foo.first)]int{} | ~~~~~~~~~~~~~~ 14 | println(c) diff --git a/vlib/v/checker/used_features.v b/vlib/v/checker/used_features.v index 601498da24..c1c77ec403 100644 --- a/vlib/v/checker/used_features.v +++ b/vlib/v/checker/used_features.v @@ -64,7 +64,8 @@ fn (mut c Checker) markused_castexpr(mut _ ast.CastExpr, _ ast.Type, mut final_t } fn (mut c Checker) markused_comptimecall(mut node ast.ComptimeCall) { - c.markused_comptime_call(true, '${int(c.unwrap_generic(c.comptime.comptime_for_method.receiver_type))}.${c.comptime.comptime_for_method.name}') + c.markused_comptime_call(true, + '${int(c.unwrap_generic(c.comptime.comptime_for_method.receiver_type))}.${c.comptime.comptime_for_method.name}') if c.inside_anon_fn { // $method passed to anon fn, mark all methods as used sym := c.table.sym(c.unwrap_generic(node.left_type)) @@ -156,7 +157,8 @@ fn (mut c Checker) markused_print_call(mut node ast.CallExpr) { c.table.used_features.auto_str_ptr = sym.info.fields.any(it.typ.is_ptr() || it.typ.is_pointer()) } - c.table.used_features.auto_str_arr = sym.info.fields.any(c.table.final_sym(it.typ).kind == .array) + c.table.used_features.auto_str_arr = + sym.info.fields.any(c.table.final_sym(it.typ).kind == .array) } } } diff --git a/vlib/v/compiler_errors_test.v b/vlib/v/compiler_errors_test.v index db75ea18fc..71d6316560 100644 --- a/vlib/v/compiler_errors_test.v +++ b/vlib/v/compiler_errors_test.v @@ -108,8 +108,7 @@ fn test_all() { run_tests := get_tests_in_dir(run_dir, false) su_dir_tests := get_tests_in_dir(su_dir, false) no_closures_tests := get_tests_in_dir(no_closures_dir, false) - checker_with_check_option_tests := get_tests_in_dir(checker_with_check_option_dir, - false) + checker_with_check_option_tests := get_tests_in_dir(checker_with_check_option_dir, false) if os.user_os() == 'linux' { mut su_tasks := Tasks{ @@ -176,10 +175,8 @@ fn test_all() { tasks.add('', checker_dir, '', '.out', checker_tests, false) tasks.add('', checker_dir, '-b js', '.js.out', js_checker_tests, false) tasks.add('', scanner_dir, '', '.out', scanner_tests, false) - tasks.add('', checker_dir, '-enable-globals run', '.run.out', ['globals_error.vv'], - false) - tasks.add('', global_run_dir, '-enable-globals run', '.run.out', global_run_tests, - false) + tasks.add('', checker_dir, '-enable-globals run', '.run.out', ['globals_error.vv'], false) + tasks.add('', global_run_dir, '-enable-globals run', '.run.out', global_run_tests, false) tasks.add('', global_dir, '-enable-globals', '.out', global_tests, false) tasks.add('', module_dir, '-prod run', '.out', module_tests, true) tasks.add('', run_dir, 'run', '.run.out', run_tests, false) diff --git a/vlib/v/debug/interactive_test.v b/vlib/v/debug/interactive_test.v index 425df318e8..a3ec8c983f 100644 --- a/vlib/v/debug/interactive_test.v +++ b/vlib/v/debug/interactive_test.v @@ -36,8 +36,8 @@ fn test_debugger() { for eidx, efile in all_expect_files.sorted() { // if !efile.contains('sumtype') { gprintln('skipping ${efile}') continue } vfile := efile.replace('.expect', '.vv') - output_file := os.join_path(test_module_path, os.file_name(efile).replace('.expect', - '.exe')) + output_file := os.join_path(test_module_path, + os.file_name(efile).replace('.expect', '.exe')) if be_verbose { println(bar) @@ -48,7 +48,8 @@ fn test_debugger() { } compile_sw := time.new_stopwatch() - comp_res := os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(output_file)} ${os.quoted_path(vfile)}') + comp_res := + os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(output_file)} ${os.quoted_path(vfile)}') cdur_ms := compile_sw.elapsed().milliseconds() if be_verbose { gprintln('>>>>>>>>>>> compilation took ${cdur_ms} ms, comp_res: ${comp_res}') diff --git a/vlib/v/depgraph/depgraph.v b/vlib/v/depgraph/depgraph.v index 1129b27114..9aaf35d9be 100644 --- a/vlib/v/depgraph/depgraph.v +++ b/vlib/v/depgraph/depgraph.v @@ -7,7 +7,7 @@ module depgraph import v.dotgraph -struct DepGraphNode { +pub struct DepGraphNode { pub mut: name string value i64 diff --git a/vlib/v/eval/expr.c.v b/vlib/v/eval/expr.c.v index c870d029f4..0484827add 100644 --- a/vlib/v/eval/expr.c.v +++ b/vlib/v/eval/expr.c.v @@ -46,7 +46,8 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object { } match expr.name.all_after('C.') { 'read' { - return Int{C.read(args[0].int_val(), args[1] as voidptr, args[2].int_val()), 64} + return Int{C.read(args[0].int_val(), args[1] as voidptr, + args[2].int_val()), 64} } 'write' { return Int{C.write(args[0].int_val(), args[1] as voidptr, @@ -65,7 +66,8 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object { 'getcwd' { unsafe { return Ptr{ - val: C.getcwd((args[0] as Ptr).val as voidptr, args[1].int_val()) + val: C.getcwd((args[0] as Ptr).val as voidptr, + args[1].int_val()) } } } diff --git a/vlib/v/eval/stmt.v b/vlib/v/eval/stmt.v index 53151273f1..b5c4d285b5 100644 --- a/vlib/v/eval/stmt.v +++ b/vlib/v/eval/stmt.v @@ -57,8 +57,8 @@ pub fn (mut e Eval) stmt(stmt ast.Stmt) { .left_shift_assign { infix_op := token.assign_op_to_infix_op(stmt.op) for i, left in stmt.left { - res := e.infix_expr(e.expr(left, stmt.left_types[i]), rights[i], - infix_op, stmt.left_types[i]) + res := e.infix_expr(e.expr(left, stmt.left_types[i]), rights[i], infix_op, + stmt.left_types[i]) e.set(left, res, false, stmt.left_types[i]) } } diff --git a/vlib/v/eval/tests/push_val_test.v b/vlib/v/eval/tests/push_val_test.v index 4660af5c9a..779821424d 100644 --- a/vlib/v/eval/tests/push_val_test.v +++ b/vlib/v/eval/tests/push_val_test.v @@ -18,7 +18,8 @@ fn test_ret() { e.push_val(f64(2.2)) e.push_val('calc') - ret := e.run('fn test() string { return "\${host_pop()}: \${i64(host_pop())+i64(host_pop())}" } test()')! + ret := + e.run('fn test() string { return "\${host_pop()}: \${i64(host_pop())+i64(host_pop())}" } test()')! assert ret[0].string() == 'calc: 4' } diff --git a/vlib/v/eval/var.v b/vlib/v/eval/var.v index 816d62e318..89e4848686 100644 --- a/vlib/v/eval/var.v +++ b/vlib/v/eval/var.v @@ -58,8 +58,8 @@ pub fn (mut e Eval) set(expr ast.Expr, val Object, init bool, typ ast.Type) { pub fn (mut e Eval) add(expr ast.Expr, val Object) { match expr { ast.Ident { - e.local_vars[expr.name].val = e.infix_expr(e.local_vars[expr.name].val, val, - .plus, e.local_vars[expr.name].typ) + e.local_vars[expr.name].val = e.infix_expr(e.local_vars[expr.name].val, val, .plus, + e.local_vars[expr.name].typ) } else { panic('unknown left value to add statement: ${expr.type_name()}') diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 552abd0bb7..1a0b0450d6 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -347,7 +347,8 @@ pub fn (mut f Fmt) import_stmt(imp ast.Import) { f.global_processed_imports << imp_stmt } if !f.format_state.is_vfmt_on { - original_imp_line := f.get_source_lines()#[imp.pos.line_nr..imp.pos.last_line + 1].join('\n') + original_imp_line := + f.get_source_lines()#[imp.pos.line_nr..imp.pos.last_line + 1].join('\n') // Same line comments(`imp.comments`) are included in the `original_imp_line`. f.writeln(original_imp_line) f.import_comments(imp.next_comments) @@ -1072,7 +1073,8 @@ pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) { attrs_len := inline_attrs_len(field.attrs) if field.attrs.len > 0 { if field.has_expr { - attr_align.add_info(field.expr.str().len + 2, field.pos.line_nr, field.has_break_line) + attr_align.add_info(field.expr.str().len + 2, field.pos.line_nr, + field.has_break_line) } else { attr_align.add_info(field.name.len, field.pos.line_nr, field.has_break_line) } @@ -1081,7 +1083,8 @@ pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) { if field.attrs.len > 0 { comment_align.add_info(attrs_len, field.pos.line_nr, field.has_break_line) } else if field.has_expr { - comment_align.add_info(field.expr.str().len + 2, field.pos.line_nr, field.has_break_line) + comment_align.add_info(field.expr.str().len + 2, field.pos.line_nr, + field.has_break_line) } else { comment_align.add_info(field.name.len, field.pos.line_nr, field.has_break_line) } @@ -1115,7 +1118,8 @@ pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) { if field.attrs.len > 0 { f.write(' '.repeat(comment_align.max_len(field.pos.line_nr) - attrs_len + 1)) } else if field.has_expr { - f.write(' '.repeat(comment_align.max_len(field.pos.line_nr) - field.expr.str().len - 1)) + f.write(' '.repeat(comment_align.max_len(field.pos.line_nr) - field.expr.str().len - + 1)) } else { f.write(' '.repeat(comment_align.max_len(field.pos.line_nr) - field.name.len + 1)) } @@ -1217,7 +1221,8 @@ pub fn (mut f Fmt) for_c_stmt(node ast.ForCStmt) { } init_comments := node.comments.filter(it.pos.pos < node.init.pos.pos) cond_comments := node.comments[init_comments.len..].filter(it.pos.pos < node.cond.pos().pos) - inc_comments := node.comments[(init_comments.len + cond_comments.len)..].filter(it.pos.pos < node.inc.pos.pos) + inc_comments := + node.comments[(init_comments.len + cond_comments.len)..].filter(it.pos.pos < node.inc.pos.pos) after_inc_comments := node.comments[(init_comments.len + cond_comments.len + inc_comments.len)..] f.write('for ') if node.has_init { @@ -1438,7 +1443,8 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) { end_comments := method.comments.filter(it.pos.pos > method.pos.pos) if end_comments.len > 0 { f.table.new_int_fmt_fix = f.table.new_int && (f.is_translated_module || f.is_c_function) - method_str := f.table.stringify_fn_decl(&method, f.cur_mod, f.mod2alias, false).all_after_first('fn ') + method_str := + f.table.stringify_fn_decl(&method, f.cur_mod, f.mod2alias, false).all_after_first('fn ') f.table.new_int_fmt_fix = false method_comment_align.add_info(method_str.len, method.pos.line_nr, method.has_break_line) } @@ -1506,7 +1512,8 @@ pub fn (mut f Fmt) calculate_alignment(fields []ast.StructField, mut type_align if prev_state != AlignState.has_attributes { comment_align.add_new_info(attrs_len, comment.pos.line_nr) } else { - comment_align.add_info(attrs_len, comment.pos.line_nr, field.has_break_line) + comment_align.add_info(attrs_len, comment.pos.line_nr, + field.has_break_line) } prev_state = AlignState.has_attributes } else if field.has_default_expr { @@ -1514,15 +1521,16 @@ pub fn (mut f Fmt) calculate_alignment(fields []ast.StructField, mut type_align comment_align.add_new_info(field.default_expr.str().len + 2, comment.pos.line_nr) } else { - comment_align.add_info(field.default_expr.str().len + 2, comment.pos.line_nr, - field.has_break_line) + comment_align.add_info(field.default_expr.str().len + 2, + comment.pos.line_nr, field.has_break_line) } prev_state = AlignState.has_default_expression } else { if prev_state != AlignState.has_everything { comment_align.add_new_info(ft.len, comment.pos.line_nr) } else { - comment_align.add_info(ft.len, comment.pos.line_nr, field.has_break_line) + comment_align.add_info(ft.len, comment.pos.line_nr, + field.has_break_line) } prev_state = AlignState.has_everything } @@ -1581,7 +1589,8 @@ pub fn (mut f Fmt) interface_method(method ast.FnDecl, mut comment_align FieldAl } f.write('\t') f.table.new_int_fmt_fix = f.table.new_int && (f.is_translated_module || f.is_c_function) - method_str := f.table.stringify_fn_decl(&method, f.cur_mod, f.mod2alias, false).all_after_first('fn ') + method_str := + f.table.stringify_fn_decl(&method, f.cur_mod, f.mod2alias, false).all_after_first('fn ') f.table.new_int_fmt_fix = false f.write(method_str) if end_comments.len > 0 { @@ -2454,7 +2463,8 @@ pub fn (mut f Fmt) if_expr(node ast.IfExpr) { if i < node.branches.len - 1 || !node.has_else { f.write('${dollar}if ') cur_pos := f.out.len - pre_comments := branch.comments[sum_len..].filter(it.pos.pos < branch.cond.pos().pos) + pre_comments := + branch.comments[sum_len..].filter(it.pos.pos < branch.cond.pos().pos) sum_len += pre_comments.len post_comments := branch.comments[sum_len..] if pre_comments.len > 0 { @@ -3293,8 +3303,7 @@ pub fn (mut f Fmt) type_expr(node ast.TypeNode) { if node.stmt == ast.empty_stmt { f.write(f.type_to_str_using_aliases(node.typ, f.mod2alias)) } else { - f.struct_decl(ast.StructDecl{ fields: (node.stmt as ast.StructDecl).fields }, - true) + f.struct_decl(ast.StructDecl{ fields: (node.stmt as ast.StructDecl).fields }, true) } } diff --git a/vlib/v/fmt/struct.v b/vlib/v/fmt/struct.v index 032590c605..baa284b98f 100644 --- a/vlib/v/fmt/struct.v +++ b/vlib/v/fmt/struct.v @@ -122,7 +122,8 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) { // Handle comments at the end of the line if field.comments.len > 0 { if field.has_default_expr { - f.write(' '.repeat(comment_align.max_len(field.pos.line_nr) - field.default_expr.str().len - 2)) + f.write(' '.repeat(comment_align.max_len(field.pos.line_nr) - + field.default_expr.str().len - 2)) } else if field.attrs.len > 0 { f.write(' '.repeat(comment_align.max_len(field.pos.line_nr) - attrs_len)) } else { @@ -215,6 +216,35 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) { f.write('?') } if node.is_anon { + // Write the full anonymous struct definition inline, e.g.: + // `struct { foo string; bar int }{}` + sym := f.table.sym(node.typ) + if sym.info is ast.Struct && sym.info.is_anon { + f.writeln('struct {') + f.indent++ + for field in sym.info.fields { + f.write(field.name) + f.write(' ') + f.write(f.table.type_to_str_using_aliases(field.typ, f.mod2alias)) + f.writeln('') + } + f.indent-- + f.write('}') + if node.init_fields.len == 0 && !node.has_update_expr { + f.write('{}') + } else { + f.writeln('{') + f.indent++ + for init_field in node.init_fields { + f.write('${init_field.name}: ') + f.expr(init_field.expr) + f.writeln('') + } + f.indent-- + f.write('}') + } + return + } f.write('struct ') } if node.init_fields.len == 0 && !node.has_update_expr { @@ -285,7 +315,8 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) { mut value_align := new_field_align(use_break_line: true) mut comment_align := new_field_align(use_threshold: true) for init_field in node.init_fields { - value_align.add_info(init_field.name.len, init_field.pos.line_nr, init_field.has_break_line) + value_align.add_info(init_field.name.len, init_field.pos.line_nr, + init_field.has_break_line) if init_field.end_comments.len > 0 { comment_align.add_info(init_field.expr.str().len, init_field.pos.line_nr, init_field.has_break_line) @@ -304,9 +335,8 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) { } f.expr(init_field.expr) if init_field.end_comments.len > 0 { - f.write(' '.repeat( - comment_align.max_len(init_field.pos.line_nr) - init_field.expr.str().len + - 1)) + f.write(' '.repeat(comment_align.max_len(init_field.pos.line_nr) - + init_field.expr.str().len + 1)) f.comments(init_field.end_comments, has_nl: false, level: .indent) } if single_line_fields { diff --git a/vlib/v/fmt/tests/additive_infix_wrap_input.vv b/vlib/v/fmt/tests/additive_infix_wrap_input.vv index c857a9d27c..eef24f3e3f 100644 --- a/vlib/v/fmt/tests/additive_infix_wrap_input.vv +++ b/vlib/v/fmt/tests/additive_infix_wrap_input.vv @@ -1,9 +1,11 @@ fn main() { long_var_name := 0 - x := long_var_name + long_var_name + long_var_name + long_var_name + long_var_name + long_var_name + long_var_name + x := long_var_name + long_var_name + long_var_name + long_var_name + long_var_name + + long_var_name + long_var_name - y := long_var_name + long_var_name + long_var_name + long_var_name + long_var_name - long_var_name - long_var_name + y := long_var_name + long_var_name + long_var_name + long_var_name + long_var_name - + long_var_name - long_var_name println(x + y) } diff --git a/vlib/v/fmt/tests/long_assign_wrap_input.vv b/vlib/v/fmt/tests/long_assign_wrap_input.vv index db5d34e8ca..aab7c73a2e 100644 --- a/vlib/v/fmt/tests/long_assign_wrap_input.vv +++ b/vlib/v/fmt/tests/long_assign_wrap_input.vv @@ -49,9 +49,12 @@ fn main() { if true { if true { if true { - enum_stmt = v.extract_const_or_enum(decl.tree, enum_stmt, enum_stmt.name.len > 0) - mut imp_name := v.get_name(tree.child['Path'].tree, .snake_case, .other)#[1..-1].replace('/', '.') - values[v.get_name(field_name.tree, .snake_case, .field)] = BasicValueStmt{v.get_type(field.tree)} + enum_stmt = v.extract_const_or_enum(decl.tree, enum_stmt, + enum_stmt.name.len > 0) + mut imp_name := + v.get_name(tree.child['Path'].tree, .snake_case, .other)#[1..-1].replace('/', '.') + values[v.get_name(field_name.tree, .snake_case, .field)] = + BasicValueStmt{v.get_type(field.tree)} println(imp_name) } } diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 1afa6dfc14..66bc5f7ace 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -129,7 +129,8 @@ fn (mut g Gen) array_init(node ast.ArrayInit, var_name string) { } if g.cur_concrete_types.len > 0 && array_type.unaliased_sym.kind == .array && resolved_elem_type.typ != 0 { - current_elem_type := g.unwrap_generic(g.recheck_concrete_type(g.table.value_type(array_type.typ))) + current_elem_type := + g.unwrap_generic(g.recheck_concrete_type(g.table.value_type(array_type.typ))) if current_elem_type != resolved_elem_type.typ { resolved_array_type := g.table.find_or_register_array(resolved_elem_type.typ) array_type = g.unwrap(resolved_array_type) @@ -268,7 +269,8 @@ fn (mut g Gen) register_array_interface_cast_fn(got_type ast.Type, expected_type fn_builder.writeln('\t${expected_styp} res = builtin____new_array_with_default${noscan}(a.len, a.cap, sizeof(${expected_elem_styp}), 0);') fn_builder.writeln('\tfor (${ast.int_type_name} i = 0; i < a.len; ++i) {') src_elem_expr := '((${g.styp(got_info.elem_type)}*)a.data)[i]' - converted_expr := g.array_interface_cast_expr(src_elem_expr, got_info.elem_type, expected_info.elem_type) + converted_expr := g.array_interface_cast_expr(src_elem_expr, got_info.elem_type, + expected_info.elem_type) fn_builder.writeln('\t\t((${expected_elem_styp}*)res.data)[i] = ${converted_expr};') fn_builder.writeln('\t}') fn_builder.writeln('\treturn res;') @@ -760,7 +762,7 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) { ret_styp := g.styp(return_type) ret_sym := g.table.final_sym(return_type) - left_type := g.resolve_array_call_left_type(node) + left_type := g.resolved_array_receiver_type(node) left_sym := g.table.final_sym(left_type) left_is_array := left_sym.kind == .array inp_sym := left_sym @@ -796,8 +798,7 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) { } } noscan := g.check_noscan(ret_elem_type) - has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, ret_styp, - '{0}') + has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, ret_styp, '{0}') if left_is_array { g.writeln('${past.tmp_var} = builtin____new_array${noscan}(0, ${past.tmp_var}_len, sizeof(${ret_elem_styp}));\n') } @@ -922,7 +923,8 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) { } } if left_is_array { - g.writeln2(';', 'builtin__array_push${noscan}((array*)&${past.tmp_var}, &${tmp_map_expr_result_name});') + g.writeln2(';', + 'builtin__array_push${noscan}((array*)&${past.tmp_var}, &${tmp_map_expr_result_name});') } else { g.writeln2(';', '${past.tmp_var}[${i}] = ${tmp_map_expr_result_name};') } @@ -1142,7 +1144,10 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) { } stype_arg := g.styp(elem_type) - g.sort_fn_definitions.writeln('VV_LOC int ${compare_fn}(${stype_arg}* a, ${stype_arg}* b) {') + // In -parallel-cc these bodies are seen by every split C translation unit via `out.h`, + // so they need internal linkage to avoid duplicate symbols at link time. + sort_fn_visibility := if g.static_modifier != '' { g.static_modifier } else { 'VV_LOC ' } + g.sort_fn_definitions.writeln('${sort_fn_visibility}int ${compare_fn}(${stype_arg}* a, ${stype_arg}* b) {') c_condition := if comparison_type.sym.has_method('<') { method_name := if comparison_type.sym.is_builtin() { 'builtin__${g.styp(comparison_type.typ)}__lt' @@ -1921,8 +1926,7 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) { (sym.info as ast.ArrayFixed).elem_type } elem_type_str := g.styp(elem_type) - has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, 'bool', - 'false') + has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, 'bool', 'false') mut expr := node.args[0].expr var_name := g.get_array_expr_param_name(mut expr) @@ -1939,8 +1943,7 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) { g.writeln('for (${ast.int_type_name} ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {') g.indent++ - g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, - false) + g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, false) g.set_current_pos_as_last_stmt_pos() mut is_embed_map_filter := false match mut expr { @@ -2015,8 +2018,8 @@ fn (mut g Gen) gen_array_count(node ast.CallExpr) { (sym.info as ast.ArrayFixed).elem_type } elem_type_str := g.styp(elem_type) - has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, ast.int_type_name, - '0') + has_infix_left_var_name := + g.write_prepared_tmp_value(past.tmp_var, node, ast.int_type_name, '0') mut expr := node.args[0].expr var_name := g.get_array_expr_param_name(mut expr) @@ -2033,8 +2036,7 @@ fn (mut g Gen) gen_array_count(node ast.CallExpr) { g.writeln('for (${ast.int_type_name} ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {') g.indent++ - g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, - false) + g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, false) g.set_current_pos_as_last_stmt_pos() mut is_embed_map_filter := false match mut expr { @@ -2110,8 +2112,7 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) { } elem_type_str := g.styp(elem_type) - has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, 'bool', - 'true') + has_infix_left_var_name := g.write_prepared_tmp_value(past.tmp_var, node, 'bool', 'true') i := g.new_tmp_var() mut expr := node.args[0].expr @@ -2128,8 +2129,7 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) { g.writeln('for (${ast.int_type_name} ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {') g.indent++ - g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, - false) + g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array, false) g.empty_line = true g.set_current_pos_as_last_stmt_pos() mut is_embed_map_filter := false @@ -2350,7 +2350,8 @@ fn (mut g Gen) fixed_array_var_init(expr_str string, is_auto_deref bool, elem_ty for i in 0 .. size { if elem_sym.info is ast.ArrayFixed { init_str := if g.inside_array_fixed_struct { '${expr_str}' } else { '${expr_str}[${i}]' } - g.fixed_array_var_init(init_str, is_auto_deref, elem_sym.info.elem_type, elem_sym.info.size) + g.fixed_array_var_init(init_str, is_auto_deref, elem_sym.info.elem_type, + elem_sym.info.size) } else { if is_auto_deref { g.write('(*') diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index e53ea4acca..42aeac20b3 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -63,8 +63,7 @@ fn (mut g Gen) gen_self_recursing_anon_fn_capture_patch(left ast.Expr, anon_fn a if ident.name !in anon_fn.inherited_vars.map(it.name) { return } - concrete_types := g.get_anon_fn_concrete_types(anon_fn) - ctx_struct := g.closure_ctx(anon_fn.decl, concrete_types) + ctx_struct := g.closure_ctx(anon_fn.decl) left_expr := g.expr_string(left) g.writeln('((${ctx_struct}*)builtin__closure__closure_data(${left_expr}))->${c_name(ident.name)} = ${left_expr};') } @@ -115,8 +114,8 @@ fn (mut g Gen) expr_with_opt_or_block(expr ast.Expr, expr_typ ast.Type, var_expr var_expr_name := c_name(var_expr.str()) if last_stmt.expr is ast.Ident && last_stmt.expr.or_expr.kind != .absent { g.write('${var_expr_name} = ') - g.expr_with_opt_or_block(ast.Expr(last_stmt.expr), last_stmt.typ, - var_expr, ret_typ, in_heap) + g.expr_with_opt_or_block(ast.Expr(last_stmt.expr), last_stmt.typ, var_expr, + ret_typ, in_heap) } else { g.gen_or_block_stmts(var_expr_name, '', stmts, ret_typ, false, scope, expr.pos()) @@ -271,8 +270,7 @@ fn (mut g Gen) expr_with_opt(expr ast.Expr, expr_typ ast.Type, ret_typ ast.Type) } } else { tmp_out_var := g.new_tmp_var() - g.expr_with_tmp_var(expr, unwrapped_expr_typ, unwrapped_ret_typ, tmp_out_var, - true) + g.expr_with_tmp_var(expr, unwrapped_expr_typ, unwrapped_ret_typ, tmp_out_var, true) return tmp_out_var } return '' @@ -493,7 +491,27 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { val := node.right[i] if is_decl && g.cur_concrete_types.len > 0 && val is ast.CallExpr && val.return_type_generic != 0 { - resolved_val_type := g.unwrap_generic(val.return_type_generic).clear_option_and_result() + mut resolved_val_type := g.resolve_return_type(val).clear_option_and_result() + if resolved_val_type == ast.void_type || resolved_val_type.has_flag(.generic) { + resolved_val_type = + g.unwrap_generic(val.return_type_generic).clear_option_and_result() + } + // When unwrap_generic couldn't resolve (e.g. cur_fn.generic_names is empty + // for methods whose generics come from the receiver), try resolving using + // the receiver's generic type names from the current fn. + if (resolved_val_type == ast.void_type || resolved_val_type.has_flag(.generic) + || g.type_has_unresolved_generic_parts(resolved_val_type)) + && g.cur_fn != unsafe { nil } && g.cur_fn.is_method + && g.cur_fn.receiver.typ.has_flag(.generic) { + receiver_generic_names := g.table.generic_type_names(g.cur_fn.receiver.typ) + if receiver_generic_names.len == g.cur_concrete_types.len { + if gen_type := g.table.convert_generic_type(val.return_type_generic, + receiver_generic_names, g.cur_concrete_types) + { + resolved_val_type = gen_type.clear_option_and_result() + } + } + } if resolved_val_type != ast.void_type && !resolved_val_type.has_flag(.generic) { var_type = ast.mktyp(resolved_val_type) val_type = resolved_val_type @@ -521,7 +539,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { left_is_auto_heap := left is ast.Ident && g.resolved_ident_is_auto_heap_not_stack(left) resolved_decl_type := g.resolved_expr_type(val, decl_default) if resolved_decl_type != 0 && resolved_decl_type != ast.void_type && !left_is_auto_heap { - mut resolved_unwrapped := g.unwrap_generic(g.recheck_concrete_type(resolved_decl_type)) + mut resolved_unwrapped := + g.unwrap_generic(g.recheck_concrete_type(resolved_decl_type)) // Don't propagate pointer flag from auto-deref mut parameters. // `mut e := expr` where expr is a mut param should create a value copy. // Also handles the case where var_type is already a pointer (e.g. @@ -540,7 +559,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { if !var_type.has_flag(.shared_f) && resolved_unwrapped.has_flag(.shared_f) { resolved_unwrapped = resolved_unwrapped.clear_flag(.shared_f) if resolved_unwrapped.nr_muls() > 0 { - resolved_unwrapped = resolved_unwrapped.set_nr_muls(resolved_unwrapped.nr_muls() - 1) + resolved_unwrapped = + resolved_unwrapped.set_nr_muls(resolved_unwrapped.nr_muls() - 1) } } if !var_type.has_flag(.atomic_f) && resolved_unwrapped.has_flag(.atomic_f) { @@ -688,11 +708,11 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { g.type_resolver.update_ct_type(left.name, var_type) } } else if left.obj.ct_type_var == .generic_var && val is ast.CallExpr { - if val.return_type_generic != 0 - && val.return_type_generic.has_flag(.generic) { - mut fn_ret_type := g.unwrap_generic(val.return_type_generic).clear_option_and_result() + if val.return_type_generic != 0 { + mut fn_ret_type := g.resolve_return_type(val).clear_option_and_result() if fn_ret_type == ast.void_type || fn_ret_type.has_flag(.generic) { - fn_ret_type = g.resolve_return_type(val) + fn_ret_type = + g.unwrap_generic(val.return_type_generic).clear_option_and_result() } if fn_ret_type != ast.void_type { var_type = fn_ret_type @@ -710,7 +730,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { && val.name == 'map' && val.args.len > 0 && val.args[0].expr is ast.AsCast && val.args[0].expr.typ.has_flag(.generic) { - var_type = g.table.find_or_register_array(g.unwrap_generic((val.args[0].expr as ast.AsCast).typ)) + var_type = + g.table.find_or_register_array(g.unwrap_generic((val.args[0].expr as ast.AsCast).typ)) val_type = var_type left.obj.typ = var_type g.assign_ct_type[val.pos.pos] = var_type @@ -932,7 +953,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { resolved_val_sym := g.table.final_sym(resolved_val_type) if resolved_val_sym.kind == .array && !resolved_val_type.is_ptr() && g.table.sym(resolved_val_type).kind != .alias { - mut resolved_elem_type := g.unwrap_generic(g.recheck_concrete_type(resolved_val_sym.array_info().elem_type)) + mut resolved_elem_type := + g.unwrap_generic(g.recheck_concrete_type(resolved_val_sym.array_info().elem_type)) if resolved_elem_type == ast.int_literal_type { resolved_elem_type = ast.int_type } else if resolved_elem_type == ast.float_literal_type { @@ -940,7 +962,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } if resolved_elem_type != 0 && !resolved_elem_type.has_flag(.generic) && !g.type_has_unresolved_generic_parts(resolved_elem_type) { - mut new_arr_type := ast.idx_to_type(g.table.find_or_register_array(resolved_elem_type)) + mut new_arr_type := + ast.idx_to_type(g.table.find_or_register_array(resolved_elem_type)) // Preserve option/result flags from the original resolved type if resolved_val_type.has_flag(.option) { new_arr_type = new_arr_type.set_flag(.option) @@ -1042,8 +1065,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } // if it's a decl assign (`:=`) or a blank assignment `_ =`/`_ :=` then generate `void (*ident) (args) =` if (is_decl || blank_assign) && left is ast.Ident { - sig := g.fn_var_signature(val.typ, val.decl.return_type, val.decl.params.map(it.typ), - ident.name) + sig := g.fn_var_signature(val.typ, val.decl.return_type, + val.decl.params.map(it.typ), ident.name) g.write(sig + ' = ') } else { g.is_assign_lhs = true @@ -1361,8 +1384,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } else if left_sym.kind == .alias && struct_info.kind == .struct && struct_info.info is ast.Struct && struct_info.info.generic_types.len > 0 { mut method_name := struct_info.cname + '_' + util.replace_op(extracted_op) - specialized_suffix := g.generic_fn_name(struct_info.info.concrete_types, - '') + specialized_suffix := g.generic_fn_name(struct_info.info.concrete_types, '') if specialized_suffix != '' && !method_name.ends_with(specialized_suffix) { method_name = g.generic_fn_name(struct_info.info.concrete_types, method_name) @@ -1654,7 +1676,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } if (var_type.has_flag(.option) && val !in [ast.Ident, ast.SelectorExpr]) || gen_or { - g.expr_with_opt_or_block(val, val_type, left, var_type, is_option_auto_heap) + g.expr_with_opt_or_block(val, val_type, left, var_type, + is_option_auto_heap) } else if val is ast.ArrayInit { cvar_name := c_name(ident.name) if val.is_fixed && ident.name in g.defer_vars { @@ -1695,8 +1718,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } else { tmp_var } - g.fixed_array_var_init(init_expr, false, unaliased_right_sym.info.elem_type, - unaliased_right_sym.info.size) + g.fixed_array_var_init(init_expr, false, + unaliased_right_sym.info.elem_type, unaliased_right_sym.info.size) } else if is_large_struct_heap && val is ast.StructInit { // For large structs, use vcalloc directly to avoid stack overflow // from compound literals on the stack @@ -1868,7 +1891,8 @@ fn (mut g Gen) gen_multi_return_assign(node &ast.AssignStmt, return_type ast.Typ field_sym := g.table.sym(field_type) if field_sym.info is ast.Map { map_info := field_sym.info as ast.Map - ret_type = g.table.find_or_register_multi_return([map_info.key_type, map_info.value_type]) + ret_type = + g.table.find_or_register_multi_return([map_info.key_type, map_info.value_type]) ret_sym = *g.table.sym(ret_type) } } @@ -1901,7 +1925,8 @@ fn (mut g Gen) gen_multi_return_assign(node &ast.AssignStmt, return_type ast.Typ if fn_var_type != 0 { fn_sym := g.table.final_sym(fn_var_type) if fn_sym.info is ast.FnType { - resolved_ret_type := g.unwrap_generic(g.recheck_concrete_type(fn_sym.info.func.return_type)) + resolved_ret_type := + g.unwrap_generic(g.recheck_concrete_type(fn_sym.info.func.return_type)) if resolved_ret_type != 0 && g.table.sym(resolved_ret_type).kind == .multi_return { ret_type = resolved_ret_type ret_sym = *g.table.sym(ret_type) @@ -2034,7 +2059,8 @@ fn (mut g Gen) gen_multi_return_assign(node &ast.AssignStmt, return_type ast.Typ } else { g.expr(lx) if sym.kind == .array_fixed { - g.writeln2(';', 'memcpy(&${g.expr_string(lx)}, &${mr_var_name}.arg${i}, sizeof(${styp}));') + g.writeln2(';', + 'memcpy(&${g.expr_string(lx)}, &${mr_var_name}.arg${i}, sizeof(${styp}));') } else { if cur_indexexpr != -1 { if is_auto_heap { @@ -2109,7 +2135,8 @@ fn (mut g Gen) gen_cross_var_assign(node &ast.AssignStmt) { if g.cur_fn != unsafe { nil } && g.cur_concrete_types.len > 0 { resolved_container_type := g.resolved_expr_type(left.left, left.left_type) if resolved_container_type != 0 { - container_type = g.unwrap_generic(g.recheck_concrete_type(resolved_container_type)) + container_type = + g.unwrap_generic(g.recheck_concrete_type(resolved_container_type)) } } sym := g.table.sym(g.table.unaliased_type(container_type)) diff --git a/vlib/v/gen/c/auto_eq_methods.v b/vlib/v/gen/c/auto_eq_methods.v index 683b2022b7..8cbcf3e81c 100644 --- a/vlib/v/gen/c/auto_eq_methods.v +++ b/vlib/v/gen/c/auto_eq_methods.v @@ -552,8 +552,8 @@ fn (mut g Gen) gen_map_equality_fn(left_type ast.Type) string { initializer := if !(sym.info is ast.Struct && sym.info.is_empty_struct()) { '0' } else { '' } if kind == .function { info := value.sym.info as ast.FnType - sig := g.fn_var_signature(ast.void_type, info.func.return_type, info.func.params.map(it.typ), - 'v') + sig := g.fn_var_signature(ast.void_type, info.func.return_type, + info.func.params.map(it.typ), 'v') fn_builder.writeln('\t\t${sig} = *(voidptr*)builtin__map_get(${a}, k, &(voidptr[]){ 0 });') } else { fn_builder.writeln('\t\t${ptr_value_styp} v = *(${ptr_value_styp}*)builtin__map_get(${a}, k, &(${ptr_value_styp}[]){ ${initializer} });') diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index 1c12e3bf88..7414ed96e9 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -121,6 +121,10 @@ fn (mut g Gen) final_gen_str(typ StrType) { || typ.typ.has_flag(.result)) { return } + // Skip str generation for unresolved generic parameter types (e.g. T) + if sym.kind == .any && !sym.is_builtin() { + return + } styp := typ.styp str_fn_name := g.get_str_fn(typ.typ) if str_fn_name in g.str_fn_names { @@ -188,8 +192,7 @@ fn (mut g Gen) final_gen_str(typ StrType) { g.gen_str_for_multi_return(sym.info, styp, str_fn_name) } ast.SumType { - g.gen_str_for_union_sum_type(sym.info, styp, g.table.type_to_str(typ.typ), - str_fn_name) + g.gen_str_for_union_sum_type(sym.info, styp, g.table.type_to_str(typ.typ), str_fn_name) } ast.Interface { g.gen_str_for_interface(sym.info, styp, g.table.type_to_str(typ.typ), str_fn_name) @@ -284,7 +287,7 @@ fn (mut g Gen) gen_str_for_result(typ ast.Type, styp string, str_fn_name string) } g.auto_str_funcs.writeln('\t} else {') - tmp_str := str_intp_sub('error: %%', 'IError_str(it.err)') + tmp_str := str_intp_sub('error: %%', 'builtin__IError_str(it.err)') g.auto_str_funcs.writeln('\t\tres = ${tmp_str};') g.auto_str_funcs.writeln('\t}') @@ -325,7 +328,7 @@ fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string } g.auto_str_funcs.writeln('\tstring res = builtin__str_intp(2, _MOV((StrIntpData[]){ {_S("${clean_type_v_type_name}("), ${si_s_code}, {.d_s = tmp_ds }, 0, 0, 0}, - {_S(")"), 0, {.d_c = 0 }, 0, 0, 0} + {_S(")"), 0, {0}, 0, 0, 0} }));') g.auto_str_funcs.writeln('\tbuiltin__string_free(&tmp_ds);') g.auto_str_funcs.writeln('\treturn res;') @@ -456,7 +459,7 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, typ_str st val += ')' res := 'builtin__str_intp(2, _MOV((StrIntpData[]){ {_S("${clean_interface_v_type_name}(\'"), ${si_s_code}, {.d_s = ${val}}, 0, 0, 0}, - {_S("\')"), 0, {.d_c = 0 }, 0, 0, 0} + {_S("\')"), 0, {0}, 0, 0, 0} }))' fn_builder.write_string2('\tif (x._typ == _${styp}_${sub_sym.cname}_index)', ' return ${res};') @@ -469,7 +472,7 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, typ_str st val += ')' res := 'builtin__str_intp(2, _MOV((StrIntpData[]){ {_S("${clean_interface_v_type_name}("), ${si_s_code}, {.d_s = ${val}}, 0, 0, 0}, - {_S(")"), 0, {.d_c = 0 }, 0, 0, 0} + {_S(")"), 0, {0}, 0, 0, 0} }))' fn_builder.write_string2('\tif (x._typ == _${styp}_${sub_sym.cname}_index)', ' return ${res};\n') @@ -531,19 +534,18 @@ fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, typ_str val += ')' res := 'builtin__str_intp(2, _MOV((StrIntpData[]){ {_S("${clean_sum_type_v_type_name}(\'"), ${si_s_code}, {.d_s = ${val}}, 0, 0, 0}, - {_S("\')"), 0, {.d_c = 0 }, 0, 0, 0} + {_S("\')"), 0, {0}, 0, 0, 0} }))' fn_builder.write_string('\t\tcase ${int(typ)}: return ${res};\n') } else { - mut val := '${func_name}(${deref}(${typ_name}*)x._${g.get_sumtype_variant_name(typ, - sym)}' + mut val := '${func_name}(${deref}(${typ_name}*)x._${g.get_sumtype_variant_name(typ, sym)}' if should_use_indent_func(sym.kind) && !sym_has_str_method { val += ', indent_count' } val += ')' res := 'builtin__str_intp(2, _MOV((StrIntpData[]){ {_S("${clean_sum_type_v_type_name}("), ${si_s_code}, {.d_s = ${val}}, 0, 0, 0}, - {_S(")"), 0, {.d_c = 0 }, 0, 0, 0} + {_S(")"), 0, {0}, 0, 0, 0} }))' fn_builder.write_string('\t\tcase ${int(typ)}: return ${res};\n') } @@ -687,8 +689,7 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string } if should_use_indent_func(sym.kind) && !sym_has_str_method { if is_elem_ptr { - deref, deref_label := deref_kind(str_method_expects_ptr, is_elem_ptr, - typ) + deref, deref_label := deref_kind(str_method_expects_ptr, is_elem_ptr, typ) g.auto_str_funcs.writeln('\t\tstring x = _S("nil");') if !typ.has_flag(.option) { g.auto_str_funcs.writeln('\t\tif (it != 0) {') @@ -714,15 +715,15 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string } } else if sym.kind == .rune { // Rune are managed at this level as strings - g.auto_str_funcs.writeln('\t\tstring x = builtin__str_intp(2, _MOV((StrIntpData[]){{_S("\`"), ${si_s_code}, {.d_s = ${elem_str_fn_name}(it) }, 0, 0, 0}, {_S("\`"), 0, {.d_c = 0 }, 0, 0, 0}}));\n') + g.auto_str_funcs.writeln('\t\tstring x = builtin__str_intp(2, _MOV((StrIntpData[]){{_S("\`"), ${si_s_code}, {.d_s = ${elem_str_fn_name}(it) }, 0, 0, 0}, {_S("\`"), 0, {0}, 0, 0, 0}}));\n') } else if sym.kind == .string { if typ.has_flag(.option) { func := g.get_str_fn(typ) g.auto_str_funcs.writeln('\t\tstring x = ${func}(it);\n') } else if is_elem_ptr { - g.auto_str_funcs.writeln('\t\tstring x = builtin__str_intp(2, _MOV((StrIntpData[]){{_S("&\'"), ${si_s_code}, {.d_s = *it }, 0, 0, 0}, {_S("\'"), 0, {.d_c = 0 }, 0, 0, 0}}));\n') + g.auto_str_funcs.writeln('\t\tstring x = builtin__str_intp(2, _MOV((StrIntpData[]){{_S("&\'"), ${si_s_code}, {.d_s = *it }, 0, 0, 0}, {_S("\'"), 0, {0}, 0, 0, 0}}));\n') } else { - g.auto_str_funcs.writeln('\t\tstring x = builtin__str_intp(2, _MOV((StrIntpData[]){{_S("\'"), ${si_s_code}, {.d_s = it }, 0, 0, 0}, {_S("\'"), 0, {.d_c = 0 }, 0, 0, 0}}));\n') + g.auto_str_funcs.writeln('\t\tstring x = builtin__str_intp(2, _MOV((StrIntpData[]){{_S("\'"), ${si_s_code}, {.d_s = it }, 0, 0, 0}, {_S("\'"), 0, {0}, 0, 0, 0}}));\n') } } else { // There is a custom .str() method, so use it. @@ -922,7 +923,8 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) { } } } else if val_sym.kind == .rune { - tmp_str := str_intp_rune('${elem_str_fn_name}(*(${val_styp}*)builtin__DenseArray_value(&m.key_values, i))') + tmp_str := + str_intp_rune('${elem_str_fn_name}(*(${val_styp}*)builtin__DenseArray_value(&m.key_values, i))') g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${tmp_str});') } else { ptr_str := '*'.repeat(val_typ.nr_muls()) @@ -1058,7 +1060,7 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, lang ast.Language, styp strin } } fn_body.writeln('\tstring res = builtin__str_intp( ${(info.fields.len - field_skips.len) * 4 + 3}, _MOV((StrIntpData[]){') - fn_body.writeln('\t\t{_S("${clean_struct_v_type_name}{\\n"), 0, {.d_c=0}},') + fn_body.writeln('\t\t{_S("${clean_struct_v_type_name}{\\n"), 0, {0}, 0, 0, 0},') mut is_first := true for i, field in info.fields { @@ -1094,10 +1096,10 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, lang ast.Language, styp strin if is_first { // first field doesn't need \n - fn_body.write_string('\t\t{_SLIT0, ${si_s_code}, {.d_s=indents}, 0, 0, 0}, {_S(" ${field.name}: ${ptr_amp}${prefix}"), 0, {.d_c=0}, 0, 0, 0}, ') + fn_body.write_string('\t\t{_SLIT0, ${si_s_code}, {.d_s=indents}, 0, 0, 0}, {_S(" ${field.name}: ${ptr_amp}${prefix}"), 0, {0}, 0, 0, 0}, ') is_first = false } else { - fn_body.write_string('\t\t{_S("\\n"), ${si_s_code}, {.d_s=indents}, 0, 0, 0}, {_S(" ${field.name}: ${ptr_amp}${prefix}"), 0, {.d_c=0}, 0, 0, 0}, ') + fn_body.write_string('\t\t{_S("\\n"), ${si_s_code}, {.d_s=indents}, 0, 0, 0}, {_S(" ${field.name}: ${ptr_amp}${prefix}"), 0, {0}, 0, 0, 0}, ') } // custom methods management @@ -1199,9 +1201,9 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, lang ast.Language, styp strin } } - fn_body.writeln('}, 0, 0, 0}, {_S("${quote_str}"), 0, {.d_c=0}, 0, 0, 0},') + fn_body.writeln('}, 0, 0, 0}, {_S("${quote_str}"), 0, {0}, 0, 0, 0},') } - fn_body.writeln('\t\t{_S("\\n"), ${si_s_code}, {.d_s=indents}, 0, 0, 0}, {_S("}"), 0, {.d_c=0}, 0, 0, 0},') + fn_body.writeln('\t\t{_S("\\n"), ${si_s_code}, {.d_s=indents}, 0, 0, 0}, {_S("}"), 0, {0}, 0, 0, 0},') fn_body.writeln('\t}));') } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 17f5f0c6d9..9acad3ad89 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -44,194 +44,195 @@ mut: out strings.Builder extern_out strings.Builder // extern declarations for -parallel-cc // line_nr int - cheaders strings.Builder - preincludes strings.Builder // allows includes to go before `definitions` - postincludes strings.Builder // allows includes to go after all the rest of the code generation - includes strings.Builder // all C #includes required by V modules - typedefs strings.Builder - enum_typedefs strings.Builder // enum types - definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) - type_definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) - sort_fn_definitions strings.Builder // sort fns - alias_definitions strings.Builder // alias fixed array of non-builtin - hotcode_definitions strings.Builder // -live declarations & functions - channel_definitions strings.Builder // channel related code - thread_definitions strings.Builder // thread defines - comptime_definitions strings.Builder // custom defines, given by -d/-define flags on the CLI - type_default_vars strings.Builder // type_default() var declarations - cleanup strings.Builder - cleanups map[string]strings.Builder // contents of `void _vcleanup(){}` - gowrappers strings.Builder // all go callsite wrappers - waiter_fn_definitions strings.Builder // waiter fns definitions - auto_str_funcs strings.Builder // function bodies of all auto generated _str funcs - dump_funcs strings.Builder // function bodies of all auto generated _str funcs - pcs_declarations strings.Builder // -prof profile counter declarations for each function - cov_declarations strings.Builder // -cov coverage - embedded_data strings.Builder // data to embed in the executable/binary - shared_types strings.Builder // shared/lock types - shared_functions strings.Builder // shared constructors - out_options_forward strings.Builder // forward `option_xxxx` types - out_options strings.Builder // `option_xxxx` types - out_results_forward strings.Builder // forward`result_xxxx` types - out_results strings.Builder // `result_xxxx` types - json_forward_decls strings.Builder // json type forward decls - sql_buf strings.Builder // for writing exprs to args via `sqlite3_bind_int()` etc - global_const_defs map[string]GlobalConstDef - vsafe_arithmetic_ops map[string]VSafeArithmeticOp // 'VSAFE_DIV_u8' -> {11, /}, 'VSAFE_MOD_u8' -> {11,%}, 'VSAFE_MOD_i64' -> the same but with 9 - sorted_global_const_names []string - file &ast.File = unsafe { nil } - table &ast.Table = unsafe { nil } - styp_cache map[ast.Type]string - no_eq_method_types map[ast.Type]bool // types that does not need to call its auto eq methods for optimization - unique_file_path_hash u64 // a hash of file.path, used for making auxiliary fn generation unique (like `compare_xyz`) - fn_decl &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0 - last_fn_c_name string - tmp_count int // counter for unique tmp vars (_tmp1, _tmp2 etc); resets at the start of each fn. - tmp_count_af int // a separate tmp var counter for autofree fn calls - tmp_count_declarations int // counter for unique tmp names (_d1, _d2 etc); does NOT reset, used for C declarations - global_tmp_count int // like tmp_count but global and not reset in each function - discard_or_result bool // do not safe last ExprStmt of `or` block in tmp variable to defer ongoing expr usage - is_direct_array_access bool // inside a `[direct_array_access fn a() {}` function - is_assign_lhs bool // inside left part of assign expr (for array_set(), etc) - is_void_expr_stmt bool // ExprStmt whose result is discarded - is_arraymap_set bool // map or array set value state - is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&u8(unsafe { nil })` etc - is_sql bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc) - is_shared bool // for initialization of hidden mutex in `[rw]shared` literals - is_vlines_enabled bool // is it safe to generate #line directives when -g is passed - is_autofree bool // false, inside the bodies of fns marked with [manualfree], otherwise === g.pref.autofree - is_autofree_tmp bool // when generating autofree temporary variables - is_builtin_mod bool - is_json_fn bool // inside json.encode() - is_js_call bool // for handling a special type arg #1 `json.decode(User, ...)` - is_fn_index_call bool - is_cc_msvc bool // g.pref.ccompiler == 'msvc' - is_option_auto_heap bool - vlines_path string // set to the proper path for generating #line directives - options_pos_forward int // insertion point to forward - options_forward []string // to forward - options map[string]string // to avoid duplicates - results_forward []string // to forward - results map[string]string // to avoid duplicates - done_options shared []string // to avoid duplicates - done_results shared []string // to avoid duplicates - array_typedefs []string // to avoid duplicate array typedefs - written_array_typedefs int - done_typedef_phase bool // set after write_typedef_types() completes - late_chan_types shared []string // concrete channel cnames discovered during file generation - emitted_chan_types map[string]bool // concrete channel typedefs/helpers already emitted - chan_pop_options map[string]string // types for `x := <-ch or {...}` - chan_push_options map[string]string // types for `ch <- x or {...}` - mtxs string // array of mutexes if the `lock` has multiple variables - tmp_var_ptr map[string]bool // indicates if the tmp var passed to or_block() is a ptr - labeled_loops map[string]&ast.Stmt - contains_ptr_cache map[ast.Type]bool - inner_loop &ast.Stmt = unsafe { nil } - cur_indexexpr []int // list of nested indexexpr which generates array_set/map_set - shareds map[int]string // types with hidden mutex for which decl has been emitted - coverage_files map[u64]&CoverageInfo - inside_smartcast bool - inside_ternary int // ?: comma separated statements on a single line - inside_map_postfix bool // inside map++/-- postfix expr - inside_map_infix bool // inside map< fn counter name - hotcode_fn_names []string - hotcode_fpaths []string - embedded_files []ast.EmbeddedFile - sql_i int - sql_stmt_name string - sql_bind_name string - sql_idents []string - sql_idents_types []ast.Type - sql_left_type ast.Type - sql_table_name string - sql_table_typ ast.Type // the table type, used for generic types lookup - sql_fkey string - sql_parent_id string - sql_side SqlExprSide // left or right, to distinguish idents in `name == name` - sql_last_stmt_out_len int - strs_to_free0 []string // strings.Builder + cheaders strings.Builder + preincludes strings.Builder // allows includes to go before `definitions` + postincludes strings.Builder // allows includes to go after all the rest of the code generation + includes strings.Builder // all C #includes required by V modules + typedefs strings.Builder + enum_typedefs strings.Builder // enum types + definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) + type_definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) + sort_fn_definitions strings.Builder // sort fns + alias_definitions strings.Builder // alias fixed array of non-builtin + hotcode_definitions strings.Builder // -live declarations & functions + channel_definitions strings.Builder // channel related code + thread_definitions strings.Builder // thread defines + comptime_definitions strings.Builder // custom defines, given by -d/-define flags on the CLI + type_default_vars strings.Builder // type_default() var declarations + cleanup strings.Builder + cleanups map[string]strings.Builder // contents of `void _vcleanup(){}` + gowrappers strings.Builder // all go callsite wrappers + waiter_fn_definitions strings.Builder // waiter fns definitions + auto_str_funcs strings.Builder // function bodies of all auto generated _str funcs + dump_funcs strings.Builder // function bodies of all auto generated _str funcs + pcs_declarations strings.Builder // -prof profile counter declarations for each function + cov_declarations strings.Builder // -cov coverage + embedded_data strings.Builder // data to embed in the executable/binary + shared_types strings.Builder // shared/lock types + shared_functions strings.Builder // shared constructors + out_options_forward strings.Builder // forward `option_xxxx` types + out_options strings.Builder // `option_xxxx` types + out_results_forward strings.Builder // forward`result_xxxx` types + out_results strings.Builder // `result_xxxx` types + json_forward_decls strings.Builder // json type forward decls + sql_buf strings.Builder // for writing exprs to args via `sqlite3_bind_int()` etc + global_const_defs map[string]GlobalConstDef + vsafe_arithmetic_ops map[string]VSafeArithmeticOp // 'VSAFE_DIV_u8' -> {11, /}, 'VSAFE_MOD_u8' -> {11,%}, 'VSAFE_MOD_i64' -> the same but with 9 + sorted_global_const_names []string + file &ast.File = unsafe { nil } + table &ast.Table = unsafe { nil } + styp_cache map[ast.Type]string + no_eq_method_types map[ast.Type]bool // types that does not need to call its auto eq methods for optimization + unique_file_path_hash u64 // a hash of file.path, used for making auxiliary fn generation unique (like `compare_xyz`) + fn_decl &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0 + last_fn_c_name string + tmp_count int // counter for unique tmp vars (_tmp1, _tmp2 etc); resets at the start of each fn. + tmp_count_af int // a separate tmp var counter for autofree fn calls + tmp_count_declarations int // counter for unique tmp names (_d1, _d2 etc); does NOT reset, used for C declarations + global_tmp_count int // like tmp_count but global and not reset in each function + discard_or_result bool // do not safe last ExprStmt of `or` block in tmp variable to defer ongoing expr usage + is_direct_array_access bool // inside a `[direct_array_access fn a() {}` function + is_assign_lhs bool // inside left part of assign expr (for array_set(), etc) + is_void_expr_stmt bool // ExprStmt whose result is discarded + is_arraymap_set bool // map or array set value state + is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&u8(unsafe { nil })` etc + is_sql bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc) + is_shared bool // for initialization of hidden mutex in `[rw]shared` literals + is_vlines_enabled bool // is it safe to generate #line directives when -g is passed + is_autofree bool // false, inside the bodies of fns marked with [manualfree], otherwise === g.pref.autofree + is_autofree_tmp bool // when generating autofree temporary variables + is_builtin_mod bool + is_json_fn bool // inside json.encode() + is_js_call bool // for handling a special type arg #1 `json.decode(User, ...)` + is_fn_index_call bool + is_cc_msvc bool // g.pref.ccompiler == 'msvc' + is_option_auto_heap bool + vlines_path string // set to the proper path for generating #line directives + options_pos_forward int // insertion point to forward + options_forward []string // to forward + options map[string]string // to avoid duplicates + results_forward []string // to forward + results map[string]string // to avoid duplicates + done_options shared []string // to avoid duplicates + done_results shared []string // to avoid duplicates + array_typedefs []string // to avoid duplicate array typedefs + written_array_typedefs int + done_typedef_phase bool // set after write_typedef_types() completes + late_chan_types shared []string // concrete channel cnames discovered during file generation + emitted_chan_types map[string]bool // concrete channel typedefs/helpers already emitted + chan_pop_options map[string]string // types for `x := <-ch or {...}` + chan_push_options map[string]string // types for `ch <- x or {...}` + mtxs string // array of mutexes if the `lock` has multiple variables + tmp_var_ptr map[string]bool // indicates if the tmp var passed to or_block() is a ptr + labeled_loops map[string]&ast.Stmt + contains_ptr_cache map[ast.Type]bool + inner_loop &ast.Stmt = unsafe { nil } + cur_indexexpr []int // list of nested indexexpr which generates array_set/map_set + shareds map[int]string // types with hidden mutex for which decl has been emitted + coverage_files map[u64]&CoverageInfo + inside_smartcast bool + inside_ternary int // ?: comma separated statements on a single line + inside_map_postfix bool // inside map++/-- postfix expr + inside_map_infix bool // inside map< fn counter name + hotcode_fn_names []string + hotcode_fpaths []string + embedded_files []ast.EmbeddedFile + sql_i int + sql_stmt_name string + sql_bind_name string + sql_idents []string + sql_idents_types []ast.Type + sql_left_type ast.Type + sql_table_name string + sql_table_typ ast.Type // the table type, used for generic types lookup + sql_fkey string + sql_parent_id string + sql_side SqlExprSide // left or right, to distinguish idents in `name == name` + sql_last_stmt_out_len int + strs_to_free0 []string // strings.Builder // strs_to_free []string // strings.Builder // tmp_arg_vars_to_free []string // autofree_pregen map[string]string @@ -316,12 +317,15 @@ pub: pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) GenOutput { mut module_built := '' - if pref_.build_mode == .build_module { + if pref_.build_mode == .build_module || pref_.is_o { for file in files { - if file.path.contains(pref_.path) + if pref_.build_mode == .build_module && file.path.contains(pref_.path) && file.mod.short_name == pref_.path.all_after_last(os.path_separator).trim_right(os.path_separator) { module_built = file.mod.name break + } else if pref_.is_o && file.path.contains(pref_.path) { + module_built = file.mod.name + break } } } @@ -381,7 +385,7 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) GenO variant_data_type: table.find_type('VariantData') is_cc_msvc: pref_.ccompiler == 'msvc' use_segfault_handler: pref_.should_use_segfault_handler() - static_modifier: if pref_.parallel_cc { 'static ' } else { '' } + static_modifier: if pref_.parallel_cc || pref_.is_o { 'static ' } else { '' } static_non_parallel: if !pref_.parallel_cc { 'static ' } else { '' } has_reflection: 'v.reflection' in table.modules has_debugger: 'v.debug' in table.modules @@ -503,6 +507,11 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) GenO global_g.array_get_types << g.array_get_types global_g.pcs << g.pcs global_g.json_types << g.json_types + for k, v in g.json_types_pos { + if k !in global_g.json_types_pos || global_g.json_types_pos[k] == token.Pos{} { + global_g.json_types_pos[k] = v + } + } global_g.hotcode_fn_names << g.hotcode_fn_names global_g.hotcode_fpaths << g.hotcode_fpaths global_g.test_function_names << g.test_function_names @@ -533,6 +542,10 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) GenO global_g.gen_jsons() global_g.dump_expr_definitions() // this uses global_g.get_str_fn, so it has to go before the below for loop + // Pre-register auto-str types for interface implementing types that need str() + // but don't have an explicit str() method. This must happen before final_gen_str + // processing so all transitive str types are included. + global_g.register_auto_str_for_interfaces() for i := 0; i < global_g.str_types.len; i++ { global_g.final_gen_str(global_g.str_types[i]) } @@ -764,7 +777,8 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) GenO } if g.waiter_fn_definitions.len > 0 { if g.pref.parallel_cc { - g.extern_out.write_string2('\n// V gowrappers waiter fns:\n', g.waiter_fn_definitions.bytestr()) + g.extern_out.write_string2('\n// V gowrappers waiter fns:\n', + g.waiter_fn_definitions.bytestr()) } helpers.write_string2('\n// V gowrappers waiter fns:\n', g.waiter_fn_definitions.str()) } @@ -897,6 +911,8 @@ fn cgen_process_one_file_cb(mut p pool.PoolProcessor, idx int, wid int) voidptr anon_fn: unsafe { nil } indent: -1 module_built: global_g.module_built + static_non_parallel: global_g.static_non_parallel + static_modifier: global_g.static_modifier timers: util.new_timers( should_print: global_g.timers_should_print label: 'cgen_process_one_file_cb idx: ${idx}, wid: ${wid}' @@ -914,7 +930,7 @@ fn cgen_process_one_file_cb(mut p pool.PoolProcessor, idx int, wid int) voidptr results_forward: global_g.results_forward done_options: global_g.done_options done_results: global_g.done_results - late_chan_types: global_g.late_chan_types + late_chan_types: global_g.late_chan_types is_autofree: global_g.pref.autofree obf_table: global_g.obf_table referenced_fns: global_g.referenced_fns @@ -923,8 +939,6 @@ fn cgen_process_one_file_cb(mut p pool.PoolProcessor, idx int, wid int) voidptr done_typedef_phase: global_g.done_typedef_phase array_typedefs: global_g.array_typedefs.clone() written_array_typedefs: global_g.written_array_typedefs - static_modifier: global_g.static_modifier - static_non_parallel: global_g.static_non_parallel has_reflection: 'v.reflection' in global_g.table.modules has_debugger: 'v.debug' in global_g.table.modules reflection_strings: global_g.reflection_strings @@ -1048,9 +1062,11 @@ pub fn (mut g Gen) init() { // int64_t etc; allow a fallback to for toolchains that do not ship . g.cheaders.writeln(get_inttypes_or_stdint_include_text('The C compiler can not find .${install_compiler_msg}')) if g.pref.os == .ios { - g.cheaders.writeln(get_guarded_include_text('', 'The C compiler can not find .${install_compiler_msg}')) // bool, true, false + g.cheaders.writeln(get_guarded_include_text('', + 'The C compiler can not find .${install_compiler_msg}')) // bool, true, false } - g.cheaders.writeln(get_guarded_include_text('', 'The C compiler can not find .${install_compiler_msg}')) // size_t, ptrdiff_t + g.cheaders.writeln(get_guarded_include_text('', + 'The C compiler can not find .${install_compiler_msg}')) // size_t, ptrdiff_t } } if g.pref.nofloat { @@ -1145,6 +1161,9 @@ pub fn (mut g Gen) init() { if g.pref.build_mode == .build_module { g.comptime_definitions.writeln('#define _VBUILDMODULE (1)') } + if g.pref.is_o { + g.comptime_definitions.writeln('#define _VOBJECTFILE (1)') + } if g.pref.is_livemain || g.pref.is_liveshared { g.generate_hotcode_reloading_declarations() } @@ -1159,6 +1178,10 @@ pub fn (mut g Gen) init() { // muttable.used_features.used_fns['exit'] = true } +fn (g &Gen) should_use_object_local_linkage(mod string) bool { + return g.pref.is_o && g.module_built != '' && mod != g.module_built +} + pub fn (mut g Gen) finish() { if g.pref.is_prof && g.pref.build_mode != .build_module { g.gen_vprint_profile_stats() @@ -1204,7 +1227,11 @@ pub fn (mut g Gen) write_typeof_functions() { if g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms { continue } - static_prefix := if g.pref.build_mode == .build_module { 'static ' } else { '' } + static_prefix := if g.pref.build_mode == .build_module || g.pref.is_o { + 'static ' + } else { + '' + } sum_info := sym.info as ast.SumType if sum_info.is_generic { continue @@ -1215,8 +1242,7 @@ pub fn (mut g Gen) write_typeof_functions() { g.writeln('\t\tif( sidx == _v_type_idx_${sym.cname}() ) return "${util.strip_main_name(sym.name)}";') for v in sum_info.variants { subtype := g.table.sym(v) - g.writeln('\tif( sidx == _v_type_idx_${g.get_sumtype_variant_name(v, - subtype)}() ) return "${util.strip_main_name(subtype.name)}";') + g.writeln('\tif( sidx == _v_type_idx_${g.get_sumtype_variant_name(v, subtype)}() ) return "${util.strip_main_name(subtype.name)}";') } g.writeln('\treturn "unknown ${util.strip_main_name(sym.name)}";') } else { @@ -1295,9 +1321,11 @@ pub fn (mut g Gen) write_typeof_functions() { g.writeln2('\treturn _S("unknown ${util.strip_main_name(sym.name)}");', '}') // Avoid duplicate symbol '_v_typeof_interface_idx_IError' when using -usecache if g.pref.build_mode != .build_module { - g.definitions.writeln('u32 v_typeof_interface_idx_${sym.cname}(u32 sidx);') - g.writeln2('', 'u32 v_typeof_interface_idx_${sym.cname}(u32 sidx) {') - if g.pref.parallel_cc { + interface_idx_static_prefix := if g.pref.is_o { 'static ' } else { '' } + g.definitions.writeln('${interface_idx_static_prefix}u32 v_typeof_interface_idx_${sym.cname}(u32 sidx);') + g.writeln2('', + '${interface_idx_static_prefix}u32 v_typeof_interface_idx_${sym.cname}(u32 sidx) {') + if g.pref.parallel_cc && interface_idx_static_prefix == '' { g.extern_out.writeln('extern u32 v_typeof_interface_idx_${sym.cname}(u32 sidx);') } for t in inter_info.types { @@ -3803,11 +3831,16 @@ fn (mut g Gen) gen_interface_to_interface_conversion(expr ast.Expr, expr_type as g.write(')') mut info := expr_type_sym.info as ast.Interface + right_info := to_sym.info as ast.Interface lock info.conversions { if to_type !in info.conversions { - left_variants := g.table.iface_types[expr_type_sym.name] - right_variants := g.table.iface_types[to_sym.name] - info.conversions[to_type] = left_variants.filter(it in right_variants) + // For conversion into an empty interface, all of the left's variants + // are valid (empty interfaces accept anything). + if right_info.methods.len == 0 && right_info.fields.len == 0 { + info.conversions[to_type] = info.types.clone() + } else { + info.conversions[to_type] = info.types.filter(it in right_info.types) + } } } expr_type_sym.info = info @@ -3852,8 +3885,8 @@ fn (mut g Gen) expr_with_array_element_upcast(expr ast.Expr, got_type ast.Type, } g.writeln('${expected_elem_styp} ${converted_tmp} = ${fname}(&(((${got_elem_styp}*)${source_tmp}_orig.data)[${index_tmp}]));') } else { - g.write_prepared_var(item_tmp, got_elem_type, got_elem_styp, source_tmp, index_tmp, - true, false) + g.write_prepared_var(item_tmp, got_elem_type, got_elem_styp, source_tmp, index_tmp, true, + false) g.write('${expected_elem_styp} ${converted_tmp} = ') g.expr_with_cast(ast.Ident{ name: item_tmp @@ -3917,8 +3950,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ if exp_sym.info.is_generic { fname = g.generic_fn_name(exp_sym.info.concrete_types, fname) } - g.call_cfn_for_casting_expr(fname, expr, expected_type, got_type, exp_styp, - true, false, got_styp) + g.call_cfn_for_casting_expr(fname, expr, expected_type, got_type, exp_styp, true, + false, got_styp) g.inside_cast_in_heap-- } else { got_styp := g.cc_type(got_type, true) @@ -3999,8 +4032,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ mut sumtype_got_styp := got_styp mut sumtype_got_is_fn := got_is_fn mut sumtype_got_is_ptr := got_is_ptr - nil_sumtype_variant := g.single_pointer_sumtype_nil_variant(unwrapped_expected_type, - expr, got_type) + nil_sumtype_variant := g.single_pointer_sumtype_nil_variant(unwrapped_expected_type, expr, + got_type) if nil_sumtype_variant != 0 { sumtype_got_type = nil_sumtype_variant sumtype_got_sym = g.table.sym(sumtype_got_type) @@ -4222,6 +4255,9 @@ fn (mut g Gen) asm_stmt(stmt ast.AsmStmt) { } g.writeln(' (') g.indent++ + if stmt.templates.len == 0 { + g.writeln('""') + } for template_tmp in stmt.templates { mut template := template_tmp g.write('"') @@ -4904,7 +4940,7 @@ fn (mut g Gen) expr(node_ ast.Expr) { g.write('(*') g.expr(node.expr) g.write(')') - } else if !handled_atomic_postfix && node.op == .question { + } else if node.op == .question { mut expr_type := ast.void_type if mut node.expr is ast.ComptimeSelector { if node.expr.field_expr is ast.SelectorExpr @@ -5400,14 +5436,12 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { name_type = g.type_resolver.typeof_field_type(resolved, node.field_name) } else { - name_type = g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(node.expr.expr, - g.resolve_typeof_expr_type(node.expr.expr, name_type)), - node.field_name) + name_type = g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(node.expr.expr, g.resolve_typeof_expr_type(node.expr.expr, + name_type)), node.field_name) } } else { - name_type = g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(node.expr.expr, - g.resolve_typeof_expr_type(node.expr.expr, name_type)), - node.field_name) + name_type = g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(node.expr.expr, g.resolve_typeof_expr_type(node.expr.expr, + name_type)), node.field_name) } // For mut params (auto_deref), strip pointer so that // typeof(mut_param).idx == typeof(val_param).idx @@ -5426,8 +5460,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } else if node.field_name in ['key_type', 'value_type', 'element_type'] { // `T.`, `typeof(expr).` mut name_type := node.name_type - name_type = g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(node.expr, - g.resolve_typeof_expr_type(node.expr, name_type)), node.field_name) + name_type = g.type_resolver.typeof_field_type(g.type_resolver.typeof_type(node.expr, g.resolve_typeof_expr_type(node.expr, + name_type)), node.field_name) g.write(int(name_type).str()) return } else if node.field_name == 'indirections' { @@ -5438,8 +5472,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { if resolved != 0 { name_type = resolved } else { - name_type = g.type_resolver.typeof_type(node.expr.expr, - g.resolve_typeof_expr_type(node.expr.expr, name_type)) + name_type = g.type_resolver.typeof_type(node.expr.expr, g.resolve_typeof_expr_type(node.expr.expr, + name_type)) } } else { name_type = g.type_resolver.typeof_type(node.expr.expr, g.resolve_typeof_expr_type(node.expr.expr, @@ -5961,8 +5995,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { || is_interface_smartcast_selector is_interface_smartcast_lhs := is_interface_smartcast_expr || is_interface_smartcast_selector exposed_interface_smartcast_type := if is_interface_smartcast_expr { - g.exposed_smartcast_type(smartcast_expr_var.orig_type, smartcast_expr_var.smartcasts.last(), - smartcast_expr_var.is_mut) + g.exposed_smartcast_type(smartcast_expr_var.orig_type, + smartcast_expr_var.smartcasts.last(), smartcast_expr_var.is_mut) } else { ast.void_type } @@ -6553,7 +6587,8 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) { g.writeln('->mtx);') } else { mtxs = g.new_tmp_var() - g.writeln2('uintptr_t _arr_${mtxs}[${node.lockeds.len}];', 'bool _isrlck_${mtxs}[${node.lockeds.len}];') + g.writeln2('uintptr_t _arr_${mtxs}[${node.lockeds.len}];', + 'bool _isrlck_${mtxs}[${node.lockeds.len}];') mut j := 0 for i, is_rlock in node.is_rlock { if !is_rlock { @@ -6585,7 +6620,8 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) { } g.writeln2('for (${ast.int_type_name} ${mtxs}=0; ${mtxs}<${node.lockeds.len}; ${mtxs}++) {', '\tif (${mtxs} && _arr_${mtxs}[${mtxs}] == _arr_${mtxs}[${mtxs}-1]) continue;') - g.writeln2('\tif (_isrlck_${mtxs}[${mtxs}])', '\t\tsync__RwMutex_rlock((sync__RwMutex*)_arr_${mtxs}[${mtxs}]);') + g.writeln2('\tif (_isrlck_${mtxs}[${mtxs}])', + '\t\tsync__RwMutex_rlock((sync__RwMutex*)_arr_${mtxs}[${mtxs}]);') g.writeln2('\telse', '\t\tsync__RwMutex_lock((sync__RwMutex*)_arr_${mtxs}[${mtxs}]);') g.writeln('}') } @@ -7248,7 +7284,8 @@ fn (mut g Gen) ident(node ast.Ident) { if has_resolved_var && resolved_var.smartcasts.len > 0 && !skip_smartcasts { mut smartcast_types := resolved_var.smartcasts.clone() if resolved_var.orig_type.has_flag(.option) { - unwrapped_option_type := g.unwrap_generic(g.recheck_concrete_type(resolved_var.typ.clear_option_and_result())) + unwrapped_option_type := + g.unwrap_generic(g.recheck_concrete_type(resolved_var.typ.clear_option_and_result())) if unwrapped_option_type != 0 && g.table.final_sym(unwrapped_option_type).kind == .function { smartcast_types = [unwrapped_option_type] @@ -7393,8 +7430,7 @@ fn (mut g Gen) ident(node ast.Ident) { } } else if !is_option_unwrap && obj_sym.kind in [.sum_type, .interface] { - g.write('${dot}_${g.get_sumtype_variant_name(typ, - cast_sym)}') + g.write('${dot}_${g.get_sumtype_variant_name(typ, cast_sym)}') } if i != 0 && unwrap_sumtype { g.write(')') @@ -7517,6 +7553,11 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) { } else if node.expr is ast.Ident && g.comptime.is_comptime_variant_var(node.expr) { g.expr_with_cast(ast.Expr(node.expr), g.type_resolver.get_ct_type_or_default('${g.comptime.comptime_for_variant_var}.typ', ast.void_type), effective_node_typ) + } else if node_typ_is_option + && g.table.unaliased_type(expr_type) == node_typ.clear_option_and_result() { + // Wrapping an already-correct sumtype/interface value in an option: + // ?SumType(value) where value is already SumType + g.expr_with_opt(node.expr, expr_type, node_typ) } else if node_typ_is_option { g.expr_with_opt(node.expr, expr_type, effective_node_typ) } else { @@ -8082,7 +8123,8 @@ fn (mut g Gen) branch_stmt(node ast.BranchStmt) { // continue or break if g.needs_scope_cleanup() && !g.is_builtin_mod { g.trace_autofree('// free before continue/break') - g.autofree_scope_vars_stop(node.pos.pos - 1, node.pos.line_nr, true, g.branch_parent_pos) + g.autofree_scope_vars_stop(node.pos.pos - 1, node.pos.line_nr, true, + g.branch_parent_pos) } g.writeln('${node.kind};') } @@ -8406,8 +8448,7 @@ fn (mut g Gen) return_stmt(node ast.Return) { } } else if exprs_len >= 1 { if ret_expr_types.len == 0 { - g.checker_bug('node.exprs.len == ${node.exprs.len} && node.types.len == 0', - node.pos) + g.checker_bug('node.exprs.len == ${node.exprs.len} && node.types.len == 0', node.pos) } // normal return return_sym := g.table.final_sym(type0) @@ -8644,7 +8685,8 @@ fn (mut g Gen) write_debug_calls_typeof_functions() { return } - g.writeln2('\t// we call these functions in debug mode so that the C compiler', '\t// does not optimize them and we can access them in the debugger.') + g.writeln2('\t// we call these functions in debug mode so that the C compiler', + '\t// does not optimize them and we can access them in the debugger.') for _, sym in g.table.type_symbols { if sym.kind == .sum_type { sum_info := sym.info as ast.SumType @@ -8955,7 +8997,8 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) { && (!g.pref.skip_unused || sym.idx in g.table.used_features.used_syms) { // generate field option types for fixed array of option struct/interface/sumtype // before the struct declaration - opt_fields := sym.info.fields.filter(g.table.final_sym(it.typ).kind == .array_fixed) + opt_fields := + sym.info.fields.filter(g.table.final_sym(it.typ).kind == .array_fixed) for opt_field in opt_fields { field_sym := g.table.final_sym(opt_field.typ) arr := field_sym.info as ast.ArrayFixed @@ -9361,7 +9404,8 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast } } else if g.inside_opt_or_res && return_is_option && g.inside_assign { g.write('builtin___option_ok(&(${cast_typ}[]) { ') - g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_option_and_result()) + g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, + return_type.clear_option_and_result()) g.writeln(' }, (${option_name}*)&${cvar_name}, sizeof(${cast_typ}));') g.indent-- return @@ -9401,7 +9445,8 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast } else { old_inside_opt_data := g.inside_opt_data g.inside_opt_data = true - g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_option_and_result()) + g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, + return_type.clear_option_and_result()) g.inside_opt_data = old_inside_opt_data } if is_array_fixed { @@ -9456,8 +9501,8 @@ fn (mut g Gen) or_block_on_value(var_name string, or_block ast.OrExpr, return_ty } stmts := or_block.stmts if stmts.len > 0 && stmts.last() is ast.ExprStmt && stmts.last().typ != ast.void_type { - g.gen_or_block_stmts(cvar_name, g.base_type(return_type), stmts, return_type, - false, or_block.scope, or_block.pos) + g.gen_or_block_stmts(cvar_name, g.base_type(return_type), stmts, return_type, false, + or_block.scope, or_block.pos) } else { g.stmts(stmts) if stmts.len > 0 { @@ -9616,7 +9661,8 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty } else if g.fn_decl.return_type.clear_option_and_result() == return_type.clear_option_and_result() { styp := g.styp(g.fn_decl.return_type).replace('*', '_ptr') err_obj := g.new_tmp_var() - g.writeln2('\t${styp} ${err_obj};', '\tmemcpy(&${err_obj}, &${cvar_name}, sizeof(_option));') + g.writeln2('\t${styp} ${err_obj};', + '\tmemcpy(&${err_obj}, &${cvar_name}, sizeof(_option));') g.writeln('\treturn ${err_obj};') } else { g.write('\treturn ') @@ -10003,6 +10049,13 @@ fn (mut g Gen) as_cast(node ast.AsCast) { defer { g.inside_selector_lhs = old_inside_selector_lhs } + // When expr_type and typ refer to the same sumtype (e.g. from assert autocasts + // after `assert a != none` where a is ?SumType), just emit the expression directly. + // The ident codegen already handles any needed smartcast/option unwrapping. + if expr_type_sym.kind == .sum_type && g.unwrap_generic(node.expr_type) == unwrapped_node_typ { + g.expr(node.expr) + return + } if mut expr_type_sym.info is ast.SumType { dot := if node.expr_type.is_ptr() { '->' } else { '.' } if node.expr.has_fn_call() && !g.is_cc_msvc { @@ -10059,11 +10112,14 @@ fn (mut g Gen) as_cast(node ast.AsCast) { g.write(')') mut info := expr_type_sym.info as ast.Interface + right_info := sym.info as ast.Interface lock info.conversions { if node.typ !in info.conversions { - left_variants := g.table.iface_types[expr_type_sym.name] - right_variants := g.table.iface_types[sym.name] - info.conversions[node.typ] = left_variants.filter(it in right_variants) + if right_info.methods.len == 0 && right_info.fields.len == 0 { + info.conversions[node.typ] = info.types.clone() + } else { + info.conversions[node.typ] = info.types.filter(it in right_info.types) + } } } expr_type_sym.info = info @@ -10134,12 +10190,13 @@ fn (mut g Gen) as_cast(node ast.AsCast) { } else if node.expr is ast.SelectorExpr { if node.expr.expr is ast.Ident && node.expr.typ.has_flag(.option) && !unwrapped_node_typ.has_flag(.option) { - g.unwrap_option_type(node.expr.typ, '${node.expr.expr.name}.${node.expr.field_name}', - node.expr.expr.is_auto_heap()) + g.unwrap_option_type(node.expr.typ, + '${node.expr.expr.name}.${node.expr.field_name}', node.expr.expr.is_auto_heap()) is_optional_ident_var = true } else if node.expr.expr is ast.SelectorExpr && node.expr.typ.has_flag(.option) { if node.expr.expr.expr is ast.Ident { - g.unwrap_option_type(node.expr.typ, '${node.expr.expr.expr.name}.${node.expr.expr.field_name}.${node.expr.field_name}', + g.unwrap_option_type(node.expr.typ, + '${node.expr.expr.expr.name}.${node.expr.expr.field_name}.${node.expr.field_name}', node.expr.expr.expr.is_auto_heap()) is_optional_ident_var = true } @@ -10196,6 +10253,37 @@ fn (mut g Gen) register_iface_return_types() { } } +// Pre-register auto-str functions for types that implement interfaces requiring str() +// but don't have an explicit str() method. This ensures the auto-str functions are +// generated during the main str_types processing loop, before interface_table() runs. +fn (mut g Gen) register_auto_str_for_interfaces() { + interfaces := g.table.type_symbols.filter(it.kind == .interface && it.info is ast.Interface) + for isym in interfaces { + inter_info := isym.info as ast.Interface + if inter_info.is_generic { + continue + } + if g.pref.skip_unused && isym.idx !in g.table.used_features.used_syms { + continue + } + inter_methods := inter_info.get_methods() + has_str := 'str' in inter_methods + if !has_str { + continue + } + for st in inter_info.types { + if st == ast.voidptr_type || st == ast.nil_type { + continue + } + st_sym := g.table.sym(st) + if st_sym.kind in [.struct, .enum, .sum_type, .array, .array_fixed, .map] + && !st_sym.has_method_with_generic_parent('str') { + g.get_str_fn(ast.mktyp(st)) + } + } + } +} + // Generates interface table and interface indexes fn (mut g Gen) interface_table() string { util.timing_start(@METHOD) @@ -10329,9 +10417,7 @@ fn (mut g Gen) interface_table() string { cast_struct.write_string('\t\t.${cname} = (${field_styp}*)((char*)x') if st != ast.voidptr_type && st != ast.nil_type { if st_sym.kind == .struct { - if _, embeds := g.table.find_field_from_embeds(st_sym, - field.name) - { + if _, embeds := g.table.find_field_from_embeds(st_sym, field.name) { mut typ_name := '' for i, embed in embeds { esym := g.table.sym(embed) @@ -10550,6 +10636,28 @@ return ${cast_shared_struct_str}; methods_struct.writeln('\t\t._method_${c_fn_name(method.name)} = (void*) ${method_call},') } } + // For interface methods not found in the type's explicit methods, + // check if auto-generated methods (like str) can fill the gap. + // The auto-str functions were already generated by register_auto_str_for_interfaces() + // before the main str_types processing loop. + if g.pref.build_mode != .build_module && st != ast.voidptr_type && st != ast.nil_type { + filled_methods := ordered_methods.filter(it.name in methodidx).map(it.name) + for imethod_name in inter_methods { + if imethod_name in filled_methods { + continue + } + if imethod_name == 'str' + && st_sym.kind in [.struct, .enum, .sum_type, .array, .array_fixed, .map] { + str_fn_name := g.get_str_fn(ast.mktyp(st)) + iwpostfix := '_Interface_${interface_name}_method_wrapper' + wrapper_name := '${cctype}_str${iwpostfix}' + methods_wrapper.writeln('static inline string ${wrapper_name}(${cctype}* x) {') + methods_wrapper.writeln('\treturn ${str_fn_name}(*x);') + methods_wrapper.writeln('}') + methods_struct.writeln('\t\t._method_str = (void*) ${wrapper_name},') + } + } + } if g.pref.build_mode != .build_module { methods_struct.writeln('\t},') @@ -10815,6 +10923,75 @@ fn (mut g Gen) check_noscan(elem_typ ast.Type) string { return '' } +fn (mut g Gen) write_heap_alloc(styp string, typ ast.Type) { + if g.pref.gc_mode == .vgc { + ptrmap, _ := g.vgc_ptrmap(typ) + if ptrmap.len > 0 { + g.write('HEAP_vgc(${styp}, (') + return + } + } + g.write('HEAP(${styp}, (') +} + +// write_heap_alloc_close writes the closing part of a HEAP_vgc or HEAP call. +fn (mut g Gen) write_heap_alloc_close(typ ast.Type) { + if g.pref.gc_mode == .vgc { + ptrmap, nptrs := g.vgc_ptrmap(typ) + if ptrmap.len > 0 { + g.write('), ${ptrmap}, ${nptrs})') + return + } + } + g.write('))') +} + +// vgc_ptrmap computes a precise pointer bitmap for simple VGC heap allocations. +fn (mut g Gen) vgc_ptrmap(typ ast.Type) (string, string) { + if g.pref.gc_mode != .vgc { + return '', '' + } + if !g.contains_ptr(typ) { + return '', '' + } + unwrapped := g.unwrap_generic(typ) + sym := g.table.final_sym(unwrapped) + if sym.kind != .struct { + return '', '' + } + info := sym.info as ast.Struct + styp := g.styp(unwrapped) + mut parts := []string{} + mut nptrs := 0 + for embed in info.embeds { + if g.contains_ptr(embed) { + return '', '' + } + } + for field in info.fields { + if field.typ.is_any_kind_of_pointer() || field.typ.is_ptr() { + fname := c_name(field.name) + parts << '(1ULL << (offsetof(${styp}, ${fname}) / sizeof(void*)))' + nptrs++ + } else { + fsym := g.table.final_sym(field.typ) + if fsym.kind in [.array, .map, .string] { + fname := c_name(field.name) + parts << '(1ULL << (offsetof(${styp}, ${fname}) / sizeof(void*)))' + nptrs++ + } else if fsym.kind in [.interface, .sum_type] { + return '', '' + } else if g.contains_ptr(field.typ) { + return '', '' + } + } + } + if parts.len == 0 { + return '', '' + } + return '(uint64_t)(${parts.join(' | ')})', '${nptrs}' +} + // vint2int rename `_vint_t` to `int` fn vint2int(name string) string { $if new_int ? && x64 { diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index ed413943c6..5c1dda29f0 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -361,7 +361,8 @@ static int v__vsnprintf(char *s, size_t n, const char *fmt, va_list ap) { if (n > 0) { const int written = _vsnprintf_s(s, n, _TRUNCATE, fmt, ap); if (written < 0) { - s[n - 1] = 0; + s[n - + 1] = 0; } } return needed; diff --git a/vlib/v/gen/c/cmain.v b/vlib/v/gen/c/cmain.v index 3427d1c7cd..48a13c3e8d 100644 --- a/vlib/v/gen/c/cmain.v +++ b/vlib/v/gen/c/cmain.v @@ -319,7 +319,8 @@ pub fn (mut g Gen) gen_c_main_for_tests() { if g.pref.show_asserts { g.writeln('\tmain__BenchedTests bt = main__start_testing(${all_tfuncs.len}, v_test_file);') } - g.writeln2('', '\tstruct _main__TestRunner_interface_methods _vtrunner = main__TestRunner_name_table[test_runner._typ];') + g.writeln2('', + '\tstruct _main__TestRunner_interface_methods _vtrunner = main__TestRunner_name_table[test_runner._typ];') g.writeln2('\tvoid * _vtobj = test_runner._object;', '') g.writeln('\tmain__VTestFileMetaInfo_free(test_runner.file_test_info);') g.writeln('\t*(test_runner.file_test_info) = main__vtest_new_filemetainfo(v_test_file, ${all_tfuncs.len});') diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index 4174e17232..7e75800996 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -145,7 +145,7 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) { } ret_sym := g.table.sym(g.fn_decl.return_type) - fn_name := g.fn_decl.name.replace('.', '__') + node.pos.pos.str() + fn_name := g.fn_decl.name.replace('.', '__').to_lower() + node.pos.pos.str() is_x_vweb := ret_sym.cname == 'x__vweb__Result' is_veb := ret_sym.cname == 'veb__Result' @@ -533,6 +533,15 @@ fn (g &Gen) can_preserve_comptime_if_condition_in_c(cond ast.Expr) bool { ast.BoolLiteral { return true } + ast.Ident { + // CPU architecture and compiler conditions are safe to preserve as C + // preprocessor checks because they are mutually exclusive categories + // derived from real compiler intrinsics (see cheaders.v). + // This is important for Android builds where one C file is compiled + // by the NDK for multiple architectures (arm64, armv7a, x86, x86_64). + return cond.name in ast.valid_comptime_if_platforms + || cond.name in ast.valid_comptime_if_compilers + } ast.ParExpr { return g.can_preserve_comptime_if_condition_in_c(cond.expr) } @@ -619,9 +628,14 @@ fn (mut g Gen) comptime_if(node ast.IfExpr) { // `g.table.comptime_is_true` are the branch condition results set by `checker` is_true = comptime_is_true } else { - g.error('checker error: condition result idx string not found => [${idx_str}]', - node.branches[i].cond.pos()) - return + // No checker data found for this key. This can happen when: + // 1. The markused walker spuriously registers generic instantiations + // that the checker never evaluated (e.g. from dead comptime branches). + // 2. Type alias resolution causes key mismatches. + // Default all branches to false (#if 0) since the function body + // is either dead code or will be generated correctly by another + // instantiation with matching types. + is_true = ast.ComptTimeCondResult{} } if !node.has_else || i < node.branches.len - 1 { if i == 0 { @@ -1304,9 +1318,9 @@ fn (mut g Gen) comptime_match(node ast.MatchExpr) { // `g.table.comptime_is_true` are the branch condition results set by `checker` is_true = comptime_is_true } else { - g.error('checker error: match branch result idx string not found => [${idx_str}]', - branch.pos) - return + // No checker data - spurious instantiation or alias mismatch. + // Default all branches to false (#if 0). + is_true = ast.ComptTimeCondResult{} } if !branch.is_else { if i == 0 { diff --git a/vlib/v/gen/c/consts_and_globals.v b/vlib/v/gen/c/consts_and_globals.v index 80e3838387..6c9eee1d3a 100644 --- a/vlib/v/gen/c/consts_and_globals.v +++ b/vlib/v/gen/c/consts_and_globals.v @@ -117,7 +117,8 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) { if field.is_simple_define_const() { // "Simple" expressions are not going to need multiple statements, // only the ones which are inited later, so it's safe to use expr_string - g.const_decl_simple_define(field.mod, field.name, const_name, g.expr_string(field_expr)) + g.const_decl_simple_define(field.mod, field.name, const_name, + g.expr_string(field_expr)) } else if field.expr is ast.CastExpr { if field.expr.expr is ast.ArrayInit { if field.expr.expr.is_fixed && g.pref.build_mode != .build_module { @@ -350,8 +351,7 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, cname string, expr if expr_sym.kind == .function { // allow for: `const xyz = abc`, where `abc` is `fn abc() {}` func := (expr_sym.info as ast.FnType).func - def = g.fn_var_signature(ast.void_type, func.return_type, func.params.map(it.typ), - cname) + def = g.fn_var_signature(ast.void_type, func.return_type, func.params.map(it.typ), cname) } init_str := init.str().trim_right('\n') g.global_const_defs[util.no_dots(name)] = GlobalConstDef{ @@ -398,8 +398,7 @@ fn (mut g Gen) const_decl_init_later_msvc_string_fixed_array(mod string, name st init.writeln(g.expr_string_surround('\tmemcpy(${cname}[${i}], ', elem_expr, ', sizeof(${elem_styp}));')) } else { - init.writeln(g.expr_string_surround('\t${cname}[${i}] = ', elem_expr, - ';')) + init.writeln(g.expr_string_surround('\t${cname}[${i}] = ', elem_expr, ';')) } } else { init.writeln(g.expr_string_surround('\t${cname}[${i}] = ', elem_expr, ';')) diff --git a/vlib/v/gen/c/coutput_test.v b/vlib/v/gen/c/coutput_test.v index 46d2ac5cf0..62a9e2cfae 100644 --- a/vlib/v/gen/c/coutput_test.v +++ b/vlib/v/gen/c/coutput_test.v @@ -45,7 +45,8 @@ fn test_out_files() { mut total_oks_panic := 0 mut total_skips := 0 paths := vtest.filter_vtest_only(tests, basepath: testdata_folder).sorted() - println(term.colorize(term.green, '> testing whether ${paths.len} .out files in ${local_tdata_path} match:')) + println(term.colorize(term.green, + '> testing whether ${paths.len} .out files in ${local_tdata_path} match:')) for out_path in paths { basename, path, relpath, out_relpath := target2paths(out_path, '.out') if should_skip(relpath) { @@ -134,7 +135,8 @@ fn test_c_must_have_files() { mut total_oks_panic := 0 mut total_skips := 0 mut failed_descriptions := []string{cap: paths.len} - println(term.colorize(term.green, '> testing whether all line patterns in ${paths.len} `.c.must_have` files in ${local_tdata_path} match:')) + println(term.colorize(term.green, + '> testing whether all line patterns in ${paths.len} `.c.must_have` files in ${local_tdata_path} match:')) for must_have_path in paths { basename, path, relpath, must_have_relpath := target2paths(must_have_path, '.c.must_have') if should_skip(relpath) { diff --git a/vlib/v/gen/c/coverage.v b/vlib/v/gen/c/coverage.v index f4a9d51a68..8a8980e2b7 100644 --- a/vlib/v/gen/c/coverage.v +++ b/vlib/v/gen/c/coverage.v @@ -53,7 +53,8 @@ fn (mut g Gen) write_coverage_stats() { if !os.exists(coverage_meta_folder) { os.mkdir_all(coverage_meta_folder) or {} } - counter_ulid := rand.ulid() // rand.ulid provides a hash+timestamp, so that a collision is extremely unlikely + counter_ulid := + rand.ulid() // rand.ulid provides a hash+timestamp, so that a collision is extremely unlikely g.cov_declarations.writeln('') g.cov_declarations.writeln('void vprint_coverage_stats() {') g.cov_declarations.writeln('\tchar cov_filename[2048];') diff --git a/vlib/v/gen/c/custom_start_freestanding_test.v b/vlib/v/gen/c/custom_start_freestanding_test.v index 89b1fd2308..26e4c18519 100644 --- a/vlib/v/gen/c/custom_start_freestanding_test.v +++ b/vlib/v/gen/c/custom_start_freestanding_test.v @@ -11,10 +11,10 @@ fn generate_bare_output(main_src string) string { mut pref_ := pref.new_preferences() pref_.is_bare = true builtin_src := 'module builtin\n\nasm amd64 {\n\t.globl _start\n\t_start:\n\tret\n}\n' - mut builtin_file := parser.parse_text(builtin_src, os.join_path('/virtual', 'vlib', - 'builtin', 'linux_bare', 'linux_syscalls.v'), mut table, .skip_comments, pref_) - mut main_file := parser.parse_text(main_src, os.join_path('/virtual', 'main.v'), mut - table, .skip_comments, pref_) + mut builtin_file := parser.parse_text(builtin_src, os.join_path('/virtual', 'vlib', 'builtin', + 'linux_bare', 'linux_syscalls.v'), mut table, .skip_comments, pref_) + mut main_file := parser.parse_text(main_src, os.join_path('/virtual', 'main.v'), mut table, + .skip_comments, pref_) mut chk := checker.new_checker(table, pref_) chk.check(mut builtin_file) chk.check(mut main_file) @@ -23,7 +23,8 @@ fn generate_bare_output(main_src string) string { } fn test_linux_bare_startup_stub_is_suppressed_for_exported_start() { - generated := generate_bare_output("module main\n\n@[export: '_start']\nfn start() {}\n\nfn main() {}\n") + generated := + generate_bare_output("module main\n\n@[export: '_start']\nfn start() {}\n\nfn main() {}\n") assert !generated.contains('.globl _start') assert generated.contains('// export alias: _start -> main__start') assert generated.contains('void _start(void) {') diff --git a/vlib/v/gen/c/dumpexpr.v b/vlib/v/gen/c/dumpexpr.v index 8a4ba3bcb1..1f773da50e 100644 --- a/vlib/v/gen/c/dumpexpr.v +++ b/vlib/v/gen/c/dumpexpr.v @@ -19,8 +19,7 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { resolved_call_type := g.resolve_return_type(node.expr) if resolved_call_type != ast.void_type { expr_type = g.unwrap_generic(resolved_call_type) - name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', - '') + name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', '') } } } @@ -29,13 +28,12 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { resolved_postfix_type := g.resolve_return_type(node.expr.expr) if resolved_postfix_type != ast.void_type { expr_type = g.unwrap_generic(resolved_postfix_type) - name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', - '') + name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', '') } } } - resolved_expr_type := g.unwrap_generic(g.type_resolver.get_type_or_default(node.expr, - expr_type)) + resolved_expr_type := + g.unwrap_generic(g.type_resolver.get_type_or_default(node.expr, expr_type)) if resolved_expr_type != 0 && resolved_expr_type != expr_type { expr_type = resolved_expr_type name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', '') @@ -89,12 +87,11 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { } } } - name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', - '') + name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', '') } } else if node.expr is ast.CallExpr { - name = g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*', - '') + name = + g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*', '') } else { expr_type = g.unwrap_generic(g.type_resolver.get_type_or_default(ast.Expr(node.expr), expr_type)) @@ -151,8 +148,7 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { expr_type = g.type_resolver.get_type(ast.Expr(node.expr)) break } - name = g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*', - '') + name = g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*', '') } else if node.expr is ast.SelectorExpr && node.expr.expr is ast.Ident && (node.expr.expr as ast.Ident).ct_expr { ct_expr_type := g.comptime_selector_type(node.expr) @@ -166,8 +162,8 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { if ct_sym.kind !in [.sum_type, .interface] || node_sym.kind in [.sum_type, .interface] || expr_type.has_option_or_result() { expr_type = ct_expr_type - name = g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*', - '') + name = + g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*', '') } } @@ -192,8 +188,7 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { } else { current_fn_ident_type } - name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', - '') + name = g.styp(expr_type.clear_flags(.shared_f, .result)).replace('*', '') } } if expr_type.is_ptr() && expr_type.has_flag(.option) { @@ -202,7 +197,8 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { expr_type = scope_var.typ // For mut option params, the type is ?&T. Strip the inner pointer // from the name since __ptr is appended separately from is_ptr(). - mut cleared_typ := expr_type.clear_flags(.shared_f, .result, .option_mut_param_t) + mut cleared_typ := expr_type.clear_flags(.shared_f, .result, + .option_mut_param_t) if cleared_typ.has_flag(.option) { inner := cleared_typ.clear_option_and_result() if inner.is_ptr() { @@ -242,9 +238,10 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { if expr_type.has_flag(.option_mut_param_t) { g.write('*') } - if node.expr is ast.Ident && node.expr.obj is ast.Var && node.expr.obj.is_auto_deref - && !expr_type.is_ptr() { - g.write('*') + if node.expr is ast.Ident && node.expr.obj is ast.Var { + if node.expr.obj.is_auto_deref && !expr_type.is_ptr() { + g.write('*') + } } for { if node.expr is ast.Ident { @@ -368,7 +365,8 @@ fn (mut g Gen) dump_expr_definitions() { int_str := g.get_str_fn(ast.int_type) surrounder.add('\tstring sline = ${int_str}(line);', '\tbuiltin__string_free(&sline);') if dump_sym.kind == .function && !is_option { - surrounder.add('\tstring value = ${to_string_fn_name}();', '\tbuiltin__string_free(&value);') + surrounder.add('\tstring value = ${to_string_fn_name}();', + '\tbuiltin__string_free(&value);') } else if dump_sym.kind == .none { surrounder.add('\tstring value = _S("none");', '\tbuiltin__string_free(&value);') } else if is_ptr { diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 96a33fa42c..5099637765 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -210,6 +210,64 @@ fn (g &Gen) generic_file_fn_by_fkey(fkey string) ?ast.FnDecl { return none } +// find_all_receiver_concrete_types finds all concrete type instantiations +// of the receiver's generic type by looking up GenericInst types in the type table. +// find_all_receiver_concrete_types finds all concrete type instantiations +// of the receiver's generic type by examining registered concrete types of +// sibling methods on the same receiver that have complete type sets. +fn (g &Gen) find_all_receiver_concrete_types(node ast.FnDecl, receiver_generic_count int) [][]ast.Type { + receiver_typ_int := int(node.receiver.typ) + prefix := '${receiver_typ_int}.' + mut result := [][]ast.Type{} + mut seen := map[string]bool{} + // Look through all registered method generic types on this receiver + for fkey, type_sets in g.table.fn_generic_types { + if !fkey.starts_with(prefix) { + continue + } + for concrete_types in type_sets { + if concrete_types.any(it.has_flag(.generic)) { + continue + } + // We need sets that have both receiver + method generics + if concrete_types.len > receiver_generic_count { + receiver_part := concrete_types[..receiver_generic_count] + key := receiver_part.str() + if key !in seen { + seen[key] = true + result << receiver_part + } + } + } + } + // Fallback: if no sibling methods have complete type sets, look for + // concrete instantiations of the receiver type in the type table + // (GenericInst types whose parent matches the receiver). + if result.len == 0 { + receiver_parent := node.receiver.typ.set_nr_muls(0).set_flag(.generic) + receiver_parent_sym := g.table.sym(receiver_parent) + receiver_base_name := receiver_parent_sym.name.all_before('<') + for _, sym in g.table.type_symbols { + if sym.info is ast.Struct { + if sym.info.concrete_types.len == receiver_generic_count + && (sym.info.parent_type == receiver_parent + || (sym.info.parent_type != 0 + && g.table.sym(sym.info.parent_type).name.all_before('<') == receiver_base_name)) { + cts := sym.info.concrete_types + if !cts.any(it.has_flag(.generic)) { + key := cts.str() + if key !in seen { + seen[key] = true + result << cts.clone() + } + } + } + } + } + } + return result +} + fn (mut g Gen) effective_fn_generic_names(node ast.FnDecl) []string { if node.generic_names.len > 0 { return node.generic_names.clone() @@ -249,6 +307,28 @@ fn (mut g Gen) effective_fn_generic_names(node ast.FnDecl) []string { return []string{} } +// method_concrete_types_for_name returns the concrete types for the generic +// name suffix in c_fn_name. For methods where cur_concrete_types includes +// merged receiver + method types that were synthesized in gen_fn_decl +// (because the checker only registered method-own types), strip the +// receiver's types from the suffix since they're already encoded in the +// receiver type name (e.g., Foo_T_string). +fn (mut g Gen) method_concrete_types_for_name(node &ast.FnDecl) []ast.Type { + if !node.is_method || g.cur_concrete_types.len == 0 { + return g.cur_concrete_types + } + receiver_generic_names := g.table.generic_type_names(node.receiver.typ) + if receiver_generic_names.len == 0 || g.cur_concrete_types.len <= receiver_generic_names.len { + return g.cur_concrete_types + } + // Check if the checker registered incomplete types (method-only) or + // complete types (receiver + method). If the registered types are + // already complete, don't strip anything. + // Always use the full concrete types (receiver + method). The call site + // is responsible for generating matching names via method_name_concrete_types. + return g.cur_concrete_types +} + fn (mut g Gen) resolve_current_fn_generic_type(typ ast.Type) ast.Type { if typ == 0 { return 0 @@ -294,7 +374,8 @@ fn (mut g Gen) receiver_concrete_types_for_type(typ ast.Type) []ast.Type { fn (mut g Gen) method_receiver_only_specialization_types(method ast.Fn, concrete_receiver_type ast.Type) []ast.Type { mut receiver_concrete_types := g.receiver_concrete_types_for_type(concrete_receiver_type) if receiver_concrete_types.len == 0 { - receiver_concrete_types = g.receiver_concrete_types_for_type(g.recheck_concrete_type(concrete_receiver_type)) + receiver_concrete_types = + g.receiver_concrete_types_for_type(g.recheck_concrete_type(concrete_receiver_type)) } mut parent_method := ast.Fn{} _, parent_method = g.receiver_generic_call_context(concrete_receiver_type, method.name) @@ -338,7 +419,8 @@ fn (mut g Gen) method_receiver_only_specialization_types(method ast.Fn, concrete } fn (mut g Gen) specialized_method_name_from_receiver(method ast.Fn, concrete_receiver_type ast.Type, base_name string) string { - specialization_types := g.method_receiver_only_specialization_types(method, concrete_receiver_type) + specialization_types := g.method_receiver_only_specialization_types(method, + concrete_receiver_type) if specialization_types.len == 0 { return base_name } @@ -408,7 +490,9 @@ fn (mut g Gen) method_name_concrete_types(full_fkey string, concrete_types []ast && normalized_candidate.len + normalized_receiver_types.len == normalized_concrete_types.len && normalized_concrete_types[..normalized_receiver_types.len] == normalized_receiver_types && normalized_concrete_types[normalized_receiver_types.len..] == normalized_candidate { - return normalized_candidate + // Return the full types (receiver + method) to match the function + // definition which always uses complete types. + return normalized_concrete_types } } return normalized_concrete_types @@ -488,7 +572,8 @@ fn (mut g Gen) is_used_by_main(node ast.FnDecl) bool { is_used_by_main = true } if !is_used_by_main && node.generic_names.len == 0 { - recovered_generic_names, recovered_concrete_types := g.recover_specialized_generic_context_for(node.name) + recovered_generic_names, recovered_concrete_types := + g.recover_specialized_generic_context_for(node.name) if recovered_generic_names.len > 0 && recovered_generic_names.len == recovered_concrete_types.len { for generic_fn in g.file.generic_fns { @@ -715,6 +800,29 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) { $if trace_post_process_generic_fns ? { eprintln('>> gen_fn_decl, nkey: ${nkey} | generic_types_by_fn: ${generic_types_by_fn}') } + // For methods on generic structs that also have their own generic params + // (e.g. fn (f Foo[T]) method[U]()), the checker may register only the + // method's own concrete types (e.g. [U=f32]). We need to prepend the + // receiver's concrete types (e.g. [T=string]) to get the full set + // so that `unwrap_generic` can resolve both T and U in the function body. + // The receiver's concrete types come from the instantiation context stored + // in the fn_generic_types table for sibling methods that have complete sets, + // or from the type table's concrete instantiations. + // For methods on generic structs that also have their own generic params + // (e.g. fn (f Foo[T]) method[U]()), the checker may register only the + // method's own concrete types (e.g. [U=f32]). We need to prepend the + // receiver's concrete types (e.g. [T=string]) to get the full set + // so that `unwrap_generic` can resolve both T and U in the function body. + mut receiver_generic_names := []string{} + mut all_receiver_cts := [][]ast.Type{} + if node.is_method { + receiver_generic_names = g.table.generic_type_names(node.receiver.typ) + if receiver_generic_names.len > 0 + && receiver_generic_names.len < effective_generic_names.len { + all_receiver_cts = g.find_all_receiver_concrete_types(node, + receiver_generic_names.len) + } + } mut generated_fn_names := map[string]bool{} for concrete_types in generic_types_by_fn { if g.pref.is_verbose { @@ -725,18 +833,30 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) { if concrete_types.any(it.has_flag(.generic)) { continue } - // Skip incomplete concrete type sets (e.g. only receiver generics - // resolved but method generics missing) - if concrete_types.len != effective_generic_names.len { - continue + if concrete_types.len == effective_generic_names.len { + // Already complete (includes both receiver and method generics) + fn_name := g.generic_fn_name(concrete_types, nkey) + if fn_name in generated_fn_names { + continue + } + generated_fn_names[fn_name] = true + g.cur_concrete_types = concrete_types.clone() + g.gen_fn_decl(node, skip) + } else if concrete_types.len < effective_generic_names.len && all_receiver_cts.len > 0 + && concrete_types.len + receiver_generic_names.len == effective_generic_names.len { + // Incomplete: only method generics, cross with all receiver instantiations + for receiver_cts in all_receiver_cts { + mut merged := receiver_cts.clone() + merged << concrete_types + fn_name := g.generic_fn_name(merged, nkey) + if fn_name in generated_fn_names { + continue + } + generated_fn_names[fn_name] = true + g.cur_concrete_types = merged + g.gen_fn_decl(node, skip) + } } - fn_name := g.generic_fn_name(concrete_types, nkey) - if fn_name in generated_fn_names { - continue - } - generated_fn_names[fn_name] = true - g.cur_concrete_types = concrete_types - g.gen_fn_decl(node, skip) } g.cur_concrete_types = [] return @@ -765,7 +885,8 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) { if node.generic_names.len == 0 && g.cur_concrete_types.len == 0 && (!node.is_method || node.receiver.typ.has_flag(.generic) || node.name.contains('_T_')) { - recovered_generic_names, recovered_concrete_types := g.recover_specialized_generic_context_for(node.name) + recovered_generic_names, recovered_concrete_types := + g.recover_specialized_generic_context_for(node.name) if recovered_generic_names.len > 0 && recovered_generic_names.len == recovered_concrete_types.len { effective_cur_fn = ast.FnDecl{ @@ -837,8 +958,8 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) { g.definitions.write_string('VV_LOC ${trace_fn_ret_type} ${c_name(trace_fn)}(') if call_fn.is_fn_var { - sig := g.fn_var_signature(ast.void_type, call_fn.func.return_type, call_fn.func.params.map(it.typ), - call_fn.name) + sig := g.fn_var_signature(ast.void_type, call_fn.func.return_type, + call_fn.func.params.map(it.typ), call_fn.name) g.write(sig) g.definitions.write_string(sig) } else { @@ -943,7 +1064,11 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) { // as a temp solution generic functions are marked static // when -usecache is enabled to fix duplicate symbols with clang // TODO: implement a better sulution - visibility_kw := if g.cur_concrete_types.len > 0 + needs_object_local_linkage := g.should_use_object_local_linkage(node.mod) + && (node.is_pub || g.pref.is_debug) + visibility_kw := if needs_object_local_linkage { + 'static ' + } else if g.cur_concrete_types.len > 0 && (g.pref.build_mode == .build_module || g.pref.use_cache) { 'static ' } else { @@ -1147,7 +1272,7 @@ fn (mut g Gen) c_fn_name(node &ast.FnDecl) string { } if node.generic_names.len > 0 { - name = g.generic_fn_name(g.cur_concrete_types, name) + name = g.generic_fn_name(g.method_concrete_types_for_name(node), name) name = name.replace_each(c_fn_name_escape_seq) } @@ -1299,6 +1424,17 @@ fn (mut g Gen) closure_inherited_var_type(node ast.AnonFn, var ast.Param) ast.Ty return g.unwrap_generic(g.recheck_concrete_type(var.typ)) } +fn (g &Gen) variadic_voidptr_promoted_type(typ ast.Type) ast.Type { + base_typ := g.table.unaliased_type(typ).clear_flags() + if base_typ in ast.int_promoted_type_idxs || base_typ == ast.bool_type { + return ast.int_type + } + if base_typ == ast.f32_type { + return ast.f64_type + } + return ast.no_type +} + fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) { is_amp := g.is_amp g.is_amp = false @@ -1364,10 +1500,12 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) { g.writeln('.${var_name} = builtin__string_clone(${var_name}),') } else { mut is_auto_heap := false + mut is_auto_deref_capture := false mut field_name := '' if obj := node.decl.scope.parent.find(var.name) { if obj is ast.Var { is_auto_heap = !obj.is_stack_obj && obj.is_auto_heap + is_auto_deref_capture = obj.is_auto_deref && !var.is_mut && is_ptr if obj.smartcasts.len > 0 { if g.table.type_kind(obj.typ) == .sum_type { cast_sym := g.table.sym(obj.smartcasts.last()) @@ -1376,7 +1514,7 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) { } } } - if (is_auto_heap && !is_ptr) || field_name != '' { + if (is_auto_heap && !is_ptr) || is_auto_deref_capture || field_name != '' { g.writeln('.${var_name} = *${var_name}${field_name},') } else { g.writeln('.${var_name} = ${var_name},') @@ -1407,11 +1545,16 @@ fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) { // When the variable is auto-heap promoted, the closure struct // stores the dereferenced value (the init code does `*var`), // so strip one pointer level from the field type. + // Similarly, when a `mut` parameter (is_auto_deref) is captured + // without `mut`, the closure stores the dereferenced value. if node.decl.scope != unsafe { nil } && node.decl.scope.parent != unsafe { nil } { if scope_var := node.decl.scope.parent.find_var(var.name) { if scope_var.is_auto_heap && !scope_var.is_stack_obj && resolved_var_typ.is_ptr() { resolved_var_typ = resolved_var_typ.deref() + } else if scope_var.is_auto_deref && !var.is_mut + && resolved_var_typ.is_ptr() { + resolved_var_typ = resolved_var_typ.deref() } } } @@ -1420,7 +1563,8 @@ fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) { g.definitions.writeln('\t${g.mut_closure_fixed_array_field_styp(var)} ${c_name(var.name)};') } else if var_sym.info is ast.FnType { resolved_ret_type := g.recheck_concrete_type(var_sym.info.func.return_type) - resolved_param_types := var_sym.info.func.params.map(g.recheck_concrete_type(it.typ)) + resolved_param_types := + var_sym.info.func.params.map(g.recheck_concrete_type(it.typ)) mut sig := g.fn_var_signature(resolved_var_typ, resolved_ret_type, resolved_param_types, c_name(var.name)) g.definitions.writeln('\t' + sig + ';') @@ -1602,8 +1746,8 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { if node.left is ast.AnonFn { if node.left.inherited_vars.len > 0 { tmp_anon_fn_var = g.new_tmp_var() - fn_type := g.fn_var_signature(ast.void_type, node.left.decl.return_type, node.left.decl.params.map(it.typ), - tmp_anon_fn_var) + fn_type := g.fn_var_signature(ast.void_type, node.left.decl.return_type, + node.left.decl.params.map(it.typ), tmp_anon_fn_var) line := g.go_before_last_stmt().trim_space() g.empty_line = true g.write('${fn_type} = ') @@ -1635,8 +1779,8 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { left_typ := g.table.value_type(node.left.left_type) tmp_res := g.new_tmp_var() fn_sym := g.table.sym(left_typ).info as ast.FnType - fn_type := g.fn_var_signature(ast.void_type, fn_sym.func.return_type, fn_sym.func.params.map(it.typ), - tmp_res) + fn_type := g.fn_var_signature(ast.void_type, fn_sym.func.return_type, + fn_sym.func.params.map(it.typ), tmp_res) old_is_fn_index_call := g.is_fn_index_call g.is_fn_index_call = true @@ -1748,6 +1892,21 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { ret_typ = g.unwrap_generic(ret_sym.info.elem_type).derive(unwrapped_ret_typ) } } + } else if g.cur_fn != unsafe { nil } && g.cur_fn.is_method + && g.cur_fn.receiver.typ.has_flag(.generic) && g.cur_concrete_types.len > 0 { + // unwrap_generic failed because cur_fn.generic_names is empty + // (generics come from the receiver, not the method itself). + // Use the receiver's generic type names to resolve. + receiver_generic_names := g.table.generic_type_names(g.cur_fn.receiver.typ) + if receiver_generic_names.len == g.cur_concrete_types.len { + if gen_type := g.table.convert_generic_type(node.return_type_generic, + receiver_generic_names, g.cur_concrete_types) + { + if !gen_type.has_flag(.generic) { + ret_typ = gen_type + } + } + } } } effective_return_type = ret_typ @@ -1805,7 +1964,8 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { } else if !g.inside_curry_call { if !g.inside_const_opt_or_res { if g.assign_ct_type[node.pos.pos] != 0 && node.or_block.kind != .absent { - unwrapped_styp = g.styp(g.assign_ct_type[node.pos.pos].derive(effective_return_type).clear_option_and_result()) + unwrapped_styp = + g.styp(g.assign_ct_type[node.pos.pos].derive(effective_return_type).clear_option_and_result()) } if g.table.sym(effective_return_type).kind == .array_fixed && unwrapped_styp.starts_with('_v_') { @@ -1916,7 +2076,8 @@ fn (mut g Gen) gen_map_method_call(node ast.CallExpr, left_type ast.Type, left_s // In generic contexts, the left type may resolve to the base // `map` struct rather than a concrete `map[K]V`. Resolve the // key type from the argument expression instead. - arg_type := g.unwrap_generic(g.resolved_expr_type(node.args[0].expr, node.args[0].typ)) + arg_type := g.unwrap_generic(g.resolved_expr_type(node.args[0].expr, + node.args[0].typ)) g.styp(arg_type) } g.write('builtin__map_delete(') @@ -2120,12 +2281,16 @@ fn (mut g Gen) gen_fixed_array_method_call(node ast.CallExpr, left_type ast.Type return true } -fn (mut g Gen) gen_to_str_method_call(node ast.CallExpr) bool { - mut rec_type := node.receiver_type +fn (mut g Gen) gen_to_str_method_call(node ast.CallExpr, unwrapped_rec_type ast.Type) bool { + left_node := node.left + mut rec_type := g.unwrap_generic(g.type_resolver.get_type_or_default(left_node, + left_node.type())) + if rec_type in [ast.void_type, ast.no_type] { + rec_type = unwrapped_rec_type + } if rec_type.has_flag(.shared_f) { rec_type = rec_type.clear_flag(.shared_f).set_nr_muls(0) } - left_node := node.left if left_node is ast.ComptimeSelector { if left_node.typ_key != '' { rec_type = g.type_resolver.get_ct_type_or_default(left_node.typ_key, rec_type) @@ -2185,14 +2350,36 @@ fn (mut g Gen) gen_to_str_method_call(node ast.CallExpr) bool { if g.cur_fn != unsafe { nil } && g.cur_concrete_types.len > 0 { resolved_rec_type := g.resolved_expr_type(left_node, node.left_type) if resolved_rec_type != 0 && resolved_rec_type != ast.void_type { - g.gen_expr_to_string(left_node, g.unwrap_generic(g.recheck_concrete_type(resolved_rec_type))) + g.gen_expr_to_string(left_node, + g.unwrap_generic(g.recheck_concrete_type(resolved_rec_type))) return true } } + rec_sym := g.table.sym(rec_type) + if g.alias_uses_parent_str(rec_sym) { + rec_type = (rec_sym.info as ast.Alias).parent_type + } g.get_str_fn(rec_type) return false } +fn (g &Gen) alias_uses_parent_str(sym ast.TypeSymbol) bool { + if sym.info !is ast.Alias || sym.has_method('str') { + return false + } + alias_info := sym.info as ast.Alias + parent_sym := g.table.sym(alias_info.parent_type) + return parent_sym.is_string() || parent_sym.is_number() + || parent_sym.kind in [.bool, .char, .byteptr, .charptr, .voidptr, .map] +} + +fn (g &Gen) alias_keeps_parent_method_dispatch(sym ast.TypeSymbol, method_name string, kind ast.CallKind) bool { + if sym.info !is ast.Alias || sym.has_method(method_name) { + return false + } + return kind != .str || g.alias_uses_parent_str(sym) +} + // resolve_return_type resolves the generic return type of CallExpr fn (mut g Gen) resolve_return_type(node ast.CallExpr) ast.Type { if node.is_method { @@ -2320,7 +2507,8 @@ fn (mut g Gen) resolve_return_type(node ast.CallExpr) ast.Type { // g.cur_concrete_types and override if different. if arg.expr is ast.Ident && arg.expr.obj is ast.Var && (arg.expr.obj as ast.Var).ct_type_var == .generic_param { - mut resolved := g.resolve_current_fn_generic_param_type(arg.expr.name) + mut resolved := + g.resolve_current_fn_generic_param_type(arg.expr.name) if (arg.is_mut || (arg.expr.obj as ast.Var).is_mut) && resolved.is_ptr() { resolved = resolved.deref() @@ -2465,7 +2653,8 @@ fn (mut g Gen) resolve_return_type(node ast.CallExpr) ast.Type { if fn_var_type != 0 { fn_sym := g.table.final_sym(fn_var_type) if fn_sym.info is ast.FnType { - return_type := g.unwrap_generic(g.recheck_concrete_type(fn_sym.info.func.return_type)) + return_type := + g.unwrap_generic(g.recheck_concrete_type(fn_sym.info.func.return_type)) if return_type != 0 { return if node.or_block.kind == .absent { return_type @@ -2497,8 +2686,8 @@ fn (mut g Gen) resolve_return_type(node ast.CallExpr) ast.Type { } else { func.return_type } - if gen_type := g.table.convert_generic_type(return_type_generic, func.generic_names, - concrete_types) + if gen_type := g.table.convert_generic_type(return_type_generic, + func.generic_names, concrete_types) { if !gen_type.has_flag(.generic) { return if node.or_block.kind == .absent { @@ -2644,6 +2833,30 @@ fn (mut g Gen) receiver_generic_call_context(left_type ast.Type, method_name str } else {} } + // For generic fn-type aliases (e.g. `type ParseFunction[T] = fn(string) !T`), + // the concrete instantiation is stored as FnType with generic_types holding + // the concrete types. Check generic_types on the sym and its parent. + if receiver_concrete_types.len == 0 { + non_final_sym := g.table.sym(left_type) + if non_final_sym.info is ast.GenericInst { + receiver_concrete_types = non_final_sym.info.concrete_types.map(g.unwrap_generic(it)) + if non_final_sym.info.parent_idx > 0 { + parent_sym := g.table.sym(ast.idx_to_type(non_final_sym.info.parent_idx)) + if m := parent_sym.find_method(method_name) { + parent_method = m + } + } + } else if non_final_sym.generic_types.len > 0 && non_final_sym.parent_idx > 0 + && !non_final_sym.generic_types.any(it.has_flag(.generic)) { + // Concrete generic instantiation (e.g. ParseFunction[string]) + // where generic_types holds the resolved concrete types. + receiver_concrete_types = non_final_sym.generic_types.map(g.unwrap_generic(it)) + parent_sym := g.table.sym(ast.idx_to_type(non_final_sym.parent_idx)) + if m := parent_sym.find_method(method_name) { + parent_method = m + } + } + } return receiver_concrete_types, parent_method } @@ -2755,27 +2968,27 @@ fn (mut g Gen) infer_generic_call_concrete_types_from_types(generic_names []stri } if param_sym.kind == .array && arg_sym.info is ast.Array { param_info := param_sym.array_info() - g.infer_generic_call_concrete_types_from_types(generic_names, mut concrete_types, - arg, param_info.elem_type, arg_sym.info.elem_type) + g.infer_generic_call_concrete_types_from_types(generic_names, mut concrete_types, arg, + param_info.elem_type, arg_sym.info.elem_type) return } if param_sym.kind == .array_fixed && arg_sym.info is ast.ArrayFixed { param_info := param_sym.info as ast.ArrayFixed - g.infer_generic_call_concrete_types_from_types(generic_names, mut concrete_types, - arg, param_info.elem_type, arg_sym.info.elem_type) + g.infer_generic_call_concrete_types_from_types(generic_names, mut concrete_types, arg, + param_info.elem_type, arg_sym.info.elem_type) return } if param_sym.kind == .map && arg_sym.info is ast.Map { param_info := param_sym.map_info() - g.infer_generic_call_concrete_types_from_types(generic_names, mut concrete_types, - arg, param_info.key_type, arg_sym.info.key_type) - g.infer_generic_call_concrete_types_from_types(generic_names, mut concrete_types, - arg, param_info.value_type, arg_sym.info.value_type) + g.infer_generic_call_concrete_types_from_types(generic_names, mut concrete_types, arg, + param_info.key_type, arg_sym.info.key_type) + g.infer_generic_call_concrete_types_from_types(generic_names, mut concrete_types, arg, + param_info.value_type, arg_sym.info.value_type) return } if param_sym.info is ast.FnType && arg_sym.info is ast.FnType { - g.update_generic_call_concrete_types_from_fn_types(generic_names, mut concrete_types, - arg, param_sym.info, arg_sym.info) + g.update_generic_call_concrete_types_from_fn_types(generic_names, mut concrete_types, arg, + param_sym.info, arg_sym.info) return } match arg_sym.info { @@ -2791,8 +3004,8 @@ fn (mut g Gen) infer_generic_call_concrete_types_from_types(generic_names []stri if generic_types.len == arg_concrete_types.len { for i, gt in generic_types { gt_name := g.table.sym(gt).name - g.set_generic_call_concrete_type(generic_names, mut concrete_types, - gt_name, arg_concrete_types[i]) + g.set_generic_call_concrete_type(generic_names, mut concrete_types, gt_name, + arg_concrete_types[i]) } } } @@ -2808,8 +3021,8 @@ fn (mut g Gen) infer_generic_call_concrete_types_from_types(generic_names []stri if generic_types.len == arg_concrete_types.len { for i, gt in generic_types { gt_name := g.table.sym(gt).name - g.set_generic_call_concrete_type(generic_names, mut concrete_types, - gt_name, arg_concrete_types[i]) + g.set_generic_call_concrete_type(generic_names, mut concrete_types, gt_name, + arg_concrete_types[i]) } } } @@ -2825,8 +3038,8 @@ fn (mut g Gen) infer_generic_call_concrete_types_from_types(generic_names []stri if generic_types.len == arg_concrete_types.len { for i, gt in generic_types { gt_name := g.table.sym(gt).name - g.set_generic_call_concrete_type(generic_names, mut concrete_types, - gt_name, arg_concrete_types[i]) + g.set_generic_call_concrete_type(generic_names, mut concrete_types, gt_name, + arg_concrete_types[i]) } } } @@ -2905,8 +3118,7 @@ fn (mut g Gen) update_generic_call_concrete_types_from_fn_types(generic_names [] inferred.set_nr_muls(0) } } - g.set_generic_call_concrete_type(generic_names, mut concrete_types, gt_name, - inferred) + g.set_generic_call_concrete_type(generic_names, mut concrete_types, gt_name, inferred) } } if param_fn.func.return_type.has_flag(.generic) { @@ -3174,7 +3386,8 @@ fn (mut g Gen) refresh_current_generic_local_scope_vars(scope &ast.Scope) { } mut var := obj if var.generic_typ != 0 { - refreshed_generic_type := g.unwrap_generic(g.recheck_concrete_type(var.generic_typ)) + refreshed_generic_type := + g.unwrap_generic(g.recheck_concrete_type(var.generic_typ)) if refreshed_generic_type != 0 { var.typ = refreshed_generic_type } @@ -3219,7 +3432,8 @@ fn (mut g Gen) refresh_current_generic_local_scope_vars(scope &ast.Scope) { var.orig_type = g.recheck_concrete_type(var.orig_type) } if var.smartcasts.len > 0 { - var.smartcasts = var.smartcasts.filter(it != 0).map(g.recheck_concrete_type(it)) + var.smartcasts = + var.smartcasts.filter(it != 0).map(g.recheck_concrete_type(it)) } } scope_.objects[name] = var @@ -3366,6 +3580,10 @@ fn (mut g Gen) unwrap_receiver_type(node ast.CallExpr) (ast.Type, &ast.TypeSymbo concrete_types) { unwrapped_rec_type = utyp + } else if concrete_types.len > 0 && !left_type.has_flag(.generic) { + // Fallback: if convert_generic_type fails (e.g. method uses + // different generic param name than struct), use left_type directly + unwrapped_rec_type = left_type } } else {} @@ -3375,7 +3593,8 @@ fn (mut g Gen) unwrap_receiver_type(node ast.CallExpr) (ast.Type, &ast.TypeSymbo if node.left.obj is ast.Var { if node.left.obj.smartcasts.len > 0 { if node.left.obj.ct_type_var == .smartcast { - unwrapped_rec_type = g.unwrap_generic(g.type_resolver.get_type(ast.Expr(node.left))) + unwrapped_rec_type = + g.unwrap_generic(g.type_resolver.get_type(ast.Expr(node.left))) } else { unwrapped_rec_type = g.unwrap_generic(node.left.obj.smartcasts.last()) cast_sym := g.table.sym(unwrapped_rec_type) @@ -3431,6 +3650,45 @@ fn (mut g Gen) unwrap_receiver_type(node ast.CallExpr) (ast.Type, &ast.TypeSymbo return unwrapped_rec_type, typ_sym } +fn (mut g Gen) is_same_generic_receiver_family(left_type ast.Type, receiver_type ast.Type) bool { + if left_type in [ast.void_type, ast.no_type] || receiver_type in [ast.void_type, ast.no_type] { + return false + } + left_sym := g.table.final_sym(g.unwrap_generic(left_type)) + receiver_sym := g.table.final_sym(g.unwrap_generic(receiver_type)) + if left_sym.kind != receiver_sym.kind { + return false + } + match left_sym.info { + ast.Struct { + if receiver_sym.info is ast.Struct { + left_parent := left_sym.info.parent_type + receiver_parent := receiver_sym.info.parent_type + return left_parent != 0 && left_parent == receiver_parent + && left_parent.has_flag(.generic) + } + } + ast.Interface { + if receiver_sym.info is ast.Interface { + left_parent := left_sym.info.parent_type + receiver_parent := receiver_sym.info.parent_type + return left_parent != 0 && left_parent == receiver_parent + && left_parent.has_flag(.generic) + } + } + ast.SumType { + if receiver_sym.info is ast.SumType { + left_parent := left_sym.info.parent_type + receiver_parent := receiver_sym.info.parent_type + return left_parent != 0 && left_parent == receiver_parent + && left_parent.has_flag(.generic) + } + } + else {} + } + return false +} + fn (mut g Gen) method_call(node ast.CallExpr) { // TODO: there are still due to unchecked exprs (opt/some fn arg) if node.left_type == 0 { @@ -3615,9 +3873,13 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } } return - } else if typ_sym.info is ast.Thread { - waiter_fn_name := g.gen_gohandle_name(typ_sym.info.return_type) - g.create_waiter_handler(node.return_type, g.styp(typ_sym.info.return_type), waiter_fn_name) + } else { + thread_sym := typ_sym + if thread_sym.info is ast.Thread { + waiter_fn_name := g.gen_gohandle_name(thread_sym.info.return_type) + g.create_waiter_handler(node.return_type, g.styp(thread_sym.info.return_type), + waiter_fn_name) + } } left_sym := g.table.sym(left_type) final_left_sym := g.table.final_sym(left_type) @@ -3654,16 +3916,19 @@ fn (mut g Gen) method_call(node ast.CallExpr) { prefix_name := if left_sym.kind == .sum_type { 'sumtype' } else { 'interface' } match node.kind { .type_name { - if left_sym.kind in [.sum_type, .interface] { - g.conversion_function_call('builtin__tos3(v_typeof_${prefix_name}_${typ_sym.cname}', + if left_sym.kind == .sum_type { + g.conversion_function_call('builtin__tos3(v_typeof_sumtype_${typ_sym.cname}', ')', node) return + } else if left_sym.kind == .interface { + g.conversion_function_call('v_typeof_interface_${typ_sym.cname}', '', node) + return } } .type_idx { if left_sym.kind in [.sum_type, .interface] { - g.conversion_function_call('v_typeof_${prefix_name}_idx_${typ_sym.cname}', - '', node) + g.conversion_function_call('v_typeof_${prefix_name}_idx_${typ_sym.cname}', '', + node) return } } @@ -3673,7 +3938,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { mut is_free_method := false if node.kind == .str { - if g.gen_to_str_method_call(node) { + if g.gen_to_str_method_call(node, unwrapped_rec_type) { return } } else if node.kind == .free { @@ -3780,7 +4045,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } if has_method { if method_for_generics.params.len > 0 { - receiver_type = receiver_type.derive(method_for_generics.params[0].typ).clear_flag(.generic) + receiver_type = + receiver_type.derive(method_for_generics.params[0].typ).clear_flag(.generic) receiver_is_mut = method_for_generics.params[0].is_mut receiver_generic_names = g.table.generic_type_names(method_for_generics.params[0].typ) } @@ -3842,8 +4108,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) { if method_generic_names_len > 0 && g.cur_fn != unsafe { nil } && g.cur_concrete_types.len > 0 { mut resolved_arg_types := []ast.Type{} - expected_arg_generic_slots := int_max(method_generic_names_len - receiver_concrete_types.len, - 0) + expected_arg_generic_slots := + int_max(method_generic_names_len - receiver_concrete_types.len, 0) if expected_arg_generic_slots > 0 { offset := if method_for_generics.is_method { 1 } else { 0 } for i, arg in node.args { @@ -3865,7 +4131,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } if arg.expr is ast.Ident && arg.expr.obj is ast.Var && (arg.expr.obj as ast.Var).ct_type_var == .generic_param { - mut resolved_arg_type := g.resolve_current_fn_generic_param_type(arg.expr.name) + mut resolved_arg_type := + g.resolve_current_fn_generic_param_type(arg.expr.name) if (arg.is_mut || (arg.expr.obj as ast.Var).is_mut) && resolved_arg_type.is_ptr() { resolved_arg_type = resolved_arg_type.deref() @@ -3954,8 +4221,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) { concrete_types << []ast.Type{len: expected_method_generic_names_len - concrete_types.len, init: ast.void_type} } mut node_ := unsafe { node } - comptime_args := g.type_resolver.resolve_args(g.cur_fn, method_for_generics, mut - node_, concrete_types) + comptime_args := g.type_resolver.resolve_args(g.cur_fn, method_for_generics, mut node_, + concrete_types) receiver_param_type := if method_for_generics.params.len > 0 { method_for_generics.params[0].typ } else { @@ -4016,13 +4283,16 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } mut explicit_concrete_type := ast.no_type if explicit_slot >= 0 && explicit_slot < node.raw_concrete_types.len { - explicit_concrete_type = g.resolved_call_concrete_type(node.raw_concrete_types[explicit_slot]) + explicit_concrete_type = + g.resolved_call_concrete_type(node.raw_concrete_types[explicit_slot]) } else if slot < node.concrete_types.len { - explicit_concrete_type = g.resolved_call_concrete_type(node.concrete_types[slot]) + explicit_concrete_type = + g.resolved_call_concrete_type(node.concrete_types[slot]) } if arg.expr is ast.PrefixExpr && arg.expr.op == .amp && param.typ.nr_muls() > 0 { inner_type := g.resolved_expr_type(arg.expr.right, arg.expr.right_type) - mut resolved_inner_type := g.unwrap_generic(g.recheck_concrete_type(inner_type)) + mut resolved_inner_type := + g.unwrap_generic(g.recheck_concrete_type(inner_type)) if arg.expr.right.is_auto_deref_var() && resolved_inner_type.is_ptr() { resolved_inner_type = resolved_inner_type.deref() } @@ -4460,7 +4730,8 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { } } } - mut is_builtin_print := !is_selector_call && node.kind in [.print, .println, .eprint, .eprintln, .panic] + mut is_builtin_print := !is_selector_call + && node.kind in [.print, .println, .eprint, .eprintln, .panic] print_method := name is_json_encode := node.kind == .json_encode is_json_encode_pretty := node.kind == .json_encode_pretty @@ -4504,7 +4775,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { // `json.decode(User, s)` => json.decode_User(s) typ := c_name(g.styp(ast_type.typ)) fn_name := c_fn_name(name) + '_' + typ - g.gen_json_for_type(ast_type.typ) + g.gen_json_for_type_with_pos(ast_type.typ, node.args[0].expr.pos()) g.empty_line = true g.writeln('// json.decode') g.write('cJSON* ${json_obj} = json__json_parse(') @@ -4597,11 +4868,15 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { // g.generate_tmp_autofree_arg_vars(node, name) // Handle `print(x)` mut print_auto_str := false - mut print_arg_typ := if is_builtin_print && node.args.len > 0 { node.args[0].typ } else { ast.void_type } + mut print_arg_typ := if is_builtin_print && node.args.len > 0 { + node.args[0].typ + } else { + ast.void_type + } // In generic contexts, AST-stored types may be stale from a previous // instantiation. Use resolved_expr_type for Ident expressions. - if is_builtin_print && node.args.len > 0 && g.cur_fn != unsafe { nil } && g.cur_concrete_types.len > 0 - && node.args[0].expr is ast.Ident { + if is_builtin_print && node.args.len > 0 && g.cur_fn != unsafe { nil } + && g.cur_concrete_types.len > 0 && node.args[0].expr is ast.Ident { resolved := g.resolved_expr_type(node.args[0].expr, node.args[0].typ) if resolved != 0 { print_arg_typ = resolved @@ -4775,7 +5050,8 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { mut resolved_parent_value_type := ast.no_type if node.scope.parent != unsafe { nil } { if parent_var := node.scope.parent.find_var(node.name) { - resolved_parent_value_type = g.unwrap_generic(g.recheck_concrete_type(parent_var.typ)).clear_option_and_result() + resolved_parent_value_type = + g.unwrap_generic(g.recheck_concrete_type(parent_var.typ)).clear_option_and_result() if resolved_parent_value_type != 0 && g.table.final_sym(resolved_parent_value_type).kind == .function { unwrapped_fn_var_type = resolved_parent_value_type @@ -4796,14 +5072,16 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { scope: node.scope }) if unwrapped_fn_var_type == 0 && resolved_scope_type != 0 { - resolved_scope_value_type := g.unwrap_generic(g.recheck_concrete_type(resolved_scope_type)).clear_option_and_result() + resolved_scope_value_type := + g.unwrap_generic(g.recheck_concrete_type(resolved_scope_type)).clear_option_and_result() if resolved_scope_value_type != 0 && g.table.final_sym(resolved_scope_value_type).kind == .function { unwrapped_fn_var_type = resolved_scope_value_type } } if unwrapped_fn_var_type == 0 { - unwrapped_fn_var_type = g.unwrap_generic(g.recheck_concrete_type(obj.typ.clear_option_and_result())) + unwrapped_fn_var_type = + g.unwrap_generic(g.recheck_concrete_type(obj.typ.clear_option_and_result())) } if unwrapped_fn_var_type != 0 && g.table.final_sym(unwrapped_fn_var_type).kind == .function { @@ -5112,7 +5390,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { mut expected_types := node.expected_arg_types.map(g.unwrap_generic(it)) if g.has_active_call_generic_context() { for i in 0 .. expected_types.len { - resolved_expected_type := g.resolve_active_call_concrete_type(node.expected_arg_types[i].set_flag(.generic)) + resolved_expected_type := + g.resolve_active_call_concrete_type(node.expected_arg_types[i].set_flag(.generic)) if resolved_expected_type != 0 { expected_types[i] = resolved_expected_type } @@ -5136,7 +5415,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { if fn_sym.info is ast.FnType { for i in 0 .. expected_types.len { if i < fn_sym.info.func.params.len { - resolved_param_type := g.unwrap_generic(g.recheck_concrete_type(fn_sym.info.func.params[i].typ)) + resolved_param_type := + g.unwrap_generic(g.recheck_concrete_type(fn_sym.info.func.params[i].typ)) if resolved_param_type != 0 { expected_types[i] = resolved_param_type } @@ -5205,8 +5485,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { if i < info.func.params.len { mut param_typ := info.func.params[i].typ if param_typ.has_flag(.generic) { - if utyp := g.table.convert_generic_type(param_typ, g.cur_fn.generic_names, - g.cur_concrete_types) + if utyp := g.table.convert_generic_type(param_typ, + g.cur_fn.generic_names, g.cur_concrete_types) { param_typ = utyp } @@ -5285,7 +5565,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { && arg.expr.obj.ct_type_var !in [.generic_param, .no_comptime] && (expected_types[i] == 0 || expected_types[i].has_flag(.generic) || g.type_has_unresolved_generic_parts(expected_types[i])) { - resolved_arg_type := g.unwrap_generic(g.type_resolver.get_type(ast.Expr(arg.expr))) + resolved_arg_type := + g.unwrap_generic(g.type_resolver.get_type(ast.Expr(arg.expr))) if resolved_arg_type != 0 { expected_types[i] = resolved_arg_type } @@ -5335,11 +5616,11 @@ fn (mut g Gen) call_args(node ast.CallExpr) { g.writeln('\tif (${tmp_array}.len == 1) {') g.writeln('\t\t${tmp_err_msg} = builtin__str_intp(2, _MOV((StrIntpData[]){') g.writeln('\t\t\t{_S("array decompose: array has "), 0xfe07, {.d_i32 = ${tmp_array}.len}, 0, 0, 0},') - g.writeln('\t\t\t{_S(" element but ${remaining_params} ${elem_word} needed"), 0, {.d_c = 0 }, 0, 0, 0}}));') + g.writeln('\t\t\t{_S(" element but ${remaining_params} ${elem_word} needed"), 0, {0}, 0, 0, 0}}));') g.writeln('\t} else {') g.writeln('\t\t${tmp_err_msg} = builtin__str_intp(2, _MOV((StrIntpData[]){') g.writeln('\t\t\t{_S("array decompose: array has "), 0xfe07, {.d_i32 = ${tmp_array}.len}, 0, 0, 0},') - g.writeln('\t\t\t{_S(" elements but ${remaining_params} ${elem_word} needed"), 0, {.d_c = 0 }, 0, 0, 0}}));') + g.writeln('\t\t\t{_S(" elements but ${remaining_params} ${elem_word} needed"), 0, {0}, 0, 0, 0}}));') g.writeln('\t}') g.writeln('\tbuiltin___v_panic(${tmp_err_msg});') g.writeln('}') @@ -5406,7 +5687,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { } if i < expected_types.len { if param := g.call_arg_param(node, i) { - concrete_param_type := g.resolve_active_call_concrete_type(param.typ.set_flag(.generic)) + concrete_param_type := + g.resolve_active_call_concrete_type(param.typ.set_flag(.generic)) if concrete_param_type != 0 && concrete_param_type != expected_types[i] && !concrete_param_type.has_flag(.generic) && !g.type_has_unresolved_generic_parts(concrete_param_type) @@ -5421,10 +5703,12 @@ fn (mut g Gen) call_args(node ast.CallExpr) { || g.type_has_unresolved_generic_parts(expected_types[i])) || (g.cur_fn != unsafe { nil } && g.cur_concrete_types.len > 0)) if should_refresh_expected_type { - resolved_expected_type := g.resolve_active_call_concrete_type(param.typ.set_flag(.generic)) + resolved_expected_type := + g.resolve_active_call_concrete_type(param.typ.set_flag(.generic)) if resolved_expected_type != 0 && !resolved_expected_type.has_flag(.generic) && !g.type_has_unresolved_generic_parts(resolved_expected_type) { - expected_types[i] = g.unwrap_generic(g.recheck_concrete_type(resolved_expected_type)) + expected_types[i] = + g.unwrap_generic(g.recheck_concrete_type(resolved_expected_type)) } } } @@ -5490,8 +5774,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { left_sym := g.table.sym(node.left_type) if fn_def := left_sym.find_method_with_generic_parent(node.name) { mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.convert_generic_type(arr_info.elem_type, fn_def.generic_names, - node.concrete_types) + if utyp := muttable.convert_generic_type(arr_info.elem_type, + fn_def.generic_names, node.concrete_types) { arr_info.elem_type = utyp } @@ -5501,8 +5785,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { } else { if fn_def := g.table.find_fn(node.name) { mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.convert_generic_type(arr_info.elem_type, fn_def.generic_names, - node.concrete_types) + if utyp := muttable.convert_generic_type(arr_info.elem_type, + fn_def.generic_names, node.concrete_types) { arr_info.elem_type = utyp } @@ -5523,8 +5807,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { if g.table.unaliased_type(array_decompose.expr_type) == g.table.unaliased_type(varg_array_type) { g.expr(args.last().expr) } else { - g.write_converted_variadic_array_decompose_arg(array_decompose, varg_array_type, - arr_info.elem_type, node.language) + g.write_converted_variadic_array_decompose_arg(array_decompose, + varg_array_type, arr_info.elem_type, node.language) } } } else { @@ -5546,8 +5830,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { || (varg_type.has_flag(.variadic) && args[arg_nr].typ == varg_type.clear_flag(.variadic) && !g.table.sumtype_has_variant(arr_info.elem_type, args[arg_nr].typ, false))) { - g.ref_or_deref_arg(args[arg_nr], arr_info.elem_type, node.language, - false) + g.ref_or_deref_arg_ex(args[arg_nr], arr_info.elem_type, node.language, + false, true) } else { noscan := g.check_noscan(arr_info.elem_type) is_option := arr_info.elem_type.has_flag(.option) @@ -5560,8 +5844,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { } g.write('builtin__new_array_from_c_array${noscan}(${variadic_count}, ${variadic_count}, sizeof(${elem_type}), _MOV((${elem_type}[${variadic_count}]){') for j in arg_nr .. args.len { - g.ref_or_deref_arg(args[j], arr_info.elem_type, node.language, - false) + g.ref_or_deref_arg_ex(args[j], arr_info.elem_type, node.language, + false, true) if j < args.len - 1 { g.write(', ') } @@ -5685,6 +5969,10 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) { @[inline] fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type_ ast.Type, lang ast.Language, is_smartcast bool) { + g.ref_or_deref_arg_ex(arg, expected_type_, lang, is_smartcast, false) +} + +fn (mut g Gen) ref_or_deref_arg_ex(arg ast.CallArg, expected_type_ ast.Type, lang ast.Language, is_smartcast bool, is_variadic_arg bool) { expected_type := g.unwrap_generic(expected_type_) mut arg_typ := if arg.ct_expr { g.unwrap_generic(g.type_resolver.get_type(arg.expr)) @@ -5887,10 +6175,21 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type_ ast.Type, lang a } else { expected_type } + promoted_variadic_type := if is_variadic_arg && expected_deref_type.is_voidptr() { + g.variadic_voidptr_promoted_type(arg_typ) + } else { + ast.no_type + } deref_sym := g.table.sym(expected_deref_type) if arg_typ_sym.kind != .function && deref_sym.kind !in [.sum_type, .interface] && lang != .c { if arg.expr.is_lvalue() { + if promoted_variadic_type != ast.no_type { + g.write('(voidptr)ADDR(${g.styp(promoted_variadic_type)}, ') + g.expr_with_cast(arg.expr, arg_typ, promoted_variadic_type) + g.write(')') + return + } if expected_type.has_flag(.option) { if expected_type.has_flag(.option_mut_param_t) { g.write('&') @@ -5913,6 +6212,16 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type_ ast.Type, lang a } else if arg.expr is ast.None { g.expr_with_opt(ast.Expr(arg.expr), arg_typ, expected_type) return + } else if expected_deref_type.is_voidptr() && !arg_typ.is_any_kind_of_pointer() { + boxed_type := if promoted_variadic_type != ast.no_type { + promoted_variadic_type + } else { + arg_typ + } + g.write('(voidptr)ADDR(${g.styp(boxed_type)}, ') + g.expr_with_cast(arg.expr, arg_typ, boxed_type) + g.write(')') + return } else if arg.expr.is_literal() { g.write('(voidptr)ADDR(${g.styp(arg_typ)}, ') g.expr(arg.expr) @@ -6008,12 +6317,14 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type_ ast.Type, lang a } else if arg.expr is ast.Ident { if arg.expr.obj is ast.Var { if arg.expr.obj.is_arg && arg.expr.obj.is_mut && !arg.is_mut && arg_typ.is_ptr() - && !expected_type.is_any_kind_of_pointer() - && g.unwrap_generic(g.recheck_concrete_type(expected_type)) == g.unwrap_generic(arg_typ.deref()) { - g.write('(*') - g.expr(ast.Expr(arg.expr)) - g.write(')') - return + && !expected_type.is_any_kind_of_pointer() { + unwrapped_expected := g.unwrap_generic(g.recheck_concrete_type(expected_type)) + nr_derefs := arg_typ.nr_muls() + if nr_derefs > 0 && unwrapped_expected == g.unwrap_generic(arg_typ.set_nr_muls(0)) { + g.write('${'*'.repeat(nr_derefs)}') + g.expr(ast.Expr(arg.expr)) + return + } } } else if arg.expr.kind == .constant && arg_typ.is_ptr() && !expected_type.is_any_kind_of_pointer() @@ -6033,8 +6344,7 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type_ ast.Type, lang a // so expr_with_cast won't handle the sumtype wrapping. We need to prevent the smartcast // unwrapping in g.expr() since the value is already the correct sumtype at runtime. if !arg_typ.has_flag(.option) && exp_sym.kind == .sum_type && arg_typ == expected_type { - g.prevent_sum_type_unwrapping_once = g.is_expr_smartcast_to_sumtype(arg.expr, - expected_type) + g.prevent_sum_type_unwrapping_once = g.is_expr_smartcast_to_sumtype(arg.expr, expected_type) } if arg_typ.has_flag(.option) { g.expr_with_opt(arg.expr, arg_typ, expected_type.set_flag(.option)) diff --git a/vlib/v/gen/c/for.v b/vlib/v/gen/c/for.v index 224c6f0fa7..722f5caa0f 100644 --- a/vlib/v/gen/c/for.v +++ b/vlib/v/gen/c/for.v @@ -332,7 +332,8 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { node.key_type = key_type node.scope.update_var_type(node.key_var, key_type) } - base_val_type := g.recheck_concrete_type(g.table.value_type(g.table.unaliased_type(unwrapped_typ))) + base_val_type := + g.recheck_concrete_type(g.table.value_type(g.table.unaliased_type(unwrapped_typ))) node.val_type = for_in_val_type(base_val_type, node.val_is_mut, node.val_is_ref) node.scope.update_var_type(node.val_var, node.val_type) } @@ -731,8 +732,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { left_type_name := util.no_dots(left_cc_type) fn_name = '${c_name(left_type_name)}_name_table[${t_expr}._typ]._method_next' } else { - fn_name = g.specialized_method_name_from_receiver(next_fn, unwrapped_cond_type, - fn_name) + fn_name = g.specialized_method_name_from_receiver(next_fn, unwrapped_cond_type, fn_name) } g.write('\t${g.styp(ret_typ)} ${t_var} = ${fn_name}(') if !node.cond_type.is_ptr() && receiver_typ.is_ptr() { diff --git a/vlib/v/gen/c/if.v b/vlib/v/gen/c/if.v index d16d3bdbea..10d5a44362 100644 --- a/vlib/v/gen/c/if.v +++ b/vlib/v/gen/c/if.v @@ -73,6 +73,9 @@ fn (mut g Gen) need_tmp_var_in_expr(expr ast.Expr) bool { return true } for arg in expr.args { + if arg.expr is ast.ArrayDecompose { + return true + } if g.need_tmp_var_in_expr(arg.expr) { return true } @@ -514,7 +517,8 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { } else { '-> ' } - guard_typ := g.unwrap_generic(branch.cond.expr_type.clear_option_and_result()) + guard_typ := + g.unwrap_generic(branch.cond.expr_type.clear_option_and_result()) guard_is_heap_obj := g.table.final_sym(guard_typ).is_heap() && !guard_typ.is_ptr() if guard_is_heap_obj { @@ -529,7 +533,8 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { } else { expr_sym := g.table.sym(branch.cond.expr_type) if expr_sym.info is ast.FnType { - g.write_fntype_decl(left_var_name, expr_sym.info, guard_expr_type.nr_muls()) + g.write_fntype_decl(left_var_name, expr_sym.info, + guard_expr_type.nr_muls()) if guard_expr_type.nr_muls() == 0 { g.writeln(' = *(${base_type}*)${var_name}${dot_or_ptr}data;') } else { diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index dfd66a0efd..9b4d0a6dc2 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -65,13 +65,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.infix_expr_left_shift_op(node) } .right_shift { - g.write('(') - if g.pref.translated || g.file.is_translated { - g.gen_plain_infix_expr(node) - } else { - g.gen_safe_shift_expr(node) - } - g.write(')') + g.gen_safe_shift_expr(node) } .and, .logical_or { g.infix_expr_and_or_op(node) @@ -146,7 +140,12 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) { && left_sym.kind !in [.sum_type, .interface] is_option_introduction := resolved_left.has_flag(.option) && !left_type.has_flag(.option) - if !is_sumtype_override && !is_option_introduction { + // Don't strip option flag when comparing with none — the scope + // may have an unwrapped smartcast from a fallthrough guard, but + // the none check itself needs the option type. + is_option_removal_for_none := left_type.has_flag(.option) + && !resolved_left.has_flag(.option) && node.right is ast.None + if !is_sumtype_override && !is_option_introduction && !is_option_removal_for_none { left_type = resolved_left } } @@ -171,7 +170,6 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) { right := g.unwrap(right_type) mut has_defined_eq_operator := false mut eq_operator_expects_ptr := false - mut eq_method := ast.Fn{} if m := g.table.find_method(left.sym, '==') { // For != on generic struct types, check if the == operator was defined on // a generic parent (receiver type has generic flag or is a different type). @@ -184,7 +182,6 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) { if !skip_for_generic_ne { has_defined_eq_operator = true eq_operator_expects_ptr = m.receiver_type.is_ptr() - eq_method = m } } // TODO: investigate why the following is needed for vlib/v/tests/string_alias_test.v and vlib/v/tests/anon_fn_with_alias_args_test.v @@ -243,24 +240,33 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) { if node.op == .ne { g.write('!') } - mut method_name := if has_alias_eq_op_overload { - g.styp(left.typ.set_nr_muls(0)) + if left.sym.kind == .struct && (left.sym.info as ast.Struct).generic_types.len > 0 { + concrete_types := (left.sym.info as ast.Struct).concrete_types + mut method_name := '${left.sym.cname}__eq' + if left.unaliased_sym.is_builtin() { + method_name = 'builtin__${method_name}' + } + method_name = g.generic_fn_name(concrete_types, method_name) + g.write(method_name) } else { - g.styp(left.unaliased.set_nr_muls(0)) + mut method_name := if has_alias_eq_op_overload { + g.styp(left.typ.set_nr_muls(0)) + } else { + g.styp(left.unaliased.set_nr_muls(0)) + } + mut is_builtin_or_alias_to_builtin := left.sym.is_builtin() + if !has_alias_eq_op_overload && !is_builtin_or_alias_to_builtin + && left.sym.info is ast.Alias { + alias_info := left.sym.info as ast.Alias + parent_sym := g.table.sym(alias_info.parent_type) + is_builtin_or_alias_to_builtin = parent_sym.is_builtin() + } + if is_builtin_or_alias_to_builtin { + method_name = 'builtin__${method_name}' + } + g.write(method_name) + g.write('__eq') } - mut is_builtin_or_alias_to_builtin := left.sym.is_builtin() - if !has_alias_eq_op_overload && !is_builtin_or_alias_to_builtin - && left.sym.info is ast.Alias { - alias_info := left.sym.info as ast.Alias - parent_sym := g.table.sym(alias_info.parent_type) - is_builtin_or_alias_to_builtin = parent_sym.is_builtin() - } - if is_builtin_or_alias_to_builtin { - method_name = 'builtin__${method_name}' - } - mut eq_fn_name := '${method_name}__eq' - eq_fn_name = g.specialized_method_name_from_receiver(eq_method, left.typ, eq_fn_name) - g.write(eq_fn_name) g.write('(') g.write('*'.repeat(left.typ.nr_muls())) if eq_operator_expects_ptr { @@ -974,7 +980,8 @@ fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, left_type ast.Type, rig if left is ast.Ident && left.or_expr.kind == .absent && array_expr is ast.StringLiteral { var := g.expr_string(left) - slit := cescape_nonascii(util.smart_quote(array_expr.val, array_expr.is_raw)) + slit := + cescape_nonascii(util.smart_quote(array_expr.val, array_expr.is_raw)) mut needs_deref := false if left.info is ast.IdentVar && left.obj is ast.Var { if g.table.sym(left.obj.typ).kind in [.interface, .sum_type] { @@ -1367,7 +1374,8 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) { mut elem_type := g.unwrap_generic(g.recheck_concrete_type(array_info.elem_type)) if elem_type == 0 || elem_type.has_flag(.generic) || g.type_has_unresolved_generic_parts(elem_type) { - resolved_elem_type := g.recheck_concrete_type(g.table.value_type(g.unwrap_generic(resolved_left.typ))) + resolved_elem_type := + g.recheck_concrete_type(g.table.value_type(g.unwrap_generic(resolved_left.typ))) if resolved_elem_type != 0 { elem_type = g.unwrap_generic(resolved_elem_type) } @@ -1473,14 +1481,16 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) { } expected_push_many_sym := g.table.final_sym(g.unwrap_generic(expected_push_many_atype)) if expected_push_many_sym.kind == .array { - mut push_many_elem_type := g.unwrap_generic(g.recheck_concrete_type(expected_push_many_sym.array_info().elem_type)) + mut push_many_elem_type := + g.unwrap_generic(g.recheck_concrete_type(expected_push_many_sym.array_info().elem_type)) if push_many_elem_type == ast.int_literal_type { push_many_elem_type = ast.int_type } else if push_many_elem_type == ast.float_literal_type { push_many_elem_type = ast.f64_type } if push_many_elem_type != expected_push_many_sym.array_info().elem_type { - expected_push_many_atype = ast.idx_to_type(g.table.find_or_register_array(push_many_elem_type)) + expected_push_many_atype = + ast.idx_to_type(g.table.find_or_register_array(push_many_elem_type)) } } old_inside_left_shift := g.inside_left_shift @@ -1573,13 +1583,7 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) { } } } else { - g.write('(') - if g.pref.translated || g.file.is_translated { - g.gen_plain_infix_expr(node) - } else { - g.gen_safe_shift_expr(node) - } - g.write(')') + g.gen_safe_shift_expr(node) } } @@ -1674,12 +1678,41 @@ fn (mut g Gen) infix_expr_and_or_op(node ast.InfixExpr) { fn (mut g Gen) gen_is_none_check(node ast.InfixExpr) { if node.left in [ast.Ident, ast.SelectorExpr, ast.IndexExpr, ast.CallExpr, ast.CTempVar] { - old_inside_opt_or_res := g.inside_opt_or_res - g.inside_opt_or_res = true - g.write('(') - g.expr(node.left) - g.write(')') - g.inside_opt_or_res = old_inside_opt_or_res + // When a sumtype variable has been comptime-smartcast to an option variant + // (e.g. `$if t is ?string { if t == none { ... } }`), we need to access the + // sumtype's variant field directly rather than using .data on the sumtype. + if node.left is ast.Ident && node.left.obj is ast.Var + && node.left.obj.ct_type_var == .smartcast { + obj_sym := g.table.sym(g.unwrap_generic(node.left.obj.typ)) + if obj_sym.kind == .sum_type { + ctyp := g.unwrap_generic(g.type_resolver.get_type(node.left)) + cur_variant_sym := g.table.sym(ctyp) + variant_name := g.get_sumtype_variant_name(ctyp, cur_variant_sym) + dot := if node.left.obj.orig_type.is_ptr() { '->' } else { '.' } + // Sumtype stores option variants as pointers, so use -> to access state + g.write('${node.left.name}${dot}_${variant_name}->state') + g.write(' ${node.op.str()} 2') // none state + return + } + } + // For Ident nodes that have been unwrapped by a smartcast (e.g. from a + // none-guard fallthrough), write the variable name directly to avoid + // g.expr() generating the unwrapped data access instead of the option wrapper. + if node.left is ast.Ident && node.left.obj is ast.Var && node.left.obj.is_unwrapped { + name := c_name(node.left.name) + if node.left.is_auto_heap() { + g.write('(*${name})') + } else { + g.write(name) + } + } else { + old_inside_opt_or_res := g.inside_opt_or_res + g.inside_opt_or_res = true + g.write('(') + g.expr(node.left) + g.write(')') + g.inside_opt_or_res = old_inside_opt_or_res + } dot_or_ptr := if !node.left_type.has_flag(.option_mut_param_t) { '.' } else { '->' } g.write('${dot_or_ptr}state') } else { diff --git a/vlib/v/gen/c/json.v b/vlib/v/gen/c/json.v index 282fb6b11b..d2de933804 100644 --- a/vlib/v/gen/c/json.v +++ b/vlib/v/gen/c/json.v @@ -340,8 +340,7 @@ fn (mut g Gen) gen_enum_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc strin dec.writeln('\tstring ${tmp} = ${js_dec_name('string')}(root);') if is_option { g.gen_str_to_enum(utyp, sym, tmp, '&res', '\t', mut dec) - g.gen_enum_to_str(utyp, sym, '*(${g.base_type(utyp)}*)val.data', 'o', '\t\t', mut - enc) + g.gen_enum_to_str(utyp, sym, '*(${g.base_type(utyp)}*)val.data', 'o', '\t\t', mut enc) } else { g.gen_str_to_enum(utyp, sym, tmp, 'res', '\t', mut dec) g.gen_enum_to_str(utyp, sym, 'val', 'o', '\t', mut enc) @@ -390,7 +389,7 @@ fn (mut g Gen) gen_prim_enc_dec(typ ast.Type, mut enc strings.Builder, mut dec s } fn gen_struct_root_validation(ret_styp string, mut dec strings.Builder) { - dec.writeln('\tif (!cJSON_IsObject(root) && !cJSON_IsNull(root)) {') + dec.writeln('\tif (!cJSON_IsObject(root) && !cJSON_IsNull(root) && !cJSON_IsArray(root)) {') dec.writeln('\t\treturn (${result_name}_${ret_styp}){ .is_error = true, .err = builtin___v_error(builtin__string__plus(_S("Json element is not an object: "), json__json_print(root))), .data = {0} };') dec.writeln('\t}') } @@ -518,12 +517,10 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st tmp2 := g.new_tmp_var() if utyp.has_flag(.option) { enc.writeln('\t\tu64 ${tmp2} = *${var_data}${field_op}_${variant_typ};') - g.gen_enum_to_str(variant, variant_sym, tmp2, 'o', '\t\t', mut - enc) + g.gen_enum_to_str(variant, variant_sym, tmp2, 'o', '\t\t', mut enc) } else { enc.writeln('\t\tu64 ${tmp2} = *${var_data}${field_op}_${variant_typ};') - g.gen_enum_to_str(variant, variant_sym, tmp2, 'o', '\t\t', mut - enc) + g.gen_enum_to_str(variant, variant_sym, tmp2, 'o', '\t\t', mut enc) } } } else if variant_sym.name == 'time.Time' { @@ -559,15 +556,14 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st dec.writeln('\t\t${variant_typ} value;') tmp2 := g.new_tmp_var() dec.writeln('\t\tstring ${tmp2} = json__decode_string(jsonroot_${tmp});') - g.gen_enum_to_str(variant, variant_sym, tmp2, 'value', '\t\t', mut - dec) + g.gen_enum_to_str(variant, variant_sym, tmp2, 'value', '\t\t', mut dec) } } else if variant_sym.name == 'time.Time' { gen_js_get(ret_styp, tmp, unmangled_variant_name, mut dec, true) dec.writeln('\t\t${variant_typ} value = time__unix(${js_dec_name('i64')}(jsonroot_${tmp}));') } else { - gen_js_get_opt(js_dec_name(variant_typ), variant_typ, ret_styp, tmp, unmangled_variant_name, mut - dec, true) + gen_js_get_opt(js_dec_name(variant_typ), variant_typ, ret_styp, tmp, + unmangled_variant_name, mut dec, true) dec.writeln('\t\t${variant_typ} value = *(${variant_typ}*)(${tmp}.data);') } if is_option { @@ -592,8 +588,8 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st dec.writeln('\t\t\t}') } else if !is_js_prim(variant_typ) && variant_sym.kind != .enum { dec.writeln('\t\t\tif (strcmp("${unmangled_variant_name}", ${type_var}) == 0 && ${variant_sym.kind == .array} == cJSON_IsArray(root)) {') - g.gen_sumtype_variant_decode(variant_typ, sym.cname, ret_styp, prefix, - is_option, '\t\t\t\t', mut dec) + g.gen_sumtype_variant_decode(variant_typ, sym.cname, ret_styp, prefix, is_option, + '\t\t\t\t', mut dec) dec.writeln('\t\t\t}') } } @@ -815,8 +811,8 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st if utyp.has_flag(.option) { dec.writeln('\t\tres.state = 0;') } - g.gen_prim_type_validation(field.name, field.typ, tmp, is_required, '${result_name}_${styp}', mut - dec) + g.gen_prim_type_validation(field.name, field.typ, tmp, is_required, + '${result_name}_${styp}', mut dec) dec.writeln('\t\t${prefix}${op}${c_name(field.name)} = ${dec_name}(jsonroot_${tmp});') if field.has_default_expr { dec.writeln('\t} else {') @@ -828,8 +824,8 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st tmp := g.new_tmp_var() is_option_field := field.typ.has_flag(.option) if field.typ.has_flag(.option) { - gen_js_get_opt(js_dec_name(field_type), field_type, styp, tmp, name, mut - dec, is_required) + gen_js_get_opt(js_dec_name(field_type), field_type, styp, tmp, name, mut dec, + is_required) dec.writeln('\tif (jsonroot_${tmp} && !cJSON_IsNull(jsonroot_${tmp})) {') } else { gen_js_get(styp, tmp, name, mut dec, is_required) @@ -849,8 +845,8 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st } else { tmp2 := g.new_tmp_var() dec.writeln('\t\tstring ${tmp2} = json__decode_string(jsonroot_${tmp});') - g.gen_str_to_enum(field.typ, field_sym, tmp2, '${prefix}${op}${c_name(field.name)}', - '\t\t', mut dec) + g.gen_str_to_enum(field.typ, field_sym, tmp2, + '${prefix}${op}${c_name(field.name)}', '\t\t', mut dec) } } if field.has_default_expr { @@ -926,8 +922,8 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st } else { name } - g.gen_struct_enc_dec(field.typ, g.table.sym(field.typ).info, - styp, mut enc, mut dec, prefix_embed) + g.gen_struct_enc_dec(field.typ, g.table.sym(field.typ).info, styp, mut + enc, mut dec, prefix_embed) skip_embed = true break } @@ -1023,15 +1019,17 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st if field.typ.has_flag(.option) { enc.writeln('${indent}\t{') enc.writeln('${indent}\t\tcJSON *enum_val;') - g.gen_enum_to_str(field.typ, field_sym, '*(${g.base_type(field.typ)}*)${prefix_enc}${op}${c_name(field.name)}.data', + g.gen_enum_to_str(field.typ, field_sym, + '*(${g.base_type(field.typ)}*)${prefix_enc}${op}${c_name(field.name)}.data', 'enum_val', '${indent}\t\t', mut enc) enc.writeln('${indent}\t\tcJSON_AddItemToObject(o, "${name}", enum_val);') enc.writeln('${indent}\t}') } else { enc.writeln('${indent}\t{') enc.writeln('${indent}\t\tcJSON *enum_val;') - g.gen_enum_to_str(field.typ, field_sym, '${prefix_enc}${op}${c_name(field.name)}', - 'enum_val', '${indent}\t\t', mut enc) + g.gen_enum_to_str(field.typ, field_sym, + '${prefix_enc}${op}${c_name(field.name)}', 'enum_val', '${indent}\t\t', mut + enc) enc.writeln('${indent}\t\tcJSON_AddItemToObject(o, "${name}", enum_val);') enc.writeln('${indent}\t}') } diff --git a/vlib/v/gen/c/or_block_line_info_test.v b/vlib/v/gen/c/or_block_line_info_test.v index 9aeb822345..cd06fad39a 100644 --- a/vlib/v/gen/c/or_block_line_info_test.v +++ b/vlib/v/gen/c/or_block_line_info_test.v @@ -9,7 +9,8 @@ fn test_option_propagation_panic_has_matching_line_info() { os.rmdir_all(tmp_dir) or {} } source_path := os.join_path(os.real_path(tmp_dir), 'option_propagation_line_info.vv') - os.write_file(source_path, 'struct Foo{}\n\nfn (f Foo) foo() int {\n\treturn 1\n}\n\nfn new_foo() ?Foo {\n\treturn none\n}\n\nfn main() {\n\ti := new_foo()?.foo()\n\tprintln(i)\n}\n')! + os.write_file(source_path, + 'struct Foo{}\n\nfn (f Foo) foo() int {\n\treturn 1\n}\n\nfn new_foo() ?Foo {\n\treturn none\n}\n\nfn main() {\n\ti := new_foo()?.foo()\n\tprintln(i)\n}\n')! cmd := '${os.quoted_path(line_info_test_vexe)} -g -o - ${os.quoted_path(source_path)}' res := os.execute(cmd) assert res.exit_code == 0, '${cmd}\n${res.output}' diff --git a/vlib/v/gen/c/orm.v b/vlib/v/gen/c/orm.v index 0ca906ddbc..81d66ba952 100644 --- a/vlib/v/gen/c/orm.v +++ b/vlib/v/gen/c/orm.v @@ -37,6 +37,15 @@ fn (g &Gen) orm_primitive_field_name(typ ast.Type) string { return vint2int(sym.cname) } +fn (g &Gen) orm_primitive_variant_field_name(typ ast.Type) string { + final_typ := g.table.final_type(typ.clear_flag(.option)) + sym := g.table.sym(final_typ) + if sym.kind == .enum { + return 'i64' + } + return vint2int(sym.cname) +} + enum SqlExprSide { left right @@ -90,7 +99,8 @@ fn (mut g Gen) sql_insert_expr(node ast.SqlExpr) { g.write_orm_insert(hack_stmt_line, table_name, connection_var_name, result_var_name, node.or_expr, table_attrs) - g.write2(left, 'orm__Connection_name_table[${connection_var_name}._typ]._method_last_id(${connection_var_name}._object)') + g.write2(left, + 'orm__Connection_name_table[${connection_var_name}._typ]._method_last_id(${connection_var_name}._object)') } fn (mut g Gen) build_sql_stmt_line_from_sql_expr(node ast.SqlExpr) ast.SqlStmtLine { @@ -149,8 +159,7 @@ fn (mut g Gen) sql_stmt_line(stmt_line ast.SqlStmtLine, connection_var_name stri g.write_orm_create_table(node, table_name, connection_var_name, result_var_name, table_attrs) } else if node.kind == .drop { - g.write_orm_drop_table(node, table_name, connection_var_name, result_var_name, - table_attrs) + g.write_orm_drop_table(node, table_name, connection_var_name, result_var_name, table_attrs) } else if node.kind == .insert { g.write_orm_insert(node, table_name, connection_var_name, result_var_name, or_expr, table_attrs) @@ -361,7 +370,8 @@ fn (mut g Gen) write_orm_update(node &ast.SqlStmtLine, table_name string, connec g.writeln('.fields = builtin____new_array_with_default_noscan(${node.updated_columns.len}, ${node.updated_columns.len}, sizeof(string), 0') } - g.writeln2('),', '.data = builtin__new_array_from_c_array(${node.update_exprs.len}, ${node.update_exprs.len}, sizeof(orm__Primitive),') + g.writeln2('),', + '.data = builtin__new_array_from_c_array(${node.update_exprs.len}, ${node.update_exprs.len}, sizeof(orm__Primitive),') if node.update_exprs.len > 0 { g.indent++ @@ -616,8 +626,9 @@ fn (mut g Gen) write_orm_insert_with_last_ids(node ast.SqlStmtLine, connection_v } arr.fields = fff.clone() unsafe { fff.free() } - g.write_orm_insert_with_last_ids(arr, connection_var_name, g.get_table_name_by_struct_type(arr.table_expr.typ), - last_ids, res_, id_name, fkeys[i], or_expr) + g.write_orm_insert_with_last_ids(arr, connection_var_name, + g.get_table_name_by_struct_type(arr.table_expr.typ), last_ids, res_, id_name, + fkeys[i], or_expr) g.indent-- g.writeln('}') } @@ -877,8 +888,8 @@ fn (mut g Gen) write_orm_where_expr(expr ast.Expr, mut fields []string, mut pare match expr { ast.InfixExpr { g.sql_side = .left - g.write_orm_where_expr(expr.left, mut fields, mut parentheses, mut kinds, mut - data, mut is_and) + g.write_orm_where_expr(expr.left, mut fields, mut parentheses, mut kinds, mut data, mut + is_and) is_nil_comparison := expr.right is ast.Nil && expr.op in [.eq, .ne] mut ignore_rhs := expr.op in [.key_is, .not_is] || is_nil_comparison mut kind := match expr.op { @@ -950,8 +961,8 @@ fn (mut g Gen) write_orm_where_expr(expr ast.Expr, mut fields []string, mut pare } ast.ParExpr { mut par := [fields.len] - g.write_orm_where_expr(expr.expr, mut fields, mut parentheses, mut kinds, mut - data, mut is_and) + g.write_orm_where_expr(expr.expr, mut fields, mut parentheses, mut kinds, mut data, mut + is_and) par << fields.len - 1 parentheses << par } @@ -1104,7 +1115,8 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re g.writeln('NULL') } g.indent-- - g.writeln2('),', '.select_exprs = builtin__new_array_from_c_array(${select_exprs.len}, ${select_exprs.len}, sizeof(string),') + g.writeln2('),', + '.select_exprs = builtin__new_array_from_c_array(${select_exprs.len}, ${select_exprs.len}, sizeof(string),') g.indent++ if select_exprs.len > 0 { @@ -1121,7 +1133,8 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re g.writeln('NULL') } g.indent-- - g.writeln2('),', '.types = builtin__new_array_from_c_array(${types.len}, ${types.len}, sizeof(${ast.int_type_name}),') + g.writeln2('),', + '.types = builtin__new_array_from_c_array(${types.len}, ${types.len}, sizeof(${ast.int_type_name}),') g.indent++ if types.len > 0 { @@ -1204,7 +1217,7 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re } else { node.aggregate_field_type } - primitive_field_name := g.orm_primitive_field_name(aggregate_type) + primitive_field_name := g.orm_primitive_variant_field_name(aggregate_type) aggregate_value_styp := g.styp(aggregate_type.clear_flag(.option)) if node.aggregate_kind == .count { g.writeln('*(${unwrapped_c_typ}*) ${result_var}.data = 0;') diff --git a/vlib/v/gen/c/reflection.v b/vlib/v/gen/c/reflection.v index cc94f12cce..388415bee8 100644 --- a/vlib/v/gen/c/reflection.v +++ b/vlib/v/gen/c/reflection.v @@ -37,7 +37,8 @@ fn (g &Gen) gen_functionarg_array(type_name string, node ast.Fn) string { } mut out := 'builtin__new_array_from_c_array(${node.params.len},${node.params.len},sizeof(${type_name}),' out += '_MOV((${type_name}[${node.params.len}]){' - out += node.params.map('((${type_name}){.name=_S("${it.name}"),.typ=${int(it.typ)},.is_mut=${it.is_mut}})').join(',') + out += + node.params.map('((${type_name}){.name=_S("${it.name}"),.typ=${int(it.typ)},.is_mut=${it.is_mut}})').join(',') out += '}))' return out } @@ -72,7 +73,8 @@ fn (mut g Gen) gen_reflection_fn(node ast.Fn) string { arg_str += '.is_variadic=${node.is_variadic},' arg_str += '.return_typ=${int(node.return_type)},' arg_str += '.receiver_typ=${int(node.receiver_type)},' - arg_str += '.is_pub=${node.is_pub}' + arg_str += '.is_pub=${node.is_pub},' + arg_str += '.attrs=${g.gen_attrs_array(node.attrs)}' arg_str += '})' return arg_str } @@ -87,22 +89,20 @@ fn (mut g Gen) gen_reflection_sym(tsym ast.TypeSymbol) string { return '(${cprefix}TypeSymbol){.name=_S("${name}"),.mod=_S("${tsym.mod}"),.idx=${tsym.idx},.parent_idx=${tsym.parent_idx},.language=${cprefix}VLanguage__${tsym.language},.kind=${cprefix}VKind__${kind_name},.info=${info},.methods=${methods}}' } -// gen_attrs_array generates C code for []Attr +// gen_attrs_array generates C code for []VAttribute @[inline] fn (g &Gen) gen_attrs_array(attrs []ast.Attr) string { + type_name := 'VAttribute' if attrs.len == 0 { - return g.gen_empty_array('string') + return g.gen_empty_array(type_name) } mut items := []string{cap: attrs.len} for attr in attrs { - mut s := attr.name - if attr.has_arg { - s += '=${attr.arg}' - } - items << '_S("${cescape_nonascii(util.smart_quote(s, false))}")' + items << '((${type_name}){.name=_S("${cescape_nonascii(util.smart_quote(attr.name, false))}"),.has_arg=${attr.has_arg},.arg=_S("${cescape_nonascii(util.smart_quote(attr.arg, + false))}"),.kind=${int(attr.kind)}})' } - mut out := 'builtin__new_array_from_c_array(${attrs.len},${attrs.len},sizeof(string),' - out += '_MOV((string[${attrs.len}]){' + mut out := 'builtin__new_array_from_c_array(${attrs.len},${attrs.len},sizeof(${type_name}),' + out += '_MOV((${type_name}[${attrs.len}]){' out += items.join(',') out += '}))' return out @@ -116,7 +116,8 @@ fn (g &Gen) gen_fields_array(fields []ast.StructField) string { } mut out := 'builtin__new_array_from_c_array(${fields.len},${fields.len},sizeof(${cprefix}StructField),' out += '_MOV((${cprefix}StructField[${fields.len}]){' - out += fields.map('((${cprefix}StructField){.name=_S("${it.name}"),.typ=${int(it.typ)},.attrs=${g.gen_attrs_array(it.attrs)},.is_pub=${it.is_pub},.is_mut=${it.is_mut}})').join(',') + out += + fields.map('((${cprefix}StructField){.name=_S("${it.name}"),.typ=${int(it.typ)},.attrs=${g.gen_attrs_array(it.attrs)},.is_pub=${it.is_pub},.is_mut=${it.is_mut}})').join(',') out += '}))' return out } diff --git a/vlib/v/gen/c/spawn_and_go.v b/vlib/v/gen/c/spawn_and_go.v index 0bf7a4274f..adbc11d06e 100644 --- a/vlib/v/gen/c/spawn_and_go.v +++ b/vlib/v/gen/c/spawn_and_go.v @@ -50,8 +50,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { } } else if mut expr.left is ast.AnonFn { if expr.left.inherited_vars.len > 0 { - fn_var := g.fn_var_signature(ast.void_type, expr.left.decl.return_type, expr.left.decl.params.map(it.typ), - tmp_fn) + fn_var := g.fn_var_signature(ast.void_type, expr.left.decl.return_type, + expr.left.decl.params.map(it.typ), tmp_fn) g.write('\t${fn_var} = ') g.gen_anon_fn(mut expr.left) g.writeln(';') @@ -139,8 +139,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { if param.name == expr.name { if param.typ.has_flag(.generic) || g.type_has_unresolved_generic_parts(param.typ) { mut muttable := unsafe { &ast.Table(g.table) } - if resolved_type := muttable.convert_generic_type(param.typ, orig_fn.generic_names, - g.cur_concrete_types) + if resolved_type := muttable.convert_generic_type(param.typ, + orig_fn.generic_names, g.cur_concrete_types) { fn_sym := g.table.sym(resolved_type) if fn_sym.info is ast.FnType { @@ -233,8 +233,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { if param.typ.has_flag(.generic) || g.type_has_unresolved_generic_parts(param.typ) { mut muttable := unsafe { &ast.Table(g.table) } - if resolved := muttable.convert_generic_type(param.typ, orig_fn.generic_names, - g.cur_concrete_types) + if resolved := muttable.convert_generic_type(param.typ, + orig_fn.generic_names, g.cur_concrete_types) { fn_var_type = resolved } @@ -247,13 +247,13 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { info := fn_sym.info as ast.FnType resolved_fn_params = info.func.params.clone() wrapper_return_type = info.func.return_type - fn_var = g.fn_var_signature(ast.void_type, wrapper_return_type, info.func.params.map(it.typ), - 'fn') + fn_var = g.fn_var_signature(ast.void_type, wrapper_return_type, + info.func.params.map(it.typ), 'fn') } else if node.call_expr.left is ast.AnonFn { f := node.call_expr.left.decl wrapper_return_type = f.return_type - fn_var = g.fn_var_signature(ast.void_type, wrapper_return_type, f.params.map(it.typ), - 'fn') + fn_var = + g.fn_var_signature(ast.void_type, wrapper_return_type, f.params.map(it.typ), 'fn') } else { if node.call_expr.is_method { rec_sym := g.table.sym(g.unwrap_generic(node.call_expr.receiver_type)) @@ -265,8 +265,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { mut arg_types := f.params.map(it.typ) arg_types = arg_types.map(muttable.convert_generic_type(it, f.generic_names, node.call_expr.concrete_types) or { it }) - fn_var = g.fn_var_signature(ast.void_type, return_type, arg_types, - 'fn') + fn_var = g.fn_var_signature(ast.void_type, return_type, arg_types, 'fn') } } else { if f := g.table.find_fn(node.call_expr.name) { @@ -290,8 +289,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { } } } - fn_var = g.fn_var_signature(ast.void_type, return_type, arg_types, - 'fn') + fn_var = g.fn_var_signature(ast.void_type, return_type, arg_types, 'fn') } } } @@ -330,8 +328,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { } arg_sym := g.table.sym(arg_typ) if arg_sym.info is ast.FnType { - sig := g.fn_var_signature(arg_typ, arg_sym.info.func.return_type, arg_sym.info.func.params.map(it.typ), - 'arg${i + 1}') + sig := g.fn_var_signature(arg_typ, arg_sym.info.func.return_type, + arg_sym.info.func.params.map(it.typ), 'arg${i + 1}') g.type_definitions.writeln('\t' + sig + ';') } else { styp := g.styp(arg_typ) @@ -366,8 +364,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { && (typ_sym.info as ast.Interface).defines_method(expr.name) { rec_cc_type := g.cc_type(unwrapped_rec_type, false) receiver_type_name := util.no_dots(rec_cc_type) - g.gowrappers.write_string2('${c_name(receiver_type_name)}_name_table[', - 'arg->arg0') + g.gowrappers.write_string2('${c_name(receiver_type_name)}_name_table[', 'arg->arg0') dot_or_ptr := g.dot_or_ptr(unwrapped_rec_type) mname := c_name(expr.name) g.gowrappers.write_string2('${dot_or_ptr}_typ]._method_${mname}(', 'arg->arg0') diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index a4d041e1b9..9deda9c53b 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -326,8 +326,8 @@ fn (mut g Gen) struct_init(node ast.StructInit) { t_concrete_types << g.cur_concrete_types[index] } } else { - if tt := g.table.convert_generic_type(t_typ, g.cur_fn.generic_names, - g.cur_concrete_types) + if tt := g.table.convert_generic_type(t_typ, + g.cur_fn.generic_names, g.cur_concrete_types) { t_concrete_types << tt } @@ -375,8 +375,9 @@ fn (mut g Gen) struct_init(node ast.StructInit) { // workaround for tcc bug, is_auto_deref_var := ... issue #24331 is_auto_deref_var := node.update_expr.is_auto_deref_var() g.fixed_array_update_expr_field(g.expr_string(node.update_expr), - node.update_expr_type, field.name, is_auto_deref_var, update_expr_sym.info.elem_type, - update_expr_sym.info.size, node.is_update_embed) + node.update_expr_type, field.name, is_auto_deref_var, + update_expr_sym.info.elem_type, update_expr_sym.info.size, + node.is_update_embed) } else { g.write('(') g.expr(node.update_expr) @@ -607,8 +608,7 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool { g.expr_with_opt(ast.None{}, ast.none_type, field.typ) } else { tmp_var := g.new_tmp_var() - g.expr_with_tmp_var(default_init, field.typ, field.typ, tmp_var, - true) + g.expr_with_tmp_var(default_init, field.typ, field.typ, tmp_var, true) } } else { g.struct_init(default_init) @@ -641,18 +641,19 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool { return true } else if field.typ.has_flag(.option) { tmp_var := g.new_tmp_var() - g.expr_with_tmp_var(field.default_expr, field.default_expr_typ, field.typ, - tmp_var, true) + g.expr_with_tmp_var(field.default_expr, field.default_expr_typ, field.typ, tmp_var, + true) return true } else if field.typ.has_flag(.result) && !field.default_expr_typ.has_flag(.result) { tmp_var := g.new_tmp_var() - g.expr_with_tmp_var(field.default_expr, field.default_expr_typ, field.typ, - tmp_var, true) + g.expr_with_tmp_var(field.default_expr, field.default_expr_typ, field.typ, tmp_var, + true) return true } else if final_sym.info is ast.ArrayFixed && field.default_expr !is ast.ArrayInit { old_inside_memset := g.inside_memset g.inside_memset = true tmp_var := g.expr_with_var(field.default_expr, field.default_expr_typ, + field.default_expr !is ast.CallExpr && field.default_expr !is ast.CastExpr) g.fixed_array_var_init(tmp_var, false, final_sym.info.elem_type, final_sym.info.size) g.inside_memset = old_inside_memset @@ -840,7 +841,8 @@ fn (mut g Gen) struct_decl(s ast.Struct, name string, is_anon bool, is_option bo if field_sym.info.is_anon { field_is_anon = true // Recursively generate code for this anon struct (this is the field's type) - g.struct_decl(field_sym.info, field_sym.cname, true, field.typ.has_flag(.option)) + g.struct_decl(field_sym.info, field_sym.cname, true, + field.typ.has_flag(.option)) // Now the field's name g.type_definitions.writeln(' ${field_name}${size_suffix};') } @@ -966,8 +968,7 @@ fn (mut g Gen) struct_init_field_value(sfield ast.StructInitField) { field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size) } ast.CastExpr, ast.CallExpr { - tmp_var := g.expr_with_var(ast.Expr(sfield.expr), sfield.expected_type, - false) + tmp_var := g.expr_with_var(ast.Expr(sfield.expr), sfield.expected_type, false) g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size) } @@ -1012,8 +1013,7 @@ fn (mut g Gen) struct_init_field_default(field_unwrap_typ ast.Type, sfield &ast. g.expr_opt_with_cast(ast.Expr(sfield.expr), field_unwrap_typ, sfield.expected_type) } else if field_unwrap_sym.kind == .function && sfield.expected_type.has_flag(.option) { tmp_out_var := g.new_tmp_var() - g.expr_with_tmp_var(sfield.expr, field_unwrap_typ, sfield.expected_type, tmp_out_var, - true) + g.expr_with_tmp_var(sfield.expr, field_unwrap_typ, sfield.expected_type, tmp_out_var, true) } else { g.left_is_opt = true g.expr_with_cast(sfield.expr, field_unwrap_typ, sfield.expected_type) diff --git a/vlib/v/gen/c/testdata/c_extern_on_C_global_declarations.vv b/vlib/v/gen/c/testdata/c_extern_on_C_global_declarations.vv index 42181fbc0b..90cf35817c 100644 --- a/vlib/v/gen/c/testdata/c_extern_on_C_global_declarations.vv +++ b/vlib/v/gen/c/testdata/c_extern_on_C_global_declarations.vv @@ -3,10 +3,8 @@ module main #include "@DIR/c_file_for_c_extern.c" -// These could be macros, but without the @[c_extern] tag, they should still work. +// C.stdout and C.stderr are now declared in builtin/cfns.c.v as `&C.FILE`. // V should treat their type as `&C.FILE`, and *NOT* as the default `int` type for C names. -__global C.stdout &C.FILE -__global C.stderr &C.FILE // This should generate: `i16 My_non_extern_C_global = -9876;` . Note the lack of `extern `. __global C.My_non_extern_C_global = i16(-9876) diff --git a/vlib/v/gen/c/testdata/freestanding_module_import_2.out b/vlib/v/gen/c/testdata/freestanding_module_import_2.out index e2913fbe82..6f91f3f65e 100644 --- a/vlib/v/gen/c/testdata/freestanding_module_import_2.out +++ b/vlib/v/gen/c/testdata/freestanding_module_import_2.out @@ -1,2 +1,3 @@ +unbuffer_stdout is not implemented hi from a_d_freestanding.c.v f.len: 143 diff --git a/vlib/v/gen/c/testdata/freestanding_net_const_memcpy.c.must_have b/vlib/v/gen/c/testdata/freestanding_net_const_memcpy.c.must_have index 33271d1350..e40ff37d55 100644 --- a/vlib/v/gen/c/testdata/freestanding_net_const_memcpy.c.must_have +++ b/vlib/v/gen/c/testdata/freestanding_net_const_memcpy.c.must_have @@ -1,6 +1,6 @@ void *memcpy(void *dest, const void *src, size_t n); void *memmove(void *dest, const void *src, size_t n); -VV_EXP voidptr memcpy(voidptr dest, const voidptr const_src, usize n); -VV_EXP usize strlen(const char* const_s); -VV_EXP voidptr memmove(voidptr dest, const voidptr const_src, usize n); -VV_EXP int memcmp(const voidptr const_a, const voidptr const_b, usize n); +VV_EXP voidptr memcpy(voidptr dest, const void* const_src, usize n); +VV_EXP usize strlen(const void* const_s); +VV_EXP voidptr memmove(voidptr dest, const void* const_src, usize n); +VV_EXP int memcmp(const void* const_a, const void* const_b, usize n); diff --git a/vlib/v/gen/c/testdata/iface_method_embed_ptr_receiver.c.must_have b/vlib/v/gen/c/testdata/iface_method_embed_ptr_receiver.c.must_have index f9c12443e6..332e5c4617 100644 --- a/vlib/v/gen/c/testdata/iface_method_embed_ptr_receiver.c.must_have +++ b/vlib/v/gen/c/testdata/iface_method_embed_ptr_receiver.c.must_have @@ -1,3 +1 @@ -static inline int main__App_level_Interface_main__Leveler_method_wrapper(void* _) -return main__Log_level(&(_interface_obj->Log)); -._method_level = (void*) main__App_level_Interface_main__Leveler_method_wrapper, +._method_level = (void*) main__Log_level, diff --git a/vlib/v/gen/c/testdata/iface_method_mut_receiver.c.must_have b/vlib/v/gen/c/testdata/iface_method_mut_receiver.c.must_have index 50539e8411..bfe82c7fbc 100644 --- a/vlib/v/gen/c/testdata/iface_method_mut_receiver.c.must_have +++ b/vlib/v/gen/c/testdata/iface_method_mut_receiver.c.must_have @@ -1,4 +1,2 @@ -static inline void main__Bar_free_Interface_main__Foo_method_wrapper(void* _) -static inline u32 main__Bar_next_Interface_main__Foo_method_wrapper(void* _) -._method__v_free = (void*) main__Bar_free_Interface_main__Foo_method_wrapper, -._method_next = (void*) main__Bar_next_Interface_main__Foo_method_wrapper, +._method__v_free = (void*) main__Bar_free, +._method_next = (void*) main__Bar_next, diff --git a/vlib/v/gen/c/testdata/sumtype_pass_by_reference.out b/vlib/v/gen/c/testdata/sumtype_pass_by_reference.out index cf5c166e2c..5c540a7571 100644 --- a/vlib/v/gen/c/testdata/sumtype_pass_by_reference.out +++ b/vlib/v/gen/c/testdata/sumtype_pass_by_reference.out @@ -1,44 +1,20 @@ &Expr(ParExpr{ expr: Expr(InfixExpr{ - left: Expr(InfixExpr{ - left: unknown sum type value - right: unknown sum type value - }) - right: Expr(InfixExpr{ - left: unknown sum type value - right: unknown sum type value - }) + left: Expr() + right: Expr() }) }) &Expr(ParExpr{ expr: Expr(InfixExpr{ - left: Expr(InfixExpr{ - left: unknown sum type value - right: unknown sum type value - }) - right: Expr(InfixExpr{ - left: unknown sum type value - right: unknown sum type value - }) + left: Expr() + right: Expr() }) }) &Expr(InfixExpr{ - left: Expr(InfixExpr{ - left: unknown sum type value - right: unknown sum type value - }) - right: Expr(InfixExpr{ - left: unknown sum type value - right: unknown sum type value - }) + left: Expr() + right: Expr() }) &Expr(InfixExpr{ - left: Expr(InfixExpr{ - left: unknown sum type value - right: unknown sum type value - }) - right: Expr(InfixExpr{ - left: unknown sum type value - right: unknown sum type value - }) + left: Expr() + right: Expr() }) diff --git a/vlib/v/gen/c/utils.v b/vlib/v/gen/c/utils.v index 726e54384e..a7931970f7 100644 --- a/vlib/v/gen/c/utils.v +++ b/vlib/v/gen/c/utils.v @@ -128,8 +128,7 @@ fn (mut g Gen) recheck_concrete_type(typ ast.Type) ast.Type { return resolved_typ } mut muttable := unsafe { &ast.Table(g.table) } - unwrapped_typ := muttable.unwrap_generic_type_ex(typ, generic_names, concrete_types, - true) + unwrapped_typ := muttable.unwrap_generic_type_ex(typ, generic_names, concrete_types, true) if unwrapped_typ != typ { return unwrapped_typ } @@ -242,7 +241,8 @@ fn (mut g Gen) resolved_scope_var_type(expr ast.Ident) ast.Type { if (v.is_unwrapped || v.smartcasts.len > 0) && scope.parent != unsafe { nil } { if mut parent_v := scope.parent.find_var(expr.name) { if parent_v.generic_typ != 0 { - refreshed_parent_type := g.unwrap_generic(g.recheck_concrete_type(parent_v.generic_typ)) + refreshed_parent_type := + g.unwrap_generic(g.recheck_concrete_type(parent_v.generic_typ)) if refreshed_parent_type != 0 { parent_v.typ = refreshed_parent_type } @@ -253,7 +253,8 @@ fn (mut g Gen) resolved_scope_var_type(expr ast.Ident) ast.Type { && parent_v.expr.name == expr.name) { resolved_parent_expr_type := g.resolved_expr_type(parent_v.expr, parent_v.typ) if resolved_parent_expr_type != 0 { - parent_v.typ = g.unwrap_generic(g.recheck_concrete_type(resolved_parent_expr_type)) + parent_v.typ = + g.unwrap_generic(g.recheck_concrete_type(resolved_parent_expr_type)) } } if v.is_unwrapped { @@ -279,7 +280,8 @@ fn (mut g Gen) resolved_scope_var_type(expr ast.Ident) ast.Type { if v.is_inherited && scope.parent != unsafe { nil } { if mut parent_v := scope.parent.find_var(expr.name) { if parent_v.generic_typ != 0 { - refreshed_parent_type := g.unwrap_generic(g.recheck_concrete_type(parent_v.generic_typ)) + refreshed_parent_type := + g.unwrap_generic(g.recheck_concrete_type(parent_v.generic_typ)) if refreshed_parent_type != 0 { parent_v.typ = refreshed_parent_type } @@ -393,7 +395,8 @@ fn (mut g Gen) resolved_ident_array_elem_type(expr ast.Ident) ast.Type { return g.unwrap_generic(g.recheck_concrete_type(array_init.elem_type)) } if array_init.typ != 0 { - elem_type := g.recheck_concrete_type(g.table.value_type(g.unwrap_generic(array_init.typ))) + elem_type := + g.recheck_concrete_type(g.table.value_type(g.unwrap_generic(array_init.typ))) if elem_type != 0 { return g.unwrap_generic(elem_type) } @@ -595,7 +598,8 @@ fn (mut g Gen) resolved_expr_type(expr ast.Expr, default_typ ast.Type) ast.Type // since scope types may be stale from a previous checker instantiation if g.cur_concrete_types.len > 0 && (g.cur_fn.receiver.typ.has_flag(.generic) || g.type_has_unresolved_generic_parts(g.cur_fn.receiver.typ)) { - resolved_receiver_type := g.unwrap_generic(g.recheck_concrete_type(g.cur_fn.receiver.typ)) + resolved_receiver_type := + g.unwrap_generic(g.recheck_concrete_type(g.cur_fn.receiver.typ)) if resolved_receiver_type != 0 { return resolved_receiver_type } @@ -604,7 +608,8 @@ fn (mut g Gen) resolved_expr_type(expr ast.Expr, default_typ ast.Type) ast.Type if scope_type != 0 { return scope_type } - resolved_receiver_type := g.unwrap_generic(g.recheck_concrete_type(g.cur_fn.receiver.typ)) + resolved_receiver_type := + g.unwrap_generic(g.recheck_concrete_type(g.cur_fn.receiver.typ)) if resolved_receiver_type != 0 { return resolved_receiver_type } @@ -743,7 +748,8 @@ fn (mut g Gen) resolved_expr_type(expr ast.Expr, default_typ ast.Type) ast.Type source_field_type = parent_field.typ match parent_sym.info { ast.Struct, ast.Interface, ast.SumType { - generic_names = parent_sym.info.generic_types.map(g.table.sym(it).name) + generic_names = + parent_sym.info.generic_types.map(g.table.sym(it).name) } else {} } @@ -772,7 +778,8 @@ fn (mut g Gen) resolved_expr_type(expr ast.Expr, default_typ ast.Type) ast.Type } match parent_sym.info { ast.Struct, ast.Interface, ast.SumType { - generic_names := parent_sym.info.generic_types.map(g.table.sym(it).name) + generic_names := + parent_sym.info.generic_types.map(g.table.sym(it).name) if generic_names.len == sym.info.concrete_types.len && sym.info.concrete_types.len > 0 { mut muttable := unsafe { &ast.Table(g.table) } @@ -820,7 +827,8 @@ fn (mut g Gen) resolved_expr_type(expr ast.Expr, default_typ ast.Type) ast.Type if expr.index is ast.RangeExpr { mut slice_type := ast.Type(0) if expr.left is ast.Ident { - resolved_left_type := g.resolve_current_fn_generic_param_type(expr.left.name) + resolved_left_type := + g.resolve_current_fn_generic_param_type(expr.left.name) if resolved_left_type != 0 { slice_type = g.unwrap_generic(resolved_left_type) } @@ -839,12 +847,14 @@ fn (mut g Gen) resolved_expr_type(expr ast.Expr, default_typ ast.Type) ast.Type return slice_type } if expr.left is ast.Ident { - resolved_value_type := g.resolve_current_fn_generic_param_value_type(expr.left.name) + resolved_value_type := + g.resolve_current_fn_generic_param_value_type(expr.left.name) if resolved_value_type != 0 { return g.unwrap_generic(resolved_value_type) } } - value_type := g.recheck_concrete_type(g.table.value_type(g.unwrap_generic(left_type))) + value_type := + g.recheck_concrete_type(g.table.value_type(g.unwrap_generic(left_type))) if value_type != 0 { return g.unwrap_generic(value_type) } @@ -896,6 +906,29 @@ fn (mut g Gen) resolved_expr_type(expr ast.Expr, default_typ ast.Type) ast.Type if resolved != ast.void_type { return g.unwrap_generic(g.recheck_concrete_type(resolved)) } + // When resolve_return_type fails (e.g. fn field call where no method exists), + // try resolving from return_type_generic using receiver generic type names. + // This handles cases like Procedure[T,U].handle() calling p.function(p.value) + // where return_type is contaminated from the last checker pass but + // return_type_generic preserves the original generic return type (!U). + if expr.return_type_generic != 0 && expr.return_type_generic.has_flag(.generic) + && g.cur_fn != unsafe { nil } && g.cur_fn.is_method + && g.cur_fn.receiver.typ.has_flag(.generic) && g.cur_concrete_types.len > 0 { + receiver_generic_names := g.table.generic_type_names(g.cur_fn.receiver.typ) + if receiver_generic_names.len == g.cur_concrete_types.len { + if gen_type := g.table.convert_generic_type(expr.return_type_generic, + receiver_generic_names, g.cur_concrete_types) + { + if !gen_type.has_flag(.generic) { + return if expr.or_block.kind == .absent { + gen_type + } else { + gen_type.clear_option_and_result() + } + } + } + } + } if expr.return_type != 0 { return if expr.or_block.kind == .absent { g.unwrap_generic(g.recheck_concrete_type(expr.return_type)) @@ -1039,7 +1072,8 @@ fn (mut g Gen) resolved_expr_type(expr ast.Expr, default_typ ast.Type) ast.Type if resolved_inner_type.is_ptr() { resolved_inner_type.deref() } else { - resolved_right_type := g.unwrap_generic(g.recheck_concrete_type(right_default)) + resolved_right_type := + g.unwrap_generic(g.recheck_concrete_type(right_default)) if resolved_right_type.is_ptr() { resolved_right_type.deref() } else { @@ -1119,7 +1153,7 @@ fn (mut g Gen) unwrap(typ ast.Type) Type { // generate function variable definition, e.g. `void (*var_name) (int, string)` fn (mut g Gen) fn_var_signature(var_type ast.Type, return_type ast.Type, arg_types []ast.Type, var_name string) string { - if var_type.has_flag(.option) { + if var_type.has_flag(.option) || var_type.has_flag(.result) { return '${g.styp(var_type)} ${c_name(var_name)}' } ret_styp := g.styp(return_type) @@ -1129,8 +1163,7 @@ fn (mut g Gen) fn_var_signature(var_type ast.Type, return_type ast.Type, arg_typ arg_sym := g.table.sym(arg_typ) if arg_sym.info is ast.FnType { func := arg_sym.info.func - arg_sig := g.fn_var_signature(arg_typ, func.return_type, func.params.map(it.typ), - '') + arg_sig := g.fn_var_signature(arg_typ, func.return_type, func.params.map(it.typ), '') sig += arg_sig } else { arg_styp := g.styp(arg_typ) @@ -1151,7 +1184,8 @@ fn (mut g Gen) anon_fn_cname(return_type ast.Type, arg_types []ast.Type) string for j, arg_typ in arg_types { arg_sym := g.table.sym(arg_typ) if arg_sym.info is ast.FnType { - sig += g.anon_fn_cname(arg_sym.info.func.return_type, arg_sym.info.func.params.map(it.typ)) + sig += g.anon_fn_cname(arg_sym.info.func.return_type, + arg_sym.info.func.params.map(it.typ)) } else { sig += g.styp(arg_typ).replace('*', '_ptr') } diff --git a/vlib/v/gen/golang/golang.v b/vlib/v/gen/golang/golang.v index 7d3fe5e7a2..cefb8d7967 100644 --- a/vlib/v/gen/golang/golang.v +++ b/vlib/v/gen/golang/golang.v @@ -906,8 +906,7 @@ pub fn (mut f Gen) enum_decl(node ast.EnumDecl) { pub fn (mut f Gen) fn_decl(node ast.FnDecl) { f.attrs(node.attrs) - f.write(f.table.stringify_fn_decl(&node, f.cur_mod, f.mod2alias, false).replace('fn ', - 'func ')) + f.write(f.table.stringify_fn_decl(&node, f.cur_mod, f.mod2alias, false).replace('fn ', 'func ')) f.fn_body(node) } @@ -1286,8 +1285,7 @@ pub fn (mut f Gen) fn_type_decl(node ast.FnTypeDecl) { f.write(')') if fn_info.return_type.idx() != ast.void_type_idx { f.mark_types_import_as_used(fn_info.return_type) - ret_str := f.no_cur_mod(f.table.type_to_str_using_aliases(fn_info.return_type, - f.mod2alias)) + ret_str := f.no_cur_mod(f.table.type_to_str_using_aliases(fn_info.return_type, f.mod2alias)) f.write(' ${ret_str}') } else if fn_info.return_type.has_flag(.option) { f.write(' ?') diff --git a/vlib/v/gen/golang/struct.v b/vlib/v/gen/golang/struct.v index 5c080ecbb6..c0490e841c 100644 --- a/vlib/v/gen/golang/struct.v +++ b/vlib/v/gen/golang/struct.v @@ -63,7 +63,8 @@ pub fn (mut f Gen) struct_decl(node ast.StructDecl) { // keep one empty line between fields (exclude one after mut:, pub:, ...) mut before_last_line := node.fields[i - 1].pos.line_nr if node.fields[i - 1].has_default_expr { - before_last_line = int_max(before_last_line, node.fields[i - 1].default_expr.pos().last_line) + before_last_line = int_max(before_last_line, + node.fields[i - 1].default_expr.pos().last_line) } mut next_first_line := field.pos.line_nr diff --git a/vlib/v/gen/golang/tests/golang_test.v b/vlib/v/gen/golang/tests/golang_test.v index e149d07053..2679c7d732 100644 --- a/vlib/v/gen/golang/tests/golang_test.v +++ b/vlib/v/gen/golang/tests/golang_test.v @@ -51,7 +51,8 @@ fn test_golang() { } tmperrfile := '${dir}/${test}.tmperr' go_basename := $if windows { 'go.exe' } $else { 'go' } - res := os.execute('${go_basename} run ${os.quoted_path(go_out_test_path)} 2> ${os.quoted_path(tmperrfile)}') + res := + os.execute('${go_basename} run ${os.quoted_path(go_out_test_path)} 2> ${os.quoted_path(tmperrfile)}') if res.exit_code != 0 { bench.fail() eprintln(bench.step_message_fail('${full_test_path} failed to run')) diff --git a/vlib/v/gen/js/auto_str_methods.v b/vlib/v/gen/js/auto_str_methods.v index 45a47aaaa0..6c84b835b1 100644 --- a/vlib/v/gen/js/auto_str_methods.v +++ b/vlib/v/gen/js/auto_str_methods.v @@ -12,6 +12,29 @@ mut: typ ast.Type } +fn (mut g JsGen) ensure_autostr_helpers() { + if g.generated_autostr_helpers { + return + } + g.generated_autostr_helpers = true + g.definitions.writeln('const builtin__autostr_type_stack_max_depth = 64;') + g.definitions.writeln('let builtin__g_autostr_type_stack = Array(builtin__autostr_type_stack_max_depth).fill(0);') + g.definitions.writeln('let builtin__g_autostr_type_stack_len = 0;') + g.definitions.writeln('function builtin__autostr_type_in_stack(typ) {') + g.definitions.writeln('\tfor (let i = 0; i < builtin__g_autostr_type_stack_len; ++i) {') + g.definitions.writeln('\t\tif (builtin__g_autostr_type_stack[i] === typ) return true;') + g.definitions.writeln('\t}') + g.definitions.writeln('\treturn false;') + g.definitions.writeln('}') + g.definitions.writeln('function builtin__autostr_type_push(typ) {') + g.definitions.writeln('\tif (builtin__g_autostr_type_stack_len >= builtin__autostr_type_stack_max_depth) return;') + g.definitions.writeln('\tbuiltin__g_autostr_type_stack[builtin__g_autostr_type_stack_len++] = typ;') + g.definitions.writeln('}') + g.definitions.writeln('function builtin__autostr_type_pop() {') + g.definitions.writeln('\tif (builtin__g_autostr_type_stack_len > 0) builtin__g_autostr_type_stack_len--;') + g.definitions.writeln('}') +} + fn (mut g JsGen) get_str_fn(typ ast.Type) string { mut unwrapped := g.unwrap_generic(typ).set_nr_muls(0).clear_flag(.variadic) if g.pref.nofloat { @@ -719,6 +742,7 @@ fn (mut g JsGen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name st } allow_circular := info.attrs.any(it.name == 'autostr' && it.arg == 'allowrecurse') if !allow_circular { + g.ensure_autostr_helpers() fn_builder.writeln('\tif (builtin__autostr_type_in_stack(${type_idx})) {') fn_builder.writeln('\t\treturn new string("")') fn_builder.writeln('\t}') diff --git a/vlib/v/gen/js/global_export_test.v b/vlib/v/gen/js/global_export_test.v index 7ec116a712..51da6c3cea 100644 --- a/vlib/v/gen/js/global_export_test.v +++ b/vlib/v/gen/js/global_export_test.v @@ -27,7 +27,8 @@ fn test_js_backend_supports_exported_global_aliases() { source_path := os.join_path(js_global_export_test_dir, 'global_export.v') js_path := os.join_path(js_global_export_test_dir, 'global_export.js') os.write_file(source_path, js_global_export_test_source) or { panic(err) } - compile_res := os.execute('${os.quoted_path(js_global_export_test_vexe)} -b js -w -o ${os.quoted_path(js_path)} ${os.quoted_path(source_path)}') + compile_res := + os.execute('${os.quoted_path(js_global_export_test_vexe)} -b js -w -o ${os.quoted_path(js_path)} ${os.quoted_path(source_path)}') if compile_res.exit_code != 0 { panic(compile_res.output) } diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 45f91d8605..f820c2a8c1 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -43,54 +43,55 @@ mut: struct JsGen { pref &pref.Preferences mut: - table &ast.Table = unsafe { nil } - definitions strings.Builder - ns &Namespace = unsafe { nil } - namespaces map[string]&Namespace - doc &JsDoc = unsafe { nil } - enable_doc bool - file &ast.File = unsafe { nil } - tmp_count int - inside_ternary bool - inside_or bool - inside_loop bool - inside_left_shift bool - inside_map_set bool // map.set(key, value) - inside_builtin bool - inside_if_option bool - generated_builtin bool - inside_def_typ_decl bool - is_test bool - stmt_start_pos int - defer_stmts []ast.DeferStmt - fn_decl &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0 - generated_str_fns []StrType - str_types []StrType // types that need automatic str() generation - copy_types []StrType // types that need to be deep copied - generated_copy_fns []StrType - array_fn_definitions []string // array equality functions that have been defined - map_fn_definitions []string // map equality functions that have been defined - struct_fn_definitions []string // struct equality functions that have been defined - sumtype_fn_definitions []string // sumtype equality functions that have been defined - alias_fn_definitions []string // alias equality functions that have been defined - auto_fn_definitions []string // auto generated functions definition list - anon_fn_definitions []string // anon generated functions definition list - copy_fn_definitions []string - method_fn_decls map[string][]ast.FnDecl - builtin_fns []string // Functions defined in `builtin` - empty_line bool - cast_stack []ast.Type - call_stack []ast.CallExpr - is_vlines_enabled bool // is it safe to generate #line directives when -g is passed - sourcemap &sourcemap.SourceMap = unsafe { nil } // maps lines in generated javascrip file to original source files and line - comptime_var_type_map map[string]ast.Type - defer_ifdef string - cur_concrete_types []ast.Type - out strings.Builder = strings.new_builder(128) - array_sort_fn map[string]bool - wasm_export map[string][]string - wasm_import map[string][]string - init_global map[string]map[string]ast.Expr // initializers for constants or globals, should be invoked before module init. + table &ast.Table = unsafe { nil } + definitions strings.Builder + ns &Namespace = unsafe { nil } + namespaces map[string]&Namespace + doc &JsDoc = unsafe { nil } + enable_doc bool + file &ast.File = unsafe { nil } + tmp_count int + inside_ternary bool + inside_or bool + inside_loop bool + inside_left_shift bool + inside_map_set bool // map.set(key, value) + inside_builtin bool + inside_if_option bool + generated_builtin bool + generated_autostr_helpers bool + inside_def_typ_decl bool + is_test bool + stmt_start_pos int + defer_stmts []ast.DeferStmt + fn_decl &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0 + generated_str_fns []StrType + str_types []StrType // types that need automatic str() generation + copy_types []StrType // types that need to be deep copied + generated_copy_fns []StrType + array_fn_definitions []string // array equality functions that have been defined + map_fn_definitions []string // map equality functions that have been defined + struct_fn_definitions []string // struct equality functions that have been defined + sumtype_fn_definitions []string // sumtype equality functions that have been defined + alias_fn_definitions []string // alias equality functions that have been defined + auto_fn_definitions []string // auto generated functions definition list + anon_fn_definitions []string // anon generated functions definition list + copy_fn_definitions []string + method_fn_decls map[string][]ast.FnDecl + builtin_fns []string // Functions defined in `builtin` + empty_line bool + cast_stack []ast.Type + call_stack []ast.CallExpr + is_vlines_enabled bool // is it safe to generate #line directives when -g is passed + sourcemap &sourcemap.SourceMap = unsafe { nil } // maps lines in generated javascrip file to original source files and line + comptime_var_type_map map[string]ast.Type + defer_ifdef string + cur_concrete_types []ast.Type + out strings.Builder = strings.new_builder(128) + array_sort_fn map[string]bool + wasm_export map[string][]string + wasm_import map[string][]string + init_global map[string]map[string]ast.Expr // initializers for constants or globals, should be invoked before module init. } fn (mut g JsGen) write_tests_definitions() { diff --git a/vlib/v/gen/js/jsgen_test.v b/vlib/v/gen/js/jsgen_test.v index 36d6693502..593acb8718 100644 --- a/vlib/v/gen/js/jsgen_test.v +++ b/vlib/v/gen/js/jsgen_test.v @@ -33,7 +33,8 @@ fn test_example_compilation() { node_options_file += ' --enable-source-maps' // activate souremap generation } jsfile := os.join_path_single(output_dir, '${file}.js') - v_code := os.system('${os.quoted_path(vexe)} ${v_options_file} -o ${os.quoted_path(jsfile)} ${os.quoted_path(path)}') + v_code := + os.system('${os.quoted_path(vexe)} ${v_options_file} -o ${os.quoted_path(jsfile)} ${os.quoted_path(path)}') if v_code != 0 { assert false } @@ -51,7 +52,8 @@ fn test_example_compilation() { assert js_code == 0 if should_create_source_map { if there_is_grep_available { - grep_code_sourcemap_found := os.system('grep -q -E "//#\\ssourceMappingURL=data:application/json;base64,[-A-Za-z0-9+/=]+$" ${os.quoted_path(jsfile)}') + grep_code_sourcemap_found := + os.system('grep -q -E "//#\\ssourceMappingURL=data:application/json;base64,[-A-Za-z0-9+/=]+$" ${os.quoted_path(jsfile)}') assert grep_code_sourcemap_found == 0 println('file has a source map embedded') } else { @@ -67,7 +69,8 @@ fn test_issue_11379_js_browser_builtin_print_call_does_not_panic() { os.mkdir_all(output_dir) or { panic(err) } program := os.join_path(test_dir, 'testdata', 'js_browser_builtin_print_regression.v') output := os.join_path(output_dir, 'js_browser_builtin_print_regression.js') - res := os.execute('${os.quoted_path(vexe)} -enable-globals -b js_browser -o ${os.quoted_path(output)} ${os.quoted_path(program)}') + res := + os.execute('${os.quoted_path(vexe)} -enable-globals -b js_browser -o ${os.quoted_path(output)} ${os.quoted_path(program)}') assert res.exit_code == 0, res.output assert !res.output.contains('V panic:'), res.output assert os.exists(output) diff --git a/vlib/v/gen/js/sourcemap/source_map.v b/vlib/v/gen/js/sourcemap/source_map.v index ac4c84e33e..d5e34e70a1 100644 --- a/vlib/v/gen/js/sourcemap/source_map.v +++ b/vlib/v/gen/js/sourcemap/source_map.v @@ -66,8 +66,8 @@ pub fn (mut sm SourceMap) add_mapping_list(source_name string, mapping_list []Ma } else { NameIndexType(Empty{}) } - sm.mappings.add_mapping(mapping.gen_line, mapping.gen_column, sources_ind, mapping.source_position, - names_ind) + sm.mappings.add_mapping(mapping.gen_line, mapping.gen_column, sources_ind, + mapping.source_position, names_ind) } } diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v index d49515635b..08258b6bc2 100644 --- a/vlib/v/gen/native/amd64.v +++ b/vlib/v/gen/native/amd64.v @@ -1323,8 +1323,7 @@ fn (mut c Amd64) cg_gen_syscall(node ast.CallExpr) { c.mov64(ra[i], i64(1)) } else { - c.g.v_error('Unknown syscall ${expr.type_name()} argument type ${expr}', - node.pos) + c.g.v_error('Unknown syscall ${expr.type_name()} argument type ${expr}', node.pos) return } } @@ -2251,16 +2250,13 @@ pub fn (mut c Amd64) cg_call_fn(node ast.CallExpr) { c.movabs(.rcx, i64(0xffffffffffffffff - (u64(1) << (return_size * 8)) + 1)) c.bitand_reg(.rdx, .rcx) c.bitor_reg(.rdx, .rax) - c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, - .reg2) + c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, .reg2) } 8 { - c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, - .reg0) + c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, .reg0) } 9...15 { - c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, - .reg0) + c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, .reg0) c.cg_mov_var_to_reg(.reg0, LocalVar{ offset: return_pos typ: ast.i64_type_idx @@ -2270,16 +2266,13 @@ pub fn (mut c Amd64) cg_call_fn(node ast.CallExpr) { c.movabs(.rcx, i64(0xffffffffffffffff - (u64(1) << (return_size * 8)) + 1)) c.bitand_reg(.rax, .rcx) c.bitor_reg(.rax, .rdx) - c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, - .reg0, + c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, .reg0, offset: 8 ) } 16 { - c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, - .reg0) - c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, - .reg2, + c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, .reg0) + c.cg_mov_reg_to_var(LocalVar{ offset: return_pos, typ: ast.i64_type_idx }, .reg2, offset: 8 ) } @@ -2300,7 +2293,8 @@ pub fn (mut c Amd64) cg_call_fn(node ast.CallExpr) { fn (mut c Amd64) cg_call_builtin(name Builtin) i64 { c.g.println('; call builtin `${name}`: (the 0 will get replaced)') - call_addr := c.call(0) // the 0 will get replaced by the right addr when the function will be generated + call_addr := + c.call(0) // the 0 will get replaced by the right addr when the function will be generated return call_addr } @@ -2604,8 +2598,7 @@ fn (mut c Amd64) assign_ident_right_expr(node ast.AssignStmt, i i32, right ast.E if right.is_fixed { dest := c.g.allocate_by_type(name, ast.voidptr_type_idx) c.g.expr(right) - c.cg_mov_reg_to_var(LocalVar{dest, ast.voidptr_type_idx, name}, - .reg0) + c.cg_mov_reg_to_var(LocalVar{dest, ast.voidptr_type_idx, name}, .reg0) } else if right.exprs.len == 0 { // TODO: remove when ArrayInit for dynarrays will be solved in the transformer // `[]int{len: 6, cap:10, init:22}` @@ -4009,7 +4002,8 @@ fn (mut c Amd64) cg_fn_decl(node ast.FnDecl) { name := params[i].name offset := c.g.allocate_by_type(name, params[i].typ) // copy - c.mov_ssereg_to_var(LocalVar{ offset: offset, typ: params[i].typ }, c.fn_arg_sse_registers[idx]) + c.mov_ssereg_to_var(LocalVar{ offset: offset, typ: params[i].typ }, + c.fn_arg_sse_registers[idx]) } // define args on stack mut offset := i32(-2) @@ -4292,8 +4286,7 @@ fn (mut c Amd64) copy_struct_to_struct(field ast.StructField, f_offset i32, data f2_ts := c.g.table.sym(field2.typ) if f2_ts.info is ast.Struct { - c.copy_struct_to_struct(field2, f_offset + f2_offset, data_offset + f2_offset, - var) + c.copy_struct_to_struct(field2, f_offset + f2_offset, data_offset + f2_offset, var) } else { c.mov_reg(.rdx, .rax) c.add(.rdx, data_offset + f2_offset) diff --git a/vlib/v/gen/native/elf.v b/vlib/v/gen/native/elf.v index 90ca1f6d34..8ccd43ceb9 100644 --- a/vlib/v/gen/native/elf.v +++ b/vlib/v/gen/native/elf.v @@ -496,7 +496,8 @@ fn (mut g Gen) create_symtab(mut sections []Section, mut table []SymbolTableSect offset += i32(entry.str_name.len + 1) } - sections << g.create_section('.strtab', elf_sht_strtab, 0, 0, 1, 0, g.create_string_table_section(names)) + sections << g.create_section('.strtab', elf_sht_strtab, 0, 0, 1, 0, + g.create_string_table_section(names)) sections << // index of .strtab g.create_section('.symtab', elf_sht_symtab, i32(sections.len - 1), local_symbols, @@ -504,15 +505,16 @@ fn (mut g Gen) create_symtab(mut sections []Section, mut table []SymbolTableSect } fn (mut g Gen) create_relocation(name string, mut sections []Section, table []RelASection) Section { - mut section := g.create_section(name, elf_sht_rela, g.find_section_header('.symtab', - sections), 1, 8, 24, table) + mut section := g.create_section(name, elf_sht_rela, g.find_section_header('.symtab', sections), + 1, 8, 24, table) section.header.flags = i64(elf_shf_info_link) sections << section return section } fn (mut g Gen) create_progbits(name string, flags u64, data []u8) Section { - mut section := g.create_section(name, elf_sht_progbits, 0, 0, 1, data.len, ProgBitsSection{data}) + mut section := + g.create_section(name, elf_sht_progbits, 0, 0, 1, data.len, ProgBitsSection{data}) section.header.flags = i64(flags) return section } @@ -707,8 +709,8 @@ pub fn (mut g Gen) generate_linkable_elf_header() { g.symbol_table = [ SymbolTableSection{}, // first is null - g.create_symbol_table_section('main', elf_stt_notype, elf_stb_global, elf_stv_default, - 0, 0, i16(g.find_section_header('.text', sections))), // main label points to entry point address + g.create_symbol_table_section('main', elf_stt_notype, elf_stb_global, elf_stv_default, 0, + 0, i16(g.find_section_header('.text', sections))), // main label points to entry point address g.create_symbol_table_section('_GLOBAL_OFFSET_TABLE_', elf_stt_notype, elf_stb_global, elf_stv_default, 0, 0, 0), ] @@ -733,8 +735,8 @@ pub fn (mut g Gen) generate_linkable_elf_header() { } for symbol in g.extern_symbols { - g.symbol_table << g.create_symbol_table_section(symbol[2..], elf_stt_notype, elf_stb_global, - elf_stv_default, 0, 0, 0) + g.symbol_table << g.create_symbol_table_section(symbol[2..], elf_stt_notype, + elf_stb_global, elf_stv_default, 0, 0, 0) } g.create_symtab(mut sections, mut g.symbol_table) // create the .symtab section g.create_relocation('.rela.text', mut sections, []) @@ -925,8 +927,8 @@ pub fn (mut g Gen) elf_string_table() { pub fn (mut g Gen) gen_rela_section() { mut relocations := []RelASection{} for call_pos, symbol in g.extern_fn_calls { - relocations << g.create_rela_section(symbol, call_pos - g.code_start_pos + 2, - g.symtab_get_index(g.symbol_table, symbol[2..]), elf_r_amd64_gotpcrelx, -4) + relocations << g.create_rela_section(symbol, call_pos - g.code_start_pos + 2, g.symtab_get_index(g.symbol_table, + symbol[2..]), elf_r_amd64_gotpcrelx, -4) } for var_pos, symbol in g.extern_vars { relocations << g.create_rela_section(symbol, var_pos - g.code_start_pos, g.symtab_get_index(g.symbol_table, diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index 40bdedf4b0..d256c3b090 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -1048,7 +1048,8 @@ fn (mut g Gen) allocate_string(s string, opsize i32, typ RelocType) i32 { // allocates a buffer variable: name, size of stored type (nb of bytes), nb of items fn (mut g Gen) allocate_array(name string, size i32, items i32) i32 { // TODO: remove when proper strings are implemented, should not be used g.println('; allocate array `${name}` item-size:${size} items:${items}:') - pos := g.cg.cg_allocate_stack_var(name, 4, i64(items)) // store the length of the array on the stack in a 4 byte var + pos := + g.cg.cg_allocate_stack_var(name, 4, i64(items)) // store the length of the array on the stack in a 4 byte var g.stack_var_pos += (size * items) // reserve space on the stack for the items return pos } diff --git a/vlib/v/gen/native/pe.v b/vlib/v/gen/native/pe.v index 72e15afcdb..4482ddb47b 100644 --- a/vlib/v/gen/native/pe.v +++ b/vlib/v/gen/native/pe.v @@ -684,8 +684,8 @@ fn (mut g Gen) gen_pe_idata() { g.gen_pe_idt(&PeImportDirectoryTable{}, 'null entry') // null entry for imp in imports { - g.write32_at(imp.idt_pos + pe_idt_offsetof(.import_address_table_rva), - i32(g.pos() - idata_pos) + idata_section.header.virtual_address + 4) + g.write32_at(imp.idt_pos + pe_idt_offsetof(.import_address_table_rva), i32(g.pos() - + idata_pos) + idata_section.header.virtual_address + 4) for func in imp.functions { g.pe_dll_relocations[func] = g.pos() @@ -787,7 +787,8 @@ fn (mut g Gen) patch_section_virtual_addrs() { g.write32_at(g.pe_opt_hdr_pos + pe32_plus_optional_header_offsetof(.base_of_code), section.header.virtual_address) g.write32_at(g.pe_opt_hdr_pos + - pe32_plus_optional_header_offsetof(.address_of_entry_point), section.header.virtual_address) + pe32_plus_optional_header_offsetof(.address_of_entry_point), + section.header.virtual_address) } else {} } @@ -797,8 +798,7 @@ fn (mut g Gen) patch_section_virtual_addrs() { fn (mut g Gen) patch_pe_code_size() { code_size := i32(g.file_size_pos - g.code_start_pos) - g.write32_at(g.pe_opt_hdr_pos + pe32_plus_optional_header_offsetof(.size_of_code), - code_size) + g.write32_at(g.pe_opt_hdr_pos + pe32_plus_optional_header_offsetof(.size_of_code), code_size) g.write32_at(g.pe_opt_hdr_pos + pe32_plus_optional_header_offsetof(.size_of_initialized_data), code_size) @@ -814,8 +814,7 @@ fn (mut g Gen) patch_pe_image_size() { last_section := g.pe_sections.last() image_size := (last_section.header.virtual_address + last_section.header.virtual_size + pe_section_align - 1) & ~(pe_section_align - 1) - g.write32_at(g.pe_opt_hdr_pos + pe32_plus_optional_header_offsetof(.size_of_image), - image_size) + g.write32_at(g.pe_opt_hdr_pos + pe32_plus_optional_header_offsetof(.size_of_image), image_size) } pub fn (mut g Gen) generate_pe_footer() { diff --git a/vlib/v/gen/native/readdll.c.v b/vlib/v/gen/native/readdll.c.v index 157514949c..564c304619 100644 --- a/vlib/v/gen/native/readdll.c.v +++ b/vlib/v/gen/native/readdll.c.v @@ -106,7 +106,8 @@ fn get_dllexports(mut file os.File) !map[string]bool { } sec_hdroffset = opt_hdroffset + u32(pe_opt_hdr_size) - read_pe_data_dir(mut file, opt_hdroffset + pe32_plus_opt_hdr_size, pe_export_data_dir_index)! + read_pe_data_dir(mut file, opt_hdroffset + pe32_plus_opt_hdr_size, + pe_export_data_dir_index)! } u16(PeMachine.i386) { return error('32-bit (i386) dlls not supported yet') diff --git a/vlib/v/gen/native/stmt.c.v b/vlib/v/gen/native/stmt.c.v index 7dc5e70795..e05ca81294 100644 --- a/vlib/v/gen/native/stmt.c.v +++ b/vlib/v/gen/native/stmt.c.v @@ -239,7 +239,8 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) { g.println('; label ${start_label} (start of for loop)') // Condition - mut cjmp_addr := g.condition(node.cond, false) // jmp if false, location of `jne *00 00 00 00*` (to be patched by LabelPatch) + mut cjmp_addr := + g.condition(node.cond, false) // jmp if false, location of `jne *00 00 00 00*` (to be patched by LabelPatch) end_label := g.labels.new_label() g.labels.patches << LabelPatch{ id: end_label @@ -418,8 +419,9 @@ fn (mut g Gen) gen_flag_hash_stmt(node ast.HashStmt) { return } // g.v_error('`-D` and `-I` flags are not supported with the native backend', node.pos) - println(util.formatted_error('warn', '`-D` and `-I` flags are not supported with the native backend', - g.current_file.path, node.pos)) + println(util.formatted_error('warn', + '`-D` and `-I` flags are not supported with the native backend', g.current_file.path, + node.pos)) } else { g.v_error('unknown `#flag` format: `${node.main}`', node.pos) } diff --git a/vlib/v/gen/wasm/gen.v b/vlib/v/gen/wasm/gen.v index a0a8825dc3..375890b79d 100644 --- a/vlib/v/gen/wasm/gen.v +++ b/vlib/v/gen/wasm/gen.v @@ -552,7 +552,8 @@ pub fn (mut g Gen) infix_expr(node ast.InfixExpr, expected ast.Type) { g.infix_from_typ(node.left_type, node.op) res_typ := if node.op in [.eq, .ne, .gt, .lt, .ge, .le] { ast.bool_type } else { node.left_type } - g.func.cast(g.as_numtype(g.get_wasm_type(res_typ)), res_typ.is_signed(), g.as_numtype(g.get_wasm_type(expected))) + g.func.cast(g.as_numtype(g.get_wasm_type(res_typ)), res_typ.is_signed(), + g.as_numtype(g.get_wasm_type(expected))) } pub fn (mut g Gen) prefix_expr(node ast.PrefixExpr, expected ast.Type) { @@ -682,8 +683,7 @@ fn (mut g Gen) match_branch(node ast.MatchExpr, expected ast.Type, unpacked_para } if branch.exprs.len > 0 { - g.match_branch_exprs(node, expected, unpacked_params, branch_idx, 0, existing_rvars, - branch) + g.match_branch_exprs(node, expected, unpacked_params, branch_idx, 0, existing_rvars, branch) } else { if branch.stmts.len > 0 { g.rvar_expr_stmts(branch.stmts, expected, existing_rvars) @@ -1140,7 +1140,8 @@ pub fn (mut g Gen) expr(node ast.Expr, expected ast.Type) { } } - g.func.cast(g.as_numtype(g.get_wasm_type(typ)), typ.is_signed(), g.as_numtype(g.get_wasm_type(node.typ))) + g.func.cast(g.as_numtype(g.get_wasm_type(typ)), typ.is_signed(), + g.as_numtype(g.get_wasm_type(node.typ))) } ast.CallExpr { g.call_expr(node, expected, []) @@ -1535,7 +1536,8 @@ pub fn (mut g Gen) expr_stmt(node ast.Stmt, expected ast.Type) { right := node.right[0] match right { ast.IfExpr { - params := node.left_types.filter(!g.is_param_type(it)).map(g.get_wasm_type(it)) + params := + node.left_types.filter(!g.is_param_type(it)).map(g.get_wasm_type(it)) g.if_branch(right, right.typ, params, 0, rvars) set = true } @@ -1757,7 +1759,8 @@ pub fn gen(files []&ast.File, mut table ast.Table, out_name string, w_pref &pref exe := $if windows { 'wasm-opt.exe' } $else { 'wasm-opt' } if rt := os.find_abs_path_of_executable(exe) { // -lmu: low memory unused, very important optimisation - res := os.execute('${os.quoted_path(rt)} -all -lmu -c -O4 ${os.quoted_path(out_name)} -o ${os.quoted_path(out_name)}') + res := + os.execute('${os.quoted_path(rt)} -all -lmu -c -O4 ${os.quoted_path(out_name)} -o ${os.quoted_path(out_name)}') if res.exit_code != 0 { eprintln(res.output) g.w_error('${rt} failed, this should not happen. Report an issue with the above messages, the webassembly generated, and appropriate code.') diff --git a/vlib/v/gen/wasm/mem.v b/vlib/v/gen/wasm/mem.v index 282d465738..b120e0cc7d 100644 --- a/vlib/v/gen/wasm/mem.v +++ b/vlib/v/gen/wasm/mem.v @@ -289,8 +289,8 @@ pub fn (mut g Gen) new_global(name string, typ_ ast.Type, init ast.Expr, is_glob typ: typ is_address: is_address is_global: true - g_idx: g.mod.new_global(g.dbg_type_name(name, typ), false, g.get_wasm_type_int_literal(typ), - is_mut, cexpr) + g_idx: g.mod.new_global(g.dbg_type_name(name, typ), false, + g.get_wasm_type_int_literal(typ), is_mut, cexpr) } } @@ -888,8 +888,7 @@ pub fn (mut g Gen) housekeeping() { mut buf := g.pool.buf.clone() for reloc in g.pool.relocs { - binary.little_endian_put_u32_at(mut buf, u32(g.data_base + reloc.offset), - reloc.pos) + binary.little_endian_put_u32_at(mut buf, u32(g.data_base + reloc.offset), reloc.pos) } g.mod.new_data_segment(none, g.data_base, buf) } diff --git a/vlib/v/gen/wasm/tests/wasm_test.v b/vlib/v/gen/wasm/tests/wasm_test.v index ccd1d43633..46bf70314c 100644 --- a/vlib/v/gen/wasm/tests/wasm_test.v +++ b/vlib/v/gen/wasm/tests/wasm_test.v @@ -92,8 +92,7 @@ fn test_wasm() { continue } } else { - os.write_file(outfile, res_wasm.output.trim_right('\r\n').replace('\r\n', - '\n'))! + os.write_file(outfile, res_wasm.output.trim_right('\r\n').replace('\r\n', '\n'))! } bench.ok() eprintln(bench.step_message_ok(relative_test_path)) diff --git a/vlib/v/generics/generics.v b/vlib/v/generics/generics.v index 7935b2ad0a..d46c8fab2c 100644 --- a/vlib/v/generics/generics.v +++ b/vlib/v/generics/generics.v @@ -814,14 +814,12 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr { name := if mut node.expr is ast.Ident { // var if node.expr.info is ast.IdentVar && node.expr.language == .v { - g.styp(g.unwrap_generic(node.expr.info.typ.clear_flags(.shared_f, - .result))).replace('*', '') + g.styp(g.unwrap_generic(node.expr.info.typ.clear_flags(.shared_f, .result))).replace('*', '') } else { node.cname } } else if mut node.expr is ast.CallExpr { - g.styp(g.unwrap_generic(node.expr_type.clear_flags(.shared_f, .result))).replace('*', - '').replace('.', '__') + g.styp(g.unwrap_generic(node.expr_type.clear_flags(.shared_f, .result))).replace('*', '').replace('.', '__') } else { node.cname } @@ -1274,7 +1272,9 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr { fn (mut g Generics) unwrap_generic(typ ast.Type) ast.Type { if typ.has_flag(.generic) { if g.cur_fn != unsafe { nil } && g.cur_fn.generic_names.len > 0 { - if t_typ := g.table.convert_generic_type(typ, g.cur_fn.generic_names, g.cur_concrete_types) { + if t_typ := g.table.convert_generic_type(typ, g.cur_fn.generic_names, + g.cur_concrete_types) + { return t_typ } } @@ -1284,7 +1284,9 @@ fn (mut g Generics) unwrap_generic(typ ast.Type) ast.Type { if sym.info is ast.Struct { if sym.info.generic_types.len > 0 { generic_names := sym.info.generic_types.map(g.table.sym(it).name) - if t_typ := g.table.convert_generic_type(typ, generic_names, g.cur_struct_init_node.generic_types.map(g.unwrap_generic(it))) { + if t_typ := g.table.convert_generic_type(typ, generic_names, + g.cur_struct_init_node.generic_types.map(g.unwrap_generic(it))) + { return t_typ } } @@ -1296,11 +1298,15 @@ fn (mut g Generics) unwrap_generic(typ ast.Type) ast.Type { if sym.info is ast.Struct { if sym.info.generic_types.len > 0 { generic_names := sym.info.generic_types.map(g.table.sym(it).name) - if t_typ := g.table.convert_generic_type(typ, generic_names, sym.info.concrete_types) { + if t_typ := g.table.convert_generic_type(typ, generic_names, + sym.info.concrete_types) + { return t_typ } - if t_typ := g.table.convert_generic_type(typ, generic_names, g.cur_concrete_types) { + if t_typ := g.table.convert_generic_type(typ, generic_names, + g.cur_concrete_types) + { return t_typ } } diff --git a/vlib/v/generics/new_generics_regression_test.v b/vlib/v/generics/new_generics_regression_test.v index 4d178bcfe1..4f82cdc9c3 100644 --- a/vlib/v/generics/new_generics_regression_test.v +++ b/vlib/v/generics/new_generics_regression_test.v @@ -30,11 +30,14 @@ fn testsuite_begin() { } fn test_new_generic_solver_does_not_regress_silently() { - run_new_generic_solver_tests('vlib/math/vec', '${os.quoted_path(vexe)} -new-generic-solver test vlib/math/vec', - expected_summary_vec, expected_summsvc_vec, failing_math_vec_tests[..]) - run_new_generic_solver_tests('vlib/flag', '${os.quoted_path(vexe)} -new-generic-solver test vlib/flag/', - expected_summary_flag, expected_summsvc_flag, failing_flag_tests[..]) - run_new_generic_solver_tests('vlib/v/tests/generics/', '${os.quoted_path(vexe)} -new-generic-solver test vlib/v/tests/generics/', + run_new_generic_solver_tests('vlib/math/vec', + '${os.quoted_path(vexe)} -new-generic-solver test vlib/math/vec', expected_summary_vec, + expected_summsvc_vec, failing_math_vec_tests[..]) + run_new_generic_solver_tests('vlib/flag', + '${os.quoted_path(vexe)} -new-generic-solver test vlib/flag/', expected_summary_flag, + expected_summsvc_flag, failing_flag_tests[..]) + run_new_generic_solver_tests('vlib/v/tests/generics/', + '${os.quoted_path(vexe)} -new-generic-solver test vlib/v/tests/generics/', expected_summary_generics, expected_summsvc_generics, failing_tests[..]) } @@ -96,7 +99,8 @@ fn run_new_generic_solver_tests(root_label string, test_cmd string, expected_sum } } if found_clean_summary { - log.info('>>> Found an accepted clean summary: ${term.colorize(term.yellow, actual_clean_summary)}, OK') + log.info('>>> Found an accepted clean summary: ${term.colorize(term.yellow, + actual_clean_summary)}, OK') println('') return } @@ -106,24 +110,23 @@ fn run_new_generic_solver_tests(root_label string, test_cmd string, expected_sum assert found_expected_failure, 'expected failing test ${known} , was not found.\nRun `v -new-generic-solver test ${root_label}` manually to verify, and then edit ${@FILE} to reflect the new state.' if vtrace_output { - eprintln('>>>>> found_expected_failure ${idx + 1} `${term.colorize(term.green, - known)}`, OK') + eprintln('>>>>> found_expected_failure ${idx + 1} `${term.colorize(term.green, known)}`, OK') } } log.info('>>> Found the expected summary: ${term.colorize(term.yellow, actual_expected_summary)}, OK') println('') } -const expected_summsvc_generics = 'Summary for all V _test.v files: 104 failed, 171 passed, 275 total.' +const expected_summsvc_generics = 'Summary for all V _test.v files: 106 failed, 174 passed, 280 total.' // The exact failure count varies slightly across compilers: -// gcc/tcc: 102, clang: 103, msvc/windows-gcc: 104. -const expected_summary_generics = 'Summary for all V _test.v files: 102 failed, 173 passed, 275 total.' +// gcc/tcc: 104, clang: 105, msvc/windows-gcc: 106. +const expected_summary_generics = 'Summary for all V _test.v files: 104 failed, 176 passed, 280 total.' const expected_summsvc_vec = 'Summary for all V _test.v files: 3 failed, 3 total.' const expected_summary_vec = 'Summary for all V _test.v files: 3 failed, 3 total.' -const expected_summsvc_flag = 'Summary for all V _test.v files: 2 failed, 17 passed, 19 total.' -const expected_summary_flag = 'Summary for all V _test.v files: 2 failed, 17 passed, 19 total.' -const expected_summsvc_flag_clean = 'Summary for all V _test.v files: 19 passed, 19 total.' -const expected_summary_flag_clean = 'Summary for all V _test.v files: 19 passed, 19 total.' +const expected_summsvc_flag = 'Summary for all V _test.v files: 20 passed, 20 total.' +const expected_summary_flag = 'Summary for all V _test.v files: 20 passed, 20 total.' +const expected_summsvc_flag_clean = 'Summary for all V _test.v files: 20 passed, 20 total.' +const expected_summary_flag_clean = 'Summary for all V _test.v files: 20 passed, 20 total.' const failing_tests = [ 'vlib/v/tests/generics/checks_for_operator_overrides_should_happen_on_the_concrete_types_when_using_generics_test.v', 'vlib/v/tests/generics/default_type_with_ref_test.v', @@ -148,7 +151,9 @@ const failing_tests = [ 'vlib/v/tests/generics/generic_interface_nested_generic_type_infer_test.v', 'vlib/v/tests/generics/generic_interface_test.v', 'vlib/v/tests/generics/generic_map_alias_test.v', + 'vlib/v/tests/generics/generic_match_generic_interface_type_test.v', 'vlib/v/tests/generics/generic_method_with_variadic_generic_args_test.v', + 'vlib/v/tests/generics/generic_mut_pointer_param_test.v', 'vlib/v/tests/generics/generic_operator_overload_test.v', 'vlib/v/tests/generics/generic_receiver_embed_test.v', 'vlib/v/tests/generics/generic_recursive_fn_test.v', @@ -179,6 +184,7 @@ const failing_tests = [ 'vlib/v/tests/generics/generics_assign_reference_generic_struct_test.v', 'vlib/v/tests/generics/generics_call_with_reference_arg_test.v', 'vlib/v/tests/generics/generics_chans_select_test.v', + 'vlib/v/tests/generics/generics_fn_field_multi_instance_test.v', 'vlib/v/tests/generics/generics_fn_return_generic_interface_test.v', 'vlib/v/tests/generics/generics_fn_return_result_test.v', 'vlib/v/tests/generics/generics_fn_variable_3_test.v', @@ -234,7 +240,4 @@ const failing_math_vec_tests = [ 'vlib/math/vec/vec4_test.v', ]! -const failing_flag_tests = [ - 'vlib/flag/default_flag_options_test.v', - 'vlib/flag/usage_example_test.v', -]! +const failing_flag_tests = []string{} diff --git a/vlib/v/live/live_test.v b/vlib/v/live/live_test.v index 3681b5f348..18fd809fb2 100644 --- a/vlib/v/live/live_test.v +++ b/vlib/v/live/live_test.v @@ -141,8 +141,8 @@ fn change_source(new string) { fn remove_live_attr_from_source() { log.info('> remove @[live] attr from pmessage() while program is running ...') - source_without_live := live_program_source.replace('ORIGINAL', 'NO_LIVE').replace('@[live]\n', - '') + source_without_live := + live_program_source.replace('ORIGINAL', 'NO_LIVE').replace('@[live]\n', '') atomic_write_source(source_without_live) } diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index 8e0097a9df..7ad5e6dc18 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -242,8 +242,9 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a // handle assertions and testing framework callbacks: if pref_.is_debug { all_fn_root_names << 'panic_debug' - all_fn_root_names << 'tos3' } + // tos3 is used by cgen for typeof() on sum_types at runtime: + all_fn_root_names << 'tos3' if pref_.is_test { all_fn_root_names << 'main.cb_assertion_ok' all_fn_root_names << 'main.cb_assertion_failed' @@ -258,7 +259,8 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a handle_vweb(mut table, mut all_fn_root_names, 'veb.Result', 'veb.filter', 'veb.Context') handle_vweb(mut table, mut all_fn_root_names, 'vweb.Result', 'vweb.filter', 'vweb.Context') - handle_vweb(mut table, mut all_fn_root_names, 'x.vweb.Result', 'x.vweb.filter', 'x.vweb.Context') + handle_vweb(mut table, mut all_fn_root_names, 'x.vweb.Result', 'x.vweb.filter', + 'x.vweb.Context') if 'debug_used_features' in pref_.compile_defines { eprintln('> debug_used_features: ${table.used_features}') @@ -399,9 +401,8 @@ fn all_global_decl_in_stmts(stmts []ast.Stmt, mut all_fns map[string]ast.FnDecl, if node.expr.is_comptime { // top level comptime $if for branch in node.expr.branches { - all_global_decl_in_stmts(branch.stmts, mut all_fns, mut - all_consts, mut all_globals, mut all_decltypes, mut - all_structs) + all_global_decl_in_stmts(branch.stmts, mut all_fns, mut all_consts, mut + all_globals, mut all_decltypes, mut all_structs) } } } @@ -409,9 +410,8 @@ fn all_global_decl_in_stmts(stmts []ast.Stmt, mut all_fns map[string]ast.FnDecl, if node.expr.is_comptime { // top level comptime $match for branch in node.expr.branches { - all_global_decl_in_stmts(branch.stmts, mut all_fns, mut - all_consts, mut all_globals, mut all_decltypes, mut - all_structs) + all_global_decl_in_stmts(branch.stmts, mut all_fns, mut all_consts, mut + all_globals, mut all_decltypes, mut all_structs) } } } @@ -434,8 +434,8 @@ fn all_global_decl(ast_files []&ast.File) (map[string]ast.FnDecl, map[string]ast mut all_decltypes := map[string]ast.TypeDecl{} mut all_structs := map[string]ast.StructDecl{} for i in 0 .. ast_files.len { - all_global_decl_in_stmts(ast_files[i].stmts, mut all_fns, mut all_consts, mut - all_globals, mut all_decltypes, mut all_structs) + all_global_decl_in_stmts(ast_files[i].stmts, mut all_fns, mut all_consts, mut all_globals, mut + all_decltypes, mut all_structs) } return all_fns, all_consts, all_globals, all_decltypes, all_structs } diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index 80e38e6e6d..ad7ba5dfe6 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -130,7 +130,13 @@ fn (w &Walker) fn_generic_names(node ast.FnDecl) []string { else {} } } - generic_names << node.generic_names + // Only add method-level generic names that aren't already from the receiver + // (V puts inherited receiver generics into node.generic_names too). + for gn in node.generic_names { + if gn !in generic_names { + generic_names << gn + } + } return generic_names } @@ -171,12 +177,14 @@ fn (mut w Walker) record_used_fn_generic_types(fkey string, concrete_types []ast @[inline] pub fn (mut w Walker) mark_builtin_array_method_as_used(method_name string) { - w.mark_builtin_type_method_as_used('${ast.array_type_idx}.${method_name}', '${int(ast.array_type.ref())}.${method_name}') + w.mark_builtin_type_method_as_used('${ast.array_type_idx}.${method_name}', + '${int(ast.array_type.ref())}.${method_name}') } @[inline] pub fn (mut w Walker) mark_builtin_map_method_as_used(method_name string) { - w.mark_builtin_type_method_as_used('${ast.map_type_idx}.${method_name}', '${int(ast.map_type.ref())}.${method_name}') + w.mark_builtin_type_method_as_used('${ast.map_type_idx}.${method_name}', + '${int(ast.map_type.ref())}.${method_name}') } pub fn (mut w Walker) mark_builtin_type_method_as_used(k string, rk string) { @@ -855,7 +863,8 @@ fn (mut w Walker) expr(node_ ast.Expr) { } .function { if mut stmt := w.all_fns[node.name] { - ident_concrete_types := w.resolve_current_concrete_types(node.concrete_types) + ident_concrete_types := + w.resolve_current_concrete_types(node.concrete_types) if stmt.generic_names.len > 0 && (ident_concrete_types.len == 0 || w.inside_comptime > 0) { w.keep_all_fn_generic_types[node.name] = true @@ -1105,11 +1114,7 @@ fn (mut w Walker) fn_decl_with_concrete_types(mut node ast.FnDecl, concrete_type w.table.used_features.used_attr_noreturn = w.table.used_features.used_attr_noreturn || node.is_noreturn if node.language == .c { - fkey := if walk_fkey != '' { walk_fkey } else { node.fkey() } - w.mark_fn_as_used(fkey) - if fkey != node.fkey() { - w.mark_fn_as_used(node.fkey()) - } + w.mark_fn_as_used(node.fkey()) w.mark_fn_ret_and_params(node.return_type, node.params) return } @@ -1127,9 +1132,6 @@ fn (mut w Walker) fn_decl_with_concrete_types(mut node ast.FnDecl, concrete_type return } w.mark_fn_as_used(fkey) - if fkey != base_fkey { - w.mark_fn_as_used(base_fkey) - } last_is_direct_array_access := w.is_direct_array_access w.is_direct_array_access = node.is_direct_arr || w.pref.no_bounds_checking defer { w.is_direct_array_access = last_is_direct_array_access } @@ -1204,6 +1206,49 @@ fn (mut w Walker) fn_decl_with_fkey(mut node ast.FnDecl, walk_fkey string) { w.fn_decl_with_concrete_types(mut node, []) } +fn (w &Walker) receiver_concrete_types(typ ast.Type) []ast.Type { + sym := w.table.final_sym(typ) + return match sym.info { + ast.Struct { sym.info.concrete_types.clone() } + ast.Interface { sym.info.concrete_types.clone() } + ast.SumType { sym.info.concrete_types.clone() } + else { []ast.Type{} } + } +} + +fn (w &Walker) used_receiver_generic_instantiations(receiver_typ ast.Type) [][]ast.Type { + if receiver_typ == 0 || !receiver_typ.has_flag(.generic) { + return [] + } + receiver_parent := receiver_typ.set_nr_muls(0).set_flag(.generic) + mut concrete_type_lists := [][]ast.Type{} + for sym_idx, _ in w.used_syms { + sym := w.table.type_symbols[sym_idx] + match sym.info { + ast.Struct { + if sym.info.parent_type == receiver_parent && sym.info.concrete_types.len > 0 + && sym.info.concrete_types !in concrete_type_lists { + concrete_type_lists << sym.info.concrete_types.clone() + } + } + ast.Interface { + if sym.info.parent_type == receiver_parent && sym.info.concrete_types.len > 0 + && sym.info.concrete_types !in concrete_type_lists { + concrete_type_lists << sym.info.concrete_types.clone() + } + } + ast.SumType { + if sym.info.parent_type == receiver_parent && sym.info.concrete_types.len > 0 + && sym.info.concrete_types !in concrete_type_lists { + concrete_type_lists << sym.info.concrete_types.clone() + } + } + else {} + } + } + return concrete_type_lists +} + pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { if node == unsafe { nil } { return @@ -1229,11 +1274,16 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { w.mark_by_type(exp_type) } } - call_concrete_types := w.resolve_current_concrete_types(node.concrete_types) + source_concrete_types := if node.raw_concrete_types.len > 0 { + node.raw_concrete_types + } else { + node.concrete_types + } + mut call_concrete_types := w.resolve_current_concrete_types(source_concrete_types) concrete_types_to_mark := if call_concrete_types.len > 0 { call_concrete_types } else { - node.concrete_types + source_concrete_types } for concrete_type in concrete_types_to_mark { w.mark_by_type(concrete_type) @@ -1257,6 +1307,31 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { } } } + // When inside a generic function, the checker may have resolved + // the left_type to the last-processed concrete type. Re-resolve + // through the current concrete types to get the correct type for + // this specific instantiation. + if node.is_method && w.cur_fn_concrete_types.len > 0 && w.cur_fn != '' { + if cur_fn_decl := w.all_fns[w.cur_fn] { + generic_names := w.fn_generic_names(cur_fn_decl) + if generic_names.len > 0 && generic_names.len == w.cur_fn_concrete_types.len { + // Check if resolved_left_type matches any concrete type from a + // DIFFERENT instantiation of the same generic function. If so, + // substitute it with the correct one for the current instantiation. + for concrete_type_list in w.table.fn_generic_types[w.cur_fn] { + if concrete_type_list.len != generic_names.len { + continue + } + for i, ct in concrete_type_list { + if ct == resolved_left_type && w.cur_fn_concrete_types[i] != ct { + resolved_left_type = w.cur_fn_concrete_types[i] + break + } + } + } + } + } + } if node.is_method && resolved_left_type != 0 { w.mark_by_type(resolved_left_type) left_sym := w.table.sym(resolved_left_type) @@ -1288,10 +1363,21 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { if embed_types.len != 0 { w.fn_by_name(method.fkey()) } - } else if node.left_type.has_flag(.generic) { - concrete_type := w.resolve_current_generic_type(node.left_type) + } else if node.left_type.has_flag(.generic) || resolved_left_type != node.left_type { + // Generic type parameter or re-resolved type from generic instantiation. + // Use resolve_method_fkey_for_type which handles value/reference type lookup. + concrete_type := if node.left_type.has_flag(.generic) { + w.resolve_current_generic_type(node.left_type) + } else { + resolved_left_type + } if concrete_type != 0 && !concrete_type.has_flag(.generic) { - method_name := '${int(concrete_type)}.${node.name}' + resolved_fkey, _ := w.resolve_method_fkey_for_type(concrete_type, node.name) + method_name := if resolved_fkey != '' { + resolved_fkey + } else { + '${int(concrete_type)}.${node.name}' + } if !w.used_fns[method_name] { w.fn_by_name(method_name) } @@ -1368,52 +1454,105 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { } else if node.is_fn_var { w.mark_global_as_used(node.name) } - if node.is_method && node.receiver_type.has_flag(.generic) && node.receiver_concrete_type != 0 - && !node.receiver_concrete_type.has_flag(.generic) { - // if receiver is generic, then cgen requires `node.receiver_type` to be T. - // We therefore need to get the concrete type from `node.receiver_concrete_type`. - fn_name = '${int(node.receiver_concrete_type)}.${node.name}' - receiver_typ = node.receiver_concrete_type + if node.is_method && node.receiver_type.has_flag(.generic) { + if call_concrete_types.len == 0 && node.left_type != 0 && !node.left_type.has_flag(.generic) { + call_concrete_types = w.receiver_concrete_types(node.left_type) + receiver_typ = node.left_type + } + if call_concrete_types.len == 0 && node.receiver_concrete_type != 0 + && !node.receiver_concrete_type.has_flag(.generic) { + call_concrete_types = w.receiver_concrete_types(node.receiver_concrete_type) + receiver_typ = node.receiver_concrete_type + } + concrete_fn_name := '${int(receiver_typ)}.${node.name}' + if concrete_fn_name in w.all_fns { + fn_name = concrete_fn_name + } + } + // Handle concrete instantiations of generic struct methods: when the + // receiver type is a concrete instantiation (e.g. Vec3[f64]) but the + // method is only registered under the parent generic type key (Vec3[T]), + // remap fn_name to the generic key and preserve all registered generic + // types so that other instantiations are not stripped. + if node.is_method && fn_name !in w.all_fns && !node.receiver_type.has_flag(.generic) + && receiver_typ != 0 { + rsym := w.table.sym(receiver_typ) + parent_type := match rsym.info { + ast.Struct { rsym.info.parent_type } + ast.Interface { rsym.info.parent_type } + ast.SumType { rsym.info.parent_type } + else { ast.Type(0) } + } + if parent_type != 0 && parent_type.has_flag(.generic) { + generic_fn_name := '${int(parent_type.set_nr_muls(0))}.${node.name}' + if generic_fn_name in w.all_fns { + fn_name = generic_fn_name + call_concrete_types = w.receiver_concrete_types(receiver_typ) + receiver_typ = parent_type.set_nr_muls(0) + w.keep_all_fn_generic_types[generic_fn_name] = true + } + } } w.mark_by_type(node.return_type) - mut stmt := w.all_fns[fn_name] or { return } - if !stmt.should_be_skipped && stmt.name == node.name { - if stmt.generic_names.len > 0 && (call_concrete_types.len == 0 || w.inside_comptime > 0) { - w.keep_all_fn_generic_types[fn_name] = true + mut resolved_fn_name := fn_name + if fn_name !in w.all_fns { + if fn_name != node.fkey() && node.fkey() in w.all_fns { + resolved_fn_name = node.fkey() + } else { + return } - if !node.is_method || receiver_typ == stmt.receiver.typ { - w.fn_decl_with_concrete_types(mut stmt, call_concrete_types) - } - if node.return_type.has_flag(.option) { - w.used_option++ - } else if node.return_type.has_flag(.result) { - w.used_result++ - } - if ((node.is_method && stmt.params.len > 1) || !node.is_method) - && stmt.generic_names.len > 0 { - // mark concrete generic param types (e.g. []T, ...Node[T]) as used - max_param_len := if node.is_method { stmt.params.len - 1 } else { stmt.params.len } - param_i := if node.is_method { 1 } else { 0 } - concrete_type_lists := if call_concrete_types.len > 0 { - [call_concrete_types] - } else { - w.table.fn_generic_types[fn_name] + } + if mut stmt := w.all_fns[resolved_fn_name] { + if !stmt.should_be_skipped && stmt.name == node.name { + keep_all_generic_types := stmt.generic_names.len > 0 && (call_concrete_types.len == 0 + || w.inside_comptime > 0 || (w.cur_fn_concrete_types.len > 0 + && node.raw_concrete_types.len == 0)) + if keep_all_generic_types { + w.keep_all_fn_generic_types[fn_name] = true } - for concrete_type_list in concrete_type_lists { - for k, concrete_type in concrete_type_list { - if k >= max_param_len { - break + can_walk_method := !node.is_method || receiver_typ == stmt.receiver.typ + || (node.receiver_type.has_flag(.generic) && stmt.receiver.typ.has_flag(.generic) + && call_concrete_types.len > 0) + if can_walk_method { + if keep_all_generic_types { + for concrete_type_list in w.table.fn_generic_types[fn_name] { + w.fn_decl_with_concrete_types(mut stmt, concrete_type_list) } - param_typ := stmt.params[k + param_i].typ - if param_typ.has_flag(.generic) { - if resolved := w.table.convert_generic_type(param_typ, stmt.generic_names, - concrete_type_list) - { - w.mark_by_type(resolved) - } else if w.table.type_kind(param_typ) == .array { - w.mark_by_type(w.table.find_or_register_array(concrete_type)) - } else if param_typ.has_flag(.option) { - w.used_option++ + } else { + w.fn_decl_with_concrete_types(mut stmt, call_concrete_types) + } + } + if node.return_type.has_flag(.option) { + w.used_option++ + } else if node.return_type.has_flag(.result) { + w.used_result++ + } + if ((node.is_method && stmt.params.len > 1) || !node.is_method) + && stmt.generic_names.len > 0 { + // mark concrete generic param types (e.g. []T, ...Node[T]) as used + max_param_len := if node.is_method { stmt.params.len - 1 } else { stmt.params.len } + param_i := if node.is_method { 1 } else { 0 } + concrete_type_lists := if call_concrete_types.len > 0 { + [call_concrete_types] + } else { + w.table.fn_generic_types[fn_name] + } + for concrete_type_list in concrete_type_lists { + for k, concrete_type in concrete_type_list { + if k >= max_param_len { + break + } + param_typ := stmt.params[k + param_i].typ + if param_typ.has_flag(.generic) { + if resolved := w.table.convert_generic_type(param_typ, + stmt.generic_names, concrete_type_list) + { + w.mark_by_type(resolved) + } else if w.table.type_kind(param_typ) == .array { + w.mark_by_type(w.table.find_or_register_array(concrete_type)) + } else if param_typ.has_flag(.option) { + w.used_option++ + } } } } @@ -1617,10 +1756,13 @@ fn (w &Walker) generic_concrete_name(base_name string, concrete_types []ast.Type } fn (w &Walker) resolve_current_specialized_var_type(var_name string) ast.Type { - if var_name == '' || w.cur_fn == '' || !w.cur_fn.contains('_T_') { + if var_name == '' || w.cur_fn == '' { return ast.no_type } - base_name := w.cur_fn.all_before('_T_') + mut base_name := w.cur_fn + if w.cur_fn.contains('_T_') { + base_name = w.cur_fn.all_before('_T_') + } mut base_fn := w.all_fns[base_name] or { ast.FnDecl{} } if base_fn.name == '' { for generic_fn in w.generic_fns { @@ -1633,7 +1775,15 @@ fn (w &Walker) resolve_current_specialized_var_type(var_name string) ast.Type { return ast.no_type } } - generic_names, concrete_types := w.specialized_generic_context_for(w.cur_fn) + mut generic_names := []string{} + mut concrete_types := []ast.Type{} + if w.cur_fn.contains('_T_') { + generic_names, concrete_types = w.specialized_generic_context_for(w.cur_fn) + } else if w.cur_fn_concrete_types.len > 0 + && base_fn.generic_names.len == w.cur_fn_concrete_types.len { + generic_names = base_fn.generic_names.clone() + concrete_types = w.cur_fn_concrete_types.clone() + } if generic_names.len == 0 || generic_names.len != concrete_types.len { return ast.no_type } @@ -1700,7 +1850,8 @@ fn (w &Walker) call_specialization_fkey(node ast.CallExpr, stmt ast.FnDecl, base if receiver_generic_names.len > 0 { mut receiver_concrete_types := w.receiver_concrete_types_for_type(receiver_typ) if receiver_concrete_types.len == 0 && node.receiver_concrete_type != 0 { - receiver_concrete_types = w.receiver_concrete_types_for_type(node.receiver_concrete_type) + receiver_concrete_types = + w.receiver_concrete_types_for_type(node.receiver_concrete_type) } if receiver_concrete_types.len > 0 { if concrete_types.len == 0 { @@ -1723,25 +1874,24 @@ pub fn (mut w Walker) fn_by_name(fn_name string) { if w.used_fns[fn_name] { return } - mut stmt := w.all_fns[fn_name] or { + if mut stmt := w.all_fns[fn_name] { + w.fn_decl(mut stmt) + } else { if fn_name.contains('_T_') { base_name := fn_name.all_before('_T_') - mut base_fn := w.all_fns[base_name] or { ast.FnDecl{} } - if base_fn.name == '' { + if mut base_fn := w.all_fns[base_name] { + w.fn_decl_with_fkey(mut base_fn, fn_name) + } else { for generic_fn in w.generic_fns { if generic_fn.name == base_name || generic_fn.fkey() == base_name { - base_fn = *generic_fn + mut gfn := *generic_fn + w.fn_decl_with_fkey(mut gfn, fn_name) break } } } - if base_fn.name != '' { - w.fn_decl_with_fkey(mut base_fn, fn_name) - } } - return } - w.fn_decl(mut stmt) } pub fn (mut w Walker) struct_fields(sfields []ast.StructField) { @@ -2037,12 +2187,185 @@ pub fn (mut w Walker) mark_by_sym(isym ast.TypeSymbol) { } fn (mut w Walker) remove_unused_fn_generic_types() { + // Phase 1: Compute the union of concrete type lists per generic + // receiver type, grouped by arity (number of type parameters). + // Include types from ALL methods (walked and un-walked) in fn_generic_types, + // so that every method on the same receiver type ends up with a consistent + // set of concrete instantiations. + mut receiver_used_types := map[string]map[int][][]ast.Type{} + // First, collect from walked methods (used_fn_generic_types) + for nkey, concrete_types in w.used_fn_generic_types { + if fn_decl := w.all_fns[nkey] { + if fn_decl.receiver.typ.has_flag(.generic) { + rkey := int(fn_decl.receiver.typ).str() + actual_types := if w.keep_all_fn_generic_types[nkey] { + w.table.fn_generic_types[nkey] + } else { + concrete_types + } + for ctl in actual_types { + arity := ctl.len + if ctl !in receiver_used_types[rkey][arity] { + receiver_used_types[rkey][arity] << ctl + } + } + } + } + } + // Also collect from un-walked methods in fn_generic_types whose receiver + // type is already in used_syms (the struct instantiation is used). + for fkey, fgt_types in w.table.fn_generic_types { + if fkey in w.used_fn_generic_types || w.keep_all_fn_generic_types[fkey] { + continue + } + if fn_decl := w.all_fns[fkey] { + if fn_decl.receiver.typ.has_flag(.generic) { + rkey := int(fn_decl.receiver.typ).str() + for ctl in fgt_types { + arity := ctl.len + if ctl !in receiver_used_types[rkey][arity] { + receiver_used_types[rkey][arity] << ctl + } + } + } + } + } + // Phase 2: Strip walked methods. For methods on generic receiver types, + // use the arity-matched union to ensure consistency across all methods on + // the same receiver type. for nkey, concrete_types in w.used_fn_generic_types { if concrete_types.len == 0 || w.keep_all_fn_generic_types[nkey] { continue } + if fn_decl := w.all_fns[nkey] { + if fn_decl.receiver.typ.has_flag(.generic) { + rkey := int(fn_decl.receiver.typ).str() + if arity_map := receiver_used_types[rkey] { + if concrete_types.len > 0 { + arity := concrete_types[0].len + if union_types := arity_map[arity] { + w.table.fn_generic_types[nkey] = union_types.clone() + continue + } + } + } + } + } w.table.fn_generic_types[nkey] = concrete_types.clone() } + // Phase 3: Strip un-walked methods on generic receiver types to the + // arity-matched union. This ensures un-walked methods don't keep a wider + // set of concrete types than walked methods, preventing C errors when + // un-walked method bodies call walked (stripped) methods. + // Also collect these un-walked methods so we can walk them in Phase 4. + mut unwalked_methods := map[string]bool{} + for fkey, fgt_types in w.table.fn_generic_types { + if fkey in w.used_fn_generic_types || w.keep_all_fn_generic_types[fkey] { + continue + } + if fgt_types.len == 0 { + continue + } + mut rkey := '' + if fn_decl := w.all_fns[fkey] { + if fn_decl.receiver.typ.has_flag(.generic) { + rkey = int(fn_decl.receiver.typ).str() + } + } + if rkey == '' { + dot_idx := fkey.index_u8(`.`) + if dot_idx > 0 { + rkey = fkey[..dot_idx] + } + } + if rkey == '' { + continue + } + if arity_map := receiver_used_types[rkey] { + if fgt_types.len > 0 { + arity := fgt_types[0].len + if union_types := arity_map[arity] { + w.table.fn_generic_types[fkey] = union_types.clone() + unwalked_methods[fkey] = true + } + } + } + } + // Phase 4: Walk un-walked method bodies so that any internal method + // calls (e.g. ec.generate_id() inside wait()) get properly marked. + // Iterate until no new un-walked methods are discovered. + // Also walk already-walked methods that got new concrete types from Phase 2. + // Phase 2 may add new concrete type lists (from the receiver union) that + // were not walked during the initial traversal. + for nkey, used_concrete_types in w.used_fn_generic_types { + if w.keep_all_fn_generic_types[nkey] { + continue + } + for concrete_type_list in w.table.fn_generic_types[nkey] { + if concrete_type_list !in used_concrete_types { + unwalked_methods[nkey] = true + } + } + } + for unwalked_methods.len > 0 { + mut next_unwalked := map[string]bool{} + for fkey, _ in unwalked_methods { + if mut fn_decl := w.all_fns[fkey] { + for concrete_type_list in w.table.fn_generic_types[fkey] { + w.fn_decl_with_concrete_types(mut fn_decl, concrete_type_list) + } + } + } + // Check if walking those methods discovered new un-walked methods + for fkey2, fgt_types2 in w.table.fn_generic_types { + if fkey2 in w.used_fn_generic_types || w.keep_all_fn_generic_types[fkey2] + || fkey2 in unwalked_methods { + continue + } + if fgt_types2.len == 0 { + continue + } + mut rkey2 := '' + if fn_decl2 := w.all_fns[fkey2] { + if fn_decl2.receiver.typ.has_flag(.generic) { + rkey2 = int(fn_decl2.receiver.typ).str() + } + } + if rkey2 == '' { + dot_idx := fkey2.index_u8(`.`) + if dot_idx > 0 { + rkey2 = fkey2[..dot_idx] + } + } + if rkey2 == '' { + continue + } + if fkey2 !in w.used_fn_generic_types { + if arity_map := receiver_used_types[rkey2] { + if fgt_types2.len > 0 { + arity := fgt_types2[0].len + if union_types := arity_map[arity] { + w.table.fn_generic_types[fkey2] = union_types.clone() + next_unwalked[fkey2] = true + } + } + } + } + } + unwalked_methods = next_unwalked.move() + } + // Phase 5: Propagate newly-discovered concrete types from walking + // (used_fn_generic_types / walked_fn_generic_types) back into + // fn_generic_types so that the cgen emits all required instantiations. + // Phase 4 may walk generic functions (including non-method ones) with + // new concrete types that were not in fn_generic_types originally. + for fkey, walked_types in w.walked_fn_generic_types { + for ctl in walked_types { + if ctl !in w.table.fn_generic_types[fkey] { + w.table.fn_generic_types[fkey] << ctl + } + } + } } fn (mut w Walker) mark_resource_dependencies() { @@ -2172,7 +2495,20 @@ fn (mut w Walker) mark_resource_dependencies() { orm_impls := w.table.iface_types['orm.Connection'] or { []ast.Type{} } for k, mut func in w.all_fns { if has_str_call && k.ends_with('.str') { - if func.receiver.typ.idx() in w.used_syms { + if func.receiver.typ.has_flag(.generic) { + concrete_type_lists := w.used_receiver_generic_instantiations(func.receiver.typ) + if concrete_type_lists.len > 0 { + for concrete_type_list in concrete_type_lists { + w.fn_decl_with_concrete_types(mut func, concrete_type_list) + } + } else if func.receiver.typ.idx() in w.used_syms { + w.fn_by_name(k) + } + if !has_ptr_print && func.receiver.typ.is_ptr() { + w.fn_by_name('ptr_str') + has_ptr_print = true + } + } else if func.receiver.typ.idx() in w.used_syms { w.fn_by_name(k) if !has_ptr_print && func.receiver.typ.is_ptr() { w.fn_by_name('ptr_str') diff --git a/vlib/v/parser/asm.v b/vlib/v/parser/asm.v index b3a89834be..296e9d56cc 100644 --- a/vlib/v/parser/asm.v +++ b/vlib/v/parser/asm.v @@ -600,8 +600,7 @@ fn (mut p Parser) asm_ios(output bool) []ast.AsmIO { } else if p.tok.kind == .plus { constraint += '+' } else { - p.error_with_pos('Output constraint must starts with `=` or `+`', - pos) + p.error_with_pos('Output constraint must starts with `=` or `+`', pos) return [] } p.next() diff --git a/vlib/v/parser/attribute.v b/vlib/v/parser/attribute.v index 34edf6afcb..88ec98ea49 100644 --- a/vlib/v/parser/attribute.v +++ b/vlib/v/parser/attribute.v @@ -262,7 +262,8 @@ fn (mut p Parser) attributes() { attrs := p.parse_attr(is_at) for attr in attrs { if p.attrs.contains(attr.name) && attr.name != 'wasm_export' { - p.error_with_pos('duplicate attribute `${attr.name}`', attr_start_pos.extend(p.prev_tok.pos())) + p.error_with_pos('duplicate attribute `${attr.name}`', + attr_start_pos.extend(p.prev_tok.pos())) return } if attr.kind == .comptime_define { diff --git a/vlib/v/parser/codegen.v b/vlib/v/parser/codegen.v index 5b5af90115..bcbd6033aa 100644 --- a/vlib/v/parser/codegen.v +++ b/vlib/v/parser/codegen.v @@ -21,8 +21,7 @@ fn (mut p Parser) handle_codegen_for_file() { return } ptext := 'module ' + p.mod.all_after_last('.') + '\n' + p.codegen_text - codegen_files << parse_text(ptext, p.file_path, mut p.table, p.scanner.comments_mode, - p.pref) + codegen_files << parse_text(ptext, p.file_path, mut p.table, p.scanner.comments_mode, p.pref) } fn handle_codegen_for_multiple_files(mut files []&ast.File) { diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index 089500caf6..c49c43b77e 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -159,10 +159,10 @@ fn (p &Parser) resolve_tmpl_path_expr_with_depth(expr ast.Expr, depth int) ?stri if expr.args.len == 0 { return '' } - mut path := p.resolve_tmpl_path_expr_with_depth(expr.args[0].expr, - depth + 1)? + mut path := p.resolve_tmpl_path_expr_with_depth(expr.args[0].expr, depth + 1)? for arg in expr.args[1..] { path = os.join_path_single(path, p.resolve_tmpl_path_expr_with_depth(arg.expr, + depth + 1)?) } return path @@ -172,8 +172,9 @@ fn (p &Parser) resolve_tmpl_path_expr_with_depth(expr ast.Expr, depth int) ?stri return none } return os.join_path_single(p.resolve_tmpl_path_expr_with_depth(expr.args[0].expr, - depth + 1)?, p.resolve_tmpl_path_expr_with_depth(expr.args[1].expr, - depth + 1)?) + + depth + 1)?, p.resolve_tmpl_path_expr_with_depth(expr.args[1].expr, depth + + 1)?) } else { return none @@ -284,13 +285,15 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall { import_mods := p.ast_imports.map(it.mod) if name == 'vweb' { if 'vweb' !in import_mods && 'x.vweb' !in import_mods { - p.error_with_pos('`\$vweb` cannot be used without importing vweb', start_pos.extend(p.prev_tok.pos())) + p.error_with_pos('`\$vweb` cannot be used without importing vweb', + start_pos.extend(p.prev_tok.pos())) return err_node } p.register_used_import('vweb') } else if name == 'veb' { if 'veb' !in import_mods { - p.error_with_pos('`\$veb` cannot be used without importing veb', start_pos.extend(p.prev_tok.pos())) + p.error_with_pos('`\$veb` cannot be used without importing veb', + start_pos.extend(p.prev_tok.pos())) return err_node } p.register_used_import('veb') @@ -486,7 +489,7 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall { } // println('path is now "$path"') } - tmp_fn_name := p.cur_fn_name.replace('.', '__') + start_pos.pos.str() + tmp_fn_name := p.cur_fn_name.replace('.', '__').to_lower() + start_pos.pos.str() $if trace_comptime ? { println('>>> compiling comptime template file "${path}" for ${tmp_fn_name}') } diff --git a/vlib/v/parser/containers.v b/vlib/v/parser/containers.v index 28e1e4b731..cacfead56f 100644 --- a/vlib/v/parser/containers.v +++ b/vlib/v/parser/containers.v @@ -127,8 +127,7 @@ fn (mut p Parser) array_init(is_option bool, alias_array_type ast.Type) ast.Arra } if p.tok.kind == .not && p.tok.line_nr == p.prev_tok.line_nr { last_pos = p.tok.pos() - p.error_with_pos('use e.g. `[1, 2, 3]!` instead of `[1, 2, 3]!!`', - last_pos) + p.error_with_pos('use e.g. `[1, 2, 3]!` instead of `[1, 2, 3]!!`', last_pos) p.next() } } diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index 3004125ed4..ba9af69672 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -259,7 +259,11 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr { mut pos := p.tok.pos() p.next() if p.inside_unsafe { - return p.error_with_pos('already inside `unsafe` block', pos) + err := p.error_with_pos('already inside `unsafe` block', pos) + if p.tok.kind != .eof { + p.recover_until_closing_rcbr() + } + return err } p.inside_unsafe = true p.check(.lcbr) @@ -831,7 +835,8 @@ fn (mut p Parser) gen_or_block() ast.OrExpr { // `foo()?` p.next() if p.inside_defer { - p.error_with_pos('error propagation not allowed inside `defer` blocks', p.prev_tok.pos()) + p.error_with_pos('error propagation not allowed inside `defer` blocks', + p.prev_tok.pos()) } return ast.OrExpr{ kind: if is_not { ast.OrKind.propagate_result } else { ast.OrKind.propagate_option } diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index beddbca9b8..bf810805b4 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -88,7 +88,8 @@ fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr { // `foo()?` p.next() if p.inside_defer { - p.error_with_pos('error propagation not allowed inside `defer` blocks', p.prev_tok.pos()) + p.error_with_pos('error propagation not allowed inside `defer` blocks', + p.prev_tok.pos()) } or_kind = if is_not { .propagate_result } else { .propagate_option } or_scope = p.scope @@ -724,8 +725,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { } else if p.tok.kind in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && p.peek_tok.kind == .lpar { name = p.tok.kind.str() // op_to_fn_name() if rec.typ == ast.void_type { - p.error_with_pos('cannot use operator overloading with normal functions', - p.tok.pos()) + p.error_with_pos('cannot use operator overloading with normal functions', p.tok.pos()) } if type_sym.has_method(name) { p.error_with_pos('cannot duplicate operator overload `${name}`', p.tok.pos()) @@ -769,11 +769,10 @@ fn (mut p Parser) fn_decl() ast.FnDecl { else {} } if rec_generic_types.len > 0 { - decl_generic_names := p.types_to_names(rec_generic_types, p.tok.pos(), 'rec_generic_types') or { - return ast.FnDecl{ - scope: unsafe { nil } - } - } + decl_generic_names := p.types_to_names(rec_generic_types, p.tok.pos(), + 'rec_generic_types') or { return ast.FnDecl{ + scope: unsafe { nil } + } } fn_generic_names := generic_names.clone() generic_names = p.table.generic_type_names(rec.typ) if decl_generic_names.len != generic_names.len { @@ -954,7 +953,8 @@ run them via `v file.v` instead', if file_mode == .v && existing.file_mode != .v { // a definition made in a .c.v file, should have a priority over a .v file definition of the same function if !p.pref.is_fmt { - name = p.prepend_mod('pure_v_but_overridden_by_${existing.file_mode}_${short_fn_name}') + name = + p.prepend_mod('pure_v_but_overridden_by_${existing.file_mode}_${short_fn_name}') } } else if !p.pref.translated { p.table.redefined_fns << name @@ -1144,12 +1144,14 @@ fn (mut p Parser) fn_receiver(mut params []ast.Param, mut rec ReceiverParsingInf rec.is_mut = p.tok.kind == .key_mut if rec.is_mut { ptoken2 := p.peek_token(2) // needed to prevent codegen bug, where .pos() expects &Token - p.warn_with_pos('use `(mut f Foo)` instead of `(f mut Foo)`', lpar_pos.extend(ptoken2.pos())) + p.warn_with_pos('use `(mut f Foo)` instead of `(f mut Foo)`', + lpar_pos.extend(ptoken2.pos())) } } if p.tok.kind == .key_shared { ptoken2 := p.peek_token(2) // needed to prevent codegen bug, where .pos() expects &Token - p.error_with_pos('use `(shared f Foo)` instead of `(f shared Foo)`', lpar_pos.extend(ptoken2.pos())) + p.error_with_pos('use `(shared f Foo)` instead of `(f shared Foo)`', + lpar_pos.extend(ptoken2.pos())) } rec.pos = rec_start_pos.extend(p.tok.pos()) is_amp := p.tok.kind == .amp @@ -1423,7 +1425,8 @@ fn (mut p Parser) fn_params() ([]ast.Param, bool, bool, bool) { } } if is_variadic { - param_type = ast.new_type(p.table.find_or_register_array(param_type)).set_flag(.variadic) + param_type = + ast.new_type(p.table.find_or_register_array(param_type)).set_flag(.variadic) } if p.tok.kind == .eof { p.error_with_pos('expecting `)`', p.prev_tok.pos()) @@ -1543,8 +1546,7 @@ fn (mut p Parser) fn_params() ([]ast.Param, bool, bool, bool) { p.check_fn_mutable_arguments(typ, pos) } } else if is_shared || is_atomic { - p.error_with_pos('generic object cannot be `atomic` or `shared`', - pos) + p.error_with_pos('generic object cannot be `atomic` or `shared`', pos) return []ast.Param{}, false, false, false } if typ.is_ptr() && p.table.sym(typ).kind == .struct { @@ -1564,7 +1566,8 @@ fn (mut p Parser) fn_params() ([]ast.Param, bool, bool, bool) { } if is_variadic { // derive flags, however nr_muls only needs to be set on the array elem type, so clear it on the arg type - typ = ast.new_type(p.table.find_or_register_array(typ)).derive(typ).set_nr_muls(0).set_flag(.variadic) + typ = + ast.new_type(p.table.find_or_register_array(typ)).derive(typ).set_nr_muls(0).set_flag(.variadic) } for i, para_name in param_names { alanguage := p.table.sym(typ).language diff --git a/vlib/v/parser/if_match.v b/vlib/v/parser/if_match.v index 7b3c226810..845748feed 100644 --- a/vlib/v/parser/if_match.v +++ b/vlib/v/parser/if_match.v @@ -541,8 +541,7 @@ fn (mut p Parser) select_expr() ast.SelectExpr { return ast.SelectExpr{} } if has_else { - p.error_with_pos('at most one `else` branch allowed in `select` block', - p.tok.pos()) + p.error_with_pos('at most one `else` branch allowed in `select` block', p.tok.pos()) return ast.SelectExpr{} } is_else = true @@ -616,8 +615,7 @@ fn (mut p Parser) select_expr() ast.SelectExpr { match expr { ast.PrefixExpr { if expr.op != .arrow { - p.error_with_pos('select key: `<-` operator expected', - expr.pos) + p.error_with_pos('select key: `<-` operator expected', expr.pos) return ast.SelectExpr{} } } diff --git a/vlib/v/parser/lock.v b/vlib/v/parser/lock.v index f4c3339a3b..566abbfb51 100644 --- a/vlib/v/parser/lock.v +++ b/vlib/v/parser/lock.v @@ -16,6 +16,10 @@ fn (mut p Parser) lock_expr() ast.LockExpr { is_rlock := p.tok.kind == .key_rlock if !is_rlock && p.tok.kind != .key_lock { p.unexpected(expecting: 'one or more shared variable names') + return ast.LockExpr{ + pos: pos + scope: p.scope + } } p.next() if p.tok.kind == .lcbr { diff --git a/vlib/v/parser/messages.v b/vlib/v/parser/messages.v index 453dfa868a..722d3c7cd1 100644 --- a/vlib/v/parser/messages.v +++ b/vlib/v/parser/messages.v @@ -66,6 +66,17 @@ fn (mut p Parser) note(s string) { } fn (mut p Parser) error_with_pos(s string, pos token.Pos) ast.NodeError { + if p.should_abort { + // Even after abort, always advance the token to prevent infinite loops + // in parser code that doesn't check should_abort (e.g. fn_params loops). + if p.tok.kind != .eof { + p.next() + } + return ast.NodeError{ + idx: if p.errors.len > 0 { p.errors.len - 1 } else { 0 } + pos: pos + } + } // print_backtrace() mut kind := 'error:' file_path := if pos.file_idx < 0 { p.file_path } else { p.table.filelist[pos.file_idx] } @@ -91,10 +102,6 @@ fn (mut p Parser) error_with_pos(s string, pos token.Pos) ast.NodeError { // while it is unwinding after a printed error. if (should_abort_after_print || p.pref.check_only || p.pref.only_check_syntax || p.pref.output_mode == .silent) && p.tok.kind != .eof { - // Normally, parser errors mean that the parser exits immediately, so there can be only 1 parser error. - // In the silent mode however, the parser continues to run, even though it would have stopped. Some - // of the parser logic does not expect that, and may loop forever. - // The p.next() here is needed, so the parser is more robust, and *always* advances, even in the -silent mode. p.next() } return ast.NodeError{ @@ -104,6 +111,12 @@ fn (mut p Parser) error_with_pos(s string, pos token.Pos) ast.NodeError { } fn (mut p Parser) error_with_error(error errors.Error) { + if p.should_abort { + if p.tok.kind != .eof { + p.next() + } + return + } mut kind := 'error:' should_abort_after_print := p.pref.fatal_errors || (p.pref.output_mode == .stdout && !p.pref.check_only) @@ -120,16 +133,16 @@ fn (mut p Parser) error_with_error(error errors.Error) { return } p.errors << error - if (should_abort_after_print || p.pref.output_mode == .silent) && p.tok.kind != .eof { - // Normally, parser errors mean that the parser exits immediately, so there can be only 1 parser error. - // In the silent mode however, the parser continues to run, even though it would have stopped. Some - // of the parser logic does not expect that, and may loop forever. - // The p.next() here is needed, so the parser is more robust, and *always* advances, even in the -silent mode. + if (should_abort_after_print || p.pref.check_only || p.pref.only_check_syntax + || p.pref.output_mode == .silent) && p.tok.kind != .eof { p.next() } } fn (mut p Parser) warn_with_pos(s string, pos token.Pos) { + if p.should_abort { + return + } if p.pref.warns_are_errors { p.error_with_pos(s, pos) return @@ -155,6 +168,9 @@ fn (mut p Parser) warn_with_pos(s string, pos token.Pos) { } fn (mut p Parser) note_with_pos(s string, pos token.Pos) { + if p.should_abort { + return + } if p.pref.skip_warnings { return } diff --git a/vlib/v/parser/module.v b/vlib/v/parser/module.v index cb0cb70c36..9977aae88b 100644 --- a/vlib/v/parser/module.v +++ b/vlib/v/parser/module.v @@ -316,16 +316,14 @@ fn (mut p Parser) import_syms(mut parent ast.Import) { return } if p.tok.kind != .name { // not a valid inner name - p.error_with_pos('import syntax error, please specify a valid fn or type name', - pos_t) + p.error_with_pos('import syntax error, please specify a valid fn or type name', pos_t) return } for p.tok.kind == .name { pos := p.tok.pos() alias := p.check_name() if p.is_imported_symbol(alias) && !(p.pref.is_fmt && p.inside_ct_if_expr) { - p.error_with_pos('cannot register symbol `${alias}`, it was already imported', - pos) + p.error_with_pos('cannot register symbol `${alias}`, it was already imported', pos) return } p.imported_symbols[alias] = parent.mod + '.' + alias diff --git a/vlib/v/parser/orm.v b/vlib/v/parser/orm.v index fa563803b2..b345a607dd 100644 --- a/vlib/v/parser/orm.v +++ b/vlib/v/parser/orm.v @@ -103,8 +103,7 @@ fn (mut p Parser) sql_expr() ast.Expr { p.next() where_expr = p.expr(0) - where_check_result := p.check_sql_where_expr_has_no_undefined_variables(&where_expr, - []) + where_check_result := p.check_sql_where_expr_has_no_undefined_variables(&where_expr, []) if where_check_result is ast.NodeError { return where_check_result } @@ -419,8 +418,7 @@ fn (mut p Parser) parse_sql_stmt_line() ast.SqlStmtLine { p.check_sql_keyword('where') or { return ast.SqlStmtLine{} } where_expr = p.expr(0) - where_expr_result := p.check_sql_where_expr_has_no_undefined_variables(&where_expr, - []) + where_expr_result := p.check_sql_where_expr_has_no_undefined_variables(&where_expr, []) if where_expr_result is ast.NodeError { return ast.SqlStmtLine{} } @@ -430,8 +428,7 @@ fn (mut p Parser) parse_sql_stmt_line() ast.SqlStmtLine { p.check_sql_keyword('where') or { return ast.SqlStmtLine{} } where_expr = p.expr(0) - where_expr_result := p.check_sql_where_expr_has_no_undefined_variables(&where_expr, - []) + where_expr_result := p.check_sql_where_expr_has_no_undefined_variables(&where_expr, []) if where_expr_result is ast.NodeError { return ast.SqlStmtLine{} } @@ -480,8 +477,7 @@ fn (mut p Parser) check_sql_where_expr_has_no_undefined_variables(expr &ast.Expr } } - left_check_result := p.check_sql_where_expr_has_no_undefined_variables(expr.left, - []) + left_check_result := p.check_sql_where_expr_has_no_undefined_variables(expr.left, []) if left_check_result is ast.NodeError { return left_check_result diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index cb4927814d..b264488e38 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -52,7 +52,9 @@ fn (mut p Parser) eval_array_fixed_sizes(mut size_expr ast.Expr) (int, bool) { size_unresolved = false } ast.EnumVal { - if val := p.table.find_enum_field_val(size_expr.expr.enum_name, size_expr.expr.val) { + if val := p.table.find_enum_field_val(size_expr.expr.enum_name, + size_expr.expr.val) + { fixed_size = int(val) size_unresolved = false } @@ -137,6 +139,7 @@ fn (mut p Parser) parse_array_type(expecting token.Kind, is_option bool) ast.Typ p.error_with_pos('fixed size cannot be zero or negative', size_expr.pos()) } idx := p.table.find_or_register_array_fixed(elem_type, fixed_size, size_expr, + p.array_dim == 1 && p.fixed_array_dim == 1 && !is_option && p.inside_fn_return) if elem_type.has_flag(.generic) { return ast.new_type(idx).set_flag(.generic) @@ -611,14 +614,15 @@ fn (mut p Parser) parse_type() ast.Type { p.chan_type_error() return 0 } - if typ == ast.void_type { + if is_option && typ == ast.void_type { p.error_with_pos('use `?` instead of `?void`', pos) return 0 } sym := p.table.sym(typ) if p.inside_fn_concrete_type && sym.info is ast.Struct { if !typ.has_flag(.generic) && sym.info.generic_types.len > 0 { - p.error_with_pos('missing concrete type on generic type', option_pos.extend(p.prev_tok.pos())) + p.error_with_pos('missing concrete type on generic type', + option_pos.extend(p.prev_tok.pos())) } } @@ -836,9 +840,8 @@ fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_dot b } fn (mut p Parser) find_or_register_placeholder_generic_type(sym &ast.TypeSymbol) ast.Type { - generic_names := p.types_to_names(p.init_generic_types, p.tok.pos(), 'struct_init_generic_types') or { - return ast.no_type - } + generic_names := p.types_to_names(p.init_generic_types, p.tok.pos(), + 'struct_init_generic_types') or { return ast.no_type } mut sym_name := sym.name + '<' for i, gt in generic_names { sym_name += gt diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 604aaf592c..72eddc3b99 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -229,14 +229,13 @@ fn (mut p Parser) free_scanner() { } } -const normalised_working_folder = (os.real_path(os.getwd()) + os.path_separator).replace('\\', - '/') +const normalised_working_folder = (os.real_path(os.getwd()) + os.path_separator).replace('\\', '/') pub fn (mut p Parser) set_path(path string) { p.file_path = path p.file_base = os.base(path) - p.file_display_path = os.real_path(p.file_path).replace_once(normalised_working_folder, - '').replace('\\', '/') + p.file_display_path = + os.real_path(p.file_path).replace_once(normalised_working_folder, '').replace('\\', '/') p.inside_vlib_file = os.dir(path).contains('vlib') p.inside_test_file = p.file_base.ends_with('_test.v') || p.file_base.ends_with('_test.vv') || p.file_base.all_before_last('.v').all_before_last('.').ends_with('_test') @@ -656,6 +655,21 @@ fn (mut p Parser) check(expected token.Kind) { } } +// recover_until_closing_rcbr skips the remaining contents of a `{ ... }` block after +// the opening `{` has already been consumed, leaving the parser positioned after the +// matching closing brace or at EOF. +fn (mut p Parser) recover_until_closing_rcbr() { + mut brace_level := 1 + for p.tok.kind != .eof && brace_level > 0 { + if p.tok.kind == .lcbr { + brace_level++ + } else if p.tok.kind == .rcbr { + brace_level-- + } + p.next() + } +} + // JS functions can have multiple dots in their name: // JS.foo.bar.and.a.lot.more.dots() fn (mut p Parser) check_js_name() string { @@ -1053,8 +1067,7 @@ fn (mut p Parser) stmt(is_top_level bool) ast.Stmt { return stmt } p.attrs = [] - return p.error_with_pos('attributes can only be used before declarations', - attr_pos) + return p.error_with_pos('attributes can only be used before declarations', attr_pos) } return p.parse_multi_expr(is_top_level) } @@ -1224,8 +1237,7 @@ fn (mut p Parser) stmt(is_top_level bool) ast.Stmt { defer_mode = .function } else { - return p.error_with_pos('unknown `defer` mode: `${mode}`', - mode_pos) + return p.error_with_pos('unknown `defer` mode: `${mode}`', mode_pos) } } p.check(.rpar) @@ -1898,8 +1910,7 @@ fn (mut p Parser) name_expr() ast.Expr { full_type_name := if mod != '' { '${mod}.${type_name}' } else { p.imported_symbols[type_name] or { p.prepend_mod(type_name)} } if func := p.table.find_fn(full_type_name + '__static__' + p.peek_token(2).lit) { - fn_type := ast.new_type(p.table.find_or_register_fn_type(func, false, - true)) + fn_type := ast.new_type(p.table.find_or_register_fn_type(func, false, true)) pos := p.tok.pos() p.check_name() p.check(.dot) @@ -2239,8 +2250,10 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr { } } mut field_name := '' - // check if the name is on the same line as the dot - if p.prev_tok.pos().line_nr == name_pos.line_nr || p.tok.kind != .name { + dot_line := p.prev_tok.pos().line_nr + // check if the name is on the same line as the dot, or the dot + // is on the same line as the expression before (trailing dot for chaining) + if dot_line == name_pos.line_nr || prev_line == dot_line || p.tok.kind != .name { if p.is_vls && p.tok.kind != .name { if p.tok.kind in [.rpar, .rcbr] { // Simplify the dot expression for VLS, so that the parser doesn't error @@ -2709,6 +2722,17 @@ fn (mut p Parser) const_decl() ast.ConstDecl { full_name := if is_virtual_c_const { name } else { p.prepend_mod(name) } if p.tok.kind == .comma { p.error_with_pos('const declaration do not support multiple assign yet', p.tok.pos()) + if is_block { + for p.tok.kind !in [.eof, .rpar] { + p.next() + } + } else { + line_nr := p.tok.line_nr + for p.tok.kind != .eof && p.tok.line_nr == line_nr { + p.next() + } + } + break } // Allow for `const x := 123`, and for `const x = 123` too. // Supporting `const x := 123` in addition to `const x = 123`, makes extracting local variables to constants @@ -3026,8 +3050,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl { } } if p.is_imported_symbol(name) { - p.error_with_pos('cannot register alias `${name}`, this type was already imported', - end_pos) + p.error_with_pos('cannot register alias `${name}`, this type was already imported', end_pos) return ast.AliasTypeDecl{} } mut sum_variants := []ast.TypeNode{} @@ -3164,7 +3187,8 @@ fn (mut p Parser) type_decl() ast.TypeDecl { } if idx == pidx { type_alias_pos := sum_variants[0].pos - p.error_with_pos('a type alias can not refer to itself: ${name}', decl_pos.extend(type_alias_pos)) + p.error_with_pos('a type alias can not refer to itself: ${name}', + decl_pos.extend(type_alias_pos)) return ast.AliasTypeDecl{} } comments = sum_variants[0].end_comments.clone() @@ -3284,7 +3308,9 @@ fn (mut p Parser) unsafe_stmt() ast.Stmt { } p.next() if p.inside_unsafe && !p.inside_defer { - return p.error_with_pos('already inside `unsafe` block', pos) + err := p.error_with_pos('already inside `unsafe` block', pos) + p.recover_until_closing_rcbr() + return err } p.inside_unsafe = true p.open_scope() // needed in case of `unsafe {stmt}` diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 19ef1dd3a7..765b94db8b 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -65,8 +65,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { return ast.StructDecl{} } if name == 'IError' && p.mod != 'builtin' { - p.error_with_pos('cannot register struct `IError`, it is builtin interface type', - name_pos) + p.error_with_pos('cannot register struct `IError`, it is builtin interface type', name_pos) } // append module name before any type of parsing to enable recursion parsing p.table.start_parsing_type(p.prepend_mod(name)) @@ -263,6 +262,10 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { typ = p.parse_type() comments << p.eat_comments() type_pos = type_pos.extend(p.prev_tok.pos()) + if typ.idx() == 0 { + // error is set in parse_type + return ast.StructDecl{} + } if !is_on_top { p.error_with_pos('struct embedding must be declared at the beginning of the struct body', type_pos) @@ -489,7 +492,8 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { msg := 'cannot register struct `${name}`, another type with this name exists' mut existing_sym, mut existing_idx := p.table.find_sym_and_type_idx(name) if existing_idx <= 0 && name.starts_with('main.') { - existing_sym, existing_idx = p.table.find_sym_and_type_idx(name.trim_string_left('main.')) + existing_sym, existing_idx = + p.table.find_sym_and_type_idx(name.trim_string_left('main.')) } if existing_idx > 0 { if existing_name_pos := existing_sym.info.get_name_pos() { @@ -508,8 +512,8 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { pos: name_pos reporter: .parser message: msg - details: util.formatted_error('details:', 'another declaration was found here', - existing_file_path, existing_name_pos) + details: util.formatted_error('details:', + 'another declaration was found here', existing_file_path, existing_name_pos) }) return ast.StructDecl{} } @@ -584,7 +588,8 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { } fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option bool) ast.StructInit { - first_pos := (if kind == .short_syntax && p.prev_tok.kind == .lcbr { p.prev_tok } else { p.tok }).pos() + first_pos := + (if kind == .short_syntax && p.prev_tok.kind == .lcbr { p.prev_tok } else { p.tok }).pos() p.init_generic_types = []ast.Type{} mut typ := if kind == .short_syntax { ast.void_type } else { p.parse_type() } struct_init_generic_types := p.init_generic_types.clone() @@ -842,7 +847,8 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { from_mod_typ := p.parse_type() from_mod_name := '${mod_name}.${p.prev_tok.lit}' if from_mod_name.is_lower() { - p.error_with_pos('the interface name need to have the pascal case', p.prev_tok.pos()) + p.error_with_pos('the interface name need to have the pascal case', + p.prev_tok.pos()) break } comments := p.eat_comments() @@ -895,7 +901,8 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { p.error_with_pos('duplicate method `${name}`', method_start_pos) return ast.InterfaceDecl{} } - params_t, _, is_variadic, _ := p.fn_params() // TODO: merge ast.Param and ast.Arg to avoid this + params_t, _, is_variadic, _ := + p.fn_params() // TODO: merge ast.Param and ast.Arg to avoid this mut params := [ ast.Param{ name: 'x' diff --git a/vlib/v/parser/tmpl.v b/vlib/v/parser/tmpl.v index 07b01e5122..9fc115d497 100644 --- a/vlib/v/parser/tmpl.v +++ b/vlib/v/parser/tmpl.v @@ -265,7 +265,8 @@ fn insert_template_code(fn_name string, tmpl_str_start string, line string) stri // escaped by cgen, unless it's a `veb.RawHtml` string trailing_bs := tmpl_str_end + 'sb_${fn_name}.write_u8(92)\n' + tmpl_str_start literal_dollar := tmpl_str_end + 'sb_${fn_name}.write_u8(36)\n' + tmpl_str_start - rewritten_line := escape_bare_tmpl_dollar_interpolations(rewrite_complex_template_at_expressions(line)) + rewritten_line := + escape_bare_tmpl_dollar_interpolations(rewrite_complex_template_at_expressions(line)) mut sb := strings.new_builder(rewritten_line.len + 16) mut i := 0 for i < rewritten_line.len { @@ -742,7 +743,8 @@ fn veb_tmpl_${fn_name}() string { p.append_tmpl_line_info(template_file, tline_number, 1) source.write_string(tmpl_str_start) if control.has_inline_body { - source.writeln(insert_template_code(fn_name, tmpl_str_start, control.inline_body)) + source.writeln(insert_template_code(fn_name, tmpl_str_start, + control.inline_body)) p.append_tmpl_line_info(template_file, tline_number, 1) } if control.closes_inline_block { @@ -785,7 +787,8 @@ fn veb_tmpl_${fn_name}() string { p.append_tmpl_line_info(template_file, tline_number, 1) source.write_string(tmpl_str_start) if control.has_inline_body { - source.writeln(insert_template_code(fn_name, tmpl_str_start, control.inline_body)) + source.writeln(insert_template_code(fn_name, tmpl_str_start, + control.inline_body)) p.append_tmpl_line_info(template_file, tline_number, 1) } if control.closes_inline_block { @@ -818,7 +821,8 @@ fn veb_tmpl_${fn_name}() string { p.append_tmpl_line_info(template_file, tline_number, 1) source.write_string(tmpl_str_start) if control.has_inline_body { - source.writeln(insert_template_code(fn_name, tmpl_str_start, control.inline_body)) + source.writeln(insert_template_code(fn_name, tmpl_str_start, + control.inline_body)) p.append_tmpl_line_info(template_file, tline_number, 1) } if control.closes_inline_block { @@ -969,7 +973,8 @@ fn veb_tmpl_${fn_name}() string { key := line_[pos + 5..end] if key.len > 0 { // Replace '%raw key' with just '${key}' - line_ = line_.replace('%raw ${key}', '\${veb.raw(veb.tr(ctx.lang.str(), "${key}"))}') + line_ = line_.replace('%raw ${key}', + '\${veb.raw(veb.tr(ctx.lang.str(), "${key}"))}') } search_start = pos + 1 } else { diff --git a/vlib/v/parser/v_print_v_files_works_test.v b/vlib/v/parser/v_print_v_files_works_test.v index 3b763160c5..9bdbd99edb 100644 --- a/vlib/v/parser/v_print_v_files_works_test.v +++ b/vlib/v/parser/v_print_v_files_works_test.v @@ -17,7 +17,8 @@ fn test_print_watched_files_in_silent_mode__used_by_vwatch() { } fn check_parsing_files_in_folder(folder string, options string) { - println(term.colorize(term.magenta, '> checking .vv files in folder: `${folder}`, with `${options}` ...')) + println(term.colorize(term.magenta, + '> checking .vv files in folder: `${folder}`, with `${options}` ...')) files := os.walk_ext(os.join_path(vroot, folder), '.vv') for f in files { cmd := '${os.quoted_path(vexe)} ${options} ${os.quoted_path(f)}' diff --git a/vlib/v/parser/v_silent_works_test.v b/vlib/v/parser/v_silent_works_test.v index fcf7c6c873..ba95a1a3e0 100644 --- a/vlib/v/parser/v_silent_works_test.v +++ b/vlib/v/parser/v_silent_works_test.v @@ -9,7 +9,8 @@ fn test_check_syntax_in_silent_mode() { } fn check_parsing_files_in_folder(folder string, options string) { - println(term.colorize(term.magenta, '> checking .vv files in folder: `${folder}`, with `${options}` ...')) + println(term.colorize(term.magenta, + '> checking .vv files in folder: `${folder}`, with `${options}` ...')) files := os.walk_ext(os.join_path(vroot, folder), '.vv') for f in files { cmd := '${os.quoted_path(vexe)} ${options} ${os.quoted_path(f)}' diff --git a/vlib/v/pkgconfig/bin/pkgconfig_test.v b/vlib/v/pkgconfig/bin/pkgconfig_test.v index c8fe35fb1e..568734a5f7 100644 --- a/vlib/v/pkgconfig/bin/pkgconfig_test.v +++ b/vlib/v/pkgconfig/bin/pkgconfig_test.v @@ -8,7 +8,8 @@ fn test_pkgconfig_can_be_compiled() { tmp_exe := os.join_path(os.vtmp_dir(), '${os.getpid()}_pkgconfig.exe') pkgconfig_v_file := os.real_path(os.join_path(vroot, 'vlib/v/pkgconfig/bin/pkgconfig.v')) assert !os.exists(tmp_exe) - res := os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(tmp_exe)} ${os.quoted_path(pkgconfig_v_file)}') + res := + os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(tmp_exe)} ${os.quoted_path(pkgconfig_v_file)}') if res != 0 { assert false } diff --git a/vlib/v/pkgconfig/main.v b/vlib/v/pkgconfig/main.v index c221f131f7..2382a635c2 100644 --- a/vlib/v/pkgconfig/main.v +++ b/vlib/v/pkgconfig/main.v @@ -186,18 +186,23 @@ fn parse_options(mut fp flag.FlagParser) &MainOptions { exists: fp.bool('exists', `e`, false, 'return 0 if pkg exists') variables: fp.bool('print-variables', `P`, false, 'display variable names') requires: fp.bool('print-requires', `r`, false, 'display requires of the module') - atleast: fp.string('atleast-version', `a`, '', 'return 0 if pkg version is at least the given one') - atleastpc: fp.string('atleast-pkgconfig-version', `A`, '', 'return 0 if pkgconfig version is at least the given one') - exactversion: fp.string('exact-version', ` `, '', 'return 0 if pkg version is at least the given one') + atleast: fp.string('atleast-version', `a`, '', + 'return 0 if pkg version is at least the given one') + atleastpc: fp.string('atleast-pkgconfig-version', `A`, '', + 'return 0 if pkgconfig version is at least the given one') + exactversion: fp.string('exact-version', ` `, '', + 'return 0 if pkg version is at least the given one') version: fp.bool('version', `v`, false, 'show version of this tool') - cflags: fp.bool('cflags', `c`, false, 'output all pre-processor and compiler flags') + cflags: fp.bool('cflags', `c`, false, + 'output all pre-processor and compiler flags') cflags_only_path: fp.bool('cflags-only-I', `I`, false, 'show only -I flags from CFLAGS') cflags_only_other: fp.bool('cflags-only-other', ` `, false, 'show cflags without -I') stat1c: fp.bool('static', `s`, false, 'show --libs for static linking') libs: fp.bool('libs', `l`, false, 'output all linker flags') libs_only_link: fp.bool('libs-only-l', ` `, false, 'show only -l from ldflags') libs_only_path: fp.bool('libs-only-L', `L`, false, 'show only -L from ldflags') - libs_only_other: fp.bool('libs-only-other', ` `, false, 'show flags not containing -l or -L') + libs_only_other: fp.bool('libs-only-other', ` `, false, + 'show flags not containing -l or -L') args: fp.args } } diff --git a/vlib/v/pref/arch.c.v b/vlib/v/pref/arch.c.v index 38f2ee7bd0..910824d81e 100644 --- a/vlib/v/pref/arch.c.v +++ b/vlib/v/pref/arch.c.v @@ -1,6 +1,6 @@ module pref -const C.__V_architecture int +pub const C.__V_architecture int pub enum Arch { _auto diff --git a/vlib/v/pref/default.v b/vlib/v/pref/default.v index 256a54a008..aa6f8ef102 100644 --- a/vlib/v/pref/default.v +++ b/vlib/v/pref/default.v @@ -70,17 +70,70 @@ fn (mut p Preferences) setup_os_and_arch_when_not_explicitly_set() { if host_os == .macos && p.os == .linux { // Cross compilation from macos -> linux; assume AMD64 as the target architecture for now if p.arch == ._auto { - p.arch = .amd64 - p.build_options << '-arch amd64' + p.set_default_arch(.amd64) } p.parse_define('use_bundled_libgc') } } } - if p.arch == ._auto { - p.arch = get_host_arch() - p.build_options << '-arch ${p.arch}' +} + +fn (mut p Preferences) set_default_arch(arch Arch) { + if p.arch != ._auto || arch == ._auto { + return } + p.arch = arch + p.build_options << '-arch ${arch}' +} + +fn arch_from_ccompiler_name(ccompiler string) Arch { + name := os.file_name(ccompiler).to_lower_ascii() + if name.contains('x86_64') || name.contains('amd64') { + return .amd64 + } + if name.contains('aarch64') || name.contains('arm64-v8a') || name.contains('arm64') { + return .arm64 + } + if name.contains('armeabi-v7a') || name.contains('armv7') + || name.contains('arm-linux-androideabi') || name.contains('arm32') { + return .arm32 + } + if name.contains('riscv64') { + return .rv64 + } + if name.contains('riscv32') { + return .rv32 + } + if name.contains('i686') || name.contains('i386') || name.contains('x86') { + return .i386 + } + if name.contains('s390x') { + return .s390x + } + if name.contains('ppc64le') { + return .ppc64le + } + if name.contains('loongarch64') { + return .loongarch64 + } + if name.contains('sparc64') { + return .sparc64 + } + if name.contains('ppc64') { + return .ppc64 + } + return ._auto +} + +fn (mut p Preferences) resolve_default_arch() { + if p.arch != ._auto { + return + } + host_os := if p.backend == .wasm { OS.wasi } else { get_host_os() } + if p.os != host_os { + p.set_default_arch(arch_from_ccompiler_name(p.ccompiler)) + } + p.set_default_arch(get_host_arch()) } pub fn (mut p Preferences) defines_map_unique_keys() string { @@ -178,6 +231,7 @@ pub fn (mut p Preferences) fill_with_defaults() { p.default_cpp_compiler() } p.find_cc_if_cross_compiling() + p.resolve_default_arch() p.ccompiler_type = cc_from_string(p.ccompiler) p.disable_tcc_shared_backtraces() p.is_test = p.path.ends_with('_test.v') || p.path.ends_with('_test.vv') diff --git a/vlib/v/pref/options_test.v b/vlib/v/pref/options_test.v index c78a6900f9..feb4406aa8 100644 --- a/vlib/v/pref/options_test.v +++ b/vlib/v/pref/options_test.v @@ -49,7 +49,8 @@ fn custom_compile(fname string, cflags_options string) Results { mut res := Results{} res.exe = os.join_path(tfolder, fname) res.sw = time.new_stopwatch() - res.compilation = os.execute('${os.quoted_path(vexe)} -cflags "${cflags_options}" -o ${os.quoted_path(res.exe)} examples/hello_world.v') + res.compilation = + os.execute('${os.quoted_path(vexe)} -cflags "${cflags_options}" -o ${os.quoted_path(res.exe)} examples/hello_world.v') res.delta = res.sw.elapsed().milliseconds() res.file_size = os.file_size(res.exe) println('> ${fname} build took: ${res.delta} ms with "${cflags_options}", file size: ${res.file_size}') diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 9c5fa1a7a0..23911cea2e 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -614,7 +614,8 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin res.is_shared = true } '--enable-globals' { - eprintln_cond(show_output && !res.is_quiet, '`--enable-globals` flag is deprecated, please use `-enable-globals` instead') + eprintln_cond(show_output && !res.is_quiet, + '`--enable-globals` flag is deprecated, please use `-enable-globals` instead') res.enable_globals = true } '-enable-globals' { @@ -778,7 +779,8 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin res.show_depgraph = true } '-run-only' { - res.run_only = cmdline.option(args[i..], arg, os.getenv('VTEST_ONLY_FN')).split_any(',') + res.run_only = + cmdline.option(args[i..], arg, os.getenv('VTEST_ONLY_FN')).split_any(',') i++ } '-exclude' { @@ -898,7 +900,8 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin run_http_argument := 'import net.http.file; file.serve()' mut new_args := args.filter(it != '-http') new_args << ['-e', run_http_argument] - eprintln_cond(show_output && !res.is_quiet, "Note: use `v -e '${run_http_argument}'`, if you want to customise the http server options.") + eprintln_cond(show_output && !res.is_quiet, + "Note: use `v -e '${run_http_argument}'`, if you want to customise the http server options.") run_code_in_tmp_vfile_and_exit(new_args, mut res, '-e', 'vsh', run_http_argument) } '-cross' { @@ -952,7 +955,8 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin i++ } '-thread-stack-size' { - res.thread_stack_size = cmdline.option(args[i..], arg, res.thread_stack_size.str()).int() + res.thread_stack_size = + cmdline.option(args[i..], arg, res.thread_stack_size.str()).int() i++ } '-cc' { @@ -966,8 +970,8 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin i++ } '-checker-match-exhaustive-cutoff-limit' { - res.checker_match_exhaustive_cutoff_limit = cmdline.option(args[i..], - arg, '10').int() + res.checker_match_exhaustive_cutoff_limit = + cmdline.option(args[i..], arg, '10').int() i++ } '-o', '-output' { @@ -1138,8 +1142,10 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin } if command == 'run' && res.is_prod && os.is_atty(1) > 0 { - eprintln_cond(show_output && !res.is_quiet, "Note: building an optimized binary takes much longer. It shouldn't be used with `v run`.") - eprintln_cond(show_output && !res.is_quiet, 'Use `v run` without optimization, or build an optimized binary with -prod first, then run it separately.') + eprintln_cond(show_output && !res.is_quiet, + "Note: building an optimized binary takes much longer. It shouldn't be used with `v run`.") + eprintln_cond(show_output && !res.is_quiet, + 'Use `v run` without optimization, or build an optimized binary with -prod first, then run it separately.') } if res.os in [.browser, .wasi] && res.backend != .wasm { eprintln_exit('OS `${res.os}` forbidden for backends other than wasm') @@ -1175,14 +1181,16 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin must_exist(res.path) if !res.path.ends_with('.v') && os.is_executable(res.path) && os.is_file(res.path) && os.is_file(res.path + '.v') { - eprintln_cond(show_output && !res.is_quiet, 'It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "${res.path}" is an executable.') + eprintln_cond(show_output && !res.is_quiet, + 'It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "${res.path}" is an executable.') res.path += '.v' } } else if is_source_file(command) { res.path = command } if !res.is_bare && res.bare_builtin_dir != '' { - eprintln_cond(show_output && !res.is_quiet, '`-bare-builtin-dir` must be used with `-freestanding`') + eprintln_cond(show_output && !res.is_quiet, + '`-bare-builtin-dir` must be used with `-freestanding`') } if command.ends_with('.vsh') || (res.raw_vsh_tmp_prefix != '' && !res.is_run) { // `v build.vsh gcc` is the same as `v run build.vsh gcc`, @@ -1198,7 +1206,8 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin must_exist(res.path) if !res.path.ends_with('.v') && os.is_executable(res.path) && os.is_file(res.path) && os.is_file(res.path + '.v') { - eprintln_cond(show_output && !res.is_quiet, 'It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "${res.path}" is an executable.') + eprintln_cond(show_output && !res.is_quiet, + 'It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "${res.path}" is an executable.') res.path += '.v' } } diff --git a/vlib/v/pref/pref_test.v b/vlib/v/pref/pref_test.v index 55601044ff..ecf1572c32 100644 --- a/vlib/v/pref/pref_test.v +++ b/vlib/v/pref/pref_test.v @@ -46,8 +46,8 @@ fn test_cross_compile_keeps_explicit_cc() { assert first.ccompiler_set_by_flag assert first.ccompiler == custom_cc - second, _ := pref.parse_args_and_show_errors(['help'], ['', '-os', target_os, '-cc', custom_cc], - false) + second, _ := pref.parse_args_and_show_errors(['help'], + ['', '-os', target_os, '-cc', custom_cc], false) assert second.ccompiler_set_by_flag assert second.ccompiler == custom_cc } @@ -91,6 +91,35 @@ fn test_explicit_gc_mode_is_forwarded_to_build_module() { } } +fn test_cross_compile_defaults_windows_to_the_cross_compiler_arch() { + if pref.get_host_os() == .windows { + return + } + target := os.join_path(vroot, 'examples', 'hello_world.v') + prefs, _ := pref.parse_args_and_show_errors([], ['', '-os', 'windows', target], false) + assert prefs.arch == .amd64 + assert prefs.ccompiler == 'x86_64-w64-mingw32-gcc' +} + +fn test_cross_compile_infers_android_arch_from_vcross_compiler_name() { + target := os.join_path(vroot, 'examples', 'hello_world.v') + old_cross_compiler := os.getenv('VCROSS_COMPILER_NAME') + defer { + os.setenv('VCROSS_COMPILER_NAME', old_cross_compiler, true) + } + for compiler_name, expected_arch in { + 'aarch64-linux-android21-clang': pref.Arch.arm64 + 'armv7a-linux-androideabi21-clang': pref.Arch.arm32 + 'i686-linux-android21-clang': pref.Arch.i386 + 'x86_64-linux-android21-clang': pref.Arch.amd64 + } { + os.setenv('VCROSS_COMPILER_NAME', compiler_name, true) + prefs, _ := pref.parse_args_and_show_errors([], ['', '-os', 'android', target], false) + assert prefs.arch == expected_arch + assert prefs.ccompiler == compiler_name + } +} + fn test_musl_defaults_to_no_gc() { target := os.join_path(vroot, 'examples', 'hello_world.v') prefs, _ := pref.parse_args_and_show_errors([], ['', '-musl', target], false) @@ -100,8 +129,7 @@ fn test_musl_defaults_to_no_gc() { fn test_musl_keeps_explicit_gc_selection() { target := os.join_path(vroot, 'examples', 'hello_world.v') - prefs, _ := pref.parse_args_and_show_errors([], ['', '-musl', '-gc', 'boehm', target], - false) + prefs, _ := pref.parse_args_and_show_errors([], ['', '-musl', '-gc', 'boehm', target], false) assert prefs.is_musl assert prefs.gc_mode == .boehm_full_opt } @@ -110,7 +138,8 @@ fn test_v_cmds_and_flags() { build_cmd_res := os.execute('${vexe} build ${vroot}/examples/hello_world.v') assert build_cmd_res.output.trim_space() == 'Use `v ${vroot}/examples/hello_world.v` instead.' - too_many_targets_res := os.execute('${vexe} ${vroot}/examples/hello_world.v ${vroot}/examples/fizz_buzz.v') + too_many_targets_res := + os.execute('${vexe} ${vroot}/examples/hello_world.v ${vroot}/examples/fizz_buzz.v') assert too_many_targets_res.output.trim_space() == 'Too many targets. Specify just one target: .' unknown_arg_res := os.execute('${vexe} -xyz') @@ -132,13 +161,15 @@ fn test_unknown_option_flags_no_run() { os.chdir(os.dir(@VEXE))! os.rm(tfile) or {} - res1 := os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(tfile)} examples/hello_world.v --an-unknown-option') + res1 := + os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(tfile)} examples/hello_world.v --an-unknown-option') assert res1.exit_code == 1, res1.output assert res1.output.starts_with('Unknown argument') assert res1.output.contains('--an-unknown-option') assert !os.exists(tfile) - res2 := os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(tfile)} --an-unknown-option examples/hello_world.v') + res2 := + os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(tfile)} --an-unknown-option examples/hello_world.v') assert res2.exit_code == 1, res2.output assert res2.output.starts_with('Unknown argument') assert res2.output.contains('--an-unknown-option') @@ -146,19 +177,22 @@ fn test_unknown_option_flags_no_run() { } fn test_unknown_option_flags_with_run() { - res_run_o := os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(tfile)} run examples/hello_world.v --an-unknown-option') + res_run_o := + os.execute('${os.quoted_path(@VEXE)} -o ${os.quoted_path(tfile)} run examples/hello_world.v --an-unknown-option') assert res_run_o.exit_code == 0, res_run_o.output assert res_run_o.output == '' // because of -o, there should not be an actual run, since compilation stopped after generating the .c file assert os.exists(tfile) os.rm(tfile) or {} - res_run_no_o_unknown_before_run := os.execute('${os.quoted_path(@VEXE)} --an-unknown-option run examples/hello_world.v ') + res_run_no_o_unknown_before_run := + os.execute('${os.quoted_path(@VEXE)} --an-unknown-option run examples/hello_world.v ') assert res_run_no_o_unknown_before_run.exit_code == 1, res_run_no_o_unknown_before_run.output assert res_run_no_o_unknown_before_run.output.starts_with('Unknown argument') assert res_run_no_o_unknown_before_run.output.contains('--an-unknown-option') assert !os.exists(tfile) - res_run_no_o := os.execute('${os.quoted_path(@VEXE)} run examples/hello_world.v --an-unknown-option') + res_run_no_o := + os.execute('${os.quoted_path(@VEXE)} run examples/hello_world.v --an-unknown-option') assert res_run_no_o.exit_code == 0, res_run_no_o.output assert res_run_no_o.output.trim_space() == 'Hello, World!' assert !os.exists(tfile) @@ -166,8 +200,7 @@ fn test_unknown_option_flags_with_run() { fn test_generate_c_project_flag_parsing() { target := os.join_path(vroot, 'examples', 'hello_world.v') - prefs, _ := pref.parse_args_and_show_errors([], ['-generate-c-project', 'cproj', target], - false) + prefs, _ := pref.parse_args_and_show_errors([], ['-generate-c-project', 'cproj', target], false) assert prefs.generate_c_project == 'cproj' assert prefs.use_cache == false } @@ -200,7 +233,8 @@ fn test_output_flag_accepts_directory_path() { } target := os.join_path(vroot, 'examples', 'hello_world.v') output_arg := output_dir + os.path_separator - res := os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(output_arg)} ${os.quoted_path(target)}') + res := + os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(output_arg)} ${os.quoted_path(target)}') assert res.exit_code == 0, res.output assert os.is_dir(output_dir) mut expected_output := os.join_path(output_dir, 'hello_world') diff --git a/vlib/v/pref/vsh_envbang_test.v b/vlib/v/pref/vsh_envbang_test.v index 89c3f22cfe..df19fe641e 100644 --- a/vlib/v/pref/vsh_envbang_test.v +++ b/vlib/v/pref/vsh_envbang_test.v @@ -73,7 +73,8 @@ fn main() { ")! os.write_file(existing_path, 'hello')! os.chmod(rnd_vsh_script_path, 0o700)! - res := os.execute('${os.quoted_path(rnd_vsh_script_path)} --path ${os.quoted_path(existing_path)}') + res := + os.execute('${os.quoted_path(rnd_vsh_script_path)} --path ${os.quoted_path(existing_path)}') assert res.exit_code == 0 assert res.output.trim_space() == 'File path: ${existing_path}' os.rm(rnd_vsh_script_path)! diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 47f3dd4676..06354b1a18 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1143,8 +1143,7 @@ pub fn (mut s Scanner) text_scan() token.Token { } comment = '\x01' + comment.trim(' ') } - return s.new_multiline_token(.comment, comment, comment.len + 4, - start_line) + return s.new_multiline_token(.comment, comment, comment.len + 4, start_line) } // Skip if not in fmt mode continue diff --git a/vlib/v/slow_tests/inout/compiler_test.v b/vlib/v/slow_tests/inout/compiler_test.v index 1d03aae7af..835c4711a5 100644 --- a/vlib/v/slow_tests/inout/compiler_test.v +++ b/vlib/v/slow_tests/inout/compiler_test.v @@ -55,7 +55,8 @@ fn test_all() { tname := rand.ulid() tbase := os.join_path(os.vtmp_dir(), tname) texe := if os.user_os() == 'windows' { '${tbase}.exe' } else { tbase } - compilation := os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(tbase)} -cflags "-w" -cg ${os.quoted_path(program)}') + compilation := + os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(tbase)} -cflags "-w" -cg ${os.quoted_path(program)}') if compilation.exit_code < 0 { panic(compilation.output) } diff --git a/vlib/v/slow_tests/profile/profile_test.v b/vlib/v/slow_tests/profile/profile_test.v index e4f215c639..97d9ea508a 100644 --- a/vlib/v/slow_tests/profile/profile_test.v +++ b/vlib/v/slow_tests/profile/profile_test.v @@ -128,7 +128,8 @@ fn validate_output(fn_name string, vopts string, fsource string, expected map[st println('> validating ${fn_name} with: `v ${vopts} -profile - run ${fsource}`') os.chdir(vroot) or {} program_source := os.join_path(vroot, fsource) - res := os.execute('${os.quoted_path(vexe)} ${vopts} -profile - run ${os.quoted_path(program_source)}') + res := + os.execute('${os.quoted_path(vexe)} ${vopts} -profile - run ${os.quoted_path(program_source)}') assert res.exit_code == 0 assert res.output.len > 0 res_lines := res.output.split_into_lines() diff --git a/vlib/v/slow_tests/repl/repl_test.v b/vlib/v/slow_tests/repl/repl_test.v index 1fd1f99970..9b4f06afb2 100644 --- a/vlib/v/slow_tests/repl/repl_test.v +++ b/vlib/v/slow_tests/repl/repl_test.v @@ -51,9 +51,8 @@ fn test_all_v_repl_files() { bmark: benchmark.new_benchmark() } // warmup, and ensure that the vrepl is compiled in single threaded mode if it does not exist - runner.run_repl_file(os.cache_dir(), session.options.vexec, 'vlib/v/slow_tests/repl/nothing.repl') or { - panic(err) - } + runner.run_repl_file(os.cache_dir(), session.options.vexec, + 'vlib/v/slow_tests/repl/nothing.repl') or { panic(err) } session.bmark.set_total_expected_steps(session.options.files.len) mut pool_repl := pool.new_pool_processor(callback: worker_repl) pool_repl.set_shared_context(session) diff --git a/vlib/v/slow_tests/run_project_folders_test.v b/vlib/v/slow_tests/run_project_folders_test.v index 9f1158a3cb..847f6fe477 100644 --- a/vlib/v/slow_tests/run_project_folders_test.v +++ b/vlib/v/slow_tests/run_project_folders_test.v @@ -24,8 +24,7 @@ fn test_v_profile_works() { } } for folder_path in folder_paths { - local_path := folder_path.replace(vroot + os.path_separator, '').replace('\\', - '/') + local_path := folder_path.replace(vroot + os.path_separator, '').replace('\\', '/') println('........... v run ${local_path}/') t := time.ticks() res := os.execute('${os.quoted_path(vexe)} run ${os.quoted_path(folder_path)}') diff --git a/vlib/v/slow_tests/valgrind/1.strings_and_arrays.v b/vlib/v/slow_tests/valgrind/1.strings_and_arrays.v index 9164ed83a3..dd4ee466dd 100644 --- a/vlib/v/slow_tests/valgrind/1.strings_and_arrays.v +++ b/vlib/v/slow_tests/valgrind/1.strings_and_arrays.v @@ -66,7 +66,8 @@ fn str_tmp_expr_advanced() { } fn str_tmp_expr_advanced_var_decl() { - a := handle_strings('c' + 'd', add_strings('e' + 'f', 'g')) // both lvl 1 and lvl2 exprs must be freed + a := + handle_strings('c' + 'd', add_strings('e' + 'f', 'g')) // both lvl 1 and lvl2 exprs must be freed println(a) } @@ -84,7 +85,8 @@ fn str_inter() { fn str_replace() { mut s := 'hello world' - s = s.replace('hello', 'hi') // s can't be freed as usual before the assignment, since it's used in the right expr + s = + s.replace('hello', 'hi') // s can't be freed as usual before the assignment, since it's used in the right expr println(s) mut s2 := 'aa' + 'bb' diff --git a/vlib/v/tests/bench/math_big_gcd/prime/maker.v b/vlib/v/tests/bench/math_big_gcd/prime/maker.v index 5f2b519239..6bc75f83fe 100644 --- a/vlib/v/tests/bench/math_big_gcd/prime/maker.v +++ b/vlib/v/tests/bench/math_big_gcd/prime/maker.v @@ -140,7 +140,7 @@ pub fn random_list(cfg []string) []string { return p_list } -pub fn random_set(cfg PrimeCfg) ![]PrimeSet { +pub fn random_set(cfg PrimeCfg) ![]v.tests.bench.math_big_gcd.prime.PrimeSet { p_lists := [ cfg.r.split('.'), cfg.a.split('.'), diff --git a/vlib/v/tests/builtin_arrays/array_filter_using_direct_closure_test.v b/vlib/v/tests/builtin_arrays/array_filter_using_direct_closure_test.v index 94eec19af5..f60dd2c28d 100644 --- a/vlib/v/tests/builtin_arrays/array_filter_using_direct_closure_test.v +++ b/vlib/v/tests/builtin_arrays/array_filter_using_direct_closure_test.v @@ -4,7 +4,7 @@ struct File { is_dir bool } -fn filter(all_files []File, interested_file File) []File { +fn filter(all_files []main.File, interested_file File) []main.File { println(interested_file) return all_files.filter(fn [interested_file] (f File) bool { println(interested_file) diff --git a/vlib/v/tests/builtin_arrays/array_fixed_op_overload_test.v b/vlib/v/tests/builtin_arrays/array_fixed_op_overload_test.v index 283802c1ce..a33b71ae7d 100644 --- a/vlib/v/tests/builtin_arrays/array_fixed_op_overload_test.v +++ b/vlib/v/tests/builtin_arrays/array_fixed_op_overload_test.v @@ -64,10 +64,10 @@ pub fn rotate(angle f32, w Vector3) Matrix4 { ay := axis.y az := axis.z - return matrix4((ax * ax * cv) + cs, (ax * ay * cv) + az * sn, (ax * az * cv) - ay * sn, - 0, (ay * ax * cv) - az * sn, (ay * ay * cv) + cs, (ay * az * cv) + ax * sn, 0, - (az * ax * cv) + ay * sn, (az * ay * cv) - ax * sn, (az * az * cv) + cs, 0, 0, - 0, 0, 1) + return matrix4((ax * ax * cv) + cs, (ax * ay * cv) + az * sn, (ax * az * cv) - ay * sn, 0, + (ay * ax * cv) - az * sn, (ay * ay * cv) + cs, (ay * az * cv) + ax * sn, 0, + + (az * ax * cv) + ay * sn, (az * ay * cv) - ax * sn, (az * az * cv) + cs, 0, 0, 0, 0, 1) } fn test_array_fixed_op_overload() { diff --git a/vlib/v/tests/builtin_arrays/array_ops_create_just_one_closure_test.c.v b/vlib/v/tests/builtin_arrays/array_ops_create_just_one_closure_test.c.v index aa3a841096..bde1b59a9a 100644 --- a/vlib/v/tests/builtin_arrays/array_ops_create_just_one_closure_test.c.v +++ b/vlib/v/tests/builtin_arrays/array_ops_create_just_one_closure_test.c.v @@ -1,3 +1,6 @@ +@[has_globals] +module main + struct C.builtin__closure__Closure { closure_cap int } diff --git a/vlib/v/tests/comptime/comptime_else_map_init_markused_test.v b/vlib/v/tests/comptime/comptime_else_map_init_markused_test.v index fc053f955a..985d076fff 100644 --- a/vlib/v/tests/comptime/comptime_else_map_init_markused_test.v +++ b/vlib/v/tests/comptime/comptime_else_map_init_markused_test.v @@ -23,8 +23,8 @@ pub fn fire_call[T](mut app T, method_name string, message map[string]json2.Any) $if method.return_type is string { return app.$method(message) } $else { - return new_error_detail_with_details(.invalid_method, 'Method should return string', - { + return new_error_detail_with_details(.invalid_method, + 'Method should return string', { 'method': method_name 'return_type': method.return_type }) diff --git a/vlib/v/tests/comptime/comptime_indirection_check_test.v b/vlib/v/tests/comptime/comptime_indirection_check_test.v index b4bc140ab0..2ce156e99e 100644 --- a/vlib/v/tests/comptime/comptime_indirection_check_test.v +++ b/vlib/v/tests/comptime/comptime_indirection_check_test.v @@ -30,6 +30,5 @@ fn test_check() { mut sb := Writer{} mut string_initialized_with_reference := 'ads' - e.encode_value(StructTypePointer[string]{ val: &string_initialized_with_reference }, mut - sb) or {} + e.encode_value(StructTypePointer[string]{ val: &string_initialized_with_reference }, mut sb) or {} } diff --git a/vlib/v/tests/comptime/comptime_ppc_closure_codegen_test.v b/vlib/v/tests/comptime/comptime_ppc_closure_codegen_test.v index 40932e8899..f3ff0e5232 100644 --- a/vlib/v/tests/comptime/comptime_ppc_closure_codegen_test.v +++ b/vlib/v/tests/comptime/comptime_ppc_closure_codegen_test.v @@ -21,7 +21,8 @@ fn test_cross_arch_ppc_closure_codegen() { ') or { panic(err) } - res := os.execute('${os.quoted_path(vexe)} -gc none -arch ppc -o ${os.quoted_path(output)} ${os.quoted_path(source)}') + res := + os.execute('${os.quoted_path(vexe)} -gc none -arch ppc -o ${os.quoted_path(output)} ${os.quoted_path(source)}') assert res.exit_code == 0, res.output csrc := os.read_file(output) or { panic(err) } assert csrc.contains('__V_ppc') diff --git a/vlib/v/tests/conditions/matches/match_with_return_result_test.v b/vlib/v/tests/conditions/matches/match_with_return_result_test.v index 11ddfc3353..c1c6995444 100644 --- a/vlib/v/tests/conditions/matches/match_with_return_result_test.v +++ b/vlib/v/tests/conditions/matches/match_with_return_result_test.v @@ -39,8 +39,7 @@ fn Resolved.parse(j json2.Any) !Resolved { map[string]json2.Any { return Resolved{ users: if m := j['users'] { - maybe_map_map[string, json2.Any, Snowflake, User](m as map[string]json2.Any, - fn (k string, v json2.Any) !(Snowflake, User) { + maybe_map_map[string, json2.Any, Snowflake, User](m as map[string]json2.Any, fn (k string, v json2.Any) !(Snowflake, User) { return Snowflake(k.int()), User.parse(v)! })! } else { diff --git a/vlib/v/tests/fns/anon_fn_with_alias_args_test.v b/vlib/v/tests/fns/anon_fn_with_alias_args_test.v index 022d894091..a8724ce05e 100644 --- a/vlib/v/tests/fns/anon_fn_with_alias_args_test.v +++ b/vlib/v/tests/fns/anon_fn_with_alias_args_test.v @@ -2,11 +2,11 @@ type MyString = string type MyInt = int struct S1 { - x fn (a int) MyString + x fn (a int) main.MyString } struct S2 { - y fn (a int) MyInt + y fn (a int) main.MyInt } fn get_string(a int) MyString { diff --git a/vlib/v/tests/fns/fn_index_direct_call_test.v b/vlib/v/tests/fns/fn_index_direct_call_test.v index 45f6e7dc3b..0ff266a8c0 100644 --- a/vlib/v/tests/fns/fn_index_direct_call_test.v +++ b/vlib/v/tests/fns/fn_index_direct_call_test.v @@ -13,8 +13,12 @@ fn test_fn_array_direct_call() { return false } - println(fs.array_of_fn[0](1, &Placeholder{ name: 'Bob' }, 'Builder')) - assert fs.array_of_fn[0](1, &Placeholder{ name: 'Bob' }, 'Builder') == false + println(fs.array_of_fn[0](1, &Placeholder{ + name: 'Bob' + }, 'Builder')) + assert fs.array_of_fn[0](1, &Placeholder{ + name: 'Bob' + }, 'Builder') == false } fn test_fn_map_direct_call() { diff --git a/vlib/v/tests/fns/lambda_expr_with_mut_param_test.v b/vlib/v/tests/fns/lambda_expr_with_mut_param_test.v index 9e63641989..6594afb414 100644 --- a/vlib/v/tests/fns/lambda_expr_with_mut_param_test.v +++ b/vlib/v/tests/fns/lambda_expr_with_mut_param_test.v @@ -1,8 +1,8 @@ struct Window { mut: calls int - on_init fn (mut w Window) = unsafe { nil } - cb fn (mut w Window, x int) = unsafe { nil } + on_init fn (mut w main.Window) = unsafe { nil } + cb fn (mut w main.Window, x int) = unsafe { nil } } fn (mut w Window) run() { diff --git a/vlib/v/tests/generics/generic_array_test.v b/vlib/v/tests/generics/generic_array_test.v index 0246492c05..d82e54ca1a 100644 --- a/vlib/v/tests/generics/generic_array_test.v +++ b/vlib/v/tests/generics/generic_array_test.v @@ -12,7 +12,8 @@ pub fn (canvas Canvas) size() (int, int) { pub fn (canvas Canvas) string() string { output := buffer_to_braille(canvas.layers, dots_to_braille_rune_map) - return arrays.join_to_string(output, '\n', |row| arrays.join_to_string(row, '', |character| '${character}')) + return arrays.join_to_string(output, '\n', |row| arrays.join_to_string(row, '', + |character| '${character}')) } pub fn (mut canvas Canvas) set(x int, y int) { diff --git a/vlib/v/tests/generics/generics_test.v b/vlib/v/tests/generics/generics_test.v index 29d72f89c8..5dc1225327 100644 --- a/vlib/v/tests/generics/generics_test.v +++ b/vlib/v/tests/generics/generics_test.v @@ -505,8 +505,7 @@ fn test_multi_level_generics() { } assert three.foo.foo.foo == 10 assert get_multilevel_foo[MultiLevel[int]](two) == 10 - assert get_multilevel_foo_2[MultiLevel[MultiLevel[int]], MultiLevel[MultiLevel[int]]](two, - two) == 20 + assert get_multilevel_foo_2[MultiLevel[MultiLevel[int]], MultiLevel[MultiLevel[int]]](two, two) == 20 } struct Empty_ {} diff --git a/vlib/v/tests/interfaces/interface_arg_test.v b/vlib/v/tests/interfaces/interface_arg_test.v index 9405918744..115673b059 100644 --- a/vlib/v/tests/interfaces/interface_arg_test.v +++ b/vlib/v/tests/interfaces/interface_arg_test.v @@ -6,7 +6,7 @@ struct Test { struct Cmdable { mut: - call fn (cmd ITest) + call fn (cmd main.ITest) } fn (t Test) test(a ITest) {} diff --git a/vlib/v/tests/multiple_paths_in_vmodules/vmodules_overrides_test.v b/vlib/v/tests/multiple_paths_in_vmodules/vmodules_overrides_test.v index c27429dd3b..5a9553100e 100644 --- a/vlib/v/tests/multiple_paths_in_vmodules/vmodules_overrides_test.v +++ b/vlib/v/tests/multiple_paths_in_vmodules/vmodules_overrides_test.v @@ -8,7 +8,8 @@ const vexe = os.getenv('VEXE') const vroot = os.dir(vexe) -const basepath = os.real_path(os.join_path(vroot, 'vlib', 'v', 'tests', 'multiple_paths_in_vmodules')) +const basepath = os.real_path(os.join_path(vroot, 'vlib', 'v', 'tests', + 'multiple_paths_in_vmodules')) const mainvv = os.join_path(basepath, 'main.vv') diff --git a/vlib/v/tests/options/option_call_on_orexpr_test.v b/vlib/v/tests/options/option_call_on_orexpr_test.v index 0e956770d7..4f77f7ccc1 100644 --- a/vlib/v/tests/options/option_call_on_orexpr_test.v +++ b/vlib/v/tests/options/option_call_on_orexpr_test.v @@ -18,8 +18,7 @@ fn find_any_startswith_string_unwrapped(a []string, b []string, search string) ? } fn test_main() { - var1 := find_any_startswith_string(['foobar', 'barfoo'], ['deadbeef', 'beefdead'], - 'dead') + var1 := find_any_startswith_string(['foobar', 'barfoo'], ['deadbeef', 'beefdead'], 'dead') assert var1 or { panic('unreachable') } == 'deadbeef' dump(var1) diff --git a/vlib/v/tests/options/option_if_option_test.v b/vlib/v/tests/options/option_if_option_test.v index 103511ce95..467993d024 100644 --- a/vlib/v/tests/options/option_if_option_test.v +++ b/vlib/v/tests/options/option_if_option_test.v @@ -15,8 +15,7 @@ pub fn ApplicationCommandOptionChoice.parse(j json2.Any) !ApplicationCommandOpti return ApplicationCommandOptionChoice{ name: j['name']! as string name_localizations: if m := j['name_localizations'] { - maps.to_map[string, json2.Any, Locale, string](m as map[string]json2.Any, - fn (k string, v json2.Any) (Locale, string) { + maps.to_map[string, json2.Any, Locale, string](m as map[string]json2.Any, fn (k string, v json2.Any) (Locale, string) { return k, v as string }) } else { diff --git a/vlib/v/tests/parse_invalid_map_type_test.v b/vlib/v/tests/parse_invalid_map_type_test.v index 52d84d0da8..e849a03e28 100644 --- a/vlib/v/tests/parse_invalid_map_type_test.v +++ b/vlib/v/tests/parse_invalid_map_type_test.v @@ -8,8 +8,7 @@ fn test_parser_map_type() { output_mode: .silent is_fmt: true } - result := parser.parse_text('a := map[*Node]bool', '', mut table, .parse_comments, - pref_) + result := parser.parse_text('a := map[*Node]bool', '', mut table, .parse_comments, pref_) println(result) assert true } diff --git a/vlib/v/tests/printing/print_option_ref_test.v b/vlib/v/tests/printing/print_option_ref_test.v index b93cbbbab4..f9cca343ad 100644 --- a/vlib/v/tests/printing/print_option_ref_test.v +++ b/vlib/v/tests/printing/print_option_ref_test.v @@ -1,7 +1,8 @@ import net.html fn test_nil() { - mut doc := html.parse('') + mut doc := + html.parse('') footer := doc.get_tags_by_class_name('Box-footer')[0] hrefs := footer.get_tag_by_class_name('Truncate') println(hrefs) @@ -10,7 +11,8 @@ fn test_nil() { } fn test_non_nil() { - mut doc := html.parse('') + mut doc := + html.parse('') footer := doc.get_tags_by_class_name('Box-footer')[0] hrefs := footer.get_tag_by_class_name('Truncate') println(hrefs) diff --git a/vlib/v/tests/project_compiling_to_wasm/compilation_to_wasm_works_with_d_and_notd_files_test.v b/vlib/v/tests/project_compiling_to_wasm/compilation_to_wasm_works_with_d_and_notd_files_test.v index cd1ffd2b66..653510dfea 100644 --- a/vlib/v/tests/project_compiling_to_wasm/compilation_to_wasm_works_with_d_and_notd_files_test.v +++ b/vlib/v/tests/project_compiling_to_wasm/compilation_to_wasm_works_with_d_and_notd_files_test.v @@ -40,7 +40,8 @@ fn test_emcc() { return } dump(emcc) - res := os.system('${os.quoted_path(vexe)} -os wasm32_emscripten -o wasm_check.html ${os.quoted_path(project_folder)}') + res := + os.system('${os.quoted_path(vexe)} -os wasm32_emscripten -o wasm_check.html ${os.quoted_path(project_folder)}') assert res == 0 dump(res) assert os.exists('wasm_check.html') diff --git a/vlib/v/tests/projects_that_should_compile_test.v b/vlib/v/tests/projects_that_should_compile_test.v index c1324f5866..93419a67cc 100644 --- a/vlib/v/tests/projects_that_should_compile_test.v +++ b/vlib/v/tests/projects_that_should_compile_test.v @@ -14,6 +14,38 @@ fn vroot_path(relpath string) string { return os.real_path(os.join_path(@VMODROOT, relpath)) } +fn vrun_ok_in_dir(workdir string, options string, path string) string { + old_wd := os.getwd() + os.chdir(workdir) or { panic(err) } + defer { + os.chdir(old_wd) or { panic(err) } + } + return vrun_ok(options, path) +} + +fn write_file(path string, content string) { + os.write_file(path, content) or { panic(err) } +} + +fn setup_module_resolution_workdir_fixture() string { + workspace := os.join_path(os.vtmp_dir(), + 'v_module_resolution_independent_of_workdir_${os.getpid()}') + interp := r'${' + os.rmdir_all(workspace) or {} + os.mkdir_all(os.join_path(workspace, 'app', 'src')) or { panic(err) } + os.mkdir_all(os.join_path(workspace, 'lib', 'src')) or { panic(err) } + write_file(os.join_path(workspace, '.v.mod.stop'), '') + write_file(os.join_path(workspace, 'app', 'v.mod'), + "Module {\n\tname: 'app'\n\tdescription: ''\n\tversion: ''\n\tlicense: ''\n\tdependencies: []\n}\n") + write_file(os.join_path(workspace, 'app', 'src', 'main.v'), + "module main\n\nimport lib\n\nfn main() {\n\tprintln('Hello ${interp}lib.square(4)}!')\n}\n") + write_file(os.join_path(workspace, 'lib', 'v.mod'), + "Module {\n\tname: 'lib'\n\tdescription: ''\n\tversion: ''\n\tlicense: ''\n\tdependencies: []\n}\n") + write_file(os.join_path(workspace, 'lib', 'src', 'lib.v'), + 'module lib\n\npub fn square(x int) int {\n\treturn x * x\n}\n') + return workspace +} + fn vrun_ok(options string, path string) string { cmd := '${os.quoted_path(@VEXE)} ${options} ${os.quoted_path(path)}' res := os.execute(cmd) @@ -47,8 +79,10 @@ fn test_running_subdir_project_with_parent_vmod_works() { } os.mkdir_all(os.join_path(root, 'hexagonal', 'application'))! os.write_file(os.join_path(root, 'v.mod'), 'Module {\nname: "vanilla3"\n}')! - os.write_file(os.join_path(root, 'hexagonal', 'application', 'auth_usecase.v'), 'module application\n\npub struct AuthUseCase {}\n')! - os.write_file(os.join_path(root, 'hexagonal', 'main.v'), "module main\n\nimport application\n\nfn main() {\n\t_ := application.AuthUseCase{}\n\tprintln('built')\n}\n")! + os.write_file(os.join_path(root, 'hexagonal', 'application', 'auth_usecase.v'), + 'module application\n\npub struct AuthUseCase {}\n')! + os.write_file(os.join_path(root, 'hexagonal', 'main.v'), + "module main\n\nimport application\n\nfn main() {\n\t_ := application.AuthUseCase{}\n\tprintln('built')\n}\n")! old_dir := os.getwd() defer { os.chdir(old_dir) or {} diff --git a/vlib/v/tests/relative_nested_module_lookup_test.v b/vlib/v/tests/relative_nested_module_lookup_test.v index 50f30090f8..777b26b9ba 100644 --- a/vlib/v/tests/relative_nested_module_lookup_test.v +++ b/vlib/v/tests/relative_nested_module_lookup_test.v @@ -14,13 +14,16 @@ fn test_nested_module_lookup_works_with_relative_paths() { defer { os.rmdir_all(root) or {} } - os.write_file(main_path, 'import mod\nimport mod.v2\n\nfn main() {\n\tmod.print_version()\n\tv2.print_version()\n}\n') or { + os.write_file(main_path, + 'import mod\nimport mod.v2\n\nfn main() {\n\tmod.print_version()\n\tv2.print_version()\n}\n') or { panic(err) } - os.write_file(os.join_path(mod_dir, 'mod.v'), "module mod\n\nconst version = 'v1'\n\npub fn print_version() {\n\tprintln(mod.version)\n}\n") or { + os.write_file(os.join_path(mod_dir, 'mod.v'), + "module mod\n\nconst version = 'v1'\n\npub fn print_version() {\n\tprintln(mod.version)\n}\n") or { panic(err) } - os.write_file(os.join_path(v2_dir, 'mod.v'), "module v2\n\nconst version = 'v2'\n\npub fn print_version() {\n\tprintln(v2.version)\n}\n") or { + os.write_file(os.join_path(v2_dir, 'mod.v'), + "module v2\n\nconst version = 'v2'\n\npub fn print_version() {\n\tprintln(v2.version)\n}\n") or { panic(err) } cmd := '${os.quoted_path(@VEXE)} run ${os.quoted_path(rel_main_path)}' diff --git a/vlib/v/tests/skip_unused/nested_generics_method.vv b/vlib/v/tests/skip_unused/nested_generics_method.vv index 1c6249b04c..a53e1b7b8b 100644 --- a/vlib/v/tests/skip_unused/nested_generics_method.vv +++ b/vlib/v/tests/skip_unused/nested_generics_method.vv @@ -23,6 +23,7 @@ fn (mut t TypeB) next[T](_input T) f64 { return 11 } +@[markused] fn new[S]() Calc[S] { $if S is TypeA { return Calc[TypeA]{ diff --git a/vlib/v/tests/structs/struct_field_fn_call_test.v b/vlib/v/tests/structs/struct_field_fn_call_test.v index ba4eafb6e1..b4a1de73d7 100644 --- a/vlib/v/tests/structs/struct_field_fn_call_test.v +++ b/vlib/v/tests/structs/struct_field_fn_call_test.v @@ -1,5 +1,5 @@ struct Foo { - f fn (Foo) int = dummy + f fn (main.Foo) int = dummy } fn dummy(s Foo) int { diff --git a/vlib/v/tests/structs/struct_test.v b/vlib/v/tests/structs/struct_test.v index d01e5c41c7..41ca7c0bcc 100644 --- a/vlib/v/tests/structs/struct_test.v +++ b/vlib/v/tests/structs/struct_test.v @@ -120,7 +120,8 @@ fn test_at() { fn test_reserved_keywords() { // Make sure we can initialize them correctly using full syntax. - rk_holder := ReservedKeywords{0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3} + rk_holder := + ReservedKeywords{0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3} // Test a few as it'll take too long to test all. If it's initialized // correctly, other fields are also probably valid. assert rk_holder.unix == 5 diff --git a/vlib/v/tests/sumtypes/init_multiple_branches_test.v b/vlib/v/tests/sumtypes/init_multiple_branches_test.v index aa07731262..026a5edb58 100644 --- a/vlib/v/tests/sumtypes/init_multiple_branches_test.v +++ b/vlib/v/tests/sumtypes/init_multiple_branches_test.v @@ -20,7 +20,8 @@ fn test_init_multiple_branches() { t: m['t'] or { 0 }.bool() s: if a := m['a'] { println('a => ${a}') - b := return_option(a)? // Fails only if the expr in this line has or_block (or_block kind (.propagation or .block) doesn't matter) + b := + return_option(a)? // Fails only if the expr in this line has or_block (or_block kind (.propagation or .block) doesn't matter) b } else { map[string]Sum{} diff --git a/vlib/v/tests/vls/autocomplete_module_test.v b/vlib/v/tests/vls/autocomplete_module_test.v index 5aaffaf9fa..96b1733ecf 100644 --- a/vlib/v/tests/vls/autocomplete_module_test.v +++ b/vlib/v/tests/vls/autocomplete_module_test.v @@ -8,8 +8,7 @@ const tmp_dir = os.real_path(os.temp_dir()) const text_file = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'sample_text.vv') // note: windows path separator will cause json decode fail const json_errors_text_file = os.to_slash(text_file) -const mod1_text_file = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'sample_mod1', - 'sample.v') +const mod1_text_file = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'sample_mod1', 'sample.v') const autocomplete_info_for_mod_sample_mod1 = '{"details": [ {"kind":3,"label":"public_fn1","detail":"string","declaration":"fn public_fn1(val int) string","documentation":""}, diff --git a/vlib/v/tests/vls/goto_def_test.v b/vlib/v/tests/vls/goto_def_test.v index 2d404c51cf..99c91944a9 100644 --- a/vlib/v/tests/vls/goto_def_test.v +++ b/vlib/v/tests/vls/goto_def_test.v @@ -4,8 +4,7 @@ import v.util.diff const vroot = @VMODROOT const test_file = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'goto_def_test_data.vv') -const mod1_text_file = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'sample_mod1', - 'sample.v') +const mod1_text_file = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'sample_mod1', 'sample.v') struct TestCase { name string diff --git a/vlib/v/type_resolver/comptime_resolver.v b/vlib/v/type_resolver/comptime_resolver.v index e35e120568..4f7fb70936 100644 --- a/vlib/v/type_resolver/comptime_resolver.v +++ b/vlib/v/type_resolver/comptime_resolver.v @@ -185,8 +185,7 @@ pub fn (t &ResolverInfo) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind { pub fn (t &TypeResolver) get_type_from_comptime_var(var ast.Ident) ast.Type { match var.name { t.info.comptime_for_variant_var { - return t.get_ct_type_or_default('${t.info.comptime_for_variant_var}.typ', - ast.void_type) + return t.get_ct_type_or_default('${t.info.comptime_for_variant_var}.typ', ast.void_type) } t.info.comptime_for_method_param_var { return t.get_ct_type_or_default('${t.info.comptime_for_method_param_var}.typ', diff --git a/vlib/v/type_resolver/type_resolver.v b/vlib/v/type_resolver/type_resolver.v index 16e234d650..5525337073 100644 --- a/vlib/v/type_resolver/type_resolver.v +++ b/vlib/v/type_resolver/type_resolver.v @@ -324,8 +324,8 @@ pub fn (mut t TypeResolver) get_type(node ast.Expr) ast.Type { // Struct[T] can have field with generic type if struct_sym.info is ast.Struct && struct_sym.info.generic_types.len > 0 { if field := t.table.find_field(struct_sym, node.field_name) { - f_unwrap := node.scope.find_struct_field(ast.Expr(node.expr).str(), - t.get_type_or_default(ast.Expr(node.expr), node.expr_type), node.field_name) + f_unwrap := node.scope.find_struct_field(ast.Expr(node.expr).str(), t.get_type_or_default(ast.Expr(node.expr), + node.expr_type), node.field_name) if f_unwrap != unsafe { nil } { return f_unwrap.smartcasts.last() } diff --git a/vlib/v/util/module.v b/vlib/v/util/module.v index 9916b87b98..eafcb12ff1 100644 --- a/vlib/v/util/module.v +++ b/vlib/v/util/module.v @@ -77,11 +77,18 @@ pub fn qualify_module(pref_ &pref.Preferences, mod string, file_path string) str // TODO: 2022-01-30: The lookup should be relative to the folder, in which the current file is, // TODO: 2022-01-30: *NOT* to the working folder of the compiler, which can change easily. if clean_file_path.replace(os.getwd() + os.path_separator, '') == mod { - trace_qualify(@FN, mod, file_path, 'module_res 2', mod, 'clean_file_path - getwd == mod, clean_file_path: ${clean_file_path}') + trace_qualify(@FN, mod, file_path, 'module_res 2', mod, + 'clean_file_path - getwd == mod, clean_file_path: ${clean_file_path}') return mod } - if m1 := mod_path_to_full_name(pref_, mod, clean_file_path) { - trace_qualify(@FN, mod, file_path, 'module_res 3', m1, 'm1 == f(${clean_file_path})') + // Use absolute path so mod_path_to_full_name can walk up to find v.mod + abs_clean_file_path := if os.is_abs_path(clean_file_path) { + clean_file_path + } else { + os.join_path_single(os.getwd(), clean_file_path) + } + if m1 := mod_path_to_full_name(pref_, mod, abs_clean_file_path) { + trace_qualify(@FN, mod, file_path, 'module_res 3', m1, 'm1 == f(${abs_clean_file_path})') // > qualify_module: net | file_path: /v/cleanv/vlib/net/util.v | => module_res 3: net ; m1 == f(/v/cleanv/vlib/net) // > qualify_module: term | file_path: /v/cleanv/vlib/term/control.v | => module_res 3: term ; m1 == f(/v/cleanv/vlib/term) // > qualify_module: log | file_path: /v/vls/lsp/log/log.v | => module_res 3: lsp.log ; m1 == f(/v/vls/lsp/log) @@ -92,7 +99,8 @@ pub fn qualify_module(pref_ &pref.Preferences, mod string, file_path string) str } // zzzzzzz WORKING, when there is NO ../v.mod: // zzzzzzz > qualify_module: help | file_path: /v/cleanv/cmd/v/help/help.v | => module_res 4: help ; ---, clean_file_path: /v/cleanv/cmd/v/help - trace_qualify(@FN, mod, file_path, 'module_res 4', mod, '---, clean_file_path: ${clean_file_path}') + trace_qualify(@FN, mod, file_path, 'module_res 4', mod, + '---, clean_file_path: ${clean_file_path}') return mod } @@ -172,12 +180,17 @@ fn mod_path_to_full_name(pref_ &pref.Preferences, mod string, path string) !stri } } } - if os.is_abs_path(pref_.path) && os.is_abs_path(path) && os.is_dir(path) { // && path.contains(mod ) - rel_mod_path := path.replace(pref_.path.all_before_last(os.path_separator) + + abs_pref_path := if os.is_abs_path(pref_.path) { + pref_.path + } else { + os.join_path_single(os.getwd(), pref_.path) + } + if os.is_abs_path(path) && os.is_dir(path) { // && path.contains(mod ) + rel_mod_path := path.replace(abs_pref_path.all_before_last(os.path_separator) + os.path_separator, '') if rel_mod_path != path { - full_mod_name := normalize_src_based_mod_name(rel_mod_path.replace(os.path_separator, - '.'), path) + full_mod_name := + normalize_src_based_mod_name(rel_mod_path.replace(os.path_separator, '.'), path) return full_mod_name } } diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index b06c008983..fbc1a66206 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -272,8 +272,7 @@ pub fn should_recompile_tool(vexe string, tool_source string, tool_name string, newest_sfile = sfile } } - single_file_recompile := should_recompile_tool(vexe, newest_sfile, tool_name, - tool_exe) + single_file_recompile := should_recompile_tool(vexe, newest_sfile, tool_name, tool_exe) // eprintln('>>> should_recompile_tool: tool_source: ${tool_source} | ${single_file_recompile} | ${newest_sfile}') return single_file_recompile } @@ -433,9 +432,11 @@ and the existing module `${modulename}` may still work.') if is_verbose { eprintln('check_module_is_installed: cloning from ${murl} ...') } - cloning_res := os.execute('${os.quoted_path(vexe)} retry -- git clone ${os.quoted_path(murl)} ${os.quoted_path(mpath)}') + cloning_res := + os.execute('${os.quoted_path(vexe)} retry -- git clone ${os.quoted_path(murl)} ${os.quoted_path(mpath)}') if cloning_res.exit_code != 0 { - return error_with_code('cloning failed, details: ${cloning_res.output}', cloning_res.exit_code) + return error_with_code('cloning failed, details: ${cloning_res.output}', + cloning_res.exit_code) } if !os.exists(mod_v_file) { return error('even after cloning, ${mod_v_file} is still missing') diff --git a/vlib/v/vcache/vcache.v b/vlib/v/vcache/vcache.v index aec373be99..144d2a8c03 100644 --- a/vlib/v/vcache/vcache.v +++ b/vlib/v/vcache/vcache.v @@ -49,7 +49,8 @@ fn remove_old_cache_folder() { pub fn new_cache_manager(opts []string) CacheManager { // use a path, that would not conflict with a user installable module. `import .cache` is not valid, => better than just `cache`: vcache_basepath := os.getenv_opt('VCACHE') or { os.join_path(os.vmodules_dir(), '.cache') } - nlog(@FN, 'vcache_basepath: ${vcache_basepath}\n opts: ${opts}\n os.args: ${os.args.join(' ')}') + nlog(@FN, + 'vcache_basepath: ${vcache_basepath}\n opts: ${opts}\n os.args: ${os.args.join(' ')}') dlog(@FN, 'vcache_basepath: ${vcache_basepath} | opts:\n ${opts}') if !os.is_dir(vcache_basepath) { remove_old_cache_folder() diff --git a/vlib/v2/builder/builder.v b/vlib/v2/builder/builder.v index 94108148b6..9bc068a6e1 100644 --- a/vlib/v2/builder/builder.v +++ b/vlib/v2/builder/builder.v @@ -75,22 +75,28 @@ fn sanitize_staged_c_source(c_source string) string { source = ensure_result_type(source, '_result_int', 'int') source = ensure_result_type(source, '_result_rune', 'rune') // Builtin function body replacements (V source doesn't lower correctly yet): - source = replace_generated_c_fn(source, 'string u64_to_hex(u64 nn, u8 len)', sanitized_u64_to_hex_fn()) + source = replace_generated_c_fn(source, 'string u64_to_hex(u64 nn, u8 len)', + sanitized_u64_to_hex_fn()) source = replace_generated_c_fn(source, 'string u64_to_hex_no_leading_zeros(u64 nn, u8 len)', sanitized_u64_to_hex_no_leading_zeros_fn()) - source = replace_generated_c_fn(source, 'string u8__str_escaped(u8 b)', sanitized_u8_str_escaped_fn()) + source = replace_generated_c_fn(source, 'string u8__str_escaped(u8 b)', + sanitized_u8_str_escaped_fn()) source = replace_generated_c_fn(source, 'int int_min(int a, int b)', sanitized_int_min_fn()) source = replace_generated_c_fn(source, 'int int_max(int a, int b)', sanitized_int_max_fn()) - source = replace_generated_c_fn(source, 'int string__utf32_code(string _rune)', sanitized_string_utf32_code_fn()) - source = replace_generated_c_fn(source, '_result_rune Array_u8__utf8_to_utf32(Array_u8 _bytes)', + source = replace_generated_c_fn(source, 'int string__utf32_code(string _rune)', + sanitized_string_utf32_code_fn()) + source = replace_generated_c_fn(source, + '_result_rune Array_u8__utf8_to_utf32(Array_u8 _bytes)', sanitized_array_u8_utf8_to_utf32_fn()) source = replace_generated_c_fn(source, 'rune impl_utf8_to_utf32(u8* _bytes, int _bytes_len)', sanitized_impl_utf8_to_utf32_fn()) - source = replace_generated_c_fn(source, 'int utf8_str_visible_length(string s)', sanitized_utf8_str_visible_length_fn()) + source = replace_generated_c_fn(source, 'int utf8_str_visible_length(string s)', + sanitized_utf8_str_visible_length_fn()) // Array_u8_contains call convention: source = source.replace("Array_u8_contains(res, '.')", "array__contains(res, &(u8[1]){'.'})") // tos() buffer pointer cast: - source = source.replace('return tos(((u8)(&((u8*)buf.data)[((int)(0))])), i);', 'return tos(&((u8*)buf.data)[((int)(0))], i);') + source = source.replace('return tos(((u8)(&((u8*)buf.data)[((int)(0))])), i);', + 'return tos(&((u8*)buf.data)[((int)(0))], i);') // Pointer field access: &logger._object -> &logger->_object // The C cast C.log__Logger(logger) is dropped by cleanc, leaving a missing -> dereference. source = source.replace('&logger._object', '&logger->_object') @@ -624,8 +630,8 @@ fn (mut b Builder) gen_cleanc() { // Fast path: cache one core object (builtin+strconv), compile/link only the rest. if use_cache && !b.pref.skip_builtin && b.has_module('builtin') && b.has_module('strconv') { - if b.gen_cleanc_with_cached_core(output_name, cc, cc_flags, cc_link_flags, error_limit_flag, mut - sw) + if b.gen_cleanc_with_cached_core(output_name, cc, cc_flags, cc_link_flags, + error_limit_flag, mut sw) { return } @@ -641,8 +647,7 @@ fn (mut b Builder) gen_cleanc() { } os.write_file(staged_c_file, sanitize_staged_c_source(c_source)) or { panic(err) } println('[*] Wrote ${staged_c_file}') - b.compile_cleanc_executable(output_name, cc, cc_flags, cc_link_flags, error_limit_flag, mut - sw) + b.compile_cleanc_executable(output_name, cc, cc_flags, cc_link_flags, error_limit_flag, mut sw) } fn (b &Builder) is_cmd_v2_self_build() bool { @@ -747,11 +752,14 @@ fn (mut b Builder) gen_ssa_c() { if !b.pref.skip_builtin && b.has_module('builtin') && b.has_module('strconv') && b.ensure_core_cache_dir() { cache_dir := b.core_cache_dir() - builtin_obj = b.ensure_cached_module_object(cache_dir, builtin_cache_name, builtin_cached_module_paths, - builtin_cached_module_names, cc, cc_flags, error_limit_flag) or { '' } + builtin_obj = b.ensure_cached_module_object(cache_dir, builtin_cache_name, + builtin_cached_module_paths, builtin_cached_module_names, cc, cc_flags, + error_limit_flag) or { '' } if builtin_obj.len > 0 && vlib_cached_module_paths.len > 0 { - vlib_obj = b.ensure_cached_module_object(cache_dir, vlib_cache_name, vlib_cached_module_paths, - vlib_cached_module_names, cc, cc_flags, error_limit_flag) or { '' } + vlib_obj = b.ensure_cached_module_object(cache_dir, vlib_cache_name, + vlib_cached_module_paths, vlib_cached_module_names, cc, cc_flags, error_limit_flag) or { + '' + } } } @@ -855,8 +863,7 @@ fn (mut b Builder) gen_cleanc_source(modules []string) string { } fn (mut b Builder) gen_cleanc_source_for_cache(modules []string, cache_bundle_name string) string { - return b.gen_cleanc_source_with_options(modules, true, cache_bundle_name, []string{}, - false) + return b.gen_cleanc_source_with_options(modules, true, cache_bundle_name, []string{}, false) } fn (mut b Builder) gen_cleanc_source_with_cache_init_calls(modules []string, cached_init_calls []string) string { @@ -928,8 +935,8 @@ fn (mut b Builder) gen_cleanc_with_cached_core(output_name string, cc string, cc return false } - builtin_obj := b.ensure_cached_module_object(cache_dir, builtin_cache_name, builtin_cached_module_paths, - builtin_cached_module_names, cc, cc_flags, error_limit_flag) or { + builtin_obj := b.ensure_cached_module_object(cache_dir, builtin_cache_name, + builtin_cached_module_paths, builtin_cached_module_names, cc, cc_flags, error_limit_flag) or { if os.getenv('V2_TRACE_CACHE') != '' { eprintln('TRACE_CACHE cached_core=false reason=builtin_obj_failed') } @@ -937,8 +944,8 @@ fn (mut b Builder) gen_cleanc_with_cached_core(output_name string, cc string, cc } mut vlib_obj := '' if vlib_cached_module_paths.len > 0 { - vlib_obj = b.ensure_cached_module_object(cache_dir, vlib_cache_name, vlib_cached_module_paths, - vlib_cached_module_names, cc, cc_flags, error_limit_flag) or { + vlib_obj = b.ensure_cached_module_object(cache_dir, vlib_cache_name, + vlib_cached_module_paths, vlib_cached_module_names, cc, cc_flags, error_limit_flag) or { if os.getenv('V2_TRACE_CACHE') != '' { eprintln('TRACE_CACHE cached_core=false reason=vlib_obj_failed') } @@ -1043,8 +1050,8 @@ fn (mut b Builder) gen_cleanc_with_cached_core(output_name string, cc string, cc } // Strip -c and -x flags from link command since we're linking, not compiling. // -x objective-c would cause cc to treat .o files as source code. - mut link_flags := main_cc_flags.replace('-x objective-c', '').replace('-x c', '').replace(' -c ', - ' ') + mut link_flags := + main_cc_flags.replace('-x objective-c', '').replace('-x c', '').replace(' -c ', ' ') mut link_cmd := '${main_cc} ${link_flags} -w "${main_obj}" "${builtin_obj}"' if vlib_obj.len > 0 { link_cmd += ' "${vlib_obj}"' @@ -1641,8 +1648,7 @@ fn tcc_flags(cc string, vroot string) string { return '' } tcc_dir := os.join_path(vroot, 'thirdparty', 'tcc') - return '-I "${os.join_path(tcc_dir, 'lib', 'include')}" -L "${os.join_path(tcc_dir, - 'lib')}"' + return '-I "${os.join_path(tcc_dir, 'lib', 'include')}" -L "${os.join_path(tcc_dir, 'lib')}"' } // run_cc_cmd_or_exit runs a C compiler command, falling back from tcc to cc diff --git a/vlib/v2/builder/cache_headers.v b/vlib/v2/builder/cache_headers.v index 805efa1467..bc257dc1c7 100644 --- a/vlib/v2/builder/cache_headers.v +++ b/vlib/v2/builder/cache_headers.v @@ -354,8 +354,8 @@ fn (b &Builder) can_use_cached_core_headers() bool { } cc := configured_cc(b.pref.vroot) cc_flags := configured_cflags() - if !b.can_use_cached_module_bundle(builtin_cache_name, builtin_cached_module_paths, - cc, cc_flags) { + if !b.can_use_cached_module_bundle(builtin_cache_name, builtin_cached_module_paths, cc, + cc_flags) { return false } if vlib_cached_module_paths.len > 0 @@ -685,8 +685,7 @@ fn (b &Builder) build_module_header_ast(source_files []ast.File, module_name str type_decl_seen[type_decl.name] = true } ast.InterfaceDecl { - decl_stmts << ast.Stmt(b.resolved_header_interface_decl(module_name, - stmt)) + decl_stmts << ast.Stmt(b.resolved_header_interface_decl(module_name, stmt)) } ast.GlobalDecl { mut gfields := []ast.FieldDecl{cap: stmt.fields.len} diff --git a/vlib/v2/builder/ssa_build_parallel.v b/vlib/v2/builder/ssa_build_parallel.v index 42e5acda53..97f4e6308e 100644 --- a/vlib/v2/builder/ssa_build_parallel.v +++ b/vlib/v2/builder/ssa_build_parallel.v @@ -175,7 +175,6 @@ fn (mut b Builder) ssa_build_parallel(mut ssa_builder ssa.Builder, files []ast.F params: wf.params } } - mod.merge_worker_module(w_mod, func_data, seed_values, seed_instrs, seed_blocks, - seed_types) + mod.merge_worker_module(w_mod, func_data, seed_values, seed_instrs, seed_blocks, seed_types) } } diff --git a/vlib/v2/eval/eval.v b/vlib/v2/eval/eval.v index dd5123af70..e18deebdc6 100644 --- a/vlib/v2/eval/eval.v +++ b/vlib/v2/eval/eval.v @@ -394,14 +394,16 @@ fn (mut e Eval) register_files(files []ast.File) ! { file_name: file.name } } - normalized_receiver_name := receiver_type_name.trim_left('&').trim_right('*') + normalized_receiver_name := + receiver_type_name.trim_left('&').trim_right('*') if normalized_receiver_name != '' && normalized_receiver_name != receiver_type_name { e.functions[file.mod]['${normalized_receiver_name}__${stmt.name}'] = FunctionDef{ decl: stmt file_name: file.name } - short_normalized_name := normalized_receiver_name.all_after_last('.') + short_normalized_name := + normalized_receiver_name.all_after_last('.') if short_normalized_name != normalized_receiver_name { e.functions[file.mod]['${short_normalized_name}__${stmt.name}'] = FunctionDef{ decl: stmt @@ -2486,8 +2488,8 @@ fn (mut e Eval) maybe_call_builtin_function(module_name string, fn_name string, } } 'write_file' { - os.write_file(e.expect_string_arg(args, 0) or { return MaybeValue{} }, - e.expect_string_arg(args, 1) or { return MaybeValue{} }) or { + os.write_file(e.expect_string_arg(args, 0) or { return MaybeValue{} }, e.expect_string_arg(args, + 1) or { return MaybeValue{} }) or { return MaybeValue{ found: true value: wrap_result_err(err.msg()) @@ -2763,8 +2765,9 @@ fn (mut e Eval) maybe_call_generated_array_helper(fn_name string, args []Value) if fn_name.ends_with('_join') && args.len >= 2 { return MaybeValue{ found: true - value: array_value.values.map(e.value_string(it)).join(e.expect_string_arg(args, - 1) or { return none }) + value: array_value.values.map(e.value_string(it)).join(e.expect_string_arg(args, 1) or { + return none + }) } } if fn_name.ends_with('_str') { @@ -4763,9 +4766,7 @@ fn (mut e Eval) eval_selector_expr(expr ast.SelectorExpr) !Value { if zero_payload := e.zero_value_for_sumtype_data_field(left.type_name, expr.rhs.name) { return zero_payload } - if embedded_value := e.lookup_embedded_struct_field_value(left, expr.rhs.name, - 0) - { + if embedded_value := e.lookup_embedded_struct_field_value(left, expr.rhs.name, 0) { return embedded_value } if field_type := e.lookup_struct_field_type(left.type_name, expr.rhs.name) { @@ -5165,9 +5166,8 @@ fn decode_string_literal(raw string) string { if s.len >= 2 && ((s[0] == `"` && s[s.len - 1] == `"`) || (s[0] == `'` && s[s.len - 1] == `'`)) { s = s[1..s.len - 1] } - return s.replace('\\n', '\n').replace('\\r', '\r').replace('\\t', '\t').replace('\\0', - '\0').replace('\\"', '"').replace("\\'", "'").replace('\\`', '`').replace('\\\\', - '\\').replace('\\$', '$') + return s.replace('\\n', '\n').replace('\\r', '\r').replace('\\t', '\t').replace('\\0', '\0').replace('\\"', + '"').replace("\\'", "'").replace('\\`', '`').replace('\\\\', '\\').replace('\\$', '$') } fn (mut e Eval) eval_unsafe_expr(expr ast.UnsafeExpr) !Value { @@ -5311,8 +5311,7 @@ fn (mut e Eval) call_string_method(receiver string, method_name string, args []V return receiver.repeat(int(e.value_as_int(args[0])!)) } 'replace' { - return receiver.replace(e.expect_string_arg(args, 0)!, e.expect_string_arg(args, - 1)!) + return receiver.replace(e.expect_string_arg(args, 0)!, e.expect_string_arg(args, 1)!) } 'split' { return ArrayValue{ diff --git a/vlib/v2/eval/eval_test.v b/vlib/v2/eval/eval_test.v index ab6d5ad35b..ebb3946682 100644 --- a/vlib/v2/eval/eval_test.v +++ b/vlib/v2/eval/eval_test.v @@ -168,8 +168,10 @@ import os fn main() { println(os.args.join("|")) } -', - ['alpha', 'beta']) or { panic(err) } +', [ + 'alpha', + 'beta', + ]) or { panic(err) } if res.exit_code != 0 { panic(res.output) } @@ -392,7 +394,8 @@ fn test_eval_sumtype_tag_from_type_value_uses_registered_type_kind() { mut prefs := pref.new_preferences() mut file_set := token.FileSet.new() mut par := parser.Parser.new(&prefs) - type_files := os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'types'), '.v').filter(!it.ends_with('_test.v')) + type_files := + os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'types'), '.v').filter(!it.ends_with('_test.v')) dummy_main := os.join_path(os.temp_dir(), 'v2_eval_dummy_main_${os.getpid()}.v') os.write_file(dummy_main, 'module main\nfn main() {}\n') or { panic(err) } defer { @@ -420,7 +423,8 @@ fn test_eval_type_sum_data_is_nil() { mut prefs := pref.new_preferences() mut file_set := token.FileSet.new() mut par := parser.Parser.new(&prefs) - type_files := os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'types'), '.v').filter(!it.ends_with('_test.v')) + type_files := + os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'types'), '.v').filter(!it.ends_with('_test.v')) dummy_main := os.join_path(os.temp_dir(), 'v2_eval_dummy_main_${os.getpid()}.v') os.write_file(dummy_main, 'module main\nfn main() {}\n') or { panic(err) } defer { @@ -441,7 +445,8 @@ fn test_eval_zero_value_for_sumtype_data_field() { mut prefs := pref.new_preferences() mut file_set := token.FileSet.new() mut par := parser.Parser.new(&prefs) - ast_files := os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'ast'), '.v').filter(!it.ends_with('_test.v')) + ast_files := + os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'ast'), '.v').filter(!it.ends_with('_test.v')) dummy_main := os.join_path(os.temp_dir(), 'v2_eval_dummy_main_${os.getpid()}.v') os.write_file(dummy_main, 'module main\nfn main() {}\n') or { panic(err) } defer { @@ -463,7 +468,8 @@ fn test_eval_selector_on_sumtype_data_void_field_returns_zero_value() { mut prefs := pref.new_preferences() mut file_set := token.FileSet.new() mut par := parser.Parser.new(&prefs) - ast_files := os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'ast'), '.v').filter(!it.ends_with('_test.v')) + ast_files := + os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'ast'), '.v').filter(!it.ends_with('_test.v')) dummy_main := os.join_path(os.temp_dir(), 'v2_eval_dummy_main_${os.getpid()}.v') os.write_file(dummy_main, 'module main\nfn main() {}\n') or { panic(err) } defer { @@ -507,7 +513,8 @@ fn test_eval_selector_on_sumtype_wrapper_variant_field_returns_zero_value() { mut prefs := pref.new_preferences() mut file_set := token.FileSet.new() mut par := parser.Parser.new(&prefs) - ast_files := os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'ast'), '.v').filter(!it.ends_with('_test.v')) + ast_files := + os.walk_ext(os.join_path(@VMODROOT, 'vlib', 'v2', 'ast'), '.v').filter(!it.ends_with('_test.v')) dummy_main := os.join_path(os.temp_dir(), 'v2_eval_dummy_main_${os.getpid()}.v') os.write_file(dummy_main, 'module main\nfn main() {}\n') or { panic(err) } defer { diff --git a/vlib/v2/gen/arm64/arm64.v b/vlib/v2/gen/arm64/arm64.v index fe1e1fdb86..decd63f027 100644 --- a/vlib/v2/gen/arm64/arm64.v +++ b/vlib/v2/gen/arm64/arm64.v @@ -2101,7 +2101,9 @@ fn (mut g Gen) gen_instr(val_id int) { // ValueID 0 is the SSA null/invalid sentinel. if ptr_id <= 0 || ptr_id >= g.mod.values.len { g.emit_mov_imm64(dest_reg, 0) - } else if data_word_id := g.sumtype_data_word_load_source(ptr_id, g.mod.values[val_id].typ) { + } else if data_word_id := g.sumtype_data_word_load_source(ptr_id, + g.mod.values[val_id].typ) + { if trace_load { eprintln('ARM64 LOAD fn=${g.cur_func_name} val=${val_id} ptr=${ptr_id} sumtype_data_word=${data_word_id}') } @@ -2191,8 +2193,7 @@ fn (mut g Gen) gen_instr(val_id int) { if ptr_is_null_const { g.zero_fp_bytes(result_offset, result_size) } else { - g.copy_ptr_to_fp_bytes(load_src_ptr_reg, result_offset, - result_size) + g.copy_ptr_to_fp_bytes(load_src_ptr_reg, result_offset, result_size) } loaded_into_aggregate_slot = true } else if dest_reg != load_src_ptr_reg { @@ -2292,8 +2293,7 @@ fn (mut g Gen) gen_instr(val_id int) { g.emit_mov_imm(0, 1) g.emit_mov_imm(1, u64(alloc_size)) sym_idx := g.macho.add_undefined('_calloc') - g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_branch26, - true) + g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_branch26, true) g.emit(asm_bl_reloc()) g.store_reg_to_val(0, val_id) } else { @@ -2527,8 +2527,7 @@ fn (mut g Gen) gen_instr(val_id int) { // Call function sym_idx := g.macho.add_undefined('_' + fn_name) - g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_branch26, - true) + g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_branch26, true) g.emit(asm_bl_reloc()) // Restore stack @@ -2604,11 +2603,10 @@ fn (mut g Gen) gen_instr(val_id int) { continue } if cnt > 1 { - g.load_struct_arg_word_to_reg(9, instr.operands[a + 1], - ri, expected_struct_typ, instr.operands[0]) + g.load_struct_arg_word_to_reg(9, instr.operands[a + 1], ri, + expected_struct_typ, instr.operands[0]) } else { - g.load_call_arg_to_reg(9, instr.operands[a + 1], - a, instr) + g.load_call_arg_to_reg(9, instr.operands[a + 1], a, instr) } g.emit(asm_str_imm(Reg(9), sp, u32(stack_idx))) stack_idx++ @@ -2656,8 +2654,7 @@ fn (mut g Gen) gen_instr(val_id int) { } sym_idx := g.macho.add_undefined('_' + fn_name) - g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_branch26, - true) + g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_branch26, true) g.emit(asm_bl_reloc()) if stack_space > 0 { @@ -2796,8 +2793,8 @@ fn (mut g Gen) gen_instr(val_id int) { if target_reg >= 8 { continue } - g.load_struct_arg_word_to_reg(target_reg, instr.operands[a + 1], - ri, expected_struct_typ, instr.operands[0]) + g.load_struct_arg_word_to_reg(target_reg, instr.operands[a + 1], ri, + expected_struct_typ, instr.operands[0]) } } else { g.load_call_arg_to_reg(reg, instr.operands[a + 1], a, instr) @@ -2916,8 +2913,8 @@ fn (mut g Gen) gen_instr(val_id int) { if target_reg >= 8 { continue } - g.load_struct_arg_word_to_reg(target_reg, instr.operands[a + 1], - ri, expected_struct_typ, instr.operands[0]) + g.load_struct_arg_word_to_reg(target_reg, instr.operands[a + 1], ri, + expected_struct_typ, instr.operands[0]) } } else { g.load_call_arg_to_reg(reg, instr.operands[a + 1], a, instr) @@ -2928,8 +2925,7 @@ fn (mut g Gen) gen_instr(val_id int) { if fn_val.name != '' && fn_val.kind in [.unknown, .func_ref] { // Direct call by symbol. sym_idx := g.macho.add_undefined('_' + fn_val.name) - g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_branch26, - true) + g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_branch26, true) g.emit(asm_bl_reloc()) } else { // Indirect call through function pointer value. @@ -3145,8 +3141,7 @@ fn (mut g Gen) gen_instr(val_id int) { } } else { if source_chunks > 1 || ret_typ.kind == .struct_t { - g.load_struct_src_address_to_reg(8, ret_val_id, actual_struct_typ_id, - 0) + g.load_struct_src_address_to_reg(8, ret_val_id, actual_struct_typ_id, 0) for i in 0 .. num_chunks { if i < 8 { if i < source_chunks { @@ -3557,7 +3552,8 @@ fn (mut g Gen) gen_instr(val_id int) { mut can_copy := false mut src_is_null_ptr := false mut src_copy_uses_pointee := false - src_is_ptr_carried := g.large_aggregate_stack_value_is_pointer(src_id) + src_is_ptr_carried := + g.large_aggregate_stack_value_is_pointer(src_id) if src_id > 0 && src_id < g.mod.values.len { src_typ_id := g.mod.values[src_id].typ if src_typ_id > 0 && src_typ_id < g.mod.type_store.types.len { @@ -3581,12 +3577,12 @@ fn (mut g Gen) gen_instr(val_id int) { can_reinterpret_ptr = false } if can_reinterpret_ptr { - src_is_null_ptr = g.is_effective_null_pointer_value(src_id) + src_is_null_ptr = + g.is_effective_null_pointer_value(src_id) if src_id in g.reg_map { src_ptr_reg = g.reg_map[src_id] } else if src_off := g.stack_map[src_id] { - g.emit_ldr_reg_offset(src_ptr_reg, - 29, src_off) + g.emit_ldr_reg_offset(src_ptr_reg, 29, src_off) } else { g.load_val_to_reg(src_ptr_reg, src_id) } @@ -3654,10 +3650,10 @@ fn (mut g Gen) gen_instr(val_id int) { if src_is_null_ptr { g.zero_fp_bytes(dest_off, dest_size) } else { - g.copy_ptr_to_fp_bytes(src_ptr_reg, dest_off, - copy_size) + g.copy_ptr_to_fp_bytes(src_ptr_reg, dest_off, copy_size) if copy_size < dest_size { - g.zero_fp_bytes(dest_off + copy_size, dest_size - copy_size) + g.zero_fp_bytes(dest_off + copy_size, + dest_size - copy_size) } } copied_aggregate = true @@ -3759,12 +3755,12 @@ fn (mut g Gen) gen_instr(val_id int) { } } if can_use_ptr_source { - src_is_null_ptr = g.is_effective_null_pointer_value(src_id) + src_is_null_ptr = + g.is_effective_null_pointer_value(src_id) if src_id in g.reg_map { src_ptr_reg = g.reg_map[src_id] } else if src_off := g.stack_map[src_id] { - g.emit_ldr_reg_offset(src_ptr_reg, 29, - src_off) + g.emit_ldr_reg_offset(src_ptr_reg, 29, src_off) } else { g.load_val_to_reg(src_ptr_reg, src_id) } @@ -3892,8 +3888,7 @@ fn (mut g Gen) gen_instr(val_id int) { struct_offset := base_offset + 8 str_off, _ := g.struct_field_offset_and_size(instr.typ, 0, 0, 8) len_off, len_size := g.struct_field_offset_and_size(instr.typ, 1, 8, 8) - is_lit_off, is_lit_size := g.struct_field_offset_and_size(instr.typ, 2, 16, - 8) + is_lit_off, is_lit_size := g.struct_field_offset_and_size(instr.typ, 2, 16, 8) // Store str field g.load_val_to_reg(8, str_ptr_id) @@ -3964,8 +3959,8 @@ fn (mut g Gen) gen_instr(val_id int) { tuple_is_agg_typ = true tuple_is_large_agg = g.type_size(load_ptr_typ.elem_type) > 16 if load_elem_typ.kind == .struct_t && idx >= 0 { - field_byte_off = g.struct_field_offset_bytes(load_ptr_typ.elem_type, - idx) + field_byte_off = + g.struct_field_offset_bytes(load_ptr_typ.elem_type, idx) if idx < load_elem_typ.fields.len { field_elem_size = g.type_size(load_elem_typ.fields[idx]) if field_elem_size <= 0 { @@ -4009,8 +4004,8 @@ fn (mut g Gen) gen_instr(val_id int) { if g.is_effective_null_pointer_value(scalar_load_agg_src_ptr_id) { g.zero_fp_bytes(dst_offset, result_size) } else { - g.copy_ptr_offset_to_fp_bytes(agg_ptr_reg, field_byte_off, - dst_offset, result_size) + g.copy_ptr_offset_to_fp_bytes(agg_ptr_reg, field_byte_off, dst_offset, + result_size) } handled_scalar_load_struct_extract = true } @@ -4638,8 +4633,7 @@ fn (mut g Gen) gen_instr(val_id int) { // through scalar-typed values. Recover the wrapper address and // copy the full bytes instead of falling back to a single-word store. mut src_ptr_reg := 12 - g.load_struct_src_address_to_reg(src_ptr_reg, field_id, field_typ_id, - 0) + g.load_struct_src_address_to_reg(src_ptr_reg, field_id, field_typ_id, 0) for w in 0 .. field_chunks { g.emit(asm_ldr_imm(Reg(10), Reg(src_ptr_reg), u32(w))) g.emit_str_reg_offset(10, 29, result_offset + field_off + w * 8) @@ -4837,8 +4831,7 @@ fn (mut g Gen) gen_instr(val_id int) { // Keep full wrapper bytes for small sumtype fields carried through // scalar temporaries instead of truncating to the first word. mut src_ptr_reg := 12 - g.load_struct_src_address_to_reg(src_ptr_reg, elem_id, elem_typ_id, - 0) + g.load_struct_src_address_to_reg(src_ptr_reg, elem_id, elem_typ_id, 0) for i in 0 .. elem_chunks { g.emit(asm_ldr_imm(Reg(10), Reg(src_ptr_reg), u32(i))) g.emit_str_reg_offset(10, 29, result_offset + elem_off + i * 8) @@ -5022,12 +5015,14 @@ fn (g &Gen) alloca_store_value_is_pointer_like_inner(val_id int, for_alloca_id i .bitcast, .zext, .sext, .trunc { if instr.operands.len > 0 { return g.alloca_store_value_is_pointer_like_inner(instr.operands[0], for_alloca_id, + depth + 1, mut seen_allocas) } } .assign { if instr.operands.len >= 2 { return g.alloca_store_value_is_pointer_like_inner(instr.operands[1], for_alloca_id, + depth + 1, mut seen_allocas) } } @@ -5101,8 +5096,8 @@ fn (mut g Gen) alloca_slot_stores_pointer_like_values(alloca_id int, param_elem_ return cached == 1 } mut seen_allocas := map[int]bool{} - result := g.alloca_slot_stores_pointer_like_values_inner(alloca_id, param_elem_typ_id, - 0, mut seen_allocas) + result := g.alloca_slot_stores_pointer_like_values_inner(alloca_id, param_elem_typ_id, 0, mut + seen_allocas) g.alloca_ptr_cache[alloca_id] = if result { u8(1) } else { u8(2) } return result } @@ -5739,8 +5734,8 @@ fn (mut g Gen) load_struct_src_address_to_reg(reg int, val_id int, expected_stru return } } - if wrapper_id := g.sumtype_wrapper_source_from_unwrapped_value(val_id, expected_struct_typ, - 0) + if wrapper_id := g.sumtype_wrapper_source_from_unwrapped_value(val_id, + expected_struct_typ, 0) { if trace_struct_addr { eprintln('ARM64 STRUCT_ADDR fn=${g.cur_func_name} mode=unwrap_match val=${val_id} wrapper=${wrapper_id} expected=${expected_struct_typ}') @@ -6028,8 +6023,7 @@ fn (mut g Gen) load_val_to_reg(reg int, val_id int) { g.macho.str_data << str_content g.macho.str_data << 0 - sym_idx := g.macho.add_symbol('L_str_${str_offset}', u64(str_offset), false, - 2) + sym_idx := g.macho.add_symbol('L_str_${str_offset}', u64(str_offset), false, 2) g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_page21, true) g.emit(asm_adrp(Reg(reg))) g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_pageoff12, false) @@ -6060,11 +6054,9 @@ fn (mut g Gen) load_val_to_reg(reg int, val_id int) { if is_external { // External global: load address through GOT sym_idx := g.macho.add_undefined('_' + val.name) - g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_got_load_page21, - true) + g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_got_load_page21, true) g.emit(asm_adrp(Reg(reg))) - g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_got_load_pageoff12, - false) + g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_got_load_pageoff12, false) g.emit(asm_ldr_pageoff(Reg(reg))) } else { // Local global: direct address @@ -6110,15 +6102,13 @@ fn (mut g Gen) load_val_to_reg(reg int, val_id int) { str_off, _ := g.struct_field_offset_and_size(val.typ, 0, 0, 8) len_off, len_size := g.struct_field_offset_and_size(val.typ, 1, 8, 8) - is_lit_off, is_lit_size := g.struct_field_offset_and_size(val.typ, 2, 16, - 8) + is_lit_off, is_lit_size := g.struct_field_offset_and_size(val.typ, 2, 16, 8) if trace_strlit && g.cur_func_name == 'transformer__Transformer__transform_if_expr' { eprintln('ARM64 STRLIT init fn=${g.cur_func_name} val=${val_id} typ=${val.typ} base=${base_offset} str_off=${str_off} len_off=${len_off} len_size=${len_size} lit_off=${is_lit_off} lit_size=${is_lit_size} slen=${str_len} name=`${str_content}`') } // Store str pointer: load address of string data - sym_idx := g.macho.add_symbol('L_str_${str_offset2}', u64(str_offset2), false, - 2) + sym_idx := g.macho.add_symbol('L_str_${str_offset2}', u64(str_offset2), false, 2) g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_page21, true) g.emit(asm_adrp(Reg(reg))) g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_pageoff12, false) @@ -6161,8 +6151,7 @@ fn (mut g Gen) load_val_to_reg(reg int, val_id int) { } } g.macho.str_data << 0 // null terminator - sym_idx := g.macho.add_symbol('L_cstr_${str_offset2}', u64(str_offset2), false, - 2) + sym_idx := g.macho.add_symbol('L_cstr_${str_offset2}', u64(str_offset2), false, 2) g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_page21, true) g.emit(asm_adrp(Reg(reg))) g.macho.add_reloc(g.macho.text_data.len, sym_idx, arm64_reloc_pageoff12, false) @@ -7484,8 +7473,7 @@ fn (mut g Gen) pointer_carried_aggregate_size_bytes(ptr_id int, depth int, mut s } } } - base_size := g.pointer_carried_aggregate_size_bytes(base_id, depth + 1, mut - seen) + base_size := g.pointer_carried_aggregate_size_bytes(base_id, depth + 1, mut seen) if field_size > 8 { return field_size } @@ -7506,8 +7494,7 @@ fn (mut g Gen) pointer_carried_aggregate_size_bytes(ptr_id int, depth int, mut s } mut min_size := 0 for op_id in ptr_instr.operands { - op_size := g.pointer_carried_aggregate_size_bytes(op_id, depth + 1, mut - seen) + op_size := g.pointer_carried_aggregate_size_bytes(op_id, depth + 1, mut seen) if op_size <= 8 { return 0 } @@ -7607,8 +7594,7 @@ fn (mut g Gen) inferred_aggregate_carried_size_bytes(val_id int, depth int, mut return 0 } src_id := instr.operands[0] - mut inferred := g.inferred_aggregate_carried_size_bytes(src_id, depth + 1, mut - seen) + mut inferred := g.inferred_aggregate_carried_size_bytes(src_id, depth + 1, mut seen) if op == .bitcast && src_id > 0 && src_id < g.mod.values.len { src_typ_id := g.mod.values[src_id].typ if src_typ_id > 0 && src_typ_id < g.mod.type_store.types.len { @@ -7647,8 +7633,7 @@ fn (mut g Gen) inferred_aggregate_carried_size_bytes(val_id int, depth int, mut if g.scalar_value_is_pointer_payload(val_id, 0) { return 0 } - return g.pointer_carried_aggregate_size_bytes(instr.operands[0], depth + 1, mut - seen) + return g.pointer_carried_aggregate_size_bytes(instr.operands[0], depth + 1, mut seen) } .extractvalue { return g.extractvalue_carried_field_size_bytes(instr, depth + 1, mut seen) @@ -7672,8 +7657,7 @@ fn (mut g Gen) inferred_aggregate_carried_size_bytes(val_id int, depth int, mut } mut min_size := 0 for op_id in instr.operands { - op_size := g.inferred_aggregate_carried_size_bytes(op_id, depth + 1, mut - seen) + op_size := g.inferred_aggregate_carried_size_bytes(op_id, depth + 1, mut seen) if op_size <= 8 { return 0 } @@ -8430,12 +8414,13 @@ fn (g &Gen) sumtype_wrapper_source_from_data_ptr(ptr_id int, expected_wrapper_ty return tuple_id } if wrapper_id := g.sumtype_wrapper_source_from_data_ptr(src_id, expected_wrapper_typ, + depth + 1) { return wrapper_id } - if wrapper_id := g.sumtype_wrapper_source_from_unwrapped_value(src_id, expected_wrapper_typ, - depth + 1) + if wrapper_id := g.sumtype_wrapper_source_from_unwrapped_value(src_id, + expected_wrapper_typ, depth + 1) { return wrapper_id } @@ -8447,8 +8432,8 @@ fn (g &Gen) sumtype_wrapper_source_from_data_ptr(ptr_id int, expected_wrapper_ty } .phi { for op_id in instr.operands { - if wrapper_id := g.sumtype_wrapper_source_from_data_ptr(op_id, expected_wrapper_typ, - depth + 1) + if wrapper_id := g.sumtype_wrapper_source_from_data_ptr(op_id, + expected_wrapper_typ, depth + 1) { return wrapper_id } @@ -8487,8 +8472,8 @@ fn (g &Gen) sumtype_wrapper_source_from_unwrapped_value(val_id int, expected_wra // wrapper/payload at the call site where we also have guard context. if instr.operands.len > 0 { src_id := instr.operands[0] - if wrapper_id := g.sumtype_wrapper_source_from_data_ptr(src_id, expected_wrapper_typ, - depth + 1) + if wrapper_id := g.sumtype_wrapper_source_from_data_ptr(src_id, + expected_wrapper_typ, depth + 1) { return wrapper_id } @@ -8500,12 +8485,13 @@ fn (g &Gen) sumtype_wrapper_source_from_unwrapped_value(val_id int, expected_wra } src_idx := if op == .assign && instr.operands.len > 1 { 1 } else { 0 } src_id := instr.operands[src_idx] - if wrapper_id := g.sumtype_wrapper_source_from_unwrapped_value(src_id, expected_wrapper_typ, - depth + 1) + if wrapper_id := g.sumtype_wrapper_source_from_unwrapped_value(src_id, + expected_wrapper_typ, depth + 1) { return wrapper_id } if wrapper_id := g.sumtype_wrapper_source_from_data_ptr(src_id, expected_wrapper_typ, + depth + 1) { return wrapper_id diff --git a/vlib/v2/gen/cleanc/array.v b/vlib/v2/gen/cleanc/array.v index 97a1375f09..52a3dcafc7 100644 --- a/vlib/v2/gen/cleanc/array.v +++ b/vlib/v2/gen/cleanc/array.v @@ -234,7 +234,8 @@ fn (mut g Gen) array_append_elem_type(lhs ast.Expr, rhs ast.Expr) (bool, string) if raw_type.base_type.base_type is types.Array { is_array_append = true if elem_type == '' { - elem_type = g.types_type_to_c(raw_type.base_type.base_type.elem_type) + elem_type = + g.types_type_to_c(raw_type.base_type.base_type.elem_type) } } } diff --git a/vlib/v2/gen/cleanc/cleanc.v b/vlib/v2/gen/cleanc/cleanc.v index 9dc25a2c3d..02ebbfa95c 100644 --- a/vlib/v2/gen/cleanc/cleanc.v +++ b/vlib/v2/gen/cleanc/cleanc.v @@ -581,8 +581,7 @@ pub fn (mut g Gen) gen_passes_1_to_4() { g.collect_runtime_const_targets() g.register_builder_methods() g.build_generic_spec_index() - stage_start = g.mark_cgen_step(stats_enabled, stats_scope, mut stats_sw, stage_start, - 'setup') + stage_start = g.mark_cgen_step(stats_enabled, stats_scope, mut stats_sw, stage_start, 'setup') // Pre-collect all global variable names so they can be module-qualified for file in g.files { diff --git a/vlib/v2/gen/cleanc/expr.v b/vlib/v2/gen/cleanc/expr.v index 8d60d5f1de..ac5361f3b4 100644 --- a/vlib/v2/gen/cleanc/expr.v +++ b/vlib/v2/gen/cleanc/expr.v @@ -2555,8 +2555,8 @@ fn (mut g Gen) gen_type_cast_expr(type_name string, expr ast.Expr) { // Fallback: try to infer variant from expression structure inferred := g.infer_sum_variant_from_expr(type_name, variants, expr) if inferred.tag >= 0 { - g.gen_sum_type_wrap(type_name, inferred.field_name, inferred.tag, inferred.is_primitive, - expr, inferred.inner_type) + g.gen_sum_type_wrap(type_name, inferred.field_name, inferred.tag, + inferred.is_primitive, expr, inferred.inner_type) return } } diff --git a/vlib/v2/gen/cleanc/fn.v b/vlib/v2/gen/cleanc/fn.v index 0a9a100e9e..69d6a8d8b6 100644 --- a/vlib/v2/gen/cleanc/fn.v +++ b/vlib/v2/gen/cleanc/fn.v @@ -310,7 +310,8 @@ fn (mut g Gen) infer_vector_return_type_from_stmts(stmts []ast.Stmt) string { return inferred } if stmt.expr.else_expr is ast.IfExpr { - else_inferred := g.infer_vector_return_type_from_stmts(stmt.expr.else_expr.stmts) + else_inferred := + g.infer_vector_return_type_from_stmts(stmt.expr.else_expr.stmts) if else_inferred != '' { return else_inferred } @@ -462,8 +463,7 @@ fn (mut g Gen) register_fn_signature(node ast.FnDecl, fn_name string) { mut params := []bool{} mut param_types := []string{} if node.is_method && node.receiver.name != '' { - recv_type := normalize_signature_type_name(g.expr_type_to_c(node.receiver.typ), - 'void*') + recv_type := normalize_signature_type_name(g.expr_type_to_c(node.receiver.typ), 'void*') params << (node.receiver.is_mut || recv_type.ends_with('*')) param_types << if node.receiver.is_mut && !recv_type.ends_with('*') { recv_type + '*' @@ -518,50 +518,40 @@ fn collect_generic_placeholder_names_from_expr(expr ast.Expr, mut seen map[strin ast.Type { match expr { ast.ArrayType { - collect_generic_placeholder_names_from_expr(expr.elem_type, mut seen, mut - out) + collect_generic_placeholder_names_from_expr(expr.elem_type, mut seen, mut out) } ast.ArrayFixedType { - collect_generic_placeholder_names_from_expr(expr.elem_type, mut seen, mut - out) - collect_generic_placeholder_names_from_expr(expr.len, mut seen, mut - out) + collect_generic_placeholder_names_from_expr(expr.elem_type, mut seen, mut out) + collect_generic_placeholder_names_from_expr(expr.len, mut seen, mut out) } ast.MapType { - collect_generic_placeholder_names_from_expr(expr.key_type, mut seen, mut - out) - collect_generic_placeholder_names_from_expr(expr.value_type, mut seen, mut - out) + collect_generic_placeholder_names_from_expr(expr.key_type, mut seen, mut out) + collect_generic_placeholder_names_from_expr(expr.value_type, mut seen, mut out) } ast.OptionType { - collect_generic_placeholder_names_from_expr(expr.base_type, mut seen, mut - out) + collect_generic_placeholder_names_from_expr(expr.base_type, mut seen, mut out) } ast.ResultType { - collect_generic_placeholder_names_from_expr(expr.base_type, mut seen, mut - out) + collect_generic_placeholder_names_from_expr(expr.base_type, mut seen, mut out) } ast.TupleType { for typ in expr.types { - collect_generic_placeholder_names_from_expr(typ, mut seen, mut - out) + collect_generic_placeholder_names_from_expr(typ, mut seen, mut out) } } ast.FnType { for param in expr.params { - collect_generic_placeholder_names_from_expr(param.typ, mut seen, mut - out) + collect_generic_placeholder_names_from_expr(param.typ, mut seen, mut out) } if expr.return_type !is ast.EmptyExpr { - collect_generic_placeholder_names_from_expr(expr.return_type, mut - seen, mut out) + collect_generic_placeholder_names_from_expr(expr.return_type, mut seen, mut + out) } } ast.GenericType { // Recurse into params (e.g. LinkedList[T] → extract T) for param in expr.params { - collect_generic_placeholder_names_from_expr(param, mut seen, mut - out) + collect_generic_placeholder_names_from_expr(param, mut seen, mut out) } } else {} @@ -582,8 +572,7 @@ fn (g &Gen) generic_fn_param_names(node ast.FnDecl) []string { && node.name in ['subscribe_method', 'unsubscribe_method'] { mut seen := map[string]bool{} if node.receiver.typ !is ast.EmptyExpr { - collect_generic_placeholder_names_from_expr(node.receiver.typ, mut seen, mut - names) + collect_generic_placeholder_names_from_expr(node.receiver.typ, mut seen, mut names) } for param in node.typ.params { collect_generic_placeholder_names_from_expr(param.typ, mut seen, mut names) @@ -977,8 +966,8 @@ fn infer_generic_type_bindings_from_param(param ast.Expr, concrete types.Type, g if concrete is types.Map { infer_generic_type_bindings_from_param(param.key_type, concrete.key_type, generic_params, mut bindings) - infer_generic_type_bindings_from_param(param.value_type, concrete.value_type, - generic_params, mut bindings) + infer_generic_type_bindings_from_param(param.value_type, + concrete.value_type, generic_params, mut bindings) } } ast.OptionType { @@ -1088,7 +1077,8 @@ fn (mut g Gen) try_specialize_generic_call_name(name string, call_args []ast.Exp } mut arg_type_name := g.get_expr_type(base_arg).trim_space().trim_right('*') if (arg_type_name == '' || arg_type_name == 'int') && base_arg is ast.Ident { - arg_type_name = (g.get_local_var_c_type(base_arg.name) or { '' }).trim_space().trim_right('*') + arg_type_name = + (g.get_local_var_c_type(base_arg.name) or { '' }).trim_space().trim_right('*') } if arg_type_name == 'string' { candidate := '${name}_T_string' @@ -1121,7 +1111,8 @@ fn (mut g Gen) try_specialize_generic_call_name(name string, call_args []ast.Exp } mut arg_type_name := g.get_expr_type(base_arg).trim_space().trim_right('*') if (arg_type_name == '' || arg_type_name == 'int') && base_arg is ast.Ident { - arg_type_name = (g.get_local_var_c_type(base_arg.name) or { '' }).trim_space().trim_right('*') + arg_type_name = + (g.get_local_var_c_type(base_arg.name) or { '' }).trim_space().trim_right('*') } if arg_type_name != '' && arg_type_name != 'int' { if candidate := g.find_specialized_call_name('json2__Encoder__encode_value', @@ -1170,7 +1161,9 @@ fn (mut g Gen) try_specialize_generic_call_name(name string, call_args []ast.Exp candidate_types << '${g.cur_module}__${arg_type_name}' } for concrete_type_name in candidate_types { - if candidate := g.find_specialized_call_name(name, sanitize_generic_token_part(concrete_type_name)) { + if candidate := g.find_specialized_call_name(name, + sanitize_generic_token_part(concrete_type_name)) + { return candidate } } @@ -1225,7 +1218,9 @@ fn (mut g Gen) try_specialize_generic_call_name(name string, call_args []ast.Exp candidate_types << '${g.cur_module}__${arg_type_name}' } for concrete_type_name in candidate_types { - if candidate := g.find_specialized_call_name(name, sanitize_generic_token_part(concrete_type_name)) { + if candidate := g.find_specialized_call_name(name, + sanitize_generic_token_part(concrete_type_name)) + { return candidate } } @@ -1257,8 +1252,7 @@ fn (mut g Gen) try_specialize_generic_call_name(name string, call_args []ast.Exp continue } } - infer_generic_type_bindings_from_param(param.typ, concrete, generic_params, mut - bindings) + infer_generic_type_bindings_from_param(param.typ, concrete, generic_params, mut bindings) } if bindings.len != generic_params.len { return none @@ -2608,7 +2602,8 @@ fn (mut g Gen) gen_call_arg(fn_name string, idx int, arg ast.Expr) { if g.is_interface_type(param_base) { mut arg_type := g.get_expr_type(base_arg).trim_space() if (arg_type == '' || arg_type == 'int') && base_arg is ast.Ident { - arg_type = (g.get_local_var_c_type(base_arg.name) or { '' }).trim_space() + arg_type = + (g.get_local_var_c_type(base_arg.name) or { '' }).trim_space() } if arg_type == '' || arg_type == 'int' { if raw := g.get_raw_type(base_arg) { @@ -2751,8 +2746,8 @@ fn (mut g Gen) gen_call_arg(fn_name string, idx int, arg ast.Expr) { is_primitive := arg_type in ['int', 'i8', 'i16', 'i32', 'i64', 'u8', 'u16', 'u32', 'u64', 'f32', 'f64', 'bool', 'rune', 'byte', 'usize', 'isize'] || arg_type in g.primitive_type_aliases - g.gen_sum_type_wrap(param_type, field_name, tag, is_primitive, - base_arg, arg_type) + g.gen_sum_type_wrap(param_type, field_name, tag, is_primitive, base_arg, + arg_type) return } } @@ -3623,8 +3618,7 @@ fn (mut g Gen) call_expr(lhs ast.Expr, args []ast.Expr) { param_idx := i - param_offset if method := g.interface_method_by_name(base_receiver, method_name) { if param_idx >= 0 && param_idx < method.param_types.len { - g.gen_interface_call_arg(method.param_types[param_idx], - arg) + g.gen_interface_call_arg(method.param_types[param_idx], arg) } else { g.expr(arg) } @@ -3709,9 +3703,7 @@ fn (mut g Gen) call_expr(lhs ast.Expr, args []ast.Expr) { return } // Try embedded struct method resolution - if emb := g.resolve_method_on_embedded_receiver(narrowed_receiver, - method_name) - { + if emb := g.resolve_method_on_embedded_receiver(narrowed_receiver, method_name) { call_args := g.interface_call_args_without_object(lhs.lhs, args) g.sb.write_string('${emb.method_c_name}(') ptr_params := g.fn_param_is_ptr[emb.method_c_name] or { []bool{} } @@ -3740,9 +3732,7 @@ fn (mut g Gen) call_expr(lhs ast.Expr, args []ast.Expr) { if !is_iface_receiver && base_receiver != '' && base_receiver != 'int' && !g.is_interface_type(base_receiver) { method_name := lhs.rhs.name - if concrete_method := g.resolve_method_on_concrete_type(base_receiver, - method_name) - { + if concrete_method := g.resolve_method_on_concrete_type(base_receiver, method_name) { ptr_params := g.fn_param_is_ptr[concrete_method] or { []bool{} } receiver_as_ptr := ptr_params.len > 0 && ptr_params[0] g.sb.write_string('${concrete_method}(') diff --git a/vlib/v2/gen/cleanc/stmt.v b/vlib/v2/gen/cleanc/stmt.v index fb5f08b275..2dfc10818b 100644 --- a/vlib/v2/gen/cleanc/stmt.v +++ b/vlib/v2/gen/cleanc/stmt.v @@ -22,8 +22,7 @@ fn (mut g Gen) set_file_module(file ast.File) { fn (mut g Gen) gen_stmts(stmts []ast.Stmt) { if g.cur_fn_name == 'decode_value' && stmts.len > 0 { - C.fprintf(C.stderr, c'[gen_stmts] cur_fn=%s stmts.len=%d\n', g.cur_fn_name.str, - stmts.len) + C.fprintf(C.stderr, c'[gen_stmts] cur_fn=%s stmts.len=%d\n', g.cur_fn_name.str, stmts.len) } for i in 0 .. stmts.len { if g.cur_fn_name == 'decode_value' { @@ -51,8 +50,12 @@ fn (mut g Gen) gen_stmt(node ast.Stmt) { is_if := node.expr is ast.IfExpr is_call := node.expr is ast.CallExpr is_ident := node.expr is ast.Ident - C.fprintf(C.stderr, c'[gen_stmt/ExprStmt] valid=%d comptime=%d if=%d call=%d ident=%d\n', - if expr_has_valid_data(node.expr) { 1 } else { 0 }, if is_comptime { + C.fprintf(C.stderr, + c'[gen_stmt/ExprStmt] valid=%d comptime=%d if=%d call=%d ident=%d\n', if expr_has_valid_data(node.expr) { + 1 + } else { + 0 + }, if is_comptime { 1 } else { 0 diff --git a/vlib/v2/gen/cleanc/struct.v b/vlib/v2/gen/cleanc/struct.v index c7b4eab04e..2e7a66b372 100644 --- a/vlib/v2/gen/cleanc/struct.v +++ b/vlib/v2/gen/cleanc/struct.v @@ -101,8 +101,9 @@ fn (mut g Gen) propagate_generic_bindings(e ast.Expr, parent_bindings map[string } else { base_name } - g.record_generic_struct_bindings_with_parent(struct_base, base_name, - [e.expr], parent_bindings) + g.record_generic_struct_bindings_with_parent(struct_base, base_name, [ + e.expr, + ], parent_bindings) } else if !is_generic_placeholder_type_name(arg_name) { struct_base := if base_name.contains('__') { base_name.all_after_last('__') diff --git a/vlib/v2/gen/x64/elf.v b/vlib/v2/gen/x64/elf.v index 1c56890b68..7d8d70c450 100644 --- a/vlib/v2/gen/x64/elf.v +++ b/vlib/v2/gen/x64/elf.v @@ -337,20 +337,20 @@ pub fn (mut e ElfObject) write(path string) { break } } - write_shdr(mut buf, u32(off_symtab_name), sht_symtab, 0, u64(off_symtab), u64(size_symtab), - 5, u32(first_global), 8, 24) + write_shdr(mut buf, u32(off_symtab_name), sht_symtab, 0, u64(off_symtab), u64(size_symtab), 5, + u32(first_global), 8, 24) // 5: .strtab write_shdr(mut buf, u32(off_strtab_name), sht_strtab, 0, u64(off_strtab), u64(e.str_table.len), 0, 0, 1, 0) // 6: .rela.text (EntSize = 24) - write_shdr(mut buf, u32(off_rela_text_name), sht_rela, 0, u64(off_rela_text), u64(size_rela_text), - 4, 1, 8, 24) + write_shdr(mut buf, u32(off_rela_text_name), sht_rela, 0, u64(off_rela_text), + u64(size_rela_text), 4, 1, 8, 24) // 7: .shstrtab - write_shdr(mut buf, u32(off_shstrtab_name), sht_strtab, 0, u64(off_shstrtab), u64(e.shstr_table.len), - 0, 0, 1, 0) + write_shdr(mut buf, u32(off_shstrtab_name), sht_strtab, 0, u64(off_shstrtab), + u64(e.shstr_table.len), 0, 0, 1, 0) os.write_file_array(path, buf) or { panic(err) } } diff --git a/vlib/v2/gen/x64/x64.v b/vlib/v2/gen/x64/x64.v index a1287aa8fd..e94b89c845 100644 --- a/vlib/v2/gen/x64/x64.v +++ b/vlib/v2/gen/x64/x64.v @@ -373,8 +373,7 @@ fn (mut g Gen) gen_instr(val_id int) { // Load register arguments for i in 1 .. instr.operands.len { if i - 1 < 6 { - g.load_call_arg_to_reg(abi_regs[i - 1], instr.operands[i], i - 1, - instr) + g.load_call_arg_to_reg(abi_regs[i - 1], instr.operands[i], i - 1, instr) } } fn_val := g.mod.values[instr.operands[0]] @@ -481,8 +480,7 @@ fn (mut g Gen) gen_instr(val_id int) { // Load register arguments for i in 1 .. instr.operands.len { if i - 1 < 6 { - g.load_call_arg_to_reg(abi_regs[i - 1], instr.operands[i], i - 1, - instr) + g.load_call_arg_to_reg(abi_regs[i - 1], instr.operands[i], i - 1, instr) } } diff --git a/vlib/v2/markused/markused.v b/vlib/v2/markused/markused.v index a75a217e14..e7dc223f96 100644 --- a/vlib/v2/markused/markused.v +++ b/vlib/v2/markused/markused.v @@ -931,8 +931,7 @@ fn (mut w Walker) walk_stmt(stmt ast.Stmt, mod_name string) { // If the function returns an interface type and the return expr // is a concrete struct InitExpr, mark the concrete type's // interface methods so the vtable wrapper can call them. - w.mark_interface_conversion_methods(w.cur_fn_decl.typ.return_type, expr, - mod_name) + w.mark_interface_conversion_methods(w.cur_fn_decl.typ.return_type, expr, mod_name) } } ast.StructDecl { diff --git a/vlib/v2/ssa/builder.v b/vlib/v2/ssa/builder.v index d782b96c9f..b89b8aef41 100644 --- a/vlib/v2/ssa/builder.v +++ b/vlib/v2/ssa/builder.v @@ -551,7 +551,8 @@ fn (mut b Builder) build_unwrapped_postfix(expr ast.PostfixExpr, wrapped_val Val } fail_block := b.mod.add_block(b.cur_func, 'postfix_fail') ok_block := b.mod.add_block(b.cur_func, 'postfix_ok') - b.mod.add_instr(.br, b.cur_block, 0, [fail_cond, b.mod.blocks[fail_block].val_id, b.mod.blocks[ok_block].val_id]) + b.mod.add_instr(.br, b.cur_block, 0, + [fail_cond, b.mod.blocks[fail_block].val_id, b.mod.blocks[ok_block].val_id]) b.add_edge(b.cur_block, fail_block) b.add_edge(b.cur_block, ok_block) @@ -653,7 +654,8 @@ fn (mut b Builder) build_wrapper_value(wrapper_type TypeID, success bool, payloa } else { b.mod.get_or_add_const(flag_type, if success { '0' } else { '1' }) } - wrapper = b.mod.add_instr(.insertvalue, b.cur_block, wrapper_type, [wrapper, flag_val, flag_idx]) + wrapper = b.mod.add_instr(.insertvalue, b.cur_block, wrapper_type, + [wrapper, flag_val, flag_idx]) if !success { err_type := wrapper_info.fields[1] mut err_val := payload @@ -662,7 +664,8 @@ fn (mut b Builder) build_wrapper_value(wrapper_type TypeID, success bool, payloa } else if b.mod.values[err_val].typ != err_type { err_val = b.cast_value_to_type(err_val, err_type) } - wrapper = b.mod.add_instr(.insertvalue, b.cur_block, wrapper_type, [wrapper, err_val, err_idx]) + wrapper = b.mod.add_instr(.insertvalue, b.cur_block, wrapper_type, + [wrapper, err_val, err_idx]) } if has_payload && b.wrapper_has_data(wrapper_type) { data_idx := b.mod.get_or_add_const(i32_t, '2') @@ -1196,8 +1199,7 @@ fn (mut b Builder) register_consts_and_globals(file ast.File) { b.mod.type_store.get_int(8) } if is_fixed_array { - b.mod.add_global_with_data(const_name, elem_type, true, - arr_data) + b.mod.add_global_with_data(const_name, elem_type, true, arr_data) b.const_array_globals[const_name] = true b.const_array_globals[field.name] = true b.const_array_elem_count[const_name] = field.value.exprs.len @@ -1206,8 +1208,7 @@ fn (mut b Builder) register_consts_and_globals(file ast.File) { } else { // Dynamic array constant: serialize data, create array struct global data_name := '${const_name}__data' - b.mod.add_global_with_data(data_name, elem_type, true, - arr_data) + b.mod.add_global_with_data(data_name, elem_type, true, arr_data) b.const_array_globals[data_name] = true // Add array struct global (initialized in _vinit) arr_struct_type := b.get_array_type() @@ -2616,8 +2617,8 @@ fn (mut b Builder) build_assign(stmt ast.AssignStmt) { if ident := b.unwrap_ident(lhs) { if stmt.op == .decl_assign { elem_type := b.mod.values[elem_val].typ - alloca := b.mod.add_instr(.alloca, b.cur_block, b.mod.type_store.get_ptr(elem_type), - []ValueID{}) + alloca := b.mod.add_instr(.alloca, b.cur_block, + b.mod.type_store.get_ptr(elem_type), []ValueID{}) b.mod.add_instr(.store, b.cur_block, 0, [elem_val, alloca]) b.vars[ident.name] = alloca } else if ident.name == '_' { @@ -2777,12 +2778,15 @@ fn (mut b Builder) build_assign(stmt ast.AssignStmt) { } else { OpCode.sitofp } - actual_rhs = b.mod.add_instr(conv_op, b.cur_block, elem_typ, - [rhs_val]) + actual_rhs = b.mod.add_instr(conv_op, b.cur_block, elem_typ, [ + rhs_val, + ]) } } - result := b.mod.add_instr(op, b.cur_block, b.mod.values[loaded].typ, - [loaded, actual_rhs]) + result := b.mod.add_instr(op, b.cur_block, b.mod.values[loaded].typ, [ + loaded, + actual_rhs, + ]) b.mod.add_instr(.store, b.cur_block, 0, [result, ptr]) } } @@ -2842,12 +2846,15 @@ fn (mut b Builder) build_assign(stmt ast.AssignStmt) { } else { OpCode.sitofp } - actual_rhs = b.mod.add_instr(conv_op, b.cur_block, elem_typ, - [rhs_val]) + actual_rhs = b.mod.add_instr(conv_op, b.cur_block, elem_typ, [ + rhs_val, + ]) } } - result := b.mod.add_instr(op, b.cur_block, b.mod.values[loaded].typ, - [loaded, actual_rhs]) + result := b.mod.add_instr(op, b.cur_block, b.mod.values[loaded].typ, [ + loaded, + actual_rhs, + ]) b.mod.add_instr(.store, b.cur_block, 0, [result, base]) } } @@ -2965,12 +2972,15 @@ fn (mut b Builder) build_assign(stmt ast.AssignStmt) { } else { OpCode.sitofp } - actual_rhs = b.mod.add_instr(conv_op, b.cur_block, elem_typ, - [rhs_val]) + actual_rhs = b.mod.add_instr(conv_op, b.cur_block, elem_typ, [ + rhs_val, + ]) } } - result := b.mod.add_instr(op, b.cur_block, b.mod.values[loaded].typ, - [loaded, actual_rhs]) + result := b.mod.add_instr(op, b.cur_block, b.mod.values[loaded].typ, [ + loaded, + actual_rhs, + ]) b.mod.add_instr(.store, b.cur_block, 0, [result, base]) } } @@ -3065,7 +3075,8 @@ fn (mut b Builder) build_for(stmt ast.ForStmt) { b.cur_block = cond_block if has_cond { cond_val := b.build_expr(stmt.cond) - b.mod.add_instr(.br, b.cur_block, 0, [cond_val, b.mod.blocks[body_block].val_id, b.mod.blocks[exit_block].val_id]) + b.mod.add_instr(.br, b.cur_block, 0, + [cond_val, b.mod.blocks[body_block].val_id, b.mod.blocks[exit_block].val_id]) b.add_edge(cond_block, body_block) b.add_edge(cond_block, exit_block) } else { @@ -3122,7 +3133,8 @@ fn (mut b Builder) build_if_stmt(node ast.IfExpr) { // Condition cond_val := b.build_expr(node.cond) - b.mod.add_instr(.br, b.cur_block, 0, [cond_val, b.mod.blocks[then_block].val_id, b.mod.blocks[else_block].val_id]) + b.mod.add_instr(.br, b.cur_block, 0, + [cond_val, b.mod.blocks[then_block].val_id, b.mod.blocks[else_block].val_id]) b.add_edge(b.cur_block, then_block) b.add_edge(b.cur_block, else_block) @@ -3211,7 +3223,8 @@ fn (mut b Builder) build_assert(stmt ast.AssertStmt) { pass_block := b.mod.add_block(b.cur_func, 'assert_pass') fail_block := b.mod.add_block(b.cur_func, 'assert_fail') - b.mod.add_instr(.br, b.cur_block, 0, [cond, b.mod.blocks[pass_block].val_id, b.mod.blocks[fail_block].val_id]) + b.mod.add_instr(.br, b.cur_block, 0, + [cond, b.mod.blocks[pass_block].val_id, b.mod.blocks[fail_block].val_id]) b.add_edge(b.cur_block, pass_block) b.add_edge(b.cur_block, fail_block) @@ -3377,8 +3390,7 @@ fn (mut b Builder) build_basic_literal(lit ast.BasicLiteral) ValueID { if val.len >= 10 { parsed := val.i64() if parsed > 2147483647 || parsed < -2147483648 { - return b.mod.get_or_add_const(b.mod.type_store.get_int(64), - val) + return b.mod.get_or_add_const(b.mod.type_store.get_int(64), val) } } } @@ -3556,8 +3568,7 @@ fn (mut b Builder) build_string_inter_literal(expr ast.StringInterLiteral) Value i32_t := b.mod.type_store.get_int(32) snprintf_ref := b.get_or_create_fn_ref('snprintf', i32_t) size_val := b.mod.get_or_add_const(i32_t, '64') - fmt_val := b.mod.add_value_node(.c_string_literal, ptr_type, inter.resolved_fmt, - 0) + fmt_val := b.mod.add_value_node(.c_string_literal, ptr_type, inter.resolved_fmt, 0) sn_len := b.mod.add_instr(.call, b.cur_block, i32_t, [snprintf_ref, buf_ptr, size_val, fmt_val, formatted_val]) // 4. Call builtin__tos(buf_ptr, len) to make a V string @@ -3858,7 +3869,8 @@ fn (mut b Builder) build_infix(expr ast.InfixExpr) ValueID { rhs_block := b.mod.add_block(b.cur_func, 'or_rhs') merge_block := b.mod.add_block(b.cur_func, 'or_merge') // If LHS is true, short-circuit to merge; else evaluate RHS - b.mod.add_instr(.br, b.cur_block, 0, [lhs, b.mod.blocks[merge_block].val_id, b.mod.blocks[rhs_block].val_id]) + b.mod.add_instr(.br, b.cur_block, 0, + [lhs, b.mod.blocks[merge_block].val_id, b.mod.blocks[rhs_block].val_id]) b.add_edge(b.cur_block, merge_block) b.add_edge(b.cur_block, rhs_block) // RHS block @@ -3885,7 +3897,8 @@ fn (mut b Builder) build_infix(expr ast.InfixExpr) ValueID { rhs_block := b.mod.add_block(b.cur_func, 'and_rhs') merge_block := b.mod.add_block(b.cur_func, 'and_merge') // If LHS is false, short-circuit to merge with false; else evaluate RHS - b.mod.add_instr(.br, b.cur_block, 0, [lhs, b.mod.blocks[rhs_block].val_id, b.mod.blocks[merge_block].val_id]) + b.mod.add_instr(.br, b.cur_block, 0, + [lhs, b.mod.blocks[rhs_block].val_id, b.mod.blocks[merge_block].val_id]) b.add_edge(b.cur_block, rhs_block) b.add_edge(b.cur_block, merge_block) // RHS block @@ -3976,7 +3989,8 @@ fn (mut b Builder) build_infix(expr ast.InfixExpr) ValueID { fn_ref := b.get_or_create_fn_ref('builtin__string__<', bool_type) lt_lhs := if expr.op in [.gt, .le] { string_rhs } else { string_lhs } lt_rhs := if expr.op in [.gt, .le] { string_lhs } else { string_rhs } - lt_result := b.mod.add_instr(.call, b.cur_block, bool_type, [fn_ref, lt_lhs, lt_rhs]) + lt_result := b.mod.add_instr(.call, b.cur_block, bool_type, + [fn_ref, lt_lhs, lt_rhs]) if expr.op in [.le, .ge] { return b.mod.add_instr(.xor, b.cur_block, bool_type, [lt_result, b.mod.get_or_add_const(bool_type, '1')]) @@ -3985,7 +3999,8 @@ fn (mut b Builder) build_infix(expr ast.InfixExpr) ValueID { } if expr.op == .plus { fn_ref := b.get_or_create_fn_ref('builtin__string__+', str_type) - return b.mod.add_instr(.call, b.cur_block, str_type, [fn_ref, string_lhs, string_rhs]) + return b.mod.add_instr(.call, b.cur_block, str_type, + [fn_ref, string_lhs, string_rhs]) } } } @@ -4033,8 +4048,10 @@ fn (mut b Builder) build_infix(expr ast.InfixExpr) ValueID { ptr_type := b.mod.values[ptr_val].typ if expr.op == .minus { // ptr - int: negate the integer, then GEP - int_val = b.mod.add_instr(.sub, b.cur_block, b.mod.values[int_val].typ, - [b.mod.get_or_add_const(b.mod.values[int_val].typ, '0'), int_val]) + int_val = b.mod.add_instr(.sub, b.cur_block, b.mod.values[int_val].typ, [ + b.mod.get_or_add_const(b.mod.values[int_val].typ, '0'), + int_val, + ]) } return b.mod.add_instr(.get_element_ptr, b.cur_block, ptr_type, [ ptr_val, @@ -5357,11 +5374,13 @@ fn (mut b Builder) build_selector(expr ast.SelectorExpr) ValueID { // Try: EnumType__value (local) or module__EnumType__value (qualified) enum_key := '${expr.lhs.name}__${expr.rhs.name}' if enum_key in b.enum_values { - return b.mod.get_or_add_const(b.mod.type_store.get_int(32), b.enum_values[enum_key].str()) + return b.mod.get_or_add_const(b.mod.type_store.get_int(32), + b.enum_values[enum_key].str()) } qualified_key := '${b.cur_module}__${enum_key}' if qualified_key in b.enum_values { - return b.mod.get_or_add_const(b.mod.type_store.get_int(32), b.enum_values[qualified_key].str()) + return b.mod.get_or_add_const(b.mod.type_store.get_int(32), + b.enum_values[qualified_key].str()) } } @@ -5849,8 +5868,10 @@ fn (mut b Builder) build_index(expr ast.IndexExpr) ValueID { alloca_ptr := instr.operands[0] elem_type := base_typ.elem_type elem_ptr_type := b.mod.type_store.get_ptr(elem_type) - elem_addr := b.mod.add_instr(.get_element_ptr, b.cur_block, elem_ptr_type, - [alloca_ptr, index]) + elem_addr := b.mod.add_instr(.get_element_ptr, b.cur_block, elem_ptr_type, [ + alloca_ptr, + index, + ]) return b.mod.add_instr(.load, b.cur_block, elem_type, [elem_addr]) } if instr.op == .extractvalue && instr.operands.len >= 2 { @@ -5901,8 +5922,10 @@ fn (mut b Builder) build_index(expr ast.IndexExpr) ValueID { } // GEP to the element address, then load elem_ptr_type := b.mod.type_store.get_ptr(elem_type) - elem_addr := b.mod.add_instr(.get_element_ptr, b.cur_block, elem_ptr_type, - [base_val, index]) + elem_addr := b.mod.add_instr(.get_element_ptr, b.cur_block, elem_ptr_type, [ + base_val, + index, + ]) return b.mod.add_instr(.load, b.cur_block, elem_type, [elem_addr]) } } @@ -6047,7 +6070,8 @@ fn (mut b Builder) build_if_expr(node ast.IfExpr) ValueID { } cond := b.build_expr(node.cond) - b.mod.add_instr(.br, b.cur_block, 0, [cond, b.mod.blocks[then_block].val_id, b.mod.blocks[else_block].val_id]) + b.mod.add_instr(.br, b.cur_block, 0, + [cond, b.mod.blocks[then_block].val_id, b.mod.blocks[else_block].val_id]) b.add_edge(b.cur_block, then_block) b.add_edge(b.cur_block, else_block) @@ -6253,8 +6277,7 @@ fn (mut b Builder) build_array_init_expr(expr ast.ArrayInitExpr) ValueID { i32_t := b.mod.type_store.get_int(32) for i in 0 .. arr_len { idx := b.mod.get_or_add_const(i32_t, i.str()) - gep := b.mod.add_instr(.get_element_ptr, b.cur_block, elem_ptr_type, - [ + gep := b.mod.add_instr(.get_element_ptr, b.cur_block, elem_ptr_type, [ alloca, idx, ]) @@ -6449,14 +6472,12 @@ fn (mut b Builder) heap_copy_from_address(addr ValueID) ?ValueID { for fi, field_type in elem_info.fields { field_ptr_type := b.mod.type_store.get_ptr(field_type) idx_val := b.mod.get_or_add_const(int32_t, fi.str()) - src_fptr := b.mod.add_instr(.get_element_ptr, b.cur_block, field_ptr_type, - [ + src_fptr := b.mod.add_instr(.get_element_ptr, b.cur_block, field_ptr_type, [ addr, idx_val, ]) fval := b.mod.add_instr(.load, b.cur_block, field_type, [src_fptr]) - dst_fptr := b.mod.add_instr(.get_element_ptr, b.cur_block, field_ptr_type, - [ + dst_fptr := b.mod.add_instr(.get_element_ptr, b.cur_block, field_ptr_type, [ heap_ptr, idx_val, ]) @@ -6486,8 +6507,7 @@ fn (mut b Builder) heap_copy_value(val ValueID) ?ValueID { field_ptr_type := b.mod.type_store.get_ptr(field_type) idx_val := b.mod.get_or_add_const(int32_t, fi.str()) field_val := b.mod.add_instr(.extractvalue, b.cur_block, field_type, [val, idx_val]) - field_ptr := b.mod.add_instr(.get_element_ptr, b.cur_block, field_ptr_type, - [ + field_ptr := b.mod.add_instr(.get_element_ptr, b.cur_block, field_ptr_type, [ heap_ptr, idx_val, ]) @@ -7211,8 +7231,8 @@ fn (mut b Builder) build_addr(expr ast.Expr) ValueID { if result_type == 0 { result_type = b.expr_type(ast.Expr(expr)) } - return b.mod.add_instr(.get_element_ptr, b.cur_block, b.mod.type_store.get_ptr(result_type), - [base, idx_val]) + return b.mod.add_instr(.get_element_ptr, b.cur_block, + b.mod.type_store.get_ptr(result_type), [base, idx_val]) } ast.ParenExpr { return b.build_addr(expr.expr) @@ -7316,12 +7336,14 @@ fn (mut b Builder) build_addr(expr ast.Expr) ValueID { } } elem_ptr_type := b.mod.type_store.get_ptr(elem_type) - return b.mod.add_instr(.get_element_ptr, b.cur_block, elem_ptr_type, - [base2, index]) + return b.mod.add_instr(.get_element_ptr, b.cur_block, elem_ptr_type, [ + base2, + index, + ]) } } - return b.mod.add_instr(.get_element_ptr, b.cur_block, b.mod.type_store.get_ptr(result_type), - [base2, index]) + return b.mod.add_instr(.get_element_ptr, b.cur_block, + b.mod.type_store.get_ptr(result_type), [base2, index]) } else { return 0 @@ -7487,7 +7509,8 @@ fn (mut b Builder) generate_array_eq_stub() { check_elem_block := b.mod.add_block(func_idx, 'check_elem') ret_false_block := b.mod.add_block(func_idx, 'ret_false') ret_true_block := b.mod.add_block(func_idx, 'ret_true') - b.mod.add_instr(.br, entry, 0, [len_eq, b.mod.blocks[check_elem_block].val_id, b.mod.blocks[ret_false_block].val_id]) + b.mod.add_instr(.br, entry, 0, + [len_eq, b.mod.blocks[check_elem_block].val_id, b.mod.blocks[ret_false_block].val_id]) // ret_false: return 0 zero_i1 := b.mod.get_or_add_const(i1_t, '0') @@ -7551,7 +7574,8 @@ fn (mut b Builder) generate_array_eq_stub() { map_loop_header := b.mod.add_block(func_idx, 'map_loop_header') memcmp_block := b.mod.add_block(func_idx, 'memcmp') - b.mod.add_instr(.br, check_map_block, 0, [is_map, b.mod.blocks[map_loop_header].val_id, b.mod.blocks[memcmp_block].val_id]) + b.mod.add_instr(.br, check_map_block, 0, + [is_map, b.mod.blocks[map_loop_header].val_id, b.mod.blocks[memcmp_block].val_id]) // --- String element comparison loop --- // Loop header: i stored in alloca, check if i < len @@ -7561,7 +7585,8 @@ fn (mut b Builder) generate_array_eq_stub() { b.mod.add_instr(.store, str_loop_header, 0, [zero_i32, alloca_i]) str_loop_cond := b.mod.add_block(func_idx, 'str_loop_cond') - b.mod.add_instr(.br, str_loop_header, 0, [one_i1, b.mod.blocks[str_loop_cond].val_id, b.mod.blocks[str_loop_cond].val_id]) + b.mod.add_instr(.br, str_loop_header, 0, + [one_i1, b.mod.blocks[str_loop_cond].val_id, b.mod.blocks[str_loop_cond].val_id]) // Loop condition: load i, compare with len cur_i := b.mod.add_instr(.load, str_loop_cond, i32_t, [alloca_i]) @@ -7569,7 +7594,8 @@ fn (mut b Builder) generate_array_eq_stub() { i_lt_len := b.mod.add_instr(.lt, str_loop_cond, i1_t, [cur_i, cur_len]) str_loop_body := b.mod.add_block(func_idx, 'str_loop_body') - b.mod.add_instr(.br, str_loop_cond, 0, [i_lt_len, b.mod.blocks[str_loop_body].val_id, b.mod.blocks[ret_true_block].val_id]) + b.mod.add_instr(.br, str_loop_cond, 0, + [i_lt_len, b.mod.blocks[str_loop_body].val_id, b.mod.blocks[ret_true_block].val_id]) // Loop body: compare strings at index i cur_data_a := b.mod.add_instr(.load, str_loop_body, ptr_t, [alloca_data_a]) @@ -7596,13 +7622,15 @@ fn (mut b Builder) generate_array_eq_stub() { // If not equal, return false str_loop_inc := b.mod.add_block(func_idx, 'str_loop_inc') - b.mod.add_instr(.br, str_loop_body, 0, [str_eq, b.mod.blocks[str_loop_inc].val_id, b.mod.blocks[ret_false_block].val_id]) + b.mod.add_instr(.br, str_loop_body, 0, + [str_eq, b.mod.blocks[str_loop_inc].val_id, b.mod.blocks[ret_false_block].val_id]) // Loop increment: i++ one_i32 := b.mod.get_or_add_const(i32_t, '1') next_i := b.mod.add_instr(.add, str_loop_inc, i32_t, [cur_i2, one_i32]) b.mod.add_instr(.store, str_loop_inc, 0, [next_i, alloca_i]) - b.mod.add_instr(.br, str_loop_inc, 0, [one_i1, b.mod.blocks[str_loop_cond].val_id, b.mod.blocks[str_loop_cond].val_id]) + b.mod.add_instr(.br, str_loop_inc, 0, + [one_i1, b.mod.blocks[str_loop_cond].val_id, b.mod.blocks[str_loop_cond].val_id]) // --- Nested array element comparison loop (recursive array__eq) --- alloca_ai := b.mod.add_instr(.alloca, arr_loop_header, b.mod.type_store.get_ptr(i32_t), @@ -7610,7 +7638,8 @@ fn (mut b Builder) generate_array_eq_stub() { b.mod.add_instr(.store, arr_loop_header, 0, [zero_i32, alloca_ai]) arr_loop_cond := b.mod.add_block(func_idx, 'arr_loop_cond') - b.mod.add_instr(.br, arr_loop_header, 0, [one_i1, b.mod.blocks[arr_loop_cond].val_id, b.mod.blocks[arr_loop_cond].val_id]) + b.mod.add_instr(.br, arr_loop_header, 0, + [one_i1, b.mod.blocks[arr_loop_cond].val_id, b.mod.blocks[arr_loop_cond].val_id]) // Loop condition: load i, compare with len acur_i := b.mod.add_instr(.load, arr_loop_cond, i32_t, [alloca_ai]) @@ -7618,7 +7647,8 @@ fn (mut b Builder) generate_array_eq_stub() { ai_lt_len := b.mod.add_instr(.lt, arr_loop_cond, i1_t, [acur_i, acur_len]) arr_loop_body := b.mod.add_block(func_idx, 'arr_loop_body') - b.mod.add_instr(.br, arr_loop_cond, 0, [ai_lt_len, b.mod.blocks[arr_loop_body].val_id, b.mod.blocks[ret_true_block].val_id]) + b.mod.add_instr(.br, arr_loop_cond, 0, + [ai_lt_len, b.mod.blocks[arr_loop_body].val_id, b.mod.blocks[ret_true_block].val_id]) // Loop body: compare array elements at index i acur_data_a := b.mod.add_instr(.load, arr_loop_body, ptr_t, [alloca_data_a]) @@ -7645,12 +7675,14 @@ fn (mut b Builder) generate_array_eq_stub() { // If not equal, return false arr_loop_inc := b.mod.add_block(func_idx, 'arr_loop_inc') - b.mod.add_instr(.br, arr_loop_body, 0, [arr_eq, b.mod.blocks[arr_loop_inc].val_id, b.mod.blocks[ret_false_block].val_id]) + b.mod.add_instr(.br, arr_loop_body, 0, + [arr_eq, b.mod.blocks[arr_loop_inc].val_id, b.mod.blocks[ret_false_block].val_id]) // Loop increment: i++ anext_i := b.mod.add_instr(.add, arr_loop_inc, i32_t, [acur_i2, one_i32]) b.mod.add_instr(.store, arr_loop_inc, 0, [anext_i, alloca_ai]) - b.mod.add_instr(.br, arr_loop_inc, 0, [one_i1, b.mod.blocks[arr_loop_cond].val_id, b.mod.blocks[arr_loop_cond].val_id]) + b.mod.add_instr(.br, arr_loop_inc, 0, + [one_i1, b.mod.blocks[arr_loop_cond].val_id, b.mod.blocks[arr_loop_cond].val_id]) // --- Map element comparison loop (call map_map_eq for each element) --- alloca_mi := b.mod.add_instr(.alloca, map_loop_header, b.mod.type_store.get_ptr(i32_t), @@ -7658,7 +7690,8 @@ fn (mut b Builder) generate_array_eq_stub() { b.mod.add_instr(.store, map_loop_header, 0, [zero_i32, alloca_mi]) map_loop_cond := b.mod.add_block(func_idx, 'map_loop_cond') - b.mod.add_instr(.br, map_loop_header, 0, [one_i1, b.mod.blocks[map_loop_cond].val_id, b.mod.blocks[map_loop_cond].val_id]) + b.mod.add_instr(.br, map_loop_header, 0, + [one_i1, b.mod.blocks[map_loop_cond].val_id, b.mod.blocks[map_loop_cond].val_id]) // Loop condition: load i, compare with len mcur_i := b.mod.add_instr(.load, map_loop_cond, i32_t, [alloca_mi]) @@ -7666,7 +7699,8 @@ fn (mut b Builder) generate_array_eq_stub() { mi_lt_len := b.mod.add_instr(.lt, map_loop_cond, i1_t, [mcur_i, mcur_len]) map_loop_body := b.mod.add_block(func_idx, 'map_loop_body') - b.mod.add_instr(.br, map_loop_cond, 0, [mi_lt_len, b.mod.blocks[map_loop_body].val_id, b.mod.blocks[ret_true_block].val_id]) + b.mod.add_instr(.br, map_loop_cond, 0, + [mi_lt_len, b.mod.blocks[map_loop_body].val_id, b.mod.blocks[ret_true_block].val_id]) // Loop body: compare map elements at index i mcur_data_a := b.mod.add_instr(.load, map_loop_body, ptr_t, [alloca_data_a]) @@ -7694,12 +7728,14 @@ fn (mut b Builder) generate_array_eq_stub() { // If not equal, return false map_loop_inc := b.mod.add_block(func_idx, 'map_loop_inc') - b.mod.add_instr(.br, map_loop_body, 0, [map_eq, b.mod.blocks[map_loop_inc].val_id, b.mod.blocks[ret_false_block].val_id]) + b.mod.add_instr(.br, map_loop_body, 0, + [map_eq, b.mod.blocks[map_loop_inc].val_id, b.mod.blocks[ret_false_block].val_id]) // Loop increment: i++ mnext_i := b.mod.add_instr(.add, map_loop_inc, i32_t, [mcur_i2, one_i32]) b.mod.add_instr(.store, map_loop_inc, 0, [mnext_i, alloca_mi]) - b.mod.add_instr(.br, map_loop_inc, 0, [one_i1, b.mod.blocks[map_loop_cond].val_id, b.mod.blocks[map_loop_cond].val_id]) + b.mod.add_instr(.br, map_loop_inc, 0, + [one_i1, b.mod.blocks[map_loop_cond].val_id, b.mod.blocks[map_loop_cond].val_id]) // --- memcmp fallback block --- ld_a := b.mod.add_instr(.load, memcmp_block, ptr_t, [alloca_data_a]) @@ -7922,7 +7958,8 @@ fn (mut b Builder) generate_wyhash_body(func_idx int) { blk_long := b.mod.add_block(func_idx, 'long') blk_final := b.mod.add_block(func_idx, 'final') - b.mod.add_instr(.br, entry, 0, [len_le_16, b.mod.blocks[blk_short].val_id, b.mod.blocks[blk_long].val_id]) + b.mod.add_instr(.br, entry, 0, + [len_le_16, b.mod.blocks[blk_short].val_id, b.mod.blocks[blk_long].val_id]) // === SHORT PATH (len <= 16) === // Branch: len >= 4? @@ -7931,7 +7968,8 @@ fn (mut b Builder) generate_wyhash_body(func_idx int) { blk_short_4_16 := b.mod.add_block(func_idx, 'short_4_16') blk_short_0_3 := b.mod.add_block(func_idx, 'short_0_3') - b.mod.add_instr(.br, blk_short, 0, [len_ge_4, b.mod.blocks[blk_short_4_16].val_id, b.mod.blocks[blk_short_0_3].val_id]) + b.mod.add_instr(.br, blk_short, 0, + [len_ge_4, b.mod.blocks[blk_short_4_16].val_id, b.mod.blocks[blk_short_0_3].val_id]) // --- SHORT 4-16 block --- // a = (_wyr4(p) << 32) | _wyr4(p + ((len>>3)<<2)) @@ -7984,7 +8022,8 @@ fn (mut b Builder) generate_wyhash_body(func_idx int) { // Branch: len > 0? len_gt_0 := b.mod.add_instr(.gt, blk_short_0_3, i1_t, [param_len, zero_64]) blk_wyr3 := b.mod.add_block(func_idx, 'wyr3') - b.mod.add_instr(.br, blk_short_0_3, 0, [len_gt_0, b.mod.blocks[blk_wyr3].val_id, b.mod.blocks[blk_final].val_id]) // len==0: a=0, b=0 already stored + b.mod.add_instr(.br, blk_short_0_3, 0, + [len_gt_0, b.mod.blocks[blk_wyr3].val_id, b.mod.blocks[blk_final].val_id]) // len==0: a=0, b=0 already stored // --- WYR3 block (len 1-3) --- // a = _wyr3(p, len) = (p[0] << 16) | (p[len>>1] << 8) | p[len-1] diff --git a/vlib/v2/ssa/optimize/mem2reg.v b/vlib/v2/ssa/optimize/mem2reg.v index b987037e34..286f87cc90 100644 --- a/vlib/v2/ssa/optimize/mem2reg.v +++ b/vlib/v2/ssa/optimize/mem2reg.v @@ -188,8 +188,8 @@ fn promote_memory_to_register(mut m ssa.Module, dom DomInfo, cfg &CfgData) { if func2.blocks.len > 0 { entry := func2.blocks[0] total_blocks_in_funcs += func2.blocks.len - bv, bs := rename_recursive(mut m, entry, mut ctx, promotable, mut stack_counts, - &dom, cfg) + bv, bs := + rename_recursive(mut m, entry, mut ctx, promotable, mut stack_counts, &dom, cfg) total_blocks_visited += bv total_blocks_skipped += bs } @@ -612,6 +612,5 @@ fn rename_iterative(mut m ssa.Module, root_blk int, mut ctx Mem2RegCtx, promotab } fn rename_recursive(mut m ssa.Module, blk_id int, mut ctx Mem2RegCtx, promotable []int, mut stack_counts []int, dom &DomInfo, cfg &CfgData) (int, int) { - return rename_iterative(mut m, blk_id, mut ctx, promotable, mut stack_counts, dom, - cfg) + return rename_iterative(mut m, blk_id, mut ctx, promotable, mut stack_counts, dom, cfg) } diff --git a/vlib/v2/ssa/optimize/phi.v b/vlib/v2/ssa/optimize/phi.v index 28db6bac7f..685c41a2e8 100644 --- a/vlib/v2/ssa/optimize/phi.v +++ b/vlib/v2/ssa/optimize/phi.v @@ -342,8 +342,8 @@ fn eliminate_phi_nodes(mut m ssa.Module) { // For each predecessor that has copies, resolve with Briggs algorithm for pki in 0 .. pred_copy_blocks.len { pred_blk := pred_copy_blocks[pki] - resolve_parallel_copies_flat(mut m, pred_blk, pred_copy_dests[pred_blk], pred_copy_srcs[pred_blk], mut - src_ref_count, mut touched_ids) + resolve_parallel_copies_flat(mut m, pred_blk, pred_copy_dests[pred_blk], + pred_copy_srcs[pred_blk], mut src_ref_count, mut touched_ids) } // Cleanup: clear pred_copies for blocks we touched diff --git a/vlib/v2/transformer/expr.v b/vlib/v2/transformer/expr.v index 28fef41371..953bc95e7d 100644 --- a/vlib/v2/transformer/expr.v +++ b/vlib/v2/transformer/expr.v @@ -890,8 +890,8 @@ fn (mut t Transformer) transform_match_expr(expr ast.MatchExpr) ast.Expr { // When a branch has multiple sum variants, each condition needs its own // smartcast context. Splitting preserves correct dispatch in branch bodies. for i, c_tag in cond_tags { - t.push_smartcast_full(smartcast_expr, cond_variants[i], cond_variants_full[i], - sumtype_name) + t.push_smartcast_full(smartcast_expr, cond_variants[i], + cond_variants_full[i], sumtype_name) mut transformed_stmts := t.transform_stmts(branch.stmts) if t.sumtype_return_wrap != '' && transformed_stmts.len > 0 { last_idx := transformed_stmts.len - 1 @@ -948,7 +948,9 @@ fn (mut t Transformer) transform_match_expr(expr ast.MatchExpr) ast.Expr { last_idx := else_stmts.len - 1 if else_stmts[last_idx] is ast.ExprStmt { last_expr := (else_stmts[last_idx] as ast.ExprStmt).expr - if wrapped := t.wrap_sumtype_value_transformed(last_expr, t.sumtype_return_wrap) { + if wrapped := t.wrap_sumtype_value_transformed(last_expr, + t.sumtype_return_wrap) + { else_stmts[last_idx] = ast.Stmt(ast.ExprStmt{ expr: wrapped }) @@ -1215,7 +1217,8 @@ fn (mut t Transformer) transform_if_expr(expr ast.IfExpr) ast.Expr { } if inner_vname != '' { // Get sum type from ORIGINAL expression (before smartcast) - mut inner_stype := t.get_sumtype_name_for_expr(orig_inner.lhs) + mut inner_stype := + t.get_sumtype_name_for_expr(orig_inner.lhs) if inner_stype == '' { inner_stype = t.find_sumtype_for_variant(inner_vname) } @@ -1235,7 +1238,8 @@ fn (mut t Transformer) transform_if_expr(expr ast.IfExpr) ast.Expr { } if inner_tag >= 0 { // Transform inner LHS with outer smartcast - transformed_inner_lhs := t.transform_expr(orig_inner.lhs) + transformed_inner_lhs := + t.transform_expr(orig_inner.lhs) inner_tag_check = ast.Expr(ast.InfixExpr{ op: token.Token.eq lhs: t.synth_selector(transformed_inner_lhs, @@ -1288,7 +1292,8 @@ fn (mut t Transformer) transform_if_expr(expr ast.IfExpr) ast.Expr { // Build tag check tag_check := ast.InfixExpr{ op: token.Token.eq - lhs: t.synth_selector(transformed_lhs, '_tag', types.Type(types.int_)) + lhs: t.synth_selector(transformed_lhs, '_tag', + types.Type(types.int_)) rhs: ast.BasicLiteral{ kind: token.Token.number value: '${tag_value}' @@ -1488,8 +1493,8 @@ fn (mut t Transformer) transform_if_expr(expr ast.IfExpr) ast.Expr { } // Push smart cast context for transforming body (supports nested smartcasts) - t.push_smartcast_full(smartcast_expr, qualified_variant, qualified_variant_full, - sumtype_name) + t.push_smartcast_full(smartcast_expr, qualified_variant, + qualified_variant_full, sumtype_name) // Transform body with smart cast context transformed_stmts := t.transform_stmts(expr.stmts) @@ -1723,7 +1728,8 @@ fn (mut t Transformer) transform_if_expr(expr ast.IfExpr) ast.Expr { cond_expr = ast.Expr(ast.InfixExpr{ op: .lt lhs: t.transform_expr(rhs.expr) // the index expression - rhs: t.synth_selector(t.transform_expr(rhs.lhs), 'len', types.Type(types.int_)) + rhs: t.synth_selector(t.transform_expr(rhs.lhs), 'len', + types.Type(types.int_)) pos: rhs.pos }) } @@ -1848,8 +1854,7 @@ fn (mut t Transformer) transform_infix_expr(expr ast.InfixExpr) ast.Expr { if term is ast.InfixExpr { if ctx := t.smartcast_context_from_is_check(term) { transformed_terms << t.transform_expr(term) - t.push_smartcast_full(ctx.expr, ctx.variant, ctx.variant_full, - ctx.sumtype) + t.push_smartcast_full(ctx.expr, ctx.variant, ctx.variant_full, ctx.sumtype) pushed++ changed = true continue @@ -1911,8 +1916,8 @@ fn (mut t Transformer) transform_infix_expr(expr ast.InfixExpr) ast.Expr { } else { token.Token.ne } - return t.make_infix_expr_at(cmp_op, t.synth_selector(transformed_lhs, - '_tag', types.Type(types.int_)), ast.Expr(ast.BasicLiteral{ + return t.make_infix_expr_at(cmp_op, t.synth_selector(transformed_lhs, '_tag', + types.Type(types.int_)), ast.Expr(ast.BasicLiteral{ kind: token.Token.number value: '${tag_value}' pos: expr.pos @@ -2244,8 +2249,7 @@ fn (mut t Transformer) transform_infix_expr(expr ast.InfixExpr) ast.Expr { // and return the original expression (cleanc will handle tag checks) if is_sumtype_variant_check { // Return unchanged - cleanc will generate the tag check - return t.make_infix_expr_at(expr.op, t.transform_expr(expr.lhs), expr.rhs, - expr.pos) + return t.make_infix_expr_at(expr.op, t.transform_expr(expr.lhs), expr.rhs, expr.pos) } if !has_unresolved_shorthand { mut method_info := arr_info @@ -2262,8 +2266,7 @@ fn (mut t Transformer) transform_infix_expr(expr ast.InfixExpr) ast.Expr { contains_fn_name := t.register_needed_array_method(method_info, 'contains') // Transform array with enum context if needed transformed_rhs := if enum_type != '' && expr.rhs is ast.ArrayInitExpr { - t.transform_array_with_enum_context(expr.rhs as ast.ArrayInitExpr, - enum_type) + t.transform_array_with_enum_context(expr.rhs as ast.ArrayInitExpr, enum_type) } else { t.transform_expr(expr.rhs) } @@ -2285,8 +2288,7 @@ fn (mut t Transformer) transform_infix_expr(expr ast.InfixExpr) ast.Expr { return contains_call } else { // Unresolved shorthand - return as-is for cleanc to handle expansion - return t.make_infix_expr_at(expr.op, t.transform_expr(expr.lhs), expr.rhs, - expr.pos) + return t.make_infix_expr_at(expr.op, t.transform_expr(expr.lhs), expr.rhs, expr.pos) } } } @@ -2396,7 +2398,8 @@ fn (mut t Transformer) transform_infix_expr(expr ast.InfixExpr) ast.Expr { } args: [ arr_ptr_expr, - t.synth_selector(ast.Expr(tmp_ident), 'data', types.Type(types.voidptr_)), + t.synth_selector(ast.Expr(tmp_ident), 'data', + types.Type(types.voidptr_)), t.synth_selector(ast.Expr(tmp_ident), 'len', types.Type(types.int_)), ] pos: expr.pos @@ -2474,8 +2477,8 @@ fn (mut t Transformer) transform_infix_expr(expr ast.InfixExpr) ast.Expr { enum_type := t.get_enum_type_name(expr.lhs) if enum_type != '' { resolved_rhs := t.resolve_enum_shorthand(expr.rhs, enum_type) - return t.make_infix_expr_at(expr.op, t.transform_expr(expr.lhs), t.transform_expr(resolved_rhs), - expr.pos) + return t.make_infix_expr_at(expr.op, t.transform_expr(expr.lhs), + t.transform_expr(resolved_rhs), expr.pos) } } } @@ -2918,9 +2921,7 @@ fn (mut t Transformer) transform_embed_file_comptime_chain(expr ast.Expr, compti ast.CallExpr { mut transformed_lhs := ast.empty_expr if expr.lhs is ast.SelectorExpr { - if transformed_base := t.transform_embed_file_chain_lhs(expr.lhs.lhs, - comptime_pos) - { + if transformed_base := t.transform_embed_file_chain_lhs(expr.lhs.lhs, comptime_pos) { transformed_lhs = ast.Expr(ast.SelectorExpr{ lhs: transformed_base rhs: expr.lhs.rhs diff --git a/vlib/v2/transformer/fn.v b/vlib/v2/transformer/fn.v index 4056798a91..bdac2e3239 100644 --- a/vlib/v2/transformer/fn.v +++ b/vlib/v2/transformer/fn.v @@ -1082,9 +1082,7 @@ fn (mut t Transformer) transform_call_expr(expr ast.CallExpr) ast.Expr { } } else if expr.args.len == 1 && t.is_sort_compare_lambda_expr(expr.args[0]) { // .sort(a < b) with lambda comparator - if result := t.transform_sort_call(sel.lhs, sel.rhs.name, [expr.args[0]], - expr.pos) - { + if result := t.transform_sort_call(sel.lhs, sel.rhs.name, [expr.args[0]], expr.pos) { return result } } @@ -1423,8 +1421,7 @@ fn (mut t Transformer) transform_call_expr(expr ast.CallExpr) ast.Expr { fn_info := t.lookup_call_fn_info(expr.lhs) mut transformed_call_args := []ast.Expr{cap: call_args.len} for i, arg in call_args { - transformed_call_args << t.transform_call_arg_with_sumtype_check(arg, - fn_info, i) + transformed_call_args << t.transform_call_arg_with_sumtype_check(arg, fn_info, i) } transformed_call_args = t.lower_variadic_args(expr.lhs, transformed_call_args) mut args := []ast.Expr{cap: transformed_call_args.len + 1} @@ -1464,8 +1461,7 @@ fn (mut t Transformer) transform_call_expr(expr ast.CallExpr) ast.Expr { mut args2 := []ast.Expr{cap: call_args2.len + 1} args2 << t.transform_expr(sel.lhs) for i, arg in call_args2 { - args2 << t.transform_call_arg_with_sumtype_check(arg, fn_info2, - i) + args2 << t.transform_call_arg_with_sumtype_check(arg, fn_info2, i) } return ast.CallExpr{ lhs: ast.Ident{ @@ -1482,8 +1478,7 @@ fn (mut t Transformer) transform_call_expr(expr ast.CallExpr) ast.Expr { mut args2 := []ast.Expr{cap: call_args2.len + 1} args2 << t.transform_expr(sel.lhs) for i, arg in call_args2 { - args2 << t.transform_call_arg_with_sumtype_check(arg, fn_info2, - i) + args2 << t.transform_call_arg_with_sumtype_check(arg, fn_info2, i) } return ast.CallExpr{ lhs: ast.Ident{ @@ -1500,8 +1495,7 @@ fn (mut t Transformer) transform_call_expr(expr ast.CallExpr) ast.Expr { mut args2 := []ast.Expr{cap: call_args2.len + 1} args2 << t.transform_expr(sel.lhs) for i, arg in call_args2 { - args2 << t.transform_call_arg_with_sumtype_check(arg, fn_info2, - i) + args2 << t.transform_call_arg_with_sumtype_check(arg, fn_info2, i) } return ast.CallExpr{ lhs: ast.Ident{ diff --git a/vlib/v2/transformer/for.v b/vlib/v2/transformer/for.v index 54b00bfe4f..ed1afaeee5 100644 --- a/vlib/v2/transformer/for.v +++ b/vlib/v2/transformer/for.v @@ -207,7 +207,8 @@ fn (mut t Transformer) try_expand_for_in_map(stmt ast.ForStmt) ?[]ast.Stmt { })) // key_values.len selector: map_ref.key_values.len - key_values_len_expr := t.synth_selector(ast.Expr(key_values_expr), 'len', types.Type(types.int_)) + key_values_len_expr := t.synth_selector(ast.Expr(key_values_expr), 'len', + types.Type(types.int_)) // 1. mut _map_len := map_ref.key_values.len stmts << ast.AssignStmt{ @@ -746,8 +747,8 @@ fn (mut t Transformer) transform_array_for_in(stmt ast.ForStmt, for_in ast.ForIn t.register_synth_type(idx_pos, key_type) iter_pos := t.next_synth_pos() - transformed_expr := t.iter_value_expr(for_in.expr, t.transform_expr(for_in.expr), - iter_pos, iter_type) + transformed_expr := t.iter_value_expr(for_in.expr, t.transform_expr(for_in.expr), iter_pos, + iter_type) index_pos := t.next_synth_pos() t.register_synth_type(index_pos, value_type) @@ -919,8 +920,8 @@ fn (mut t Transformer) transform_fixed_array_for_in(stmt ast.ForStmt, for_in ast // Transform the iterable expression iter_pos := t.next_synth_pos() - transformed_expr := t.iter_value_expr(for_in.expr, t.transform_expr(for_in.expr), - iter_pos, types.Type(arr_type)) + transformed_expr := t.iter_value_expr(for_in.expr, t.transform_expr(for_in.expr), iter_pos, + types.Type(arr_type)) index_pos := t.next_synth_pos() t.register_synth_type(index_pos, value_type) diff --git a/vlib/v2/transformer/if.v b/vlib/v2/transformer/if.v index df5833d877..26dc89a350 100644 --- a/vlib/v2/transformer/if.v +++ b/vlib/v2/transformer/if.v @@ -732,8 +732,9 @@ fn (mut t Transformer) try_expand_tuple_if_assign_stmts(stmt ast.AssignStmt) ?[] } } else { // else-if chain - else_if_stmts := t.build_tuple_branch_assigns(else_if.stmts, tuple_lhs, n, - stmt.pos) or { return none } + else_if_stmts := t.build_tuple_branch_assigns(else_if.stmts, tuple_lhs, n, stmt.pos) or { + return none + } else_expr = ast.IfExpr{ cond: else_if.cond stmts: else_if_stmts diff --git a/vlib/v2/transformer/struct.v b/vlib/v2/transformer/struct.v index d98eb9bcbd..b4775f191f 100644 --- a/vlib/v2/transformer/struct.v +++ b/vlib/v2/transformer/struct.v @@ -996,7 +996,8 @@ fn (mut t Transformer) transform_init_expr(expr ast.InitExpr) ast.Expr { } mt := expr.typ as ast.MapType key_type_name := t.expr_to_type_name(mt.key_type) - hash_fn, eq_fn, clone_fn, free_fn := map_runtime_key_fns_from_type_name(key_type_name) + hash_fn, eq_fn, clone_fn, free_fn := + map_runtime_key_fns_from_type_name(key_type_name) return ast.Expr(ast.CallExpr{ lhs: ast.Ident{ name: 'new_map' @@ -1156,8 +1157,7 @@ fn (mut t Transformer) transform_init_expr(expr ast.InitExpr) ast.Expr { t.transform_expr(field_value) } else { // Transform array elements with sumtype wrapping if needed. - elem_sumtype := t.get_field_array_elem_sumtype_name(struct_type_name, - field.name) + elem_sumtype := t.get_field_array_elem_sumtype_name(struct_type_name, field.name) elem_interface_typ := t.get_field_array_elem_interface_type(struct_type_name, field.name) mut new_exprs := []ast.Expr{cap: arr_value.exprs.len} diff --git a/vlib/v2/transformer/transformer.v b/vlib/v2/transformer/transformer.v index 6edd0a0996..7db58cf4e2 100644 --- a/vlib/v2/transformer/transformer.v +++ b/vlib/v2/transformer/transformer.v @@ -1284,8 +1284,7 @@ fn (mut t Transformer) collect_runtime_const_inits(files []ast.File) { if !t.needs_runtime_const_init(field.value, is_native) { continue } - t.record_runtime_const_init(file.mod, field.name, field.value, mut - known) + t.record_runtime_const_init(file.mod, field.name, field.value, mut known) } } } @@ -1305,8 +1304,7 @@ fn (mut t Transformer) collect_runtime_const_inits(files []ast.File) { if !t.expr_depends_on_runtime_const(field.value, file.mod, known) { continue } - t.record_runtime_const_init(file.mod, field.name, field.value, mut - known) + t.record_runtime_const_init(file.mod, field.name, field.value, mut known) changed = true } } @@ -2308,7 +2306,9 @@ fn find_target_or_expr_path_in_expr(expr ast.Expr, target_id int, prefix string) return path } for i, inner in expr.exprs { - if path := find_target_or_expr_path_in_expr(inner, target_id, '${prefix}/expr[${i}]') { + if path := find_target_or_expr_path_in_expr(inner, target_id, + '${prefix}/expr[${i}]') + { return path } } @@ -2334,7 +2334,9 @@ fn find_target_or_expr_path_in_expr(expr ast.Expr, target_id int, prefix string) return path } for i, field in expr.fields { - if path := find_target_or_expr_path_in_expr(field.value, target_id, '${prefix}/field[${i}]') { + if path := find_target_or_expr_path_in_expr(field.value, target_id, + '${prefix}/field[${i}]') + { return path } } @@ -2415,14 +2417,18 @@ fn find_target_or_expr_path_in_expr(expr ast.Expr, target_id int, prefix string) return path } for i, field in expr.fields { - if path := find_target_or_expr_path_in_expr(field.value, target_id, '${prefix}/field[${i}]') { + if path := find_target_or_expr_path_in_expr(field.value, target_id, + '${prefix}/field[${i}]') + { return path } } } ast.KeywordOperator { for i, inner in expr.exprs { - if path := find_target_or_expr_path_in_expr(inner, target_id, '${prefix}/expr[${i}]') { + if path := find_target_or_expr_path_in_expr(inner, target_id, + '${prefix}/expr[${i}]') + { return path } } @@ -2432,12 +2438,16 @@ fn find_target_or_expr_path_in_expr(expr ast.Expr, target_id int, prefix string) } ast.LockExpr { for i, inner in expr.lock_exprs { - if path := find_target_or_expr_path_in_expr(inner, target_id, '${prefix}/lock[${i}]') { + if path := find_target_or_expr_path_in_expr(inner, target_id, + '${prefix}/lock[${i}]') + { return path } } for i, inner in expr.rlock_exprs { - if path := find_target_or_expr_path_in_expr(inner, target_id, '${prefix}/rlock[${i}]') { + if path := find_target_or_expr_path_in_expr(inner, target_id, + '${prefix}/rlock[${i}]') + { return path } } @@ -2499,14 +2509,18 @@ fn find_target_or_expr_path_in_expr(expr ast.Expr, target_id int, prefix string) } ast.StringInterLiteral { for i, inter in expr.inters { - if path := find_target_or_expr_path_in_expr(inter.expr, target_id, '${prefix}/expr[${i}]') { + if path := find_target_or_expr_path_in_expr(inter.expr, target_id, + '${prefix}/expr[${i}]') + { return path } } } ast.Tuple { for i, inner in expr.exprs { - if path := find_target_or_expr_path_in_expr(inner, target_id, '${prefix}/expr[${i}]') { + if path := find_target_or_expr_path_in_expr(inner, target_id, + '${prefix}/expr[${i}]') + { return path } } @@ -3430,8 +3444,7 @@ fn (mut t Transformer) expand_direct_or_expr_assign(stmt ast.AssignStmt, or_expr // checker records them as `string` instead of `!string`. idx_expr := call_expr as ast.IndexExpr mut stmts := []ast.Stmt{} - result_expr := t.expand_string_range_or_native_expr(idx_expr, or_expr.stmts, mut - stmts) + result_expr := t.expand_string_range_or_native_expr(idx_expr, or_expr.stmts, mut stmts) stmts << ast.AssignStmt{ op: stmt.op lhs: stmt.lhs @@ -6181,7 +6194,9 @@ fn (mut t Transformer) transform_return_stmt(stmt ast.ReturnStmt) ast.ReturnStmt } // If wrapping failed but we have a smartcast context, use the variant from it if smartcast_variant != '' { - if wrapped := t.build_sumtype_init(transformed, smartcast_variant, t.cur_fn_ret_type_name) { + if wrapped := t.build_sumtype_init(transformed, smartcast_variant, + t.cur_fn_ret_type_name) + { exprs << wrapped continue } @@ -8871,8 +8886,9 @@ fn (mut t Transformer) generate_struct_clone_fn(fn_name string, struct_name stri value: t.clone_value_expr(field_selector, field.typ) } } - t.register_generated_fn_scope(fn_name, clone_generated_fn_scope_module(struct_name), - [param_s]) + t.register_generated_fn_scope(fn_name, clone_generated_fn_scope_module(struct_name), [ + param_s, + ]) return ast.Stmt(ast.FnDecl{ name: fn_name typ: ast.FnType{ @@ -9123,8 +9139,7 @@ fn (mut t Transformer) generate_array_method_functions() []ast.Stmt { mut index_names := t.needed_array_index_fns.keys() index_names.sort() for fn_name in index_names { - result << t.generate_array_method_fn(fn_name, t.needed_array_index_fns[fn_name], - .index) + result << t.generate_array_method_fn(fn_name, t.needed_array_index_fns[fn_name], .index) } mut last_index_names := t.needed_array_last_index_fns.keys() last_index_names.sort() @@ -9919,7 +9934,8 @@ fn (mut t Transformer) generate_map_str_fn(fn_name string, elem_type string) ast name: 'DenseArray' })) // key_values.len selector: m.key_values.len - key_values_len_expr := t.synth_selector(ast.Expr(key_values_expr), 'len', types.Type(types.int_)) + key_values_len_expr := t.synth_selector(ast.Expr(key_values_expr), 'len', + types.Type(types.int_)) kv_ref := ast.Expr(ast.PrefixExpr{ op: .amp expr: key_values_expr @@ -10332,11 +10348,9 @@ fn (mut t Transformer) expand_assert_stmt(stmt ast.AssertStmt) []ast.Stmt { if stmt.expr is ast.InfixExpr && stmt.expr.op in [.eq, .ne, .lt, .gt, .le, .ge] { if assert_expr_is_simple(stmt.expr.lhs) && assert_expr_is_simple(stmt.expr.rhs) { // eprintln(" Left value: `${lhs}`") - body_stmts << t.make_eprintln_inter(' Left value: `', stmt.expr.lhs, '`', - pos) + body_stmts << t.make_eprintln_inter(' Left value: `', stmt.expr.lhs, '`', pos) // eprintln(" Right value: `${rhs}`") - body_stmts << t.make_eprintln_inter(' Right value: `', stmt.expr.rhs, '`', - pos) + body_stmts << t.make_eprintln_inter(' Right value: `', stmt.expr.rhs, '`', pos) } } diff --git a/vlib/v2/types/checker.v b/vlib/v2/types/checker.v index 3a31fb6a2b..3e0d42bdb9 100644 --- a/vlib/v2/types/checker.v +++ b/vlib/v2/types/checker.v @@ -3008,8 +3008,8 @@ fn (mut c Checker) fn_decl(decl ast.FnDecl) { if decl_generic_params.len > 0 { c.generic_params = decl_generic_params.clone() } - fn_typ := c.fn_type_with_insert_params(decl.typ, FnTypeAttribute.from_ast_attributes(decl.attributes), - true) + fn_typ := c.fn_type_with_insert_params(decl.typ, + FnTypeAttribute.from_ast_attributes(decl.attributes), true) c.generic_params = prev_generic_params mut typ := Type(fn_typ) // Heap-allocate Fn so pointer stored in env.methods remains valid @@ -3495,8 +3495,7 @@ fn (mut c Checker) substitute_struct_generic_type_with_stack(st Struct, generic_ } mut embedded := []Struct{cap: st.embedded.len} for emb in st.embedded { - embedded << c.substitute_struct_generic_type_with_stack(emb, generic_type_map, - next_stack) + embedded << c.substitute_struct_generic_type_with_stack(emb, generic_type_map, next_stack) } return Struct{ name: st.name @@ -3581,8 +3580,7 @@ fn (mut c Checker) substitute_generic_type_with_stack(t Type, generic_type_map m for param in t.params { params << Parameter{ name: param.name - typ: c.substitute_generic_type_with_stack(param.typ, generic_type_map, - stack) + typ: c.substitute_generic_type_with_stack(param.typ, generic_type_map, stack) is_mut: param.is_mut } } @@ -3633,8 +3631,7 @@ fn (mut c Checker) substitute_generic_type_with_stack(t Type, generic_type_map m }) } Struct { - return Type(c.substitute_struct_generic_type_with_stack(t, generic_type_map, - stack)) + return Type(c.substitute_struct_generic_type_with_stack(t, generic_type_map, stack)) } Thread { if elem := t.elem_type { @@ -4945,9 +4942,7 @@ fn (mut c Checker) find_field_or_method(t Type, raw_name string) !Type { if obj := c.lookup_type_by_name(emb_n) { live_type = obj } - if embedded_field_or_method_type := c.find_field_or_method(live_type, - name) - { + if embedded_field_or_method_type := c.find_field_or_method(live_type, name) { return embedded_field_or_method_type } } diff --git a/vlib/veb/context.v b/vlib/veb/context.v index 97987a5a56..d62053af39 100644 --- a/vlib/veb/context.v +++ b/vlib/veb/context.v @@ -105,7 +105,8 @@ pub fn (mut ctx Context) send_response_to_client(mimetype string, response strin ctx.done = true $if veb_livereload ? { if mimetype == 'text/html' { - ctx.res.body = response.replace('', '\n') + ctx.res.body = response.replace('', + '\n') } else { ctx.res.body = response.clone() } @@ -244,16 +245,12 @@ fn (mut ctx Context) send_file(content_type string, file_path string) Result { } // Try zstd first if enabled, then gzip if use_zstd { - if result := ctx.serve_compressed_static(content_type, file_path, data, - .zstd) - { + if result := ctx.serve_compressed_static(content_type, file_path, data, .zstd) { return result } } if use_gzip { - if result := ctx.serve_compressed_static(content_type, file_path, data, - .gzip) - { + if result := ctx.serve_compressed_static(content_type, file_path, data, .gzip) { return result } } @@ -352,8 +349,7 @@ fn (mut ctx Context) serve_precompressed_file(content_type string, file_path str } // Then try veb-managed cache files under os.cache_dir(). cached_path := static_compression_cache_path(file_path, ext) - return ctx.serve_compressed_path_if_fresh(content_type, cached_path, encoding_name, - orig_mtime) + return ctx.serve_compressed_path_if_fresh(content_type, cached_path, encoding_name, orig_mtime) } // serve_compressed_static compresses data and serves it, optionally caching to disk. diff --git a/vlib/veb/controller.v b/vlib/veb/controller.v index 6abab0d888..94f4c6f380 100644 --- a/vlib/veb/controller.v +++ b/vlib/veb/controller.v @@ -43,8 +43,8 @@ pub fn controller[A, X](path string, mut global_app A) !&ControllerPath { // match controller paths $if A is ControllerInterface { - if completed_context := handle_controllers[X](controllers_sorted, ctx, mut - url, host) + if completed_context := handle_controllers[X](controllers_sorted, ctx, mut url, + host) { return completed_context } diff --git a/vlib/veb/csrf/csrf.v b/vlib/veb/csrf/csrf.v index 7583cc6de5..69d9278c9c 100644 --- a/vlib/veb/csrf/csrf.v +++ b/vlib/veb/csrf/csrf.v @@ -233,7 +233,8 @@ fn generate_token(expire_time i64, session_id string, nonce_length int) string { // generate_cookie converts secret key based on the request context and a random // token into an hmac key fn generate_cookie(expire_time i64, token string, secret string) string { - hash := base64.url_encode(hmac.new(secret.bytes(), token.bytes(), sha256.sum, sha256.block_size)) + hash := + base64.url_encode(hmac.new(secret.bytes(), token.bytes(), sha256.sum, sha256.block_size)) cookie := '${expire_time}.${hash}' return cookie diff --git a/vlib/veb/static_handler.v b/vlib/veb/static_handler.v index f21f898426..76ee817c44 100644 --- a/vlib/veb/static_handler.v +++ b/vlib/veb/static_handler.v @@ -58,8 +58,7 @@ fn (mut sh StaticHandler) scan_static_directory(directory_path string, mount_pat for file in files { full_path := os.join_path(directory_path, file) if os.is_dir(full_path) { - sh.scan_static_directory(full_path, mount_path.trim_right('/') + '/' + file, - host)! + sh.scan_static_directory(full_path, mount_path.trim_right('/') + '/' + file, host)! } else if file.contains('.') && !file.starts_with('.') && !file.ends_with('.') { sh.host_serve_static(host, mount_path.trim_right('/') + '/' + file, full_path)! } diff --git a/vlib/veb/tests/memory_leak_test.v b/vlib/veb/tests/memory_leak_test.v index a2e8f003f4..00618d1777 100644 --- a/vlib/veb/tests/memory_leak_test.v +++ b/vlib/veb/tests/memory_leak_test.v @@ -26,7 +26,8 @@ fn testsuite_end() { } fn test_server_compiles() { - did_compile := os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/veb/tests/memory_leak_test_server.v') + did_compile := + os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/veb/tests/memory_leak_test_server.v') assert did_compile == 0 assert os.exists(serverexe) } diff --git a/vlib/veb/tests/veb_test.v b/vlib/veb/tests/veb_test.v index a4784e3e42..919966ac6b 100644 --- a/vlib/veb/tests/veb_test.v +++ b/vlib/veb/tests/veb_test.v @@ -32,14 +32,16 @@ fn testsuite_begin() { fn test_simple_veb_app_can_be_compiled() { // did_server_compile := os.system('${os.quoted_path(vexe)} -g -o ${os.quoted_path(serverexe)} vlib/veb/tests/veb_test_server.v') - did_server_compile := os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/veb/tests/veb_test_server.v') + did_server_compile := + os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/veb/tests/veb_test_server.v') assert did_server_compile == 0 assert os.exists(serverexe) } fn test_new_veb_app_can_be_compiled() { // Ensure the new fasthttp backend builds successfully. - did_server_compile := os.system('${os.quoted_path(vexe)} -d new_veb -o ${os.quoted_path(serverexe_new)} vlib/veb/tests/veb_test_server.v') + did_server_compile := + os.system('${os.quoted_path(vexe)} -d new_veb -o ${os.quoted_path(serverexe_new)} vlib/veb/tests/veb_test_server.v') assert did_server_compile == 0 assert os.exists(serverexe_new) } diff --git a/vlib/veb/veb.v b/vlib/veb/veb.v index d54ea43a73..40b6dd79b1 100644 --- a/vlib/veb/veb.v +++ b/vlib/veb/veb.v @@ -294,9 +294,7 @@ fn handle_ssl_request[A, X](req http.Request, params &SslRequestParams) ?&Contex ctx.custom_mime_types = global_app.static_mime_types.clone() } $if A is ControllerInterface { - if completed_context := handle_controllers[X](params.controllers_sorted, ctx, mut - url, host) - { + if completed_context := handle_controllers[X](params.controllers_sorted, ctx, mut url, host) { return completed_context } } @@ -467,7 +465,8 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string // no need to check the result of `validate_middleware`, since a response has to be sent // anyhow. This function makes sure no further middleware is executed. - validate_middleware[X](mut user_context, app.Middleware.get_global_handlers_after[X]()) + validate_middleware[X](mut user_context, + app.Middleware.get_global_handlers_after[X]()) // skip route-specific after-middleware if global already sent a response if !user_context.Context.done { validate_middleware[X](mut user_context, get_handlers_for_method(route.after_middlewares, diff --git a/vlib/veb/veb_d_new_veb.v b/vlib/veb/veb_d_new_veb.v index 6781d84c82..5144ad4508 100644 --- a/vlib/veb/veb_d_new_veb.v +++ b/vlib/veb/veb_d_new_veb.v @@ -74,8 +74,7 @@ fn parallel_request_handler[A, X](req fasthttp.HttpRequest) !fasthttp.HttpRespon } } // Create and populate the `veb.Context`. - completed_context := handle_request_and_route[A, X](mut global_app, req2, client_fd, - params) + completed_context := handle_request_and_route[A, X](mut global_app, req2, client_fd, params) // params.routes, params.controllers_sorted) // Serialize the final `http.Response` into a byte array. if completed_context.takeover { @@ -135,9 +134,7 @@ fn handle_request_and_route[A, X](mut app A, req http.Request, _client_fd int, p } // Match controller paths first $if A is ControllerInterface { - if completed_context := handle_controllers[X](params.controllers_sorted, ctx, mut - url, host) - { + if completed_context := handle_controllers[X](params.controllers_sorted, ctx, mut url, host) { return completed_context } } diff --git a/vlib/veb/veb_picoev.v b/vlib/veb/veb_picoev.v index a0df837d44..65f763e933 100644 --- a/vlib/veb/veb_picoev.v +++ b/vlib/veb/veb_picoev.v @@ -239,8 +239,7 @@ $if !new_veb ? { if params.file_responses[fd].pos == params.file_responses[fd].total { // file is done writing params.file_responses[fd].done() - handle_complete_request(params.file_responses[fd].should_close_conn, mut pv, - fd) + handle_complete_request(params.file_responses[fd].should_close_conn, mut pv, fd) return } } @@ -289,8 +288,7 @@ $if !new_veb ? { // done writing params.string_responses[fd].done() pv.close_conn(fd) - handle_complete_request(params.string_responses[fd].should_close_conn, mut - pv, fd) + handle_complete_request(params.string_responses[fd].should_close_conn, mut pv, fd) return } } @@ -501,8 +499,7 @@ $if !new_veb ? { // See Context.send_file for why we use max_read instead of max_write. if completed_context.res.body.len < max_read { fast_send_resp(mut conn, completed_context.res) or {} - handle_complete_request(completed_context.client_wants_to_close, mut - pv, fd) + handle_complete_request(completed_context.client_wants_to_close, mut pv, fd) } else { params.string_responses[fd].open = true params.string_responses[fd].str = completed_context.res.body @@ -541,12 +538,12 @@ $if !new_veb ? { } // Termux file responses are sent inline because deferred write events can // leave static responses stalled. - send_file_inline(mut conn, mut file, length.i64(), params.timeout_in_seconds) or { + send_file_inline(mut conn, mut file, length.i64(), + params.timeout_in_seconds) or { pv.close_conn(fd) return } - handle_complete_request(completed_context.client_wants_to_close, mut - pv, fd) + handle_complete_request(completed_context.client_wants_to_close, mut pv, fd) } $else { params.file_responses[fd].total = length.i64() params.file_responses[fd].file = os.open(completed_context.return_file) or { @@ -634,9 +631,7 @@ $if !new_veb ? { } // match controller paths $if A is ControllerInterface { - if completed_context := handle_controllers[X](params.controllers, ctx, mut - url, host) - { + if completed_context := handle_controllers[X](params.controllers, ctx, mut url, host) { return completed_context } } diff --git a/vlib/vweb/csrf/csrf.v b/vlib/vweb/csrf/csrf.v index fa297a6ac7..36bd4be56c 100644 --- a/vlib/vweb/csrf/csrf.v +++ b/vlib/vweb/csrf/csrf.v @@ -198,7 +198,8 @@ fn generate_token(expire_time i64, session_id string, nonce_length int) string { // generate_cookie converts secret key based on the request context and a random // token into an hmac key fn generate_cookie(expire_time i64, token string, secret string) string { - hash := base64.url_encode(hmac.new(secret.bytes(), token.bytes(), sha256.sum, sha256.block_size)) + hash := + base64.url_encode(hmac.new(secret.bytes(), token.bytes(), sha256.sum, sha256.block_size)) cookie := '${expire_time}.${hash}' return cookie diff --git a/vlib/vweb/tests/controller_test.v b/vlib/vweb/tests/controller_test.v index a4ac83abad..ddeaaa525f 100644 --- a/vlib/vweb/tests/controller_test.v +++ b/vlib/vweb/tests/controller_test.v @@ -25,7 +25,8 @@ fn testsuite_begin() { fn test_middleware_vweb_app_can_be_compiled() { // did_server_compile := os.system('${os.quoted_path(vexe)} -g -o ${os.quoted_path(serverexe)} vlib/vweb/tests/controller_test_server.vv') // TODO: find out why it does not compile with -usecache and -g - did_server_compile := os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/vweb/tests/controller_test_server.v') + did_server_compile := + os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/vweb/tests/controller_test_server.v') assert did_server_compile == 0 assert os.exists(serverexe) } @@ -130,7 +131,8 @@ fn test_shutdown() { } fn test_duplicate_route() { - did_server_compile := os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/vweb/tests/controller_duplicate_server.v') + did_server_compile := + os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/vweb/tests/controller_duplicate_server.v') assert did_server_compile == 0 assert os.exists(serverexe) diff --git a/vlib/vweb/tests/middleware_test.v b/vlib/vweb/tests/middleware_test.v index ac00c32749..b07817e561 100644 --- a/vlib/vweb/tests/middleware_test.v +++ b/vlib/vweb/tests/middleware_test.v @@ -28,7 +28,8 @@ fn testsuite_begin() { fn test_middleware_vweb_app_can_be_compiled() { // did_server_compile := os.system('${os.quoted_path(vexe)} -g -o ${os.quoted_path(serverexe)} vlib/vweb/tests/middleware_test_server.vv') // TODO: find out why it does not compile with -usecache and -g - did_server_compile := os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/vweb/tests/middleware_test_server.v') + did_server_compile := + os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(serverexe)} vlib/vweb/tests/middleware_test_server.v') assert did_server_compile == 0 assert os.exists(serverexe) } diff --git a/vlib/vweb/vweb.v b/vlib/vweb/vweb.v index d0d7be1321..3a44c53d5d 100644 --- a/vlib/vweb/vweb.v +++ b/vlib/vweb/vweb.v @@ -236,7 +236,8 @@ pub fn (mut ctx Context) send_response_to_client(mimetype string, res string) bo } $if vweb_livereload ? { if mimetype == 'text/html' { - resp.body = res.replace('', '\n') + resp.body = res.replace('', + '\n') } } // build the header after the potential modification of resp.body from above @@ -570,8 +571,7 @@ pub fn run_at[T](global_app &T, params RunParams) ! { ch := chan mut net.TcpConn{cap: params.pool_channel_slots} mut ws := []thread{cap: params.nr_workers} for worker_number in 0 .. params.nr_workers { - ws << new_worker[T](ch, worker_number, unsafe { global_app }, controllers_sorted, - &routes) + ws << new_worker[T](ch, worker_number, unsafe { global_app }, controllers_sorted, &routes) } if params.show_startup_message { println('[Vweb] We have ${ws.len} workers') @@ -1002,15 +1002,13 @@ fn (mut ctx Context) scan_static_directory(directory_path string, mount_path str for file in files { full_path := os.join_path(directory_path, file) if os.is_dir(full_path) { - ctx.scan_static_directory(full_path, mount_path.trim_right('/') + '/' + file, - host) + ctx.scan_static_directory(full_path, mount_path.trim_right('/') + '/' + file, host) } else if file.contains('.') && !file.starts_with('.') && !file.ends_with('.') { ext := os.file_ext(file) // Rudimentary guard against adding files not in mime_types. // Use host_serve_static directly to add non-standard mime types. if ext in mime_types { - ctx.host_serve_static(host, mount_path.trim_right('/') + '/' + file, - full_path) + ctx.host_serve_static(host, mount_path.trim_right('/') + '/' + file, full_path) } } } diff --git a/vlib/wasm/tests/common.v b/vlib/wasm/tests/common.v index 1278a1daa1..f27214e84f 100644 --- a/vlib/wasm/tests/common.v +++ b/vlib/wasm/tests/common.v @@ -14,7 +14,8 @@ fn find_wasm_validate() !string { // through install_wabt.vsh, since it is more likely to be known, recent, and stable: thirdpart_wasm_validate_folder := os.join_path(@VEXEROOT, 'thirdparty', 'wabt', 'bin') extension := $if windows { '.exe' } $else { '' } - wasm_validate_executable := os.join_path(thirdpart_wasm_validate_folder, 'wasm-validate${extension}') + wasm_validate_executable := os.join_path(thirdpart_wasm_validate_folder, + 'wasm-validate${extension}') if os.exists(wasm_validate_executable) { return wasm_validate_executable } diff --git a/vlib/wasm/tests/debug_test.v b/vlib/wasm/tests/debug_test.v index 8d3e2e60b7..40a041dca3 100644 --- a/vlib/wasm/tests/debug_test.v +++ b/vlib/wasm/tests/debug_test.v @@ -33,8 +33,9 @@ fn test_wasi_debug() { m.new_global_import('env', 'glble', .i32_t, false) m.new_function_import('wasi_unstable', 'proc_exit', [.i32_t], []) - m.new_function_import('wasi_unstable', 'fd_write', [.i32_t, .i32_t, .i32_t, .i32_t], - [.i32_t]) + m.new_function_import('wasi_unstable', 'fd_write', [.i32_t, .i32_t, .i32_t, .i32_t], [ + .i32_t, + ]) m.assign_memory('memory', true, 1, none) m.new_data_segment('CIOVec.str', 0, [u8(8), 0, 0, 0]) // pointer to string diff --git a/vlib/x/crypto/ascon/examples/use_of_cxof.v b/vlib/x/crypto/ascon/examples/use_of_cxof.v index 36ffe56521..12d2abebf6 100644 --- a/vlib/x/crypto/ascon/examples/use_of_cxof.v +++ b/vlib/x/crypto/ascon/examples/use_of_cxof.v @@ -12,8 +12,10 @@ fn main() { // expected output generated from the tool, with 32, 64 dan 75-bytes output digest32 := hex.decode('d71492b816b1ac27f53f9c13be45c1d2d0530b8dde7fde8d34cb563f79b3d3d3')! - digest64 := hex.decode('d71492b816b1ac27f53f9c13be45c1d2d0530b8dde7fde8d34cb563f79b3d3d3601d03474ec6fe1f6b8dc5dd79bea20aff4c95ca3549202b1aaeb9e66b5df398')! - digest75 := hex.decode('d71492b816b1ac27f53f9c13be45c1d2d0530b8dde7fde8d34cb563f79b3d3d3601d03474ec6fe1f6b8dc5dd79bea20aff4c95ca3549202b1aaeb9e66b5df3985a88fd8bce0f9570962321')! + digest64 := + hex.decode('d71492b816b1ac27f53f9c13be45c1d2d0530b8dde7fde8d34cb563f79b3d3d3601d03474ec6fe1f6b8dc5dd79bea20aff4c95ca3549202b1aaeb9e66b5df398')! + digest75 := + hex.decode('d71492b816b1ac27f53f9c13be45c1d2d0530b8dde7fde8d34cb563f79b3d3d3601d03474ec6fe1f6b8dc5dd79bea20aff4c95ca3549202b1aaeb9e66b5df3985a88fd8bce0f9570962321')! out32 := ascon.cxof128(msg, 32, cs)! out64 := ascon.cxof128(msg, 64, cs)! diff --git a/vlib/x/crypto/ascon/examples/use_of_xof.v b/vlib/x/crypto/ascon/examples/use_of_xof.v index 1d02f7e12f..eb39efc39a 100644 --- a/vlib/x/crypto/ascon/examples/use_of_xof.v +++ b/vlib/x/crypto/ascon/examples/use_of_xof.v @@ -10,8 +10,10 @@ fn main() { msg := 'Example of Xof128 message'.bytes() // expected output generated from the tool, with 32, 64 dan 75-bytes output digest32 := hex.decode('424caaf68eb94aa251536bb6b565c0695b8944f932d011b1049df85b7f27d2f3')! - digest64 := hex.decode('424caaf68eb94aa251536bb6b565c0695b8944f932d011b1049df85b7f27d2f3bf704643a643c3f2dcfb1e0bc73ec55781b5283966d2d1da85d89794ca5c292e')! - digest75 := hex.decode('424caaf68eb94aa251536bb6b565c0695b8944f932d011b1049df85b7f27d2f3bf704643a643c3f2dcfb1e0bc73ec55781b5283966d2d1da85d89794ca5c292e36260815a8f10088e3804c')! + digest64 := + hex.decode('424caaf68eb94aa251536bb6b565c0695b8944f932d011b1049df85b7f27d2f3bf704643a643c3f2dcfb1e0bc73ec55781b5283966d2d1da85d89794ca5c292e')! + digest75 := + hex.decode('424caaf68eb94aa251536bb6b565c0695b8944f932d011b1049df85b7f27d2f3bf704643a643c3f2dcfb1e0bc73ec55781b5283966d2d1da85d89794ca5c292e36260815a8f10088e3804c')! out32 := ascon.xof128(msg, 32)! out64 := ascon.xof128(msg, 64)! diff --git a/vlib/x/crypto/chacha20poly1305/bench/bench.v b/vlib/x/crypto/chacha20poly1305/bench/bench.v index 0bbfe9136e..2e77f2252b 100644 --- a/vlib/x/crypto/chacha20poly1305/bench/bench.v +++ b/vlib/x/crypto/chacha20poly1305/bench/bench.v @@ -123,13 +123,15 @@ fn main() { _ := chacha20poly1305.psiv_decrypt(out1, key, nonce, ad)! // Benchmark Standard AEAD_CHACHA20_POLY1305 encryption - std_encrypt_time := benchmark_aead_std_encrypt(test_msg, key, nonce, ad, benchmark_iterations) + std_encrypt_time := benchmark_aead_std_encrypt(test_msg, key, nonce, ad, + benchmark_iterations) // Benchmark Standard AEAD_CHACHA20_POLY1305 decryption std_decrypt_time := benchmark_aead_std_decrypt(out0, key, nonce, ad, benchmark_iterations) // Benchmark AEAD_CHACHA20_POLY1305 PSIV encryption - psiv_encrypt_time := benchmark_aead_psiv_encrypt(test_msg, key, nonce, ad, benchmark_iterations) + psiv_encrypt_time := benchmark_aead_psiv_encrypt(test_msg, key, nonce, ad, + benchmark_iterations) // Benchmark AEAD_CHACHA20_POLY1305 PSIV decryption psiv_decrypt_time := benchmark_aead_psiv_decrypt(out1, key, nonce, ad, benchmark_iterations) diff --git a/vlib/x/crypto/chacha20poly1305/chacha20poly1305_test.v b/vlib/x/crypto/chacha20poly1305/chacha20poly1305_test.v index 4595f55f5a..af3b5fd1d4 100644 --- a/vlib/x/crypto/chacha20poly1305/chacha20poly1305_test.v +++ b/vlib/x/crypto/chacha20poly1305/chacha20poly1305_test.v @@ -9,7 +9,8 @@ const tag_size = chacha20poly1305.tag_size // Example and Test Vector for AEAD_CHACHA20_POLY1305 // https://datatracker.ietf.org/doc/html/rfc8439#section-2.8.2 fn test_encrypt_example_test() ! { - plaintext := "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.".bytes() + plaintext := + "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.".bytes() aad := hex.decode('50515253c0c1c2c3c4c5c6c7')! key := hex.decode('808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f')! @@ -17,7 +18,8 @@ fn test_encrypt_example_test() ! { fixed := '07000000' nonce := hex.decode(fixed + iv)! - exp_onetime_key := hex.decode('7bac2b252db447af09b67a55a4e955840ae1d6731075d9eb2a9375783ed553ff')! + exp_onetime_key := + hex.decode('7bac2b252db447af09b67a55a4e955840ae1d6731075d9eb2a9375783ed553ff')! ncsize := nonce.len mut c := chacha20poly1305.new(key, ncsize)! @@ -29,7 +31,8 @@ fn test_encrypt_example_test() ! { assert polykey == exp_onetime_key - exp_ciphertext := hex.decode('d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116')! + exp_ciphertext := + hex.decode('d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116')! expected_tag := hex.decode('1ae10b594f09e26a7e902ecbd0600691')! cipherout := c.encrypt(plaintext, nonce, aad)! @@ -46,7 +49,8 @@ fn test_aead_decrypt_vector_test_51() ! { key := hex.decode('1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0')! aad := hex.decode('f33388860000000000004e91')! nonce := hex.decode('000000000102030405060708')! - ciphertext := hex.decode('64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b')! + ciphertext := + hex.decode('64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b')! // Received Tag expected_tag := hex.decode('eead9d67890cbb22392336fea1851f38')! // Ciphertext msg is concatenation of ciphertext and tag @@ -65,13 +69,15 @@ fn test_aead_decrypt_vector_test_51() ! { expected_otk := hex.decode('bdf04aa95ce4de8995b14bb6a18fecaf26478f50c054f563dbc0a21e261572aa')! assert polykey == expected_otk - constructed_msg := hex.decode('f33388860000000000004e910000000064a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b000000000000000c000000000000000901000000000000')! + constructed_msg := + hex.decode('f33388860000000000004e910000000064a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b000000000000000c000000000000000901000000000000')! mut mac := []u8{len: tag_size} poly1305.create_tag(mut mac, constructed_msg, polykey)! assert mac == expected_tag - expected_plaintext := hex.decode('496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d')! + expected_plaintext := + hex.decode('496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d')! plaintext := c.decrypt(ciphertext_msg, nonce, aad)! assert plaintext == expected_plaintext } diff --git a/vlib/x/crypto/chacha20poly1305/psiv.v b/vlib/x/crypto/chacha20poly1305/psiv.v index ebf803ca78..8004fac1ce 100644 --- a/vlib/x/crypto/chacha20poly1305/psiv.v +++ b/vlib/x/crypto/chacha20poly1305/psiv.v @@ -131,8 +131,7 @@ pub fn (c Chacha20Poly1305RE) encrypt(plaintext []u8, nonce []u8, ad []u8) ![]u8 // setup output buffer mut out := []u8{len: plaintext.len + tag_size} // write out an authentication tag into the last tag_size bytes of output - psiv_gen_tag(mut out[plaintext.len..], mut po_ad_clone, plaintext, ad.len, c.mac_key, - nonce) + psiv_gen_tag(mut out[plaintext.len..], mut po_ad_clone, plaintext, ad.len, c.mac_key, nonce) // write out authenticated encrypted plaintext into the first plaintext.len bytes of output psiv_encrypt_internal(mut out[0..plaintext.len], plaintext, c.enc_key, out[plaintext.len..], nonce)! diff --git a/vlib/x/crypto/chacha20poly1305/usage_test.v b/vlib/x/crypto/chacha20poly1305/usage_test.v index caa026597b..fa8d8d6356 100644 --- a/vlib/x/crypto/chacha20poly1305/usage_test.v +++ b/vlib/x/crypto/chacha20poly1305/usage_test.v @@ -12,10 +12,12 @@ fn test_aead_chacha20poly1305_fn_encrypt_and_decrypt_operation() ! { nonce := hex.decode('000000000102030405060708')! // your message to be encrypted and authenticated - plaintext := 'Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as /“work in progress./”'.bytes() + plaintext := + 'Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as /“work in progress./”'.bytes() ciphertext_out := chacha20poly1305.encrypt(plaintext, key, nonce, aad)! - ciphertext := hex.decode('64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b')! + ciphertext := + hex.decode('64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b')! // Received Tag expected_tag := hex.decode('eead9d67890cbb22392336fea1851f38')! // aead output is concatenation of ciphertext and the tag @@ -40,14 +42,16 @@ fn test_aead_chacha20poly1305_instance_encrypt_and_decrypt_operation() ! { // gives your nonce nonce := hex.decode('000000000102030405060708')! // your message to be encrypted and authenticated - plaintext := hex.decode('496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d')! + plaintext := + hex.decode('496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d')! // lets create chacha20poly1305 AEAD mut co := chacha20poly1305.new(key, nonce.len)! ciphertext_out := co.encrypt(plaintext, nonce, aad)! // we have expected ciphertext - ciphertext := hex.decode('64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b')! + ciphertext := + hex.decode('64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b')! // Received Tag expected_tag := hex.decode('eead9d67890cbb22392336fea1851f38')! // aead output is concatenation of ciphertext and the tag diff --git a/vlib/x/crypto/chacha20poly1305/xchacha20poly1305_test.v b/vlib/x/crypto/chacha20poly1305/xchacha20poly1305_test.v index 77423de271..ae26429ce1 100644 --- a/vlib/x/crypto/chacha20poly1305/xchacha20poly1305_test.v +++ b/vlib/x/crypto/chacha20poly1305/xchacha20poly1305_test.v @@ -8,11 +8,13 @@ import x.crypto.chacha20poly1305 // Test from Developer-Friendly Test Vectors // See https://datatracker.ietf.org/doc/html/draft-arciszewski-xchacha#appendix-A.3 fn test_xchacha20poly1305_aead_rfc() ! { - plaintext := hex.decode('4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e')! + plaintext := + hex.decode('4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e')! aad := hex.decode('50515253c0c1c2c3c4c5c6c7')! key := hex.decode('808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f')! nonce := hex.decode('404142434445464748494a4b4c4d4e4f5051525354555657')! - ciphertext := hex.decode('bd6d179d3e83d43b9576579493c0e939572a1700252bfaccbed2902c21396cbb731c7f1b0b4aa6440bf3a82f4eda7e39ae64c6708c54c216cb96b72e1213b4522f8c9ba40db5d945b11b69b982c1bb9e3f3fac2bc369488f76b2383565d3fff921f9664c97637da9768812f615c68b13b52e')! + ciphertext := + hex.decode('bd6d179d3e83d43b9576579493c0e939572a1700252bfaccbed2902c21396cbb731c7f1b0b4aa6440bf3a82f4eda7e39ae64c6708c54c216cb96b72e1213b4522f8c9ba40db5d945b11b69b982c1bb9e3f3fac2bc369488f76b2383565d3fff921f9664c97637da9768812f615c68b13b52e')! tag := hex.decode('c0875924c1c7987947deafd8780acf49')! // encrypt produces ciphertext plus tag appends into it diff --git a/vlib/x/crypto/mldsa/mldsa_test.v b/vlib/x/crypto/mldsa/mldsa_test.v index a5b9118575..47196d905f 100644 --- a/vlib/x/crypto/mldsa/mldsa_test.v +++ b/vlib/x/crypto/mldsa/mldsa_test.v @@ -206,8 +206,7 @@ fn test_power2_round() { for val in [u32(0), 1, 100, 1000, q / 2, q - 1] { r := field_to_montgomery(val) or { panic(err) } hi, lo := power2_round(r) - reconstructed := field_add(field_to_montgomery(u32(hi) << d) or { panic(err) }, - lo) + reconstructed := field_add(field_to_montgomery(u32(hi) << d) or { panic(err) }, lo) assert field_from_montgomery(reconstructed) == val, 'power2_round failed for ${val}' } } diff --git a/vlib/x/crypto/mldsa/ntt.v b/vlib/x/crypto/mldsa/ntt.v index 7ad245ded4..8578e5b084 100644 --- a/vlib/x/crypto/mldsa/ntt.v +++ b/vlib/x/crypto/mldsa/ntt.v @@ -167,13 +167,11 @@ fn inverse_ntt(f_ NttElement) RingElement { for j < len2 { mut t := f[start + j] f[start + j] = field_add(t, f[start + len2 + j]) - f[start + len2 + j] = field_montgomery_mul_sub(zeta, f[start + len2 + j], - t) + f[start + len2 + j] = field_montgomery_mul_sub(zeta, f[start + len2 + j], t) t = f[start + j + 1] f[start + j + 1] = field_add(t, f[start + len2 + j + 1]) - f[start + len2 + j + 1] = field_montgomery_mul_sub(zeta, f[start + len2 + j + 1], - t) + f[start + len2 + j + 1] = field_montgomery_mul_sub(zeta, f[start + len2 + j + 1], t) j += 2 } diff --git a/vlib/x/crypto/poly1305/usage_test.v b/vlib/x/crypto/poly1305/usage_test.v index 849b24f1bc..0abdd4f4f3 100644 --- a/vlib/x/crypto/poly1305/usage_test.v +++ b/vlib/x/crypto/poly1305/usage_test.v @@ -63,7 +63,8 @@ fn test_create_and_verify_tag_with_poly1305_instance_in_incremental_updates() ! // we split above message to five msg block msg0 := 'Any submission to the IETF intended by the Contributor for publication as all '.bytes() msg1 := 'or part of an IETF Internet-Draft or RFC and any statement made within '.bytes() - msg2 := 'the context of an IETF activity is considered an "IETF Contribution". Such statements '.bytes() + msg2 := + 'the context of an IETF activity is considered an "IETF Contribution". Such statements '.bytes() msg3 := 'include oral statements in IETF sessions, as well as written and electronic '.bytes() msg4 := 'communications made at any time or place, which are addressed to'.bytes() // lets creates buffers output and build the tag diff --git a/vlib/x/crypto/slhdsa/base_test.v b/vlib/x/crypto/slhdsa/base_test.v index 578324db33..1867a9b857 100644 --- a/vlib/x/crypto/slhdsa/base_test.v +++ b/vlib/x/crypto/slhdsa/base_test.v @@ -9,7 +9,8 @@ import encoding.hex fn test_privatekey_from_bytes() ! { // for sha2_128s - priv := hex.decode('4329f96b412b5d5ca9c730c9d54e52595265f6fc3ea67c183aa7043d90e949b8fd320c8fc0fa6a23462483535f131b9ea265848e7bb5f4d3cfd99de2595382b3')! + priv := + hex.decode('4329f96b412b5d5ca9c730c9d54e52595265f6fc3ea67c183aa7043d90e949b8fd320c8fc0fa6a23462483535f131b9ea265848e7bb5f4d3cfd99de2595382b3')! mut pv := PrivateKey.from_bytes(priv, .sha2_128s)! sig := pv.sign('test'.bytes())! diff --git a/vlib/x/crypto/slhdsa/const.c.v b/vlib/x/crypto/slhdsa/const.c.v index 3393f947f1..462d4f5459 100644 --- a/vlib/x/crypto/slhdsa/const.c.v +++ b/vlib/x/crypto/slhdsa/const.c.v @@ -11,8 +11,34 @@ fn init() { } } -// #define LN_SLH_DSA_SHA2_128s "SLH-DSA-SHA2-128s" +// NID and LN constants for SLH-DSA algorithms +pub const C.NID_SLH_DSA_SHA2_128s int +pub const C.NID_SLH_DSA_SHA2_128f int +pub const C.NID_SLH_DSA_SHA2_192s int +pub const C.NID_SLH_DSA_SHA2_192f int +pub const C.NID_SLH_DSA_SHA2_256s int +pub const C.NID_SLH_DSA_SHA2_256f int +pub const C.NID_SLH_DSA_SHAKE_128s int +pub const C.NID_SLH_DSA_SHAKE_128f int +pub const C.NID_SLH_DSA_SHAKE_192s int +pub const C.NID_SLH_DSA_SHAKE_192f int +pub const C.NID_SLH_DSA_SHAKE_256s int +pub const C.NID_SLH_DSA_SHAKE_256f int + +pub const C.LN_SLH_DSA_SHA2_128s int +pub const C.LN_SLH_DSA_SHA2_128f int +pub const C.LN_SLH_DSA_SHA2_192s int +pub const C.LN_SLH_DSA_SHA2_192f int +pub const C.LN_SLH_DSA_SHA2_256s int +pub const C.LN_SLH_DSA_SHA2_256f int +pub const C.LN_SLH_DSA_SHAKE_128s int +pub const C.LN_SLH_DSA_SHAKE_128f int +pub const C.LN_SLH_DSA_SHAKE_192s int +pub const C.LN_SLH_DSA_SHAKE_192f int +pub const C.LN_SLH_DSA_SHAKE_256s int +pub const C.LN_SLH_DSA_SHAKE_256f int // #define LN_SLH_DSA_SHA2_128s "SLH-DSA-SHA2-128s" // #define NID_SLH_DSA_SHA2_128s 1460 + const nid_slhdsa_sha2_128s = C.NID_SLH_DSA_SHA2_128s const ln_slhdsa_sha2_128s = &char(C.LN_SLH_DSA_SHA2_128s) diff --git a/vlib/x/encoding/asn1/README.md b/vlib/x/encoding/asn1/README.md index 37d933389d..2e7c0616cf 100644 --- a/vlib/x/encoding/asn1/README.md +++ b/vlib/x/encoding/asn1/README.md @@ -60,7 +60,8 @@ fn main() { assert output2 == [u8(0xa5), 0x03, 0x02, 0x01, 0x20] // You can decode (deserialize) back the bytes into Element. - el := asn1.decode_with_options([u8(0xa5), 0x03, 0x02, 0x01, 0x20], 'context_specific:5;explicit;inner:2')! + el := asn1.decode_with_options([u8(0xa5), 0x03, 0x02, 0x01, 0x20], + 'context_specific:5;explicit;inner:2')! // el is an Element, turn it into underlying object int_el := el.into_object[asn1.Integer]()! diff --git a/vlib/x/encoding/asn1/examples/examples2.v b/vlib/x/encoding/asn1/examples/examples2.v index 4fe6f05a85..e827123049 100644 --- a/vlib/x/encoding/asn1/examples/examples2.v +++ b/vlib/x/encoding/asn1/examples/examples2.v @@ -42,8 +42,10 @@ fn (pr PersonnelRecord) payload() ![]u8 { out << asn1.encode(pr.name)! out << asn1.encode_with_options(pr.title, 'context_specific:0;explicit;inner:26')! out << asn1.encode(pr.number)! - out << asn1.encode_with_options(pr.date_of_hire, 'context_specific: 1; explicit; inner:application,false,3')! - out << asn1.encode_with_options(pr.name_of_spouse, 'context_specific: 2; explicit; inner:application,true,1')! + out << asn1.encode_with_options(pr.date_of_hire, + 'context_specific: 1; explicit; inner:application,false,3')! + out << asn1.encode_with_options(pr.name_of_spouse, + 'context_specific: 2; explicit; inner:application,true,1')! out << asn1.encode_with_options(pr.children, 'context_specific: 3; implicit; inner:16')! return out @@ -75,12 +77,14 @@ fn PersonnelRecord.decode(bytes []u8) !PersonnelRecord { employe_number := EmployeeNumber(emp_num) // dateOfHire - doh := fields[3].unwrap_with_options('context_specific: 1; explicit; inner:application,false,3')! + doh := + fields[3].unwrap_with_options('context_specific: 1; explicit; inner:application,false,3')! doh_app := doh.into_object[asn1.ApplicationElement]()! date_of_hire := Date(doh_app) // nameOfSpouse - nosp := fields[4].unwrap_with_options('context_specific: 2; explicit; inner:application,true,1')! + nosp := + fields[4].unwrap_with_options('context_specific: 2; explicit; inner:application,true,1')! nosp_app := nosp.into_object[asn1.ApplicationElement]()! name_of_spouse := Name(nosp_app) @@ -138,7 +142,8 @@ fn ChildInformation.from_set(s asn1.Set) !ChildInformation { } fields := s.fields() // serialized name and dateOfBirth of ChildInformation name := fields[0].into_object[asn1.ApplicationElement]()! - doh := fields[1].unwrap_with_options('context_specific: 0; explicit; inner:application,false,3')! + doh := + fields[1].unwrap_with_options('context_specific: 0; explicit; inner:application,false,3')! date := doh.into_object[asn1.ApplicationElement]()! ch := ChildInformation{ name: Name(name) @@ -154,7 +159,8 @@ fn (ci ChildInformation) tag() asn1.Tag { fn (ci ChildInformation) payload() ![]u8 { mut out := []u8{} out << asn1.encode(ci.name)! - out << asn1.encode_with_options(ci.date_of_birth, 'context_specific: 0; explicit; inner:application,false,3')! + out << asn1.encode_with_options(ci.date_of_birth, + 'context_specific: 0; explicit; inner:application,false,3')! return out } @@ -367,7 +373,8 @@ fn main() { assert pr_record_output == expected_record_bytes pr_record := PersonnelRecord.decode(pr_record_output)! - pr_record_encoded_back := asn1.encode_with_options(pr_record, 'application:0;implicit;inner:17')! + pr_record_encoded_back := + asn1.encode_with_options(pr_record, 'application:0;implicit;inner:17')! dump(pr_record_encoded_back == expected_record_bytes) // true } diff --git a/vlib/x/encoding/asn1/integer_test.v b/vlib/x/encoding/asn1/integer_test.v index 01754a46eb..71e7ac1005 100644 --- a/vlib/x/encoding/asn1/integer_test.v +++ b/vlib/x/encoding/asn1/integer_test.v @@ -170,7 +170,8 @@ fn test_integer_large_int() ! { 0x13, 0xd7, 0x2a, 0x6b, 0x30, 0x91, 0x19, 0xd6, 0xd4, 0x42, 0xe0, 0xc4, 0x9d, 0x7c, 0x92, 0x71, 0xe1, 0xb2, 0x2f, 0x5c, 0x8d, 0xee, 0xf0, 0xf1, 0x17, 0x1e, 0xd2, 0x5f, 0x31, 0x5b, 0xb1, 0x9c, 0xbc, 0x20, 0x55, 0xbf, 0x3a, 0x37, 0x42, 0x45, 0x75, 0xdc, 0x90, 0x65] - expected_integer := Integer.from_string('101038645214968213029489864879507742420925199145132483818978980455132582258676381289000109319204510275496178360219909358646064503513889573494768497419381751359787623037449375660247011308028102339473875820259375735204357343091558075960601364303443174344509161224592926325506446708043127306053676664799729848421')! + expected_integer := + Integer.from_string('101038645214968213029489864879507742420925199145132483818978980455132582258676381289000109319204510275496178360219909358646064503513889573494768497419381751359787623037449375660247011308028102339473875820259375735204357343091558075960601364303443174344509161224592926325506446708043127306053676664799729848421')! out, pos := Integer.decode(bytes)! assert pos == bytes.len diff --git a/vlib/x/encoding/asn1/sequence_test.v b/vlib/x/encoding/asn1/sequence_test.v index 3726c7ffe4..9aa937fc97 100644 --- a/vlib/x/encoding/asn1/sequence_test.v +++ b/vlib/x/encoding/asn1/sequence_test.v @@ -199,7 +199,8 @@ fn test_sequence_add_encode_integer() ! { } fn test_sequence_integer_bigint() ! { - inp := big.integer_from_string('84885164052257330097714121751630835360966663883732297726369399')! + inp := + big.integer_from_string('84885164052257330097714121751630835360966663883732297726369399')! mut seq := Sequence.new()! o1 := Integer.from_bigint(inp) diff --git a/vlib/x/json2/decode.v b/vlib/x/json2/decode.v index 22c40948be..c37d991619 100644 --- a/vlib/x/json2/decode.v +++ b/vlib/x/json2/decode.v @@ -496,6 +496,18 @@ fn decode_struct_key[T](mut decoder Decoder, val T, key_info ValueInfo, prefix s decoder.decode_value(mut unwrapped_val)! new_val.$(field.name) = unwrapped_val } + } $else $if field.indirections == 1 { + if decoder.current_node.value.value_kind == .null { + new_val.$(field.name) = unsafe { nil } + + if decoder.current_node != unsafe { nil } { + decoder.current_node = decoder.current_node.next + } + } else { + mut decoded_ptr := create_decoded_ptr(new_val.$(field.name)) + decoder.decode_value(mut decoded_ptr)! + new_val.$(field.name) = decoded_ptr + } } $else { decoder.decode_value(mut new_val.$(field.name))! } @@ -526,8 +538,9 @@ fn decode_struct_key[T](mut decoder Decoder, val T, key_info ValueInfo, prefix s } } { - embed_result := decode_struct_key(mut decoder, new_val.$(field.name), - key_info, prefix + field.name + '.', mut seen_required)! + embed_result := decode_struct_key(mut decoder, new_val.$(field.name), key_info, + + prefix + field.name + '.', mut seen_required)! if embed_result.matched { new_val.$(field.name) = embed_result.value return StructKeyDecodeResult[T]{ @@ -554,8 +567,8 @@ fn check_required_struct_fields[T](mut decoder Decoder, val T, seen_required []s decoder.decode_error('missing required field `${field.name}`')! } $if field.is_embed { - check_required_struct_fields(mut decoder, val.$(field.name), seen_required, - prefix + field.name + '.')! + check_required_struct_fields(mut decoder, val.$(field.name), seen_required, prefix + + field.name + '.')! } i++ } @@ -804,7 +817,8 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! { if unsafe { vmemcmp(decoder.json.str + decoder.current_node.next.value.position, - float_zero_in_string.str, float_zero_in_string.len) == 0 + float_zero_in_string.str, + float_zero_in_string.len) == 0 } { current_field_info = current_field_info.next continue @@ -819,7 +833,8 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! { // check if the key matches the field name if key_info.length - 2 == current_field_info.value.json_name_len { if unsafe { - vmemcmp(decoder.json.str + key_info.position + 1, current_field_info.value.json_name_ptr, + vmemcmp(decoder.json.str + key_info.position + 1, + current_field_info.value.json_name_ptr, current_field_info.value.json_name_len) == 0 } { $for field in T.fields { @@ -905,7 +920,8 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! { decoder.current_node = decoder.current_node.next } } else { - mut decoded_ptr := create_decoded_ptr(val.$(field.name)) + mut decoded_ptr := + create_decoded_ptr(val.$(field.name)) decoder.decode_value(mut decoded_ptr)! val.$(field.name) = decoded_ptr } @@ -913,7 +929,8 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! { mut decoded_field_value := val.$(field.name) decoder.decode_value(mut decoded_field_value)! $if field.unaliased_typ is $map { - val.$(field.name) = decoded_field_value.move() + val.$(field.name) = + decoded_field_value.move() } $else { val.$(field.name) = decoded_field_value } @@ -944,7 +961,8 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! { } if !current_field_info.value.is_decoded { decoder.decode_error('missing required field `${unsafe { - tos(current_field_info.value.field_name_str, current_field_info.value.field_name_len) + tos(current_field_info.value.field_name_str, + current_field_info.value.field_name_len) }}`')! } current_field_info = current_field_info.next @@ -1242,6 +1260,25 @@ fn has_exponent_number_syntax(str string) bool { fn scientific_number_to_integer_string(str string) !string { if !has_exponent_number_syntax(str) { + // Handle plain decimal numbers with zero fractional part (e.g., "-123.0") + dot_pos := str.index_u8(`.`) + if dot_pos >= 0 { + frac := str[dot_pos + 1..] + mut all_zeros := frac.len > 0 + for c in frac { + if c != `0` { + all_zeros = false + break + } + } + if all_zeros { + result := str[..dot_pos] + if result.len == 0 || result == '-' || result == '+' { + return '0' + } + return result + } + } return str } if str.len == 0 { diff --git a/vlib/x/json2/decode_sumtype.v b/vlib/x/json2/decode_sumtype.v index 330503f695..9fb7a710f1 100644 --- a/vlib/x/json2/decode_sumtype.v +++ b/vlib/x/json2/decode_sumtype.v @@ -111,7 +111,8 @@ fn (mut decoder Decoder) get_array_type_workaround[T](initialized_sumtype T) boo $for v in initialized_sumtype.variants { if initialized_sumtype is v { $if initialized_sumtype is $array { - return decoder.check_element_type_valid(initialized_sumtype, decoder.current_node) + return decoder.check_element_type_valid(initialized_sumtype, + decoder.current_node) } } } diff --git a/vlib/x/json2/encode.v b/vlib/x/json2/encode.v index ae5908316e..7069a8752e 100644 --- a/vlib/x/json2/encode.v +++ b/vlib/x/json2/encode.v @@ -64,10 +64,16 @@ fn (mut encoder Encoder) encode_value[T](val T) { encoder.encode_number(f64(val)) } $else $if T.unaliased_typ is voidptr { encoder.encode_number(0) + } $else $if T is $pointer { + if voidptr(val) == unsafe { nil } { + encoder.encode_null() + } else { + encoder.encode_value(*val) + } } $else $if T.unaliased_typ is $array_fixed { encoder.output << `[` - for i, item in val { - encoder.encode_value(item) + for i in 0 .. val.len { + encoder.encode_value(val[i]) if i < val.len - 1 { encoder.output << `,` } @@ -125,11 +131,21 @@ fn (mut encoder Encoder) encode_value[T](val T) { } $else $if T.unaliased_typ is $sumtype { encoder.encode_sumtype[T](val) } $else $if T is JsonEncoder { // uses T, because alias could be implementing JsonEncoder, while the base type does not - encoder.encode_custom[T](val) + integer_val := val.to_json() + unsafe { encoder.output.push_many(integer_val.str, integer_val.len) } } $else $if T is Encodable { // uses T, because alias could be implementing JsonEncoder, while the base type does not - encoder.encode_custom2[T](val) + integer_val := val.json_str() + unsafe { encoder.output.push_many(integer_val.str, integer_val.len) } } $else $if T.unaliased_typ is $struct { - unsafe { encoder.encode_struct[T](val) } + unsafe { + encoder.output << `{` + is_first := encoder.encode_struct_fields[T](val, true, [], '') + if encoder.prettify && !is_first { + encoder.decrement_level() + encoder.add_indent() + } + encoder.output << `}` + } } } @@ -190,7 +206,9 @@ fn (mut encoder Encoder) encode_string(val string) { } else { if character < 0x20 { // control characters - unsafe { encoder.output.push_many(val.str + buffer_start, buffer_end - buffer_start) } + unsafe { + encoder.output.push_many(val.str + buffer_start, buffer_end - buffer_start) + } buffer_end++ buffer_start = buffer_end @@ -205,7 +223,10 @@ fn (mut encoder Encoder) encode_string(val string) { } if encoder.escape_unicode { if character >= 0b1111_0000 { // four bytes - unsafe { encoder.output.push_many(val.str + buffer_start, buffer_end - buffer_start) } + unsafe { + encoder.output.push_many(val.str + buffer_start, + buffer_end - buffer_start) + } unicode_point_low := val[buffer_end..buffer_end + 4].bytes().byterune() or { 0 } - 0x10000 @@ -220,7 +241,10 @@ fn (mut encoder Encoder) encode_string(val string) { continue } else if character >= 0b1110_0000 { // three bytes - unsafe { encoder.output.push_many(val.str + buffer_start, buffer_end - buffer_start) } + unsafe { + encoder.output.push_many(val.str + buffer_start, + buffer_end - buffer_start) + } hex_string := '\\u${val[buffer_end..buffer_end + 3].bytes().byterune() or { 0 }:04x}' @@ -232,7 +256,10 @@ fn (mut encoder Encoder) encode_string(val string) { continue } else if character >= 0b1100_0000 { // two bytes - unsafe { encoder.output.push_many(val.str + buffer_start, buffer_end - buffer_start) } + unsafe { + encoder.output.push_many(val.str + buffer_start, + buffer_end - buffer_start) + } hex_string := '\\u${val[buffer_end..buffer_end + 2].bytes().byterune() or { 0 }:04x}' @@ -400,9 +427,14 @@ fn (mut encoder Encoder) encode_enum[T](val T) { } fn (mut encoder Encoder) encode_sumtype[T](val T) { - $for variant in T.variants { - if val is variant { - encoder.encode_value(val) + $if T is $pointer { + // Pointer types are handled by encode_value's $pointer branch; + // this instantiation is generated but never called. + } $else { + $for variant in T.variants { + if val is variant { + encoder.encode_value(val) + } } } } diff --git a/vlib/x/json2/scanner.v b/vlib/x/json2/scanner.v index cb43326e1c..6cbe64fbb8 100644 --- a/vlib/x/json2/scanner.v +++ b/vlib/x/json2/scanner.v @@ -551,17 +551,15 @@ fn (mut s ReaderScanner) text_scan(line int, col int) !Token { for _ in 0 .. 4 { digit_line, digit_col := s.line, s.col if !s.has_next_byte()! { - return new_scan_error('incomplete unicode escape', escape_line, - escape_col) + return new_scan_error('incomplete unicode escape', escape_line, escape_col) } digit := s.ch if digit == `"` { - return new_scan_error('unicode escape must have 4 hex digits', - digit_line, digit_col) + return new_scan_error('unicode escape must have 4 hex digits', digit_line, + digit_col) } else if !digit.is_hex_digit() { x := digit.ascii_str() - return new_scan_error('`${x}` is not a hex digit', digit_line, - digit_col) + return new_scan_error('`${x}` is not a hex digit', digit_line, digit_col) } codepoint << digit _ = s.read_byte()! @@ -612,8 +610,7 @@ fn (mut s ReaderScanner) num_scan(line int, col int) !Token { digits << first _ = s.read_byte()! if s.has_next_byte()! && s.ch.is_digit() { - return new_scan_error('leading zeroes in a number are not allowed', line, - col) + return new_scan_error('leading zeroes in a number are not allowed', line, col) } } } diff --git a/vlib/x/json2/strict/strict.v b/vlib/x/json2/strict/strict.v index 74d1464866..d66e6fbf4a 100644 --- a/vlib/x/json2/strict/strict.v +++ b/vlib/x/json2/strict/strict.v @@ -80,14 +80,12 @@ fn check[T](val T, tokens []string, mut duplicates []string, mut superfluous []s } } -fn get_superfluous_keys[T](key_struct []KeyStruct) []string { +fn get_superfluous_keys[T](key_struct []x.json2.strict.KeyStruct) []string { mut superfluous := []string{} struct_keys := get_keys_from_[T]() - json_keys := key_struct.map(fn (json_key KeyStruct) string { - return json_key.key - }) + json_keys := key_struct.map(it.key) for json_key in json_keys { if !struct_keys.contains(json_key) { @@ -97,7 +95,7 @@ fn get_superfluous_keys[T](key_struct []KeyStruct) []string { return superfluous } -fn get_duplicates_keys(key_struct []KeyStruct) []string { +fn get_duplicates_keys(key_struct []x.json2.strict.KeyStruct) []string { json_keys := key_struct.map(it.key).sorted() return arrays.uniq_only_repeated(json_keys) } @@ -113,7 +111,7 @@ fn get_keys_from_[T]() []string { } // get_keys_from_json . -pub fn get_keys_from_json(tokens []string) []KeyStruct { +pub fn get_keys_from_json(tokens []string) []x.json2.strict.KeyStruct { mut key_structs := []KeyStruct{} mut nested_map_count := 0 diff --git a/vlib/x/json2/tests/encode_embedded_structs_test.v b/vlib/x/json2/tests/encode_embedded_structs_test.v index e72ee39346..f9ee85d92e 100644 --- a/vlib/x/json2/tests/encode_embedded_structs_test.v +++ b/vlib/x/json2/tests/encode_embedded_structs_test.v @@ -76,7 +76,8 @@ fn test_decode_embed_roundtrip_with_flattened_keys() { } fn test_decode_embed_with_nested_objects() { - decoded := json.decode[Classifier]('{"History":{"history_events":[{"Environment":{"vflags":"legacy"}}]}}')! + decoded := + json.decode[Classifier]('{"History":{"history_events":[{"Environment":{"vflags":"legacy"}}]}}')! assert decoded.history_events.len == 1 assert decoded.history_events[0].Environment.vflags == 'legacy' } diff --git a/vlib/x/sessions/memory_store.v b/vlib/x/sessions/memory_store.v index 25b80fe948..d8247b2310 100644 --- a/vlib/x/sessions/memory_store.v +++ b/vlib/x/sessions/memory_store.v @@ -2,7 +2,7 @@ module sessions import time -struct MemoryStoreSessions[T] { +pub struct MemoryStoreSessions[T] { pub mut: created_at time.Time data T diff --git a/vlib/x/templating/dtm/dynamic_template_manager.v b/vlib/x/templating/dtm/dynamic_template_manager.v index 34d0c575f8..b831036991 100644 --- a/vlib/x/templating/dtm/dynamic_template_manager.v +++ b/vlib/x/templating/dtm/dynamic_template_manager.v @@ -299,7 +299,8 @@ pub fn (mut tm DynamicTemplateManager) expand(tmpl_path string, tmpl_var Templat tmpl_var.placeholders) or { return err.msg() } converted_cache_delay_expiration := i64(tmpl_var.cache_delay_expiration) * convert_seconds // If cache exist, return necessary fields else, 'is_cache_exist' return false. - is_cache_exist, id, path, mut last_template_mod, gen_at, cache_del_exp, content_checksum := tm.return_cache_info_isexistent(file_path) + is_cache_exist, id, path, mut last_template_mod, gen_at, cache_del_exp, content_checksum := + tm.return_cache_info_isexistent(file_path) mut html := '' // Definition of several variables used to assess the need for cache updates.sss // This determination is based on modifications within the HTML template itself. @@ -315,9 +316,9 @@ pub fn (mut tm DynamicTemplateManager) expand(tmpl_path string, tmpl_var Templat } // From this point, all the previously encountered variables are used to determine the routing in rendering the HTML template and creating/using its cache. - cash_req, unique_time := tm.cache_request_route(is_cache_exist, converted_cache_delay_expiration, - last_template_mod, test_current_template_mod, cache_del_exp, gen_at, tm.c_time, - content_checksum, current_content_checksum) + cash_req, unique_time := tm.cache_request_route(is_cache_exist, + converted_cache_delay_expiration, last_template_mod, test_current_template_mod, + cache_del_exp, gen_at, tm.c_time, content_checksum, current_content_checksum) // Each of these match statements aims to provide HTML rendering, but each one sends a specific signal 'cash_req' of type CacheRequest // or calls the appropriate function for managing the cache of the provided HTML. match cash_req { @@ -518,8 +519,7 @@ fn (mut tm DynamicTemplateManager) create_template_cache_and_display(tcs CacheRe return internat_server_error } // Parses the template and stores the rendered output in the variable. See the function itself for more details. - mut html := tm.parse_tmpl_file(file_path, tmpl_name, placeholders, tm.compress_html, - tmpl_type) + mut html := tm.parse_tmpl_file(file_path, tmpl_name, placeholders, tm.compress_html, tmpl_type) // If caching is enabled and the template content is valid, this section creates a temporary cache file, which is then used by the cache manager. // If successfully temporary is created, a cache creation/update notification is sent through its dedicated channel to the cache manager if cache_delay_expiration != -1 && html != internat_server_error && tm.active_cache_server { @@ -783,8 +783,8 @@ fn (mut tm DynamicTemplateManager) cache_handler() { } } if tc.cache_request == .new { - tm.chandler_remaining_cache_template_used(tc.cache_request, - tc.id, tm.id_to_handlered) + tm.chandler_remaining_cache_template_used(tc.cache_request, tc.id, + tm.id_to_handlered) // Increment ID counter for the next creation/update cache request tm.id_counter++ } else { @@ -797,7 +797,8 @@ fn (mut tm DynamicTemplateManager) cache_handler() { tc.id, tm.id_to_handlered) if test_b { // Finding position of cache in database ( If disk mode, cache is erased ) - key, is_success := tm.chandler_clear_specific_cache(tm.id_to_handlered) + key, is_success := + tm.chandler_clear_specific_cache(tm.id_to_handlered) if !is_success { break } @@ -883,7 +884,8 @@ fn (mut tm DynamicTemplateManager) chandler_clear_specific_cache(id int) (int, b match value.cache_storage_mode { .memory {} .disk { - file_path := os.join_path(tm.template_cache_folder, '${value.name}_${value.checksum}.cache') + file_path := os.join_path(tm.template_cache_folder, + '${value.name}_${value.checksum}.cache') os.rm(file_path) or { eprintln('${message_signature_error} While deleting the specific cache file: ${file_path}, cache server will be stopped, you need to fix and restart application: : ${err.msg()}') break diff --git a/vlib/x/templating/dtm/dynamic_template_manager_cache_system_test.v b/vlib/x/templating/dtm/dynamic_template_manager_cache_system_test.v index 85803035a3..031598c45e 100644 --- a/vlib/x/templating/dtm/dynamic_template_manager_cache_system_test.v +++ b/vlib/x/templating/dtm/dynamic_template_manager_cache_system_test.v @@ -78,7 +78,8 @@ fn test_chandler_clear_specific_cache() { dtmi.create_cache() if !dtmi.abort_test { lock dtmi.template_caches { - cache_file := os.join_path(dtmi.template_cache_folder, '${dtmi.template_caches[0].name}_${dtmi.template_caches[0].checksum}.cache') + cache_file := os.join_path(dtmi.template_cache_folder, + '${dtmi.template_caches[0].name}_${dtmi.template_caches[0].checksum}.cache') index, is_success := dtmi.chandler_clear_specific_cache(dtmi.template_caches[0].id) assert is_success == true assert index == 0 diff --git a/vlib/x/templating/dtm/dynamic_template_manager_test.v b/vlib/x/templating/dtm/dynamic_template_manager_test.v index 4dc9647bda..5a89c6d235 100644 --- a/vlib/x/templating/dtm/dynamic_template_manager_test.v +++ b/vlib/x/templating/dtm/dynamic_template_manager_test.v @@ -242,8 +242,7 @@ fn test_chandler_remaining_cache_template_used() { need_to_delete: true } } - mut can_delete := dtmi.chandler_remaining_cache_template_used(CacheRequest.update, - 3, 3) + mut can_delete := dtmi.chandler_remaining_cache_template_used(CacheRequest.update, 3, 3) assert can_delete == true can_delete = dtmi.chandler_remaining_cache_template_used(CacheRequest.update, 2, 2) assert can_delete == false @@ -286,32 +285,32 @@ fn test_cache_request_route() { mut current_content_checksum := 'checksumtest2' mut request_type, _ := dtmi.cache_request_route(is_cache_exist, cache_delay_expiration, - last_template_mod, test_current_template_mod, cache_del_exp, gen_at, get_current_unix_micro_timestamp(), - content_checksum, current_content_checksum) + last_template_mod, test_current_template_mod, cache_del_exp, gen_at, + get_current_unix_micro_timestamp(), content_checksum, current_content_checksum) assert request_type == CacheRequest.update current_content_checksum = 'checksumtest1' request_type, _ = dtmi.cache_request_route(is_cache_exist, cache_delay_expiration, - last_template_mod, test_current_template_mod, cache_del_exp, gen_at, get_current_unix_micro_timestamp(), - content_checksum, current_content_checksum) + last_template_mod, test_current_template_mod, cache_del_exp, gen_at, + get_current_unix_micro_timestamp(), content_checksum, current_content_checksum) assert request_type == CacheRequest.cached gen_at = (last_template_mod - 500) request_type, _ = dtmi.cache_request_route(is_cache_exist, cache_delay_expiration, - last_template_mod, test_current_template_mod, cache_del_exp, gen_at, get_current_unix_micro_timestamp(), - content_checksum, current_content_checksum) + last_template_mod, test_current_template_mod, cache_del_exp, gen_at, + get_current_unix_micro_timestamp(), content_checksum, current_content_checksum) assert request_type == CacheRequest.exp_update is_cache_exist = false request_type, _ = dtmi.cache_request_route(is_cache_exist, cache_delay_expiration, - last_template_mod, test_current_template_mod, cache_del_exp, gen_at, get_current_unix_micro_timestamp(), - content_checksum, current_content_checksum) + last_template_mod, test_current_template_mod, cache_del_exp, gen_at, + get_current_unix_micro_timestamp(), content_checksum, current_content_checksum) assert request_type == CacheRequest.new } diff --git a/vlib/x/templating/dtm/tmpl.v b/vlib/x/templating/dtm/tmpl.v index a535f80011..b925c181a1 100644 --- a/vlib/x/templating/dtm/tmpl.v +++ b/vlib/x/templating/dtm/tmpl.v @@ -218,7 +218,8 @@ fn compile_template_file(template_file string, fn_name string, data &map[string] // an absolute path templates_folder = '' } - file_path := os.real_path(os.join_path_single(templates_folder, '${file_name}${file_ext}')) + file_path := os.real_path(os.join_path_single(templates_folder, + '${file_name}${file_ext}')) $if trace_tmpl ? { eprintln('>>> basepath: "${basepath}" , template_file: "${template_file}" , fn_name: "${fn_name}" , @include line: "${line}" , file_name: "${file_name}" , file_ext: "${file_ext}" , templates_folder: "${templates_folder}" , file_path: "${file_path}"') } @@ -324,8 +325,7 @@ fn compile_template_file(template_file string, fn_name string, data &map[string] } .js { // if line.contains('//V_TEMPLATE') { - source.writeln(insert_template_code(fn_name, tmpl_str_start, line, data, - state)) + source.writeln(insert_template_code(fn_name, tmpl_str_start, line, data, state)) //} else { // replace `$` to `\$` at first to escape JavaScript template literal syntax // source.writeln(line.replace(r'$', r'\$').replace(r'$$', r'@').replace(r'.$', diff --git a/vlib/x/ttf/render_bmp.v b/vlib/x/ttf/render_bmp.v index 008078f0da..5f7275cc4a 100644 --- a/vlib/x/ttf/render_bmp.v +++ b/vlib/x/ttf/render_bmp.v @@ -494,7 +494,7 @@ pub fn (mut bmp BitMap) get_chars_bbox(in_string string) []int { continue } // manage unicode chars like latin greek etc - c_len := ((0xe5000000 >> ((chr >> 3) & 0x1e)) & 3) + 1 + c_len := int(((u32(0xe5000000) >> ((chr >> 3) & 0x1e)) & 3) + 1) if c_len > 1 { tmp_char := utf8.get_rune(in_string, i) // dprintln("tmp_char: ${tmp_char.hex()}") @@ -566,7 +566,7 @@ pub fn (mut bmp BitMap) get_bbox(in_string string) (int, int) { continue } // manage unicode chars like latin greek etc - c_len := ((0xe5000000 >> ((chr >> 3) & 0x1e)) & 3) + 1 + c_len := int(((u32(0xe5000000) >> ((chr >> 3) & 0x1e)) & 3) + 1) if c_len > 1 { tmp_char := utf8.get_rune(in_string, i) // dprintln("tmp_char: ${tmp_char.hex()}") @@ -663,7 +663,7 @@ pub fn (mut bmp BitMap) draw_text(in_string string) (int, int) { continue } // manage unicode chars like latin greek etc - c_len := ((0xe5000000 >> ((chr >> 3) & 0x1e)) & 3) + 1 + c_len := int(((u32(0xe5000000) >> ((chr >> 3) & 0x1e)) & 3) + 1) if c_len > 1 { tmp_char := utf8.get_rune(in_string, i) // dprintln("tmp_char: ${tmp_char.hex()}") @@ -789,8 +789,8 @@ pub fn (mut bmp BitMap) draw_glyph(index u16) (int, int) { // bmp.line(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, color2) // bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color2) - bmp.quadratic(x0, y0, (prev.x + point.x) / 2, (prev.y + point.y) / 2, - prev.x, prev.y, color) + bmp.quadratic(x0, y0, (prev.x + point.x) / 2, (prev.y + point.y) / 2, prev.x, + prev.y, color) x0 = (prev.x + point.x) / 2 y0 = (prev.y + point.y) / 2 } @@ -817,8 +817,8 @@ pub fn (mut bmp BitMap) draw_glyph(index u16) (int, int) { // bmp.line(x0, y0, start_point.x, start_point.y, u32(0x00FF0000) // u32(0xFF000000)) - bmp.quadratic(x0, y0, start_point.x, start_point.y, (point.x + start_point.x) / 2, - (point.y + start_point.y) / 2, color) + bmp.quadratic(x0, y0, start_point.x, start_point.y, + (point.x + start_point.x) / 2, (point.y + start_point.y) / 2, color) } } else { // last point not in a curve diff --git a/vlib/x/ttf/ttf.v b/vlib/x/ttf/ttf.v index a6ebf8a9f0..f6672e2ffa 100644 --- a/vlib/x/ttf/ttf.v +++ b/vlib/x/ttf/ttf.v @@ -165,8 +165,8 @@ pub fn (mut tf TTF_File) get_horizontal_metrics(glyph_index u16) (int, int) { // read the last entry of the hMetrics array tf.pos = offset + u32(tf.num_of_long_hor_metrics - 1) * 4 advance_width = tf.get_u16() - tf.pos = offset + u32(tf.num_of_long_hor_metrics) * 4 + - 2 * u32(glyph_index - tf.num_of_long_hor_metrics) + tf.pos = offset + u32(tf.num_of_long_hor_metrics) * 4 + 2 * u32(glyph_index - + tf.num_of_long_hor_metrics) left_side_bearing = tf.get_fword() } tf.pos = old_pos @@ -611,7 +611,7 @@ fn (mut tf TTF_File) get_unicode_string(length int) string { for _ in 0 .. (length >> 1) { c := tf.get_u16() - c_len := ((0xe5000000 >> ((c >> 3) & 0x1e)) & 3) + 1 + c_len := int(((u32(0xe5000000) >> ((c >> 3) & 0x1e)) & 3) + 1) real_len += c_len if c_len == 1 { tmp_txt.write_u8(u8(c & 0xff)) @@ -925,8 +925,8 @@ fn (mut tm TrueTypeCmap) map_4(char_code int, mut tf TTF_File) int { if segment.start_code <= char_code && segment.end_code >= char_code { mut index := (segment.id_delta + char_code) & 0xffff if segment.id_range_offset > 0 { - glyph_index_address := u32(segment.id_range_offset) + - 2 * u32(char_code - segment.start_code) + glyph_index_address := u32(segment.id_range_offset) + 2 * u32(char_code - + segment.start_code) tf.pos = glyph_index_address index = tf.get_u16() }