mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
patch 8.2.2033: Vim9: :def without argument gives compilation error
Problem: Vim9: :def without argument gives compilation error. Solution: Add the DEF instruction. (closes #7344)
This commit is contained in:
@@ -274,7 +274,6 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name);
|
|||||||
# define ex_continue ex_ni
|
# define ex_continue ex_ni
|
||||||
# define ex_debug ex_ni
|
# define ex_debug ex_ni
|
||||||
# define ex_debuggreedy ex_ni
|
# define ex_debuggreedy ex_ni
|
||||||
# define ex_def ex_ni
|
|
||||||
# define ex_defcompile ex_ni
|
# define ex_defcompile ex_ni
|
||||||
# define ex_delfunction ex_ni
|
# define ex_delfunction ex_ni
|
||||||
# define ex_disassemble ex_ni
|
# define ex_disassemble ex_ni
|
||||||
|
@@ -33,6 +33,7 @@ int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typva
|
|||||||
char_u *printable_func_name(ufunc_T *fp);
|
char_u *printable_func_name(ufunc_T *fp);
|
||||||
char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial);
|
char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial);
|
||||||
char_u *untrans_function_name(char_u *name);
|
char_u *untrans_function_name(char_u *name);
|
||||||
|
void list_functions(regmatch_T *regmatch);
|
||||||
ufunc_T *define_function(exarg_T *eap, char_u *name_arg);
|
ufunc_T *define_function(exarg_T *eap, char_u *name_arg);
|
||||||
void ex_function(exarg_T *eap);
|
void ex_function(exarg_T *eap);
|
||||||
void ex_defcompile(exarg_T *eap);
|
void ex_defcompile(exarg_T *eap);
|
||||||
|
@@ -905,6 +905,29 @@ def Test_nested_func()
|
|||||||
instr)
|
instr)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def NestedDefList()
|
||||||
|
def
|
||||||
|
def Info
|
||||||
|
def /Info
|
||||||
|
def /Info/
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_nested_def_list()
|
||||||
|
var instr = execute('disassemble NestedDefList')
|
||||||
|
assert_match('NestedDefList\_s*' ..
|
||||||
|
'def\_s*' ..
|
||||||
|
'\d DEF \_s*' ..
|
||||||
|
'def Info\_s*' ..
|
||||||
|
'\d DEF Info\_s*' ..
|
||||||
|
'def /Info\_s*' ..
|
||||||
|
'\d DEF /Info\_s*' ..
|
||||||
|
'def /Info/\_s*' ..
|
||||||
|
'\d DEF /Info/\_s*' ..
|
||||||
|
'\d PUSHNR 0\_s*' ..
|
||||||
|
'\d RETURN',
|
||||||
|
instr)
|
||||||
|
enddef
|
||||||
|
|
||||||
def AndOr(arg: any): string
|
def AndOr(arg: any): string
|
||||||
if arg == 1 && arg != 2 || arg == 4
|
if arg == 1 && arg != 2 || arg == 4
|
||||||
return 'yes'
|
return 'yes'
|
||||||
|
@@ -288,6 +288,33 @@ def Test_nested_global_function()
|
|||||||
CheckScriptFailure(lines, "E1073:")
|
CheckScriptFailure(lines, "E1073:")
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def DefListAll()
|
||||||
|
def
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def DefListOne()
|
||||||
|
def DefListOne
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def DefListMatches()
|
||||||
|
def /DefList
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_nested_def_list()
|
||||||
|
var funcs = split(execute('call DefListAll()'), "\n")
|
||||||
|
assert_true(len(funcs) > 10)
|
||||||
|
assert_true(funcs->index('def DefListAll()') >= 0)
|
||||||
|
|
||||||
|
funcs = split(execute('call DefListOne()'), "\n")
|
||||||
|
assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
|
||||||
|
|
||||||
|
funcs = split(execute('call DefListMatches()'), "\n")
|
||||||
|
assert_true(len(funcs) >= 3)
|
||||||
|
assert_true(funcs->index('def DefListAll()') >= 0)
|
||||||
|
assert_true(funcs->index('def DefListOne()') >= 0)
|
||||||
|
assert_true(funcs->index('def DefListMatches()') >= 0)
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_global_local_function()
|
def Test_global_local_function()
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
|
@@ -2748,7 +2748,7 @@ untrans_function_name(char_u *name)
|
|||||||
* List functions. When "regmatch" is NULL all of then.
|
* List functions. When "regmatch" is NULL all of then.
|
||||||
* Otherwise functions matching "regmatch".
|
* Otherwise functions matching "regmatch".
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
list_functions(regmatch_T *regmatch)
|
list_functions(regmatch_T *regmatch)
|
||||||
{
|
{
|
||||||
int changed = func_hashtab.ht_changed;
|
int changed = func_hashtab.ht_changed;
|
||||||
|
@@ -750,6 +750,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 */
|
||||||
|
/**/
|
||||||
|
2033,
|
||||||
/**/
|
/**/
|
||||||
2032,
|
2032,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -82,6 +82,7 @@ typedef enum {
|
|||||||
ISN_RETURN, // return, result is on top of stack
|
ISN_RETURN, // return, result is on top of stack
|
||||||
ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref
|
ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref
|
||||||
ISN_NEWFUNC, // create a global function from a lambda function
|
ISN_NEWFUNC, // create a global function from a lambda function
|
||||||
|
ISN_DEF, // list functions
|
||||||
|
|
||||||
// expression operations
|
// expression operations
|
||||||
ISN_JUMP, // jump if condition is matched isn_arg.jump
|
ISN_JUMP, // jump if condition is matched isn_arg.jump
|
||||||
|
@@ -1432,6 +1432,26 @@ generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate an ISN_DEF instruction: list functions
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
generate_DEF(cctx_T *cctx, char_u *name, size_t len)
|
||||||
|
{
|
||||||
|
isn_T *isn;
|
||||||
|
|
||||||
|
RETURN_OK_IF_SKIP(cctx);
|
||||||
|
if ((isn = generate_instr(cctx, ISN_DEF)) == NULL)
|
||||||
|
return FAIL;
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
isn->isn_arg.string = vim_strnsave(name, len);
|
||||||
|
if (isn->isn_arg.string == NULL)
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate an ISN_JUMP instruction.
|
* Generate an ISN_JUMP instruction.
|
||||||
*/
|
*/
|
||||||
@@ -4801,6 +4821,27 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*name_start == '/')
|
||||||
|
{
|
||||||
|
name_end = skip_regexp(name_start + 1, '/', TRUE);
|
||||||
|
if (*name_end == '/')
|
||||||
|
++name_end;
|
||||||
|
eap->nextcmd = check_nextcmd(name_end);
|
||||||
|
}
|
||||||
|
if (name_end == name_start || *skipwhite(name_end) != '(')
|
||||||
|
{
|
||||||
|
if (!ends_excmd2(name_start, name_end))
|
||||||
|
{
|
||||||
|
semsg(_(e_invalid_command_str), eap->cmd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "def" or "def Name": list functions
|
||||||
|
if (generate_DEF(cctx, name_start, name_end - name_start) == FAIL)
|
||||||
|
return NULL;
|
||||||
|
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
|
||||||
|
}
|
||||||
|
|
||||||
// Only g:Func() can use a namespace.
|
// Only g:Func() can use a namespace.
|
||||||
if (name_start[1] == ':' && !is_global)
|
if (name_start[1] == ':' && !is_global)
|
||||||
{
|
{
|
||||||
@@ -7736,22 +7777,23 @@ delete_instr(isn_T *isn)
|
|||||||
{
|
{
|
||||||
switch (isn->isn_type)
|
switch (isn->isn_type)
|
||||||
{
|
{
|
||||||
|
case ISN_DEF:
|
||||||
case ISN_EXEC:
|
case ISN_EXEC:
|
||||||
|
case ISN_LOADB:
|
||||||
case ISN_LOADENV:
|
case ISN_LOADENV:
|
||||||
case ISN_LOADG:
|
case ISN_LOADG:
|
||||||
case ISN_LOADB:
|
|
||||||
case ISN_LOADW:
|
|
||||||
case ISN_LOADT:
|
|
||||||
case ISN_LOADOPT:
|
case ISN_LOADOPT:
|
||||||
case ISN_STRINGMEMBER:
|
case ISN_LOADT:
|
||||||
|
case ISN_LOADW:
|
||||||
case ISN_PUSHEXC:
|
case ISN_PUSHEXC:
|
||||||
|
case ISN_PUSHFUNC:
|
||||||
case ISN_PUSHS:
|
case ISN_PUSHS:
|
||||||
|
case ISN_STOREB:
|
||||||
case ISN_STOREENV:
|
case ISN_STOREENV:
|
||||||
case ISN_STOREG:
|
case ISN_STOREG:
|
||||||
case ISN_STOREB:
|
|
||||||
case ISN_STOREW:
|
|
||||||
case ISN_STORET:
|
case ISN_STORET:
|
||||||
case ISN_PUSHFUNC:
|
case ISN_STOREW:
|
||||||
|
case ISN_STRINGMEMBER:
|
||||||
vim_free(isn->isn_arg.string);
|
vim_free(isn->isn_arg.string);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -1970,6 +1970,20 @@ call_def_function(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// List functions
|
||||||
|
case ISN_DEF:
|
||||||
|
if (iptr->isn_arg.string == NULL)
|
||||||
|
list_functions(NULL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exarg_T ea;
|
||||||
|
|
||||||
|
CLEAR_FIELD(ea);
|
||||||
|
ea.cmd = ea.arg = iptr->isn_arg.string;
|
||||||
|
define_function(&ea, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// jump if a condition is met
|
// jump if a condition is met
|
||||||
case ISN_JUMP:
|
case ISN_JUMP:
|
||||||
{
|
{
|
||||||
@@ -3371,6 +3385,15 @@ ex_disassemble(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ISN_DEF:
|
||||||
|
{
|
||||||
|
char_u *name = iptr->isn_arg.string;
|
||||||
|
|
||||||
|
smsg("%4d DEF %s", current,
|
||||||
|
name == NULL ? (char_u *)"" : name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ISN_JUMP:
|
case ISN_JUMP:
|
||||||
{
|
{
|
||||||
char *when = "?";
|
char *when = "?";
|
||||||
|
Reference in New Issue
Block a user