Patch 8.2.2225

2 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 27, 2020, 7:40:31 AM12/27/20
to vim...@googlegroups.com

Patch 8.2.2225
Problem: Vim9: error when using :import in legacy script twice.
Solution: Make it possible to redefine an import when reloading.
Files: src/vim9script.c, src/proto/vim9script.pro, src/structs.h,
src/evalvars.c, src/vim9compile.c,
src/testdir/test_vim9_script.vim


*** ../vim-8.2.2224/src/vim9script.c 2020-12-26 20:09:11.286465244 +0100
--- src/vim9script.c 2020-12-27 13:05:28.213923518 +0100
***************
*** 174,179 ****
--- 174,197 ----
}

/*
+ * Mark all imports as possible to redefine. Used when a script is loaded
+ * again but not cleared.
+ */
+ void
+ mark_imports_for_reload(int sid)
+ {
+ scriptitem_T *si = SCRIPT_ITEM(sid);
+ int idx;
+
+ for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
+ {
+ imported_T *imp = ((imported_T *)si->sn_imports.ga_data) + idx;
+
+ imp->imp_flags |= IMP_FLAGS_RELOAD;
+ }
+ }
+
+ /*
* ":import Item from 'filename'"
* ":import Item as Alias from 'filename'"
* ":import {Item} from 'filename'".
***************
*** 459,473 ****

if (*arg_start == '*')
{
! imported_T *imported = new_imported(gap != NULL ? gap
! : &SCRIPT_ITEM(import_sid)->sn_imports);

if (imported == NULL)
goto erret;
imported->imp_name = as_name;
as_name = NULL;
imported->imp_sid = sid;
! imported->imp_all = TRUE;
}
else
{
--- 477,505 ----

if (*arg_start == '*')
{
! imported_T *imported;

+ imported = find_imported(as_name, STRLEN(as_name), cctx);
+ if (imported != NULL && imported->imp_sid == sid)
+ {
+ if (imported->imp_flags & IMP_FLAGS_RELOAD)
+ // import already defined on a previous script load
+ imported->imp_flags &= ~IMP_FLAGS_RELOAD;
+ else
+ {
+ semsg(_(e_name_already_defined_str), as_name);
+ goto erret;
+ }
+ }
+
+ imported = new_imported(gap != NULL ? gap
+ : &SCRIPT_ITEM(import_sid)->sn_imports);
if (imported == NULL)
goto erret;
imported->imp_name = as_name;
as_name = NULL;
imported->imp_sid = sid;
! imported->imp_flags = IMP_FLAGS_STAR;
}
else
{
***************
*** 479,484 ****
--- 511,517 ----
for (i = 0; i < names.ga_len; ++i)
{
char_u *name = ((char_u **)names.ga_data)[i];
+ size_t len = STRLEN(name);
int idx;
imported_T *imported;
ufunc_T *ufunc = NULL;
***************
*** 489,516 ****
if (idx < 0 && ufunc == NULL)
goto erret;

! if (check_defined(name, STRLEN(name), cctx) == FAIL)
! goto erret;
!
! imported = new_imported(gap != NULL ? gap
! : &SCRIPT_ITEM(import_sid)->sn_imports);
! if (imported == NULL)
! goto erret;
!
! // TODO: check for "as" following
! // imported->imp_name = vim_strsave(as_name);
! imported->imp_name = name;
! ((char_u **)names.ga_data)[i] = NULL;
! imported->imp_sid = sid;
! if (idx >= 0)
{
! imported->imp_type = type;
! imported->imp_var_vals_idx = idx;
}
else
{
! imported->imp_type = ufunc->uf_func_type;
! imported->imp_funcname = ufunc->uf_name;
}
}
}
--- 522,568 ----
if (idx < 0 && ufunc == NULL)
goto erret;

! // If already imported with the same propertis and the
! // IMP_FLAGS_RELOAD set then we keep that entry. Otherwise create
! // a new one (and give an error for an existing import).
! imported = find_imported(name, len, cctx);
! if (imported != NULL
! && (imported->imp_flags & IMP_FLAGS_RELOAD)
! && imported->imp_sid == sid
! && (idx >= 0
! ? (equal_type(imported->imp_type, type)
! && imported->imp_var_vals_idx == idx)
! : (equal_type(imported->imp_type, ufunc->uf_func_type)
! && STRCMP(imported->imp_funcname,
! ufunc->uf_name) == 0)))
{
! imported->imp_flags &= ~IMP_FLAGS_RELOAD;
}
else
{
! if (check_defined(name, len, cctx) == FAIL)
! goto erret;
!
! imported = new_imported(gap != NULL ? gap
! : &SCRIPT_ITEM(import_sid)->sn_imports);
! if (imported == NULL)
! goto erret;
!
! // TODO: check for "as" following
! // imported->imp_name = vim_strsave(as_name);
! imported->imp_name = name;
! ((char_u **)names.ga_data)[i] = NULL;
! imported->imp_sid = sid;
! if (idx >= 0)
! {
! imported->imp_type = type;
! imported->imp_var_vals_idx = idx;
! }
! else
! {
! imported->imp_type = ufunc->uf_func_type;
! imported->imp_funcname = ufunc->uf_name;
! }
}
}
}
*** ../vim-8.2.2224/src/proto/vim9script.pro 2020-12-26 20:09:11.286465244 +0100
--- src/proto/vim9script.pro 2020-12-27 12:46:36.053572738 +0100
***************
*** 4,9 ****
--- 4,10 ----
int not_in_vim9(exarg_T *eap);
void ex_export(exarg_T *eap);
void free_imports_and_script_vars(int sid);
+ void mark_imports_for_reload(int sid);
void ex_import(exarg_T *eap);
int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, cctx_T *cctx);
char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, evalarg_T *evalarg, void *cctx);
*** ../vim-8.2.2224/src/structs.h 2020-12-26 15:39:24.615550807 +0100
--- src/structs.h 2020-12-27 12:41:44.154834241 +0100
***************
*** 1778,1794 ****
char_u *imp_name; // name imported as (allocated)
int imp_sid; // script ID of "from"

! // for "import * as Name", "imp_name" is "Name"
! int imp_all;

! // for variable
type_T *imp_type;
int imp_var_vals_idx; // index in sn_var_vals of "from"

! // for function
char_u *imp_funcname; // user func name (NOT allocated)
} imported_T;

/*
* Info about an already sourced scripts.
*/
--- 1778,1796 ----
char_u *imp_name; // name imported as (allocated)
int imp_sid; // script ID of "from"

! int imp_flags; // IMP_FLAGS_ values

! // for a variable
type_T *imp_type;
int imp_var_vals_idx; // index in sn_var_vals of "from"

! // for a function
char_u *imp_funcname; // user func name (NOT allocated)
} imported_T;

+ #define IMP_FLAGS_STAR 1 // using "import * as Name"
+ #define IMP_FLAGS_RELOAD 2 // script reloaded, OK to redefine
+
/*
* Info about an already sourced scripts.
*/
*** ../vim-8.2.2224/src/evalvars.c 2020-12-26 20:09:11.286465244 +0100
--- src/evalvars.c 2020-12-26 21:48:11.792575642 +0100
***************
*** 2531,2537 ****
rettv->vval.v_string = vim_strsave(import->imp_funcname);
}
}
! else if (import->imp_all)
{
emsg("Sorry, 'import * as X' not implemented yet");
ret = FAIL;
--- 2531,2537 ----
rettv->vval.v_string = vim_strsave(import->imp_funcname);
}
}
! else if (import->imp_flags & IMP_FLAGS_STAR)
{
emsg("Sorry, 'import * as X' not implemented yet");
ret = FAIL;
*** ../vim-8.2.2224/src/vim9compile.c 2020-12-26 20:09:11.282465257 +0100
--- src/vim9compile.c 2020-12-26 21:48:59.876426066 +0100
***************
*** 2416,2422 ****
import = find_imported(name, 0, cctx);
if (import != NULL)
{
! if (import->imp_all)
{
char_u *p = skipwhite(*end);
char_u *exp_name;
--- 2416,2422 ----
import = find_imported(name, 0, cctx);
if (import != NULL)
{
! if (import->imp_flags & IMP_FLAGS_STAR)
{
char_u *p = skipwhite(*end);
char_u *exp_name;
*** ../vim-8.2.2224/src/testdir/test_vim9_script.vim 2020-12-26 20:09:11.286465244 +0100
--- src/testdir/test_vim9_script.vim 2020-12-27 13:38:08.523351440 +0100
***************
*** 899,904 ****
--- 899,914 ----
writefile(import_star_as_lines_dot_space, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func')

+ var import_star_as_duplicated =<< trim END
+ vim9script
+ import * as Export from './Xexport.vim'
+ var some = 'other'
+ import * as Export from './Xexport.vim'
+ defcompile
+ END
+ writefile(import_star_as_duplicated, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim')
+
var import_star_as_lines_missing_name =<< trim END
vim9script
import * as Export from './Xexport.vim'
***************
*** 1160,1168 ****
--- 1170,1184 ----

def Test_vim9script_reload_noclear()
var lines =<< trim END
+ vim9script
+ export var exported = 'thexport'
+ END
+ writefile(lines, 'XExportReload')
+ lines =<< trim END
vim9script noclear
g:loadCount += 1
var s:reloaded = 'init'
+ import exported from './XExportReload'

def Again(): string
return 'again'
***************
*** 1174,1180 ****
var s:notReloaded = 'yes'
s:reloaded = 'first'
def g:Values(): list<string>
! return [s:reloaded, s:notReloaded, Again(), Once()]
enddef

def Once(): string
--- 1190,1196 ----
var s:notReloaded = 'yes'
s:reloaded = 'first'
def g:Values(): list<string>
! return [s:reloaded, s:notReloaded, Again(), Once(), exported]
enddef

def Once(): string
***************
*** 1185,1199 ****
g:loadCount = 0
source XReloaded
assert_equal(1, g:loadCount)
! assert_equal(['first', 'yes', 'again', 'once'], g:Values())
source XReloaded
assert_equal(2, g:loadCount)
! assert_equal(['init', 'yes', 'again', 'once'], g:Values())
source XReloaded
assert_equal(3, g:loadCount)
! assert_equal(['init', 'yes', 'again', 'once'], g:Values())

delete('Xreloaded')
delfunc g:Values
unlet g:loadCount
enddef
--- 1201,1216 ----
g:loadCount = 0
source XReloaded
assert_equal(1, g:loadCount)
! assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values())
source XReloaded
assert_equal(2, g:loadCount)
! assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
source XReloaded
assert_equal(3, g:loadCount)
! assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())

delete('Xreloaded')
+ delete('XExportReload')
delfunc g:Values
unlet g:loadCount
enddef
***************
*** 2762,2767 ****
--- 2779,2795 ----
enddef

def Test_source_vim9_from_legacy()
+ var vim9_lines =<< trim END
+ vim9script
+ var local = 'local'
+ g:global = 'global'
+ export var exported = 'exported'
+ export def GetText(): string
+ return 'text'
+ enddef
+ END
+ writefile(vim9_lines, 'Xvim9_script.vim')
+
var legacy_lines =<< trim END
source Xvim9_script.vim

***************
*** 2783,2801 ****
END
writefile(legacy_lines, 'Xlegacy_script.vim')

- var vim9_lines =<< trim END
- vim9script
- var local = 'local'
- g:global = 'global'
- export var exported = 'exported'
- export def GetText(): string
- return 'text'
- enddef
- END
- writefile(vim9_lines, 'Xvim9_script.vim')
-
source Xlegacy_script.vim
-
assert_equal('global', g:global)
unlet g:global

--- 2811,2817 ----
*** ../vim-8.2.2224/src/version.c 2020-12-26 20:09:11.286465244 +0100
--- src/version.c 2020-12-27 13:38:27.079292899 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2225,
/**/

--
Tips for aliens in New York: Land anywhere. Central Park, anywhere.
No one will care or indeed even notice.
-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages