0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

patch 9.1.1014: Vim9: variable not found in transitive import

Problem:  Vim9: variable not found in transitive import
Solution: Allow nested import (Hirohito Higashi)

fixe: #16379
closes: #16440

Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Hirohito Higashi
2025-01-14 17:21:42 +01:00
committed by Christian Brabandt
parent 045564d0a7
commit 57f0119358
7 changed files with 97 additions and 11 deletions

View File

@@ -1,4 +1,4 @@
*options.txt* For Vim version 9.1. Last change: 2025 Jan 12 *options.txt* For Vim version 9.1. Last change: 2025 Jan 14
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -5582,6 +5582,7 @@ A jump table for the options with a short description can be found at |Q_op|.
command recursion, see |E169|. command recursion, see |E169|.
See also |:function|. See also |:function|.
Also used for maximum depth of callback functions. Also used for maximum depth of callback functions.
Also used for maximum depth of import. See |:import-cycle|.
*'maxmapdepth'* *'mmd'* *E223* *'maxmapdepth'* *'mmd'* *E223*
'maxmapdepth' 'mmd' number (default 1000) 'maxmapdepth' 'mmd' number (default 1000)

View File

@@ -4148,6 +4148,7 @@ E1041 vim9.txt /*E1041*
E1042 vim9.txt /*E1042* E1042 vim9.txt /*E1042*
E1043 vim9.txt /*E1043* E1043 vim9.txt /*E1043*
E1044 vim9.txt /*E1044* E1044 vim9.txt /*E1044*
E1045 vim9.txt /*E1045*
E1047 vim9.txt /*E1047* E1047 vim9.txt /*E1047*
E1048 vim9.txt /*E1048* E1048 vim9.txt /*E1048*
E1049 vim9.txt /*E1049* E1049 vim9.txt /*E1049*

View File

@@ -1,4 +1,4 @@
*vim9.txt* For Vim version 9.1. Last change: 2024 Dec 23 *vim9.txt* For Vim version 9.1. Last change: 2025 Jan 14
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2051,13 +2051,14 @@ prefixing the function with |<SID>| you should use|<ScriptCmd>|. For example:
> >
noremap ,a <ScriptCmd>:call s:that.OtherFunc()<CR> noremap ,a <ScriptCmd>:call s:that.OtherFunc()<CR>
< <
*:import-cycle* *:import-cycle* *E1045*
The `import` commands are executed when encountered. If script A imports The `import` commands are executed when encountered. It can be nested up to
script B, and B (directly or indirectly) imports A, this will be skipped over. 'maxfuncdepth' levels deep. If script A imports script B, and B (directly or
At this point items in A after "import B" will not have been processed and indirectly) imports A, this will be skipped over. At this point items in A
defined yet. Therefore cyclic imports can exist and not result in an error after "import B" will not have been processed and defined yet. Therefore
directly, but may result in an error for items in A after "import B" not being cyclic imports can exist and not result in an error directly, but may result
defined. This does not apply to autoload imports, see the next section. in an error for items in A after "import B" not being defined. This does not
apply to autoload imports, see the next section.
Importing an autoload script ~ Importing an autoload script ~

View File

@@ -2738,7 +2738,8 @@ EXTERN char e_invalid_command_after_export[]
INIT(= N_("E1043: Invalid command after :export")); INIT(= N_("E1043: Invalid command after :export"));
EXTERN char e_export_with_invalid_argument[] EXTERN char e_export_with_invalid_argument[]
INIT(= N_("E1044: Export with invalid argument")); INIT(= N_("E1044: Export with invalid argument"));
// E1045 not used EXTERN char e_import_nesting_too_deep[]
INIT(= N_("E1045: Import nesting too deep"));
// E1046 not used // E1046 not used
EXTERN char e_syntax_error_in_import_str[] EXTERN char e_syntax_error_in_import_str[]
INIT(= N_("E1047: Syntax error in import: %s")); INIT(= N_("E1047: Syntax error in import: %s"));

View File

@@ -3507,7 +3507,73 @@ def Test_extend_imported_class()
v9.CheckScriptSuccess(lines) v9.CheckScriptSuccess(lines)
enddef enddef
def Test_abstract_class() " Test for multi level import
def Test_multi_level_import_normal()
var lines =<< trim END
vim9script
export class Property
public var value: string
endclass
END
writefile(lines, 'aa.vim', 'D')
lines =<< trim END
vim9script
import './aa.vim'
export class View
var content = aa.Property.new('')
endclass
END
writefile(lines, 'bb.vim', 'D')
lines =<< trim END
vim9script
import './bb.vim'
class MyView extends bb.View
def new(value: string)
this.content.value = value
enddef
endclass
var myView = MyView.new('This should be ok')
END
v9.CheckScriptSuccess(lines)
enddef
" Test for multi level import
def Test_multi_level_import_nest_over()
var lines =<< trim END
vim9script
import './xbb.vim'
export class Property
public var value: string
endclass
END
writefile(lines, 'xaa.vim', 'D')
lines =<< trim END
vim9script
import './xaa.vim'
export class View
var content = aa.Property.new('')
endclass
END
writefile(lines, 'xbb.vim', 'D')
lines =<< trim END
vim9script
set maxfuncdepth=100
import './xbb.vim'
class MyView extends bb.View
def new(value: string)
this.content.value = value
enddef
endclass
var myView = MyView.new('This should be ok')
END
v9.CheckSourceFailure(lines, 'E1045: Import nesting too deep', 3)
enddef
def Test_abtstract_class()
var lines =<< trim END var lines =<< trim END
vim9script vim9script
abstract class Base abstract class Base

View File

@@ -704,6 +704,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 */
/**/
1014,
/**/ /**/
1013, 1013,
/**/ /**/

View File

@@ -778,6 +778,7 @@ get_script_item_idx(
static imported_T * static imported_T *
find_imported_in_script(char_u *name, size_t len, int sid) find_imported_in_script(char_u *name, size_t len, int sid)
{ {
static int nesting = 0;
scriptitem_T *si; scriptitem_T *si;
int idx; int idx;
@@ -792,6 +793,19 @@ find_imported_in_script(char_u *name, size_t len, int sid)
: STRLEN(import->imp_name) == len : STRLEN(import->imp_name) == len
&& STRNCMP(name, import->imp_name, len) == 0) && STRNCMP(name, import->imp_name, len) == 0)
return import; return import;
else
{
if (nesting >= p_mfd)
{
emsg(_(e_import_nesting_too_deep));
return NULL;
}
++nesting;
import = find_imported_in_script(name, len, import->imp_sid);
--nesting;
if (import != NULL)
return import;
}
} }
return NULL; return NULL;
} }