0
0
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:
Bram Moolenaar
2021-03-17 18:42:08 +01:00
parent 3e1916947d
commit 8863bda25d
4 changed files with 38 additions and 16 deletions

View File

@@ -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*' ..

View File

@@ -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()

View File

@@ -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,
/**/ /**/

View File

@@ -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?