mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.0683: Vim9: parsing type does not always work
Problem: Vim9: parsing type does not always work. Solution: Handle func type without return value. Test more closures. Fix type check offset. Fix garbage collection.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
/* vim9execute.c */
|
/* vim9execute.c */
|
||||||
int call_def_function(ufunc_T *ufunc, int argc, typval_T *argv, typval_T *rettv);
|
int call_def_function(ufunc_T *ufunc, int argc_arg, typval_T *argv, typval_T *rettv);
|
||||||
void ex_disassemble(exarg_T *eap);
|
void ex_disassemble(exarg_T *eap);
|
||||||
int tv2bool(typval_T *tv);
|
int tv2bool(typval_T *tv);
|
||||||
int check_not_string(typval_T *tv);
|
int check_not_string(typval_T *tv);
|
||||||
|
int set_ref_in_dfunc(ufunc_T *ufunc, int copyID);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -662,5 +662,49 @@ def Test_closure_ref_after_return()
|
|||||||
unlet g:Ref
|
unlet g:Ref
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def MakeTwoRefs()
|
||||||
|
let local = ['some']
|
||||||
|
g:Extend = {s -> local->add(s)}
|
||||||
|
g:Read = {-> local}
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_closure_two_refs()
|
||||||
|
MakeTwoRefs()
|
||||||
|
assert_equal('some', join(g:Read(), ' '))
|
||||||
|
g:Extend('more')
|
||||||
|
assert_equal('some more', join(g:Read(), ' '))
|
||||||
|
g:Extend('even')
|
||||||
|
assert_equal('some more even', join(g:Read(), ' '))
|
||||||
|
|
||||||
|
unlet g:Extend
|
||||||
|
unlet g:Read
|
||||||
|
enddef
|
||||||
|
|
||||||
|
" TODO: fix memory leak when using same function again.
|
||||||
|
def MakeTwoRefs_2()
|
||||||
|
let local = ['some']
|
||||||
|
g:Extend = {s -> local->add(s)}
|
||||||
|
g:Read = {-> local}
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def ReadRef(Ref: func(): list<string>): string
|
||||||
|
return join(Ref(), ' ')
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def ExtendRef(Ref: func(string), add: string)
|
||||||
|
Ref(add)
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_closure_two_indirect_refs()
|
||||||
|
MakeTwoRefs_2()
|
||||||
|
assert_equal('some', ReadRef(g:Read))
|
||||||
|
ExtendRef(g:Extend, 'more')
|
||||||
|
assert_equal('some more', ReadRef(g:Read))
|
||||||
|
ExtendRef(g:Extend, 'even')
|
||||||
|
assert_equal('some more even', ReadRef(g:Read))
|
||||||
|
|
||||||
|
unlet g:Extend
|
||||||
|
unlet g:Read
|
||||||
|
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
|
||||||
|
@@ -4392,6 +4392,8 @@ set_ref_in_functions(int copyID)
|
|||||||
fp = HI2UF(hi);
|
fp = HI2UF(hi);
|
||||||
if (!func_name_refcount(fp->uf_name))
|
if (!func_name_refcount(fp->uf_name))
|
||||||
abort = abort || set_ref_in_func(NULL, fp, copyID);
|
abort = abort || set_ref_in_func(NULL, fp, copyID);
|
||||||
|
else if (fp->uf_dfunc_idx >= 0)
|
||||||
|
abort = abort || set_ref_in_dfunc(fp, copyID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return abort;
|
return abort;
|
||||||
@@ -4439,7 +4441,10 @@ set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
|
|||||||
{
|
{
|
||||||
for (fc = fp->uf_scoped; fc != NULL; fc = fc->func->uf_scoped)
|
for (fc = fp->uf_scoped; fc != NULL; fc = fc->func->uf_scoped)
|
||||||
abort = abort || set_ref_in_funccal(fc, copyID);
|
abort = abort || set_ref_in_funccal(fc, copyID);
|
||||||
|
if (fp->uf_dfunc_idx >= 0)
|
||||||
|
abort = abort || set_ref_in_dfunc(fp, copyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
return abort;
|
return abort;
|
||||||
}
|
}
|
||||||
|
@@ -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 */
|
||||||
|
/**/
|
||||||
|
683,
|
||||||
/**/
|
/**/
|
||||||
682,
|
682,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -824,7 +824,7 @@ generate_TYPECHECK(cctx_T *cctx, type_T *vartype, int offset)
|
|||||||
isn->isn_arg.type.ct_off = offset;
|
isn->isn_arg.type.ct_off = offset;
|
||||||
|
|
||||||
// type becomes vartype
|
// type becomes vartype
|
||||||
((type_T **)stack->ga_data)[stack->ga_len - 1] = vartype;
|
((type_T **)stack->ga_data)[stack->ga_len + offset] = vartype;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -1671,8 +1671,13 @@ skip_type(char_u *start)
|
|||||||
if (*p == ',')
|
if (*p == ',')
|
||||||
p = skipwhite(p + 1);
|
p = skipwhite(p + 1);
|
||||||
}
|
}
|
||||||
if (*p == ')' && p[1] == ':')
|
if (*p == ')')
|
||||||
p = skip_type(skipwhite(p + 2));
|
{
|
||||||
|
if (p[1] == ':')
|
||||||
|
p = skip_type(skipwhite(p + 2));
|
||||||
|
else
|
||||||
|
p = skipwhite(p + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
@@ -2437,11 +2437,12 @@ ex_disassemble(exarg_T *eap)
|
|||||||
break;
|
break;
|
||||||
case ISN_FUNCREF:
|
case ISN_FUNCREF:
|
||||||
{
|
{
|
||||||
|
funcref_T *funcref = &iptr->isn_arg.funcref;
|
||||||
dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
|
dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
|
||||||
+ iptr->isn_arg.funcref.fr_func;
|
+ funcref->fr_func;
|
||||||
|
|
||||||
smsg("%4d FUNCREF %s $%d", current, df->df_ufunc->uf_name,
|
smsg("%4d FUNCREF %s $%d", current, df->df_ufunc->uf_name,
|
||||||
iptr->isn_arg.funcref.fr_var_idx + df->df_varcount);
|
funcref->fr_var_idx + dfunc->df_varcount);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2675,5 +2676,25 @@ check_not_string(typval_T *tv)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark items in a def function as used.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
set_ref_in_dfunc(ufunc_T *ufunc, int copyID)
|
||||||
|
{
|
||||||
|
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
|
||||||
|
int abort = FALSE;
|
||||||
|
|
||||||
|
if (dfunc->df_funcstack != NULL)
|
||||||
|
{
|
||||||
|
typval_T *stack = dfunc->df_funcstack->fs_ga.ga_data;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for (idx = 0; idx < dfunc->df_funcstack->fs_ga.ga_len; ++idx)
|
||||||
|
abort = abort || set_ref_in_item(stack + idx, copyID, NULL, NULL);
|
||||||
|
}
|
||||||
|
return abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // FEAT_EVAL
|
#endif // FEAT_EVAL
|
||||||
|
Reference in New Issue
Block a user