diff --git a/.github/workflows/linux_ci.yml b/.github/workflows/linux_ci.yml index 9fde7851ecd1b9..c02e945a827469 100644 --- a/.github/workflows/linux_ci.yml +++ b/.github/workflows/linux_ci.yml @@ -58,6 +58,8 @@ jobs: run: v -o v2 cmd/v && ./v2 -o v3 cmd/v && ./v3 -o v4 cmd/v - name: v self compilation with -skip-unused run: v -skip-unused -o v2 cmd/v && ./v2 -skip-unused -o v3 cmd/v && ./v3 -skip-unused -o v4 cmd/v + - name: Test vlib modules with -skip-unused + run: v -skip-unused test vlib/builtin/ vlib/math vlib/flag/ vlib/os/ vlib/strconv/ - name: v doctor run: v doctor - name: Verify `v test` works @@ -178,6 +180,8 @@ jobs: - name: V self compilation with -parallel-cc run: | v -o v2 -parallel-cc cmd/v + - name: Test vlib modules with -skip-unused + run: v -skip-unused test vlib/builtin/ vlib/math vlib/flag/ vlib/os/ vlib/strconv/ - name: Build modules run: | v build-module vlib/os @@ -215,6 +219,8 @@ jobs: # uses: coverallsapp/github-action@v1.0.1 # with: # github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Test vlib modules with -skip-unused + run: v -skip-unused test vlib/builtin/ vlib/math vlib/flag/ vlib/os/ vlib/strconv/ clang: runs-on: ubuntu-20.04 @@ -277,6 +283,8 @@ jobs: - name: Build examples with -autofree run: | v -autofree -experimental -o tetris examples/tetris/tetris.v + - name: Test vlib modules with -skip-unused + run: v -skip-unused test vlib/builtin/ vlib/math vlib/flag/ vlib/os/ vlib/strconv/ - name: Build modules run: | v build-module vlib/os diff --git a/.github/workflows/macos_ci.yml b/.github/workflows/macos_ci.yml index 557bd7a261338f..3944eb8eed297b 100644 --- a/.github/workflows/macos_ci.yml +++ b/.github/workflows/macos_ci.yml @@ -94,3 +94,5 @@ jobs: run: v test examples/password/ - name: Test readline run: v test examples/readline/ + - name: Test vlib modules with -skip-unused + run: v -skip-unused test vlib/builtin/ vlib/math vlib/flag/ vlib/os/ vlib/strconv/ diff --git a/.github/workflows/windows_ci.yml b/.github/workflows/windows_ci.yml index eb8a2a6eb971d2..1fcd499052d589 100644 --- a/.github/workflows/windows_ci.yml +++ b/.github/workflows/windows_ci.yml @@ -75,6 +75,8 @@ jobs: run: v -showcc -skip-unused -prod cmd/tools/vdoctor.v - name: compile vup.v with -skip-unused and -prod run: v -showcc -skip-unused -prod cmd/tools/vup.v + - name: Test vlib modules with -skip-unused + run: v -skip-unused test vlib/builtin/ vlib/math vlib/flag/ vlib/os/ vlib/strconv/ msvc: runs-on: windows-2019 @@ -122,6 +124,8 @@ jobs: run: v build-examples - name: v2 self compilation run: v -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v + - name: Test vlib modules with -skip-unused + run: v -skip-unused test vlib/builtin/ vlib/math vlib/flag/ vlib/os/ vlib/strconv/ tcc: runs-on: windows-2019 @@ -176,6 +180,8 @@ jobs: run: v -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v && .\v3.exe -o v4.exe cmd/v - name: v2 self compilation with -gc boehm run: v -o v2.exe -gc boehm cmd/v && .\v2.exe -o v3.exe -gc boehm cmd/v && .\v3.exe -o v4.exe -gc boehm cmd/v + - name: Test vlib modules with -skip-unused + run: v -skip-unused test vlib/builtin/ vlib/math vlib/flag/ vlib/os/ vlib/strconv/ ## tcc32 # - name: Build with make.bat -tcc32 diff --git a/cmd/tools/vtest-all.v b/cmd/tools/vtest-all.v index 36b845cb80dc86..8b02a9b7f74f13 100644 --- a/cmd/tools/vtest-all.v +++ b/cmd/tools/vtest-all.v @@ -111,6 +111,10 @@ fn get_all_commands() []Command { okmsg: 'V can compile hello world with -skip-unused.' rmfile: 'examples/hello_world' } + res << Command{ + line: '${vexe} -skip-unused test vlib/builtin' + okmsg: 'V can test vlib/builtin with -skip-unused' + } res << Command{ line: '${vexe} -skip-unused -profile - examples/hello_world.v' okmsg: 'V can compile hello world with both -skip-unused and -profile .' diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index b409a0060e7277..b7ed8c63453575 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -52,6 +52,7 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a '_option_ok', '_result_ok', 'error', + 'ptr_str', // TODO: remove this. It is currently needed for the auto str methods for &u8, fn types, etc; See `./v -skip-unused vlib/builtin/int_test.v` // utf8_str_visible_length is used by c/str.v 'utf8_str_visible_length', 'compare_ints', diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index c21a688f6df8b6..f6c89638670e99 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -30,6 +30,25 @@ pub fn (mut w Walker) mark_fn_as_used(fkey string) { w.used_fns[fkey] = true } +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}') +} + +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}') +} + +pub fn (mut w Walker) mark_builtin_type_method_as_used(k string, rk string) { + if mut cfn := w.all_fns[k] { + w.fn_decl(mut cfn) + } + if mut cfn := w.all_fns[rk] { + w.fn_decl(mut cfn) + } + w.mark_fn_as_used(k) + w.mark_fn_as_used(rk) +} + pub fn (mut w Walker) mark_const_as_used(ckey string) { $if trace_skip_unused_marked ? { eprintln(' const > |${ckey}|') @@ -516,6 +535,21 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { if w.used_fns[fn_name] { return } + if node.is_method { + if node.left_type != 0 { + lsym := w.table.sym(node.left_type) + // Note: maps and arrays are implemented in `builtin` as concrete types `map` and `array`. + // They are not normal generics expanded, to separate structs, parametrized on the type of the element. + // All []Type or map[Type]Another types are typedefs to those `map` and `array` types, and all map and array methods + // are actually methods on the `builtin` concrete types. + match lsym.kind { + .array { w.mark_builtin_array_method_as_used(node.name) } + .map { w.mark_builtin_map_method_as_used(node.name) } + else {} + } + } + } + w.mark_fn_as_used(fn_name) if node.is_method && node.receiver_type.has_flag(.generic) && node.receiver_concrete_type != 0 && !node.receiver_concrete_type.has_flag(.generic) { diff --git a/vlib/v/tests/skip_unused/string_array_methods.run.out b/vlib/v/tests/skip_unused/string_array_methods.run.out new file mode 100644 index 00000000000000..1819af9b55fbb2 --- /dev/null +++ b/vlib/v/tests/skip_unused/string_array_methods.run.out @@ -0,0 +1,2 @@ +[vlib/v/tests/skip_unused/string_array_methods.vv:11] aa: ['hi', '1', '5', '3'] +[vlib/v/tests/skip_unused/string_array_methods.vv:12] bb: ['1', '3', '5', 'hi'] diff --git a/vlib/v/tests/skip_unused/string_array_methods.skip_unused.run.out b/vlib/v/tests/skip_unused/string_array_methods.skip_unused.run.out new file mode 100644 index 00000000000000..1819af9b55fbb2 --- /dev/null +++ b/vlib/v/tests/skip_unused/string_array_methods.skip_unused.run.out @@ -0,0 +1,2 @@ +[vlib/v/tests/skip_unused/string_array_methods.vv:11] aa: ['hi', '1', '5', '3'] +[vlib/v/tests/skip_unused/string_array_methods.vv:12] bb: ['1', '3', '5', 'hi'] diff --git a/vlib/v/tests/skip_unused/string_array_methods.vv b/vlib/v/tests/skip_unused/string_array_methods.vv new file mode 100644 index 00000000000000..89835d4c7fe1d6 --- /dev/null +++ b/vlib/v/tests/skip_unused/string_array_methods.vv @@ -0,0 +1,12 @@ +aa := ['hi', '1', '5', '3'] +bb := aa.sorted_with_compare(fn (a &string, b &string) int { + if a < b { + return -1 + } + if a > b { + return 1 + } + return 0 +}) +dump(aa) +dump(bb)