diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-01-17 20:09:08 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-17 20:09:08 +0000 |
commit | 15d1635e50896002fbd4ebbc896b78a155b2487d (patch) | |
tree | 39de10ff0adf9f2b3cd418504a0b12130699d2a0 /src/eval.c | |
parent | 3f3597be3ffa9ae226b2e9831e4ed64c8ae43c42 (diff) | |
download | vim-git-15d1635e50896002fbd4ebbc896b78a155b2487d.tar.gz |
patch 8.2.4123: complete function cannot be import.Namev8.2.4123
Problem: Complete function cannot be import.Name.
Solution: Dereference the function name if needed. Also: do not see
"import.Name" as a builtin function. (closes #9541)
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 118 |
1 files changed, 73 insertions, 45 deletions
diff --git a/src/eval.c b/src/eval.c index a21fbba85..df73ba1ae 100644 --- a/src/eval.c +++ b/src/eval.c @@ -626,6 +626,63 @@ eval_expr(char_u *arg, exarg_T *eap) } /* + * "*arg" points to what can be a function name in the form of "import.Name" or + * "Funcref". Return the name of the function. Set "tofree" to something that + * was allocated. + * If "verbose" is FALSE no errors are given. + * Return NULL for any failure. + */ + static char_u * +deref_function_name( + char_u **arg, + char_u **tofree, + evalarg_T *evalarg, + int verbose) +{ + typval_T ref; + char_u *name = *arg; + + ref.v_type = VAR_UNKNOWN; + if (eval7(arg, &ref, evalarg, FALSE) == FAIL) + return NULL; + if (*skipwhite(*arg) != NUL) + { + if (verbose) + semsg(_(e_trailing_characters_str), *arg); + name = NULL; + } + else if (ref.v_type == VAR_FUNC && ref.vval.v_string != NULL) + { + name = ref.vval.v_string; + ref.vval.v_string = NULL; + *tofree = name; + } + else if (ref.v_type == VAR_PARTIAL && ref.vval.v_partial != NULL) + { + if (ref.vval.v_partial->pt_argc > 0 + || ref.vval.v_partial->pt_dict != NULL) + { + if (verbose) + emsg(_(e_cannot_use_partial_here)); + name = NULL; + } + else + { + name = vim_strsave(partial_name(ref.vval.v_partial)); + *tofree = name; + } + } + else + { + if (verbose) + semsg(_(e_not_callable_type_str), name); + name = NULL; + } + clear_tv(&ref); + return name; +} + +/* * Call some Vim script function and return the result in "*rettv". * Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] * should have type VAR_UNKNOWN. @@ -640,15 +697,27 @@ call_vim_function( { int ret; funcexe_T funcexe; + char_u *arg; + char_u *name; + char_u *tofree = NULL; rettv->v_type = VAR_UNKNOWN; // clear_tv() uses this CLEAR_FIELD(funcexe); funcexe.fe_firstline = curwin->w_cursor.lnum; funcexe.fe_lastline = curwin->w_cursor.lnum; funcexe.fe_evaluate = TRUE; - ret = call_func(func, -1, rettv, argc, argv, &funcexe); + + // The name might be "import.Func" or "Funcref". + arg = func; + name = deref_function_name(&arg, &tofree, &EVALARG_EVALUATE, FALSE); + if (name == NULL) + name = func; + + ret = call_func(name, -1, rettv, argc, argv, &funcexe); + if (ret == FAIL) clear_tv(rettv); + vim_free(tofree); return ret; } @@ -3979,57 +4048,16 @@ eval_method( if (**arg != '(' && alias == NULL && (paren = vim_strchr(*arg, '(')) != NULL) { - typval_T ref; - *arg = name; *paren = NUL; - ref.v_type = VAR_UNKNOWN; - if (eval7(arg, &ref, evalarg, FALSE) == FAIL) + name = deref_function_name(arg, &tofree, evalarg, verbose); + if (name == NULL) { *arg = name + len; ret = FAIL; } - else if (*skipwhite(*arg) != NUL) - { - if (verbose) - semsg(_(e_trailing_characters_str), *arg); - ret = FAIL; - } - else if (ref.v_type == VAR_FUNC && ref.vval.v_string != NULL) - { - name = ref.vval.v_string; - ref.vval.v_string = NULL; - tofree = name; - len = STRLEN(name); - } - else if (ref.v_type == VAR_PARTIAL && ref.vval.v_partial != NULL) - { - if (ref.vval.v_partial->pt_argc > 0 - || ref.vval.v_partial->pt_dict != NULL) - { - emsg(_(e_cannot_use_partial_here)); - ret = FAIL; - } - else - { - name = vim_strsave(partial_name(ref.vval.v_partial)); - tofree = name; - if (name == NULL) - { - ret = FAIL; - name = *arg; - } - else - len = STRLEN(name); - } - } else - { - if (verbose) - semsg(_(e_not_callable_type_str), name); - ret = FAIL; - } - clear_tv(&ref); + len = STRLEN(name); *paren = '('; } |