mirror of
https://github.com/neovim/neovim.git
synced 2026-01-03 18:06:29 +10:00
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:
@@ -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)) { \
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) { \
|
||||
|
||||
@@ -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(''))
|
||||
|
||||
Reference in New Issue
Block a user