mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.2617: Vim9: script variable in block not found by function
Problem: Vim9: script variable in a block scope not found by a nested function. Solution: Copy the block scope IDs before compiling the function.
This commit is contained in:
@@ -947,7 +947,7 @@ def NestedOuter()
|
|||||||
enddef
|
enddef
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_nested_func()
|
def Test_disassemble_nested_func()
|
||||||
var instr = execute('disassemble NestedOuter')
|
var instr = execute('disassemble NestedOuter')
|
||||||
assert_match('NestedOuter\_s*' ..
|
assert_match('NestedOuter\_s*' ..
|
||||||
'def g:Inner()\_s*' ..
|
'def g:Inner()\_s*' ..
|
||||||
@@ -965,7 +965,7 @@ def NestedDefList()
|
|||||||
def /Info/
|
def /Info/
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_nested_def_list()
|
def Test_disassemble_nested_def_list()
|
||||||
var instr = execute('disassemble NestedDefList')
|
var instr = execute('disassemble NestedDefList')
|
||||||
assert_match('NestedDefList\_s*' ..
|
assert_match('NestedDefList\_s*' ..
|
||||||
'def\_s*' ..
|
'def\_s*' ..
|
||||||
|
@@ -393,7 +393,6 @@ def Test_nested_function()
|
|||||||
CheckDefFailure(lines, 'E1117:')
|
CheckDefFailure(lines, 'E1117:')
|
||||||
|
|
||||||
# nested function inside conditional
|
# nested function inside conditional
|
||||||
# TODO: should it work when "thecount" is inside the "if"?
|
|
||||||
lines =<< trim END
|
lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
var thecount = 0
|
var thecount = 0
|
||||||
@@ -411,6 +410,25 @@ def Test_nested_function()
|
|||||||
assert_equal(2, Test())
|
assert_equal(2, Test())
|
||||||
END
|
END
|
||||||
CheckScriptSuccess(lines)
|
CheckScriptSuccess(lines)
|
||||||
|
|
||||||
|
# also works when "thecount" is inside the "if" block
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
if true
|
||||||
|
var thecount = 0
|
||||||
|
def Test(): number
|
||||||
|
def TheFunc(): number
|
||||||
|
thecount += 1
|
||||||
|
return thecount
|
||||||
|
enddef
|
||||||
|
return TheFunc()
|
||||||
|
enddef
|
||||||
|
endif
|
||||||
|
defcompile
|
||||||
|
assert_equal(1, Test())
|
||||||
|
assert_equal(2, Test())
|
||||||
|
END
|
||||||
|
CheckScriptSuccess(lines)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_not_nested_function()
|
def Test_not_nested_function()
|
||||||
|
@@ -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 */
|
||||||
|
/**/
|
||||||
|
2617,
|
||||||
/**/
|
/**/
|
||||||
2616,
|
2616,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -5183,6 +5183,21 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
r = eap->skip ? OK : FAIL;
|
r = eap->skip ? OK : FAIL;
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy over the block scope IDs before compiling
|
||||||
|
if (!is_global && cctx->ctx_ufunc->uf_block_depth > 0)
|
||||||
|
{
|
||||||
|
int block_depth = cctx->ctx_ufunc->uf_block_depth;
|
||||||
|
|
||||||
|
ufunc->uf_block_ids = ALLOC_MULT(int, block_depth);
|
||||||
|
if (ufunc->uf_block_ids != NULL)
|
||||||
|
{
|
||||||
|
mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids,
|
||||||
|
sizeof(int) * block_depth);
|
||||||
|
ufunc->uf_block_depth = block_depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (func_needs_compiling(ufunc, PROFILING(ufunc))
|
if (func_needs_compiling(ufunc, PROFILING(ufunc))
|
||||||
&& compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx)
|
&& compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx)
|
||||||
== FAIL)
|
== FAIL)
|
||||||
@@ -5209,25 +5224,12 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
// Define a local variable for the function reference.
|
// Define a local variable for the function reference.
|
||||||
lvar_T *lvar = reserve_local(cctx, name_start, name_end - name_start,
|
lvar_T *lvar = reserve_local(cctx, name_start, name_end - name_start,
|
||||||
TRUE, ufunc->uf_func_type);
|
TRUE, ufunc->uf_func_type);
|
||||||
int block_depth = cctx->ctx_ufunc->uf_block_depth;
|
|
||||||
|
|
||||||
if (lvar == NULL)
|
if (lvar == NULL)
|
||||||
goto theend;
|
goto theend;
|
||||||
if (generate_FUNCREF(cctx, ufunc) == FAIL)
|
if (generate_FUNCREF(cctx, ufunc) == FAIL)
|
||||||
goto theend;
|
goto theend;
|
||||||
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
|
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
|
||||||
|
|
||||||
// copy over the block scope IDs
|
|
||||||
if (block_depth > 0)
|
|
||||||
{
|
|
||||||
ufunc->uf_block_ids = ALLOC_MULT(int, block_depth);
|
|
||||||
if (ufunc->uf_block_ids != NULL)
|
|
||||||
{
|
|
||||||
mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids,
|
|
||||||
sizeof(int) * block_depth);
|
|
||||||
ufunc->uf_block_depth = block_depth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// TODO: warning for trailing text?
|
// TODO: warning for trailing text?
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user