• R/O
  • SSH

vim: 提交

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

修訂3055cd26e1393bb328ba10dd9f18ca44618125e3 (tree)
時間2020-04-08 05:15:05
作者Bram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.2.0528: Vim9: function arguments insufficiently tested

Commit: https://github.com/vim/vim/commit/0b76b42d0a09fb6f1ed79cfc153da4edd6154c89
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Apr 7 22:05:08 2020 +0200

patch 8.2.0528: Vim9: function arguments insufficiently tested
Problem: Vim9: function arguments insufficiently tested.
Solution: Check types. Add more tests. Fix function with varargs only.

Change Summary

差異

diff -r a456f90669a4 -r 3055cd26e139 src/testdir/test_vim9_func.vim
--- a/src/testdir/test_vim9_func.vim Tue Apr 07 21:00:05 2020 +0200
+++ b/src/testdir/test_vim9_func.vim Tue Apr 07 22:15:05 2020 +0200
@@ -130,6 +130,19 @@
130130 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
131131 enddef
132132
133+" Only varargs
134+def MyVarargsOnly(...args: list<string>): string
135+ return join(args, ',')
136+enddef
137+
138+def Test_call_varargs_only()
139+ assert_equal('', MyVarargsOnly())
140+ assert_equal('one', MyVarargsOnly('one'))
141+ assert_equal('one,two', MyVarargsOnly('one', 'two'))
142+ call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number')
143+ call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number')
144+enddef
145+
133146 def Test_using_var_as_arg()
134147 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
135148 call assert_fails('so Xdef', 'E1006:')
diff -r a456f90669a4 -r 3055cd26e139 src/userfunc.c
--- a/src/userfunc.c Tue Apr 07 21:00:05 2020 +0200
+++ b/src/userfunc.c Tue Apr 07 22:15:05 2020 +0200
@@ -3020,7 +3020,7 @@
30203020
30213021 if (eap->cmdidx == CMD_def)
30223022 {
3023- int lnum_save = SOURCING_LNUM;
3023+ int lnum_save = SOURCING_LNUM;
30243024
30253025 // error messages are for the first function line
30263026 SOURCING_LNUM = sourcing_lnum_top;
@@ -3034,7 +3034,8 @@
30343034 // and uf_va_type.
30353035 int len = argtypes.ga_len - (varargs ? 1 : 0);
30363036
3037- fp->uf_arg_types = ALLOC_CLEAR_MULT(type_T *, len);
3037+ if (len > 0)
3038+ fp->uf_arg_types = ALLOC_CLEAR_MULT(type_T *, len);
30383039 if (fp->uf_arg_types != NULL)
30393040 {
30403041 int i;
diff -r a456f90669a4 -r 3055cd26e139 src/version.c
--- a/src/version.c Tue Apr 07 21:00:05 2020 +0200
+++ b/src/version.c Tue Apr 07 22:15:05 2020 +0200
@@ -739,6 +739,8 @@
739739 static int included_patches[] =
740740 { /* Add new patch number below this line */
741741 /**/
742+ 528,
743+/**/
742744 527,
743745 /**/
744746 526,
diff -r a456f90669a4 -r 3055cd26e139 src/vim9compile.c
--- a/src/vim9compile.c Tue Apr 07 21:00:05 2020 +0200
+++ b/src/vim9compile.c Tue Apr 07 22:15:05 2020 +0200
@@ -130,6 +130,8 @@
130130 static int compile_expr2(char_u **arg, cctx_T *cctx);
131131 static int compile_expr3(char_u **arg, cctx_T *cctx);
132132 static void delete_def_function_contents(dfunc_T *dfunc);
133+static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx);
134+static int check_type(type_T *expected, type_T *actual, int give_msg);
133135
134136 /*
135137 * Lookup variable "name" in the local scope and return the index.
@@ -1240,6 +1242,32 @@
12401242 return FAIL;
12411243 }
12421244
1245+ if (ufunc->uf_dfunc_idx >= 0)
1246+ {
1247+ int i;
1248+
1249+ for (i = 0; i < argcount; ++i)
1250+ {
1251+ type_T *expected;
1252+ type_T *actual;
1253+
1254+ if (i < regular_args)
1255+ {
1256+ if (ufunc->uf_arg_types == NULL)
1257+ continue;
1258+ expected = ufunc->uf_arg_types[i];
1259+ }
1260+ else
1261+ expected = ufunc->uf_va_type->tt_member;
1262+ actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
1263+ if (check_type(expected, actual, FALSE) == FAIL)
1264+ {
1265+ arg_type_mismatch(expected, actual, i + 1);
1266+ return FAIL;
1267+ }
1268+ }
1269+ }
1270+
12431271 // Turn varargs into a list.
12441272 if (ufunc->uf_va_name != NULL)
12451273 {
@@ -2403,6 +2431,18 @@
24032431 vim_free(tofree2);
24042432 }
24052433
2434+ static void
2435+arg_type_mismatch(type_T *expected, type_T *actual, int argidx)
2436+{
2437+ char *tofree1, *tofree2;
2438+
2439+ semsg(_("E1013: argument %d: type mismatch, expected %s but got %s"),
2440+ argidx,
2441+ type_name(expected, &tofree1), type_name(actual, &tofree2));
2442+ vim_free(tofree1);
2443+ vim_free(tofree2);
2444+}
2445+
24062446 /*
24072447 * Check if the expected and actual types match.
24082448 */
Show on old repository browser