vim-patch:8.2.3766: converting a funcref to a string leaves out "g:"

Problem:    Converting a funcref to a string leaves out "g:", causing the
            meaning of the name depending on the context.
Solution:   Prepend "g:" for a global function.

c4ec338fb8

Co-authored-by: Bram Moolenaar <Bram@vim.org>
Co-authored-by: Jan Edmund Lazo <jan.lazo@mail.utoronto.ca>
This commit is contained in:
zeertzjq
2025-12-19 15:27:09 +08:00
parent eac2f0443e
commit f15c28ed7a
6 changed files with 26 additions and 10 deletions

View File

@@ -74,7 +74,7 @@ static Object typval_cbuf_to_obj(EncodedData *edata, const char *data, size_t le
kvi_push(edata->stack, typval_cbuf_to_obj(edata, len_ ? blob_->bv_ga.ga_data : "", len_)); \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun, prefix) \
do { \
ufunc_T *fp = find_func(fun); \
if (fp != NULL && (fp->uf_flags & FC_LUAREF)) { \

View File

@@ -295,7 +295,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
const char *const buf_ = (buf); \
if ((buf) == NULL) { \
if (buf_ == NULL) { \
ga_concat(gap, "''"); \
} else { \
const size_t len_ = (len); \
@@ -370,15 +370,21 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
} \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun, prefix) \
do { \
const char *const fun_ = (fun); \
if (fun_ == NULL) { \
internal_error("string(): NULL function name"); \
ga_concat(gap, "function(NULL"); \
} else { \
const char *const prefix_ = (prefix); \
ga_concat(gap, "function("); \
const int name_off = gap->ga_len; \
ga_concat(gap, prefix_); \
TYPVAL_ENCODE_CONV_STRING(tv, fun_, strlen(fun_)); \
/* <prefix>'<fun>' -> '<prefix><fun>'. */ \
((char *)gap->ga_data)[name_off] = '\''; \
memcpy((char *)gap->ga_data + name_off + 1, prefix_, strlen(prefix_)); \
} \
} while (0)
@@ -748,7 +754,7 @@ static inline int convert_to_json_string(garray_T *const gap, const char *const
} while (0)
#undef TYPVAL_ENCODE_CONV_FUNC_START
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun, prefix) \
return conv_error(_("E474: Error while dumping %s, %s: " \
"attempt to dump function reference"), \
mpstack, objname)
@@ -932,7 +938,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
mpack_float8(&packer->ptr, (double)(flt))
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun, prefix) \
return conv_error(_("E5004: Error while dumping %s, %s: " \
"attempt to dump function reference"), \
mpstack, objname)

View File

@@ -3436,7 +3436,7 @@ static inline int _nothing_conv_func_start(typval_T *const tv, char *const fun)
}
return NOTDONE;
}
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun, prefix) \
do { \
if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
return OK; \

View File

@@ -102,6 +102,7 @@
///
/// @param tv Pointer to typval where value is stored. May not be NULL.
/// @param fun Function name. May be NULL.
/// @param prefix Prefix for converting to a string.
/// @def TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
/// @brief Macros used before starting to convert partial arguments
@@ -344,15 +345,19 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
tv_blob_len(tv->vval.v_blob));
break;
case VAR_FUNC:
TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string);
TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string, "");
TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
TYPVAL_ENCODE_CONV_FUNC_END(tv);
break;
case VAR_PARTIAL: {
partial_T *const pt = tv->vval.v_partial;
(void)pt;
TYPVAL_ENCODE_CONV_FUNC_START(tv, (pt == NULL ? NULL : partial_name(pt)));
char *const fun = pt == NULL ? NULL : partial_name(pt);
// When using uf_name prepend "g:" for a global function.
const char *const prefix = fun != NULL && pt->pt_name == NULL
&& ASCII_ISUPPER(fun[0]) ? "g:" : "";
(void)prefix;
TYPVAL_ENCODE_CONV_FUNC_START(tv, fun, prefix);
kvi_push(*mpstack, ((MPConvStackVal) {
.type = kMPConvPartial,
.tv = tv,

View File

@@ -453,7 +453,7 @@ static bool typval_conv_special = false;
lua_pushlstring(lstate, blob_ != NULL ? blob_->bv_ga.ga_data : "", (size_t)(len)); \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun, prefix) \
do { \
ufunc_T *fp = find_func(fun); \
if (fp != NULL && fp->uf_flags & FC_LUAREF) { \

View File

@@ -3719,6 +3719,11 @@ func Test_builtin_check()
unlet bar
endfunc
func Test_funcref_to_string()
let Fn = funcref('g:Test_funcref_to_string')
call assert_equal("function('g:Test_funcref_to_string')", string(Fn))
endfunc
" Test for isabsolutepath()
func Test_isabsolutepath()
call assert_false(isabsolutepath(''))