mirror of
https://github.com/neovim/neovim.git
synced 2026-07-16 14:11:28 +00:00
vim-patch:9.2.0265: unnecessary restrictions for defining dictionary function names (#38524)
Problem: unnecessary restrictions for defining dictionary function
names
Solution: Allow defining dict function with bracket key that is not a
valid identifier (thinca)
In Vim script, "function obj.func()" and "function obj['func']()" both
define a dictionary function. However, the bracket form required the
key to match function naming rules (eval_isnamec), so
"function obj['foo-bar']()" failed with E475.
Assigning and calling already work: "let obj['foo-bar'] = obj.func"
and "call obj['foo-bar']()" are valid. Only the definition was
incorrectly restricted.
Skip the identifier check when the name comes from fd_newkey (i.e. the
key was given in bracket notation). Dictionary keys may be any string.
Supported by AI
closes: vim/vim#19833
f89662722d
Co-authored-by: thinca <thinca@gmail.com>
This commit is contained in:
@@ -2737,21 +2737,27 @@ void ex_function(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) {
|
if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) {
|
||||||
char *name_base = arg;
|
char *name_base = arg;
|
||||||
if ((uint8_t)(*arg) == K_SPECIAL) {
|
// When defining a dictionary function with bracket notation
|
||||||
name_base = vim_strchr(arg, '_');
|
// (e.g. obj['foo-bar']()), the key is a dictionary key and is not
|
||||||
if (name_base == NULL) {
|
// required to follow function naming rules. Skip the identifier
|
||||||
name_base = arg + 3;
|
// check in that case.
|
||||||
} else {
|
if (arg != fudi.fd_newkey) {
|
||||||
name_base++;
|
if ((uint8_t)(*arg) == K_SPECIAL) {
|
||||||
|
name_base = vim_strchr(arg, '_');
|
||||||
|
if (name_base == NULL) {
|
||||||
|
name_base = arg + 3;
|
||||||
|
} else {
|
||||||
|
name_base++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int i;
|
||||||
|
for (i = 0; name_base[i] != NUL && (i == 0
|
||||||
|
? eval_isnamec1(name_base[i])
|
||||||
|
: eval_isnamec(name_base[i])); i++) {}
|
||||||
|
if (name_base[i] != NUL) {
|
||||||
|
emsg_funcname(e_invarg2, arg);
|
||||||
|
goto ret_free;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
int i;
|
|
||||||
for (i = 0; name_base[i] != NUL && (i == 0
|
|
||||||
? eval_isnamec1(name_base[i])
|
|
||||||
: eval_isnamec(name_base[i])); i++) {}
|
|
||||||
if (name_base[i] != NUL) {
|
|
||||||
emsg_funcname(e_invarg2, arg);
|
|
||||||
goto ret_free;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Disallow using the g: dict.
|
// Disallow using the g: dict.
|
||||||
|
|||||||
@@ -540,6 +540,18 @@ func Test_func_dict()
|
|||||||
call assert_fails('call mydict.nonexist()', 'E716:')
|
call assert_fails('call mydict.nonexist()', 'E716:')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_func_dict_bracket_key()
|
||||||
|
" Dictionary function can be defined with bracket notation using a key
|
||||||
|
" that does not follow function naming rules (e.g. containing a hyphen).
|
||||||
|
let obj = {}
|
||||||
|
function obj['foo-bar']() dict
|
||||||
|
return self.value
|
||||||
|
endfunction
|
||||||
|
let obj.value = 42
|
||||||
|
call assert_equal(42, obj['foo-bar']())
|
||||||
|
call assert_equal(42, call(obj['foo-bar'], []))
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_func_range()
|
func Test_func_range()
|
||||||
new
|
new
|
||||||
call setline(1, range(1, 8))
|
call setline(1, range(1, 8))
|
||||||
|
|||||||
Reference in New Issue
Block a user