To: vim_dev@googlegroups.com Subject: Patch 8.2.0528 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0528 Problem: Vim9: function arguments insufficiently tested. Solution: Check types. Add more tests. Fix function with varargs only. Files: src/vim9compile.c, src/userfunc.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.0527/src/vim9compile.c 2020-04-07 20:53:35.218912046 +0200 --- src/vim9compile.c 2020-04-07 21:58:16.747087832 +0200 *************** *** 130,135 **** --- 130,137 ---- static int compile_expr2(char_u **arg, cctx_T *cctx); static int compile_expr3(char_u **arg, cctx_T *cctx); static void delete_def_function_contents(dfunc_T *dfunc); + static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx); + static int check_type(type_T *expected, type_T *actual, int give_msg); /* * Lookup variable "name" in the local scope and return the index. *************** *** 1240,1245 **** --- 1242,1273 ---- return FAIL; } + if (ufunc->uf_dfunc_idx >= 0) + { + int i; + + for (i = 0; i < argcount; ++i) + { + type_T *expected; + type_T *actual; + + if (i < regular_args) + { + if (ufunc->uf_arg_types == NULL) + continue; + expected = ufunc->uf_arg_types[i]; + } + else + expected = ufunc->uf_va_type->tt_member; + actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i]; + if (check_type(expected, actual, FALSE) == FAIL) + { + arg_type_mismatch(expected, actual, i + 1); + return FAIL; + } + } + } + // Turn varargs into a list. if (ufunc->uf_va_name != NULL) { *************** *** 2402,2407 **** --- 2430,2447 ---- vim_free(tofree1); vim_free(tofree2); } + + static void + arg_type_mismatch(type_T *expected, type_T *actual, int argidx) + { + char *tofree1, *tofree2; + + semsg(_("E1013: argument %d: type mismatch, expected %s but got %s"), + argidx, + type_name(expected, &tofree1), type_name(actual, &tofree2)); + vim_free(tofree1); + vim_free(tofree2); + } /* * Check if the expected and actual types match. *** ../vim-8.2.0527/src/userfunc.c 2020-04-06 22:12:57.141652839 +0200 --- src/userfunc.c 2020-04-07 21:23:21.803935303 +0200 *************** *** 3020,3026 **** if (eap->cmdidx == CMD_def) { ! int lnum_save = SOURCING_LNUM; // error messages are for the first function line SOURCING_LNUM = sourcing_lnum_top; --- 3020,3026 ---- if (eap->cmdidx == CMD_def) { ! int lnum_save = SOURCING_LNUM; // error messages are for the first function line SOURCING_LNUM = sourcing_lnum_top; *************** *** 3034,3040 **** // and uf_va_type. int len = argtypes.ga_len - (varargs ? 1 : 0); ! fp->uf_arg_types = ALLOC_CLEAR_MULT(type_T *, len); if (fp->uf_arg_types != NULL) { int i; --- 3034,3041 ---- // and uf_va_type. int len = argtypes.ga_len - (varargs ? 1 : 0); ! if (len > 0) ! fp->uf_arg_types = ALLOC_CLEAR_MULT(type_T *, len); if (fp->uf_arg_types != NULL) { int i; *** ../vim-8.2.0527/src/testdir/test_vim9_func.vim 2020-04-07 20:53:35.218912046 +0200 --- src/testdir/test_vim9_func.vim 2020-04-07 21:49:25.593250238 +0200 *************** *** 130,135 **** --- 130,148 ---- assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three')) enddef + " Only varargs + def MyVarargsOnly(...args: list): string + return join(args, ',') + enddef + + def Test_call_varargs_only() + assert_equal('', MyVarargsOnly()) + assert_equal('one', MyVarargsOnly('one')) + assert_equal('one,two', MyVarargsOnly('one', 'two')) + call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number') + call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number') + enddef + def Test_using_var_as_arg() call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef') call assert_fails('so Xdef', 'E1006:') *** ../vim-8.2.0527/src/version.c 2020-04-07 20:53:35.218912046 +0200 --- src/version.c 2020-04-07 22:03:07.101926072 +0200 *************** *** 740,741 **** --- 740,743 ---- { /* Add new patch number below this line */ + /**/ + 528, /**/ -- Females are strictly forbidden to appear unshaven in public. [real standing law in New Mexico, United States of America] /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///