To: vim_dev@googlegroups.com Subject: Patch 8.2.0312 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@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 ///