mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.0693: closure using argument not tested
Problem: Closure using argument not tested. Solution: Add a test, make it work.
This commit is contained in:
@@ -700,5 +700,26 @@ def Test_closure_two_indirect_refs()
|
|||||||
unlet g:Read
|
unlet g:Read
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def MakeArgRefs(theArg: string)
|
||||||
|
let local = 'loc_val'
|
||||||
|
g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
|
||||||
|
let local = 'the_loc'
|
||||||
|
g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_closure_using_argument()
|
||||||
|
MakeArgRefs('arg_val')
|
||||||
|
assert_equal('arg_val/loc_val/call_val', g:UseArg('call_val'))
|
||||||
|
|
||||||
|
MakeArgRefsVarargs('arg_val', 'one', 'two')
|
||||||
|
assert_equal('arg_val/the_loc/call_val/one two', g:UseVararg('call_val'))
|
||||||
|
|
||||||
|
unlet g:UseArg
|
||||||
|
unlet g:UseVararg
|
||||||
|
enddef
|
||||||
|
|
||||||
|
|
||||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||||
|
@@ -746,6 +746,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
693,
|
||||||
/**/
|
/**/
|
||||||
692,
|
692,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -186,37 +186,74 @@ lookup_local(char_u *name, size_t len, cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup an argument in the current function.
|
* Lookup an argument in the current function and an enclosing function.
|
||||||
* Returns the argument index or -1 if not found.
|
* Returns the argument index in "idxp"
|
||||||
|
* Returns the argument type in "type"
|
||||||
|
* Sets "gen_load_outer" to TRUE if found in outer scope.
|
||||||
|
* Returns OK when found, FAIL otherwise.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
lookup_arg(char_u *name, size_t len, cctx_T *cctx)
|
lookup_arg(
|
||||||
|
char_u *name,
|
||||||
|
size_t len,
|
||||||
|
int *idxp,
|
||||||
|
type_T **type,
|
||||||
|
int *gen_load_outer,
|
||||||
|
cctx_T *cctx)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
char_u *va_name;
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return -1;
|
return FAIL;
|
||||||
for (idx = 0; idx < cctx->ctx_ufunc->uf_args.ga_len; ++idx)
|
for (idx = 0; idx < cctx->ctx_ufunc->uf_args.ga_len; ++idx)
|
||||||
{
|
{
|
||||||
char_u *arg = FUNCARG(cctx->ctx_ufunc, idx);
|
char_u *arg = FUNCARG(cctx->ctx_ufunc, idx);
|
||||||
|
|
||||||
if (STRNCMP(name, arg, len) == 0 && STRLEN(arg) == len)
|
if (STRNCMP(name, arg, len) == 0 && arg[len] == NUL)
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Lookup a vararg argument in the current function.
|
|
||||||
* Returns TRUE if there is a match.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
lookup_vararg(char_u *name, size_t len, cctx_T *cctx)
|
|
||||||
{
|
{
|
||||||
char_u *va_name = cctx->ctx_ufunc->uf_va_name;
|
if (idxp != NULL)
|
||||||
|
{
|
||||||
|
// Arguments are located above the frame pointer. One further
|
||||||
|
// if there is a vararg argument
|
||||||
|
*idxp = idx - (cctx->ctx_ufunc->uf_args.ga_len
|
||||||
|
+ STACK_FRAME_SIZE)
|
||||||
|
+ (cctx->ctx_ufunc->uf_va_name != NULL ? -1 : 0);
|
||||||
|
|
||||||
return len > 0 && va_name != NULL
|
if (cctx->ctx_ufunc->uf_arg_types != NULL)
|
||||||
&& STRNCMP(name, va_name, len) == 0 && STRLEN(va_name) == len;
|
*type = cctx->ctx_ufunc->uf_arg_types[idx];
|
||||||
|
else
|
||||||
|
*type = &t_any;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_name = cctx->ctx_ufunc->uf_va_name;
|
||||||
|
if (va_name != NULL
|
||||||
|
&& STRNCMP(name, va_name, len) == 0 && va_name[len] == NUL)
|
||||||
|
{
|
||||||
|
if (idxp != NULL)
|
||||||
|
{
|
||||||
|
// varargs is always the last argument
|
||||||
|
*idxp = -STACK_FRAME_SIZE - 1;
|
||||||
|
*type = cctx->ctx_ufunc->uf_va_type;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cctx->ctx_outer != NULL)
|
||||||
|
{
|
||||||
|
// Lookup the name for an argument of the outer function.
|
||||||
|
if (lookup_arg(name, len, idxp, type, gen_load_outer, cctx->ctx_outer)
|
||||||
|
== OK)
|
||||||
|
{
|
||||||
|
*gen_load_outer = TRUE;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1584,7 +1621,7 @@ reserve_local(cctx_T *cctx, char_u *name, size_t len, int isConst, type_T *type)
|
|||||||
{
|
{
|
||||||
lvar_T *lvar;
|
lvar_T *lvar;
|
||||||
|
|
||||||
if (lookup_arg(name, len, cctx) >= 0 || lookup_vararg(name, len, cctx))
|
if (lookup_arg(name, len, NULL, NULL, NULL, cctx) == OK)
|
||||||
{
|
{
|
||||||
emsg_namelen(_("E1006: %s is used as an argument"), name, (int)len);
|
emsg_namelen(_("E1006: %s is used as an argument"), name, (int)len);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -2452,25 +2489,9 @@ compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error)
|
|||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
idx = lookup_arg(*arg, len, cctx);
|
if (lookup_arg(*arg, len, &idx, &type, &gen_load_outer, cctx) == OK)
|
||||||
if (idx >= 0)
|
|
||||||
{
|
{
|
||||||
if (cctx->ctx_ufunc->uf_arg_types != NULL)
|
if (!gen_load_outer)
|
||||||
type = cctx->ctx_ufunc->uf_arg_types[idx];
|
|
||||||
else
|
|
||||||
type = &t_any;
|
|
||||||
|
|
||||||
// Arguments are located above the frame pointer.
|
|
||||||
idx -= cctx->ctx_ufunc->uf_args.ga_len + STACK_FRAME_SIZE;
|
|
||||||
if (cctx->ctx_ufunc->uf_va_name != NULL)
|
|
||||||
--idx;
|
|
||||||
gen_load = TRUE;
|
|
||||||
}
|
|
||||||
else if (lookup_vararg(*arg, len, cctx))
|
|
||||||
{
|
|
||||||
// varargs is always the last argument
|
|
||||||
idx = -STACK_FRAME_SIZE - 1;
|
|
||||||
type = cctx->ctx_ufunc->uf_va_type;
|
|
||||||
gen_load = TRUE;
|
gen_load = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user