Patch 8.2.0312
Problem: Vim9: insufficient script tests.
Solution: Add more tests. Make "import * as Name" work.
Files: src/testdir/test_vim9_script.vim, src/vim9script.c,
src/proto/vim9script.pro, src/vim9compile.c
*** ../vim-8.2.0311/src/testdir/test_vim9_script.vim 2020-02-23
18:08:29.463897252 +0100
--- src/testdir/test_vim9_script.vim 2020-02-23 21:14:47.294383000 +0100
***************
*** 331,336 ****
--- 331,358 ----
unlet g:imported_func
unlet g:imported_name g:imported_name_appended
delete('Ximport.vim')
+
+ let import_star_as_lines =<< trim END
+ vim9script
+ import * as Export from './Xexport.vim'
+ def UseExport()
+ g:imported = Export.exported
+ enddef
+ UseExport()
+ END
+ writefile(import_star_as_lines, 'Ximport.vim')
+ source Ximport.vim
+ assert_equal(9876, g:imported)
+
+ let import_star_lines =<< trim END
+ vim9script
+ import * from './Xexport.vim'
+ g:imported = exported
+ END
+ writefile(import_star_lines, 'Ximport.vim')
+ assert_fails('source Ximport.vim', 'E1045:')
+
+ delete('Ximport.vim')
delete('Xexport.vim')
" Check that in a Vim9 script 'cpo' is set to the Vim default.
***************
*** 352,357 ****
--- 374,380 ----
CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
CheckScriptFailure(['export let some = 123'], 'E1042:')
+ CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
*** ../vim-8.2.0311/src/vim9script.c 2020-01-28 23:13:39.458166365 +0100
--- src/vim9script.c 2020-02-23 19:53:48.406528554 +0100
***************
*** 151,156 ****
--- 151,238 ----
}
/*
+ * Find an exported item in "sid" matching the name at "*argp".
+ * When it is a variable return the index.
+ * When it is a user function return "*ufunc".
+ * When not found returns -1 and "*ufunc" is NULL.
+ */
+ int
+ find_exported(
+ int sid,
+ char_u **argp,
+ int *name_len,
+ ufunc_T **ufunc,
+ type_T **type)
+ {
+ char_u *name = *argp;
+ char_u *arg = *argp;
+ int cc;
+ int idx = -1;
+ svar_T *sv;
+ scriptitem_T *script = SCRIPT_ITEM(sid);
+
+ // isolate one name
+ while (eval_isnamec1(*arg))
+ ++arg;
+ *name_len = (int)(arg - name);
+
+ // find name in "script"
+ // TODO: also find script-local user function
+ cc = *arg;
+ *arg = NUL;
+ idx = get_script_item_idx(sid, name, FALSE);
+ if (idx >= 0)
+ {
+ sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
+ if (!sv->sv_export)
+ {
+ semsg(_("E1049: Item not exported in script: %s"), name);
+ *arg = cc;
+ return -1;
+ }
+ *type = sv->sv_type;
+ *ufunc = NULL;
+ }
+ else
+ {
+ char_u buffer[200];
+ char_u *funcname;
+
+ // it could be a user function.
+ if (STRLEN(name) < sizeof(buffer) - 10)
+ funcname = buffer;
+ else
+ {
+ funcname = alloc(STRLEN(name) + 10);
+ if (funcname == NULL)
+ {
+ *arg = cc;
+ return -1;
+ }
+ }
+ funcname[0] = K_SPECIAL;
+ funcname[1] = KS_EXTRA;
+ funcname[2] = (int)KE_SNR;
+ sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name);
+ *ufunc = find_func(funcname, NULL);
+ if (funcname != buffer)
+ vim_free(funcname);
+
+ if (*ufunc == NULL)
+ {
+ semsg(_("E1048: Item not found in script: %s"), name);
+ *arg = cc;
+ return -1;
+ }
+ }
+ *arg = cc;
+ arg = skipwhite(arg);
+ *argp = arg;
+
+ return idx;
+ }
+
+ /*
* Handle an ":import" command and add the resulting imported_T to "gap", when
* not NULL, or script "import_sid" sn_imports.
* Returns a pointer to after the command or NULL in case of failure
***************
*** 289,296 ****
}
else
{
- scriptitem_T *script = SCRIPT_ITEM(sid);
-
arg = arg_start;
if (*arg == '{')
arg = skipwhite(arg + 1);
--- 371,376 ----
***************
*** 298,365 ****
{
char_u *name = arg;
int name_len;
- int cc;
int idx;
- svar_T *sv;
imported_T *imported;
! ufunc_T *ufunc;
!
! // isolate one name
! while (eval_isnamec1(*arg))
! ++arg;
! name_len = (int)(arg - name);
! // find name in "script"
! // TODO: also find script-local user function
! cc = *arg;
! *arg = NUL;
! idx = get_script_item_idx(sid, name, FALSE);
! if (idx >= 0)
! {
! sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
! if (!sv->sv_export)
! {
! semsg(_("E1049: Item not exported in script: %s"), name);
! *arg = cc;
! return NULL;
! }
! ufunc = NULL;
! }
! else
! {
! char_u buffer[200];
! char_u *funcname;
! // it could be a user function.
! if (STRLEN(name) < sizeof(buffer) - 10)
! funcname = buffer;
! else
! {
! funcname = alloc(STRLEN(name) + 10);
! if (funcname == NULL)
! {
! *arg = cc;
! return NULL;
! }
! }
! funcname[0] = K_SPECIAL;
! funcname[1] = KS_EXTRA;
! funcname[2] = (int)KE_SNR;
! sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name);
! ufunc = find_func(funcname, NULL);
! if (funcname != buffer)
! vim_free(funcname);
!
! if (ufunc == NULL)
! {
! semsg(_("E1048: Item not found in script: %s"), name);
! *arg = cc;
! return NULL;
! }
! sv = NULL;
! }
! *arg = cc;
! arg = skipwhite(arg);
imported = new_imported(gap != NULL ? gap
: &SCRIPT_ITEM(import_sid)->sn_imports);
--- 378,392 ----
{
char_u *name = arg;
int name_len;
int idx;
imported_T *imported;
! ufunc_T *ufunc = NULL;
! type_T *type;
! idx = find_exported(sid, &arg, &name_len, &ufunc, &type);
! if (idx < 0 && ufunc == NULL)
! return NULL;
imported = new_imported(gap != NULL ? gap
: &SCRIPT_ITEM(import_sid)->sn_imports);
***************
*** 372,378 ****
imported->imp_sid = sid;
if (idx >= 0)
{
! imported->imp_type = sv->sv_type;
imported->imp_var_vals_idx = idx;
}
else
--- 399,405 ----
imported->imp_sid = sid;
if (idx >= 0)
{
! imported->imp_type = type;
imported->imp_var_vals_idx = idx;
}
else
*** ../vim-8.2.0311/src/proto/vim9script.pro 2020-01-26 15:52:33.023833239
+0100
--- src/proto/vim9script.pro 2020-02-23 19:53:32.790584049 +0100
***************
*** 4,8 ****
void ex_export(exarg_T *eap);
void free_imports(int sid);
void ex_import(exarg_T *eap);
! char_u *handle_import(char_u *arg_start, garray_T *gap, int sid);
/* vim: set ft=c : */
--- 4,9 ----
void ex_export(exarg_T *eap);
void free_imports(int sid);
void ex_import(exarg_T *eap);
! int find_exported(int sid, char_u **argp, int *name_len, ufunc_T **ufunc,
type_T **type);
! char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid);
/* vim: set ft=c : */
*** ../vim-8.2.0311/src/vim9compile.c 2020-02-22 18:36:18.608483742 +0100
--- src/vim9compile.c 2020-02-23 20:05:36.468265602 +0100
***************
*** 1522,1528 ****
* Generate an instruction to load script-local variable "name".
*/
static int
! compile_load_scriptvar(cctx_T *cctx, char_u *name)
{
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
int idx = get_script_item_idx(current_sctx.sc_sid,
name, FALSE);
--- 1522,1532 ----
* Generate an instruction to load script-local variable "name".
*/
static int
! compile_load_scriptvar(
! cctx_T *cctx,
! char_u *name, // variable NUL terminated
! char_u *start, // start of variable
! char_u **end) // end of variable
{
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
int idx = get_script_item_idx(current_sctx.sc_sid,
name, FALSE);
***************
*** 1546,1556 ****
import = find_imported(name, 0, cctx);
if (import != NULL)
{
! // TODO: check this is a variable, not a function
! generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
! import->imp_sid,
! import->imp_var_vals_idx,
! import->imp_type);
return OK;
}
--- 1550,1589 ----
import = find_imported(name, 0, cctx);
if (import != NULL)
{
! if (import->imp_all)
! {
! char_u *p = skipwhite(*end);
! int name_len;
! ufunc_T *ufunc;
! type_T *type;
!
! // Used "import * as Name", need to lookup the member.
! if (*p != '.')
! {
! semsg(_("E1060: expected dot after name: %s"), start);
! return FAIL;
! }
! ++p;
!
! idx = find_exported(import->imp_sid, &p, &name_len, &ufunc, &type);
! // TODO: what if it is a function?
! if (idx < 0)
! return FAIL;
! *end = p;
!
! generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
! import->imp_sid,
! idx,
! type);
! }
! else
! {
! // TODO: check this is a variable, not a function
! generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
! import->imp_sid,
! import->imp_var_vals_idx,
! import->imp_type);
! }
return OK;
}
***************
*** 1564,1573 ****
* When "error" is FALSE do not give an error when not found.
*/
static int
! compile_load(char_u **arg, char_u *end, cctx_T *cctx, int error)
{
type_T *type;
char_u *name;
int res = FAIL;
if (*(*arg + 1) == ':')
--- 1597,1607 ----
* When "error" is FALSE do not give an error when not found.
*/
static int
! compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error)
{
type_T *type;
char_u *name;
+ char_u *end = end_arg;
int res = FAIL;
if (*(*arg + 1) == ':')
***************
*** 1589,1595 ****
}
else if (**arg == 's')
{
! res = compile_load_scriptvar(cctx, name);
}
else
{
--- 1623,1629 ----
}
else if (**arg == 's')
{
! res = compile_load_scriptvar(cctx, name, NULL, NULL);
}
else
{
***************
*** 1645,1651 ****
else if (SCRIPT_ITEM(current_sctx.sc_sid)->sn_version
== SCRIPT_VERSION_VIM9)
// in Vim9 script "var" can be script-local.
! res = compile_load_scriptvar(cctx, name);
}
}
if (gen_load)
--- 1679,1685 ----
else if (SCRIPT_ITEM(current_sctx.sc_sid)->sn_version
== SCRIPT_VERSION_VIM9)
// in Vim9 script "var" can be script-local.
! res = compile_load_scriptvar(cctx, name, *arg, &end);
}
}
if (gen_load)
***************
*** 3412,3418 ****
generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
break;
case dest_script:
! compile_load_scriptvar(cctx, name + (name[1] == ':' ? 2 :
0));
break;
case dest_env:
// Include $ in the name here
--- 3446,3452 ----
generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
break;
case dest_script:
! compile_load_scriptvar(cctx, name + (name[1] == ':' ? 2 :
0), NULL, NULL);
break;
case dest_env:
// Include $ in the name here
*** ../vim-8.2.0311/src/version.c 2020-02-23 18:08:29.463897252 +0100
--- src/version.c 2020-02-23 21:25:11.764786291 +0100
***************
*** 740,741 ****
--- 740,743 ----
{ /* Add new patch number below this line */
+ /**/
+ 312,
/**/
--
hundred-and-one symptoms of being an internet addict:
109. You actually read -- and enjoy -- lists like this.
/// Bram Moolenaar -- [email protected] -- 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 ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/202002232026.01NKQL61019331%40masaka.moolenaar.net.