From 1df8b3fb04ce8732a0be680273c95eb4e9f5e85d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 23 Apr 2020 18:13:23 +0200 Subject: patch 8.2.0625: Vim9: confusing error when calling unknown function Problem: Vim9: confusing error when calling unknown function. Solution: Give error while compiling. --- src/testdir/test_vim9_func.vim | 27 ++++++++++++++++++--------- src/version.c | 2 ++ src/vim9compile.c | 8 ++++++-- src/vim9execute.c | 21 ++++++++++++++------- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 8a6c3d607a..d36467996f 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -193,10 +193,23 @@ def Test_using_var_as_arg() enddef def Test_call_func_defined_later() - call assert_equal('one', DefinedLater('one')) + call assert_equal('one', g:DefinedLater('one')) call assert_fails('call NotDefined("one")', 'E117:') enddef +func DefinedLater(arg) + return a:arg +endfunc + +def Test_call_funcref() + assert_equal(3, g:SomeFunc('abc')) + assert_fails('NotAFunc()', 'E117:') + assert_fails('g:NotAFunc()', 'E117:') +enddef + +let SomeFunc = function('len') +let NotAFunc = 'text' + def CombineFuncrefTypes() " same arguments, different return type let Ref1: func(bool): string @@ -217,12 +230,8 @@ def CombineFuncrefTypes() Refb3 = g:cond ? Refb1 : Refb2 enddef -func DefinedLater(arg) - return a:arg -endfunc - def FuncWithForwardCall() - return DefinedEvenLater("yes") + return g:DefinedEvenLater("yes") enddef def DefinedEvenLater(arg: string): string @@ -372,9 +381,9 @@ def Test_redef_failure() so Xdef call delete('Xdef') - call assert_equal(0, Func0()) - call assert_equal('Func1', Func1()) - call assert_equal('Func2', Func2()) + call assert_equal(0, g:Func0()) + call assert_equal('Func1', g:Func1()) + call assert_equal('Func2', g:Func2()) delfunc! Func0 delfunc! Func1 diff --git a/src/version.c b/src/version.c index 86cfce0957..da1c24326a 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 625, /**/ 624, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index 393d2b824c..7e1c22e8b5 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2463,8 +2463,12 @@ compile_call(char_u **arg, size_t varlen, cctx_T *cctx, int argcount_init) goto theend; } - // The function may be defined only later. Need to figure out at runtime. - res = generate_UCALL(cctx, name, argcount); + // A global function may be defined only later. Need to figure out at + // runtime. + if (STRNCMP(namebuf, "g:", 2) == 0) + res = generate_UCALL(cctx, name, argcount); + else + semsg(_(e_unknownfunc), namebuf); theend: vim_free(tofree); diff --git a/src/vim9execute.c b/src/vim9execute.c index 6c8b8c86ea..a98e7e3265 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -460,13 +460,20 @@ call_eval_func(char_u *name, int argcount, ectx_T *ectx, isn_T *iptr) if (call_by_name(name, argcount, ectx, iptr) == FAIL && called_emsg == called_emsg_before) { - // "name" may be a variable that is a funcref or partial - // if find variable - // call_partial() - // else - // semsg(_(e_unknownfunc), name); - emsg("call_eval_func(partial) not implemented yet"); - return FAIL; + dictitem_T *v; + + v = find_var(name, NULL, FALSE); + if (v == NULL) + { + semsg(_(e_unknownfunc), name); + return FAIL; + } + if (v->di_tv.v_type != VAR_PARTIAL && v->di_tv.v_type != VAR_FUNC) + { + semsg(_(e_unknownfunc), name); + return FAIL; + } + return call_partial(&v->di_tv, argcount, ectx); } return OK; } -- cgit v1.2.3