To: vim_dev@googlegroups.com Subject: Patch 8.2.4137 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4137 Problem: Vim9: calling import with and without method is inconsistent. Solution: Set a flag that a parenthsis follows to compile_load_scriptvar(). Add some more tests. Improve error message. Files: src/vim9expr.c, src/vim9execute.c, src/vim9script.c, src/testdir/test_vim9_import.vim *** ../vim-8.2.4136/src/vim9expr.c 2022-01-17 20:50:36.491316623 +0000 --- src/vim9expr.c 2022-01-18 16:51:42.168358403 +0000 *************** *** 21,26 **** --- 21,29 ---- # include "vim9.h" #endif + // flag passed from compile_subscript() to compile_load_scriptvar() + static int paren_follows_after_expr = 0; + /* * Generate code for any ppconst entries. */ *************** *** 277,283 **** int done = FALSE; int res = OK; - // TODO: if this is an autoload import do something else. // Need to lookup the member. if (*p != '.') { --- 280,285 ---- *************** *** 306,312 **** // autoload script must be loaded later, access by the autoload // name. ! if (cc == '(') res = generate_PUSHFUNC(cctx, auto_name, &t_func_any); else res = generate_LOAD(cctx, ISN_LOADG, 0, auto_name, &t_any); --- 308,314 ---- // autoload script must be loaded later, access by the autoload // name. ! if (cc == '(' || paren_follows_after_expr) res = generate_PUSHFUNC(cctx, auto_name, &t_func_any); else res = generate_LOAD(cctx, ISN_LOADG, 0, auto_name, &t_any); *************** *** 1736,1747 **** --- 1738,1756 ---- int save_len = cctx->ctx_ufunc->uf_lines.ga_len; *paren = NUL; + + // instead of using LOADG for "import.Func" use PUSHFUNC + ++paren_follows_after_expr; + // do not look in the next line cctx->ctx_ufunc->uf_lines.ga_len = 1; + fail = compile_expr8(arg, cctx, ppconst) == FAIL || *skipwhite(*arg) != NUL; *paren = '('; + --paren_follows_after_expr; cctx->ctx_ufunc->uf_lines.ga_len = save_len; + if (fail) { semsg(_(e_invalid_expression_str), pstart); *** ../vim-8.2.4136/src/vim9execute.c 2022-01-18 12:58:24.726772997 +0000 --- src/vim9execute.c 2022-01-18 17:29:48.517038067 +0000 *************** *** 2240,2272 **** iptr->isn_arg.string, TRUE); if (did_emsg) goto on_error; - if (di == NULL) - { - isn_T *next = &ectx->ec_instr[ectx->ec_iidx]; - - // When compiling "script.Func()" when "script" is - // an autoload import then this results in - // "LOADG script#Func" because we don't know if it - // is a funcref variable or a function name. In - // that case a PCALL follows, push the function - // name instead. - if (next->isn_type == ISN_PCALL) - { - tv = STACK_TV_BOT(0); - tv->v_type = VAR_FUNC; - tv->v_lock = 0; - tv->vval.v_string = - vim_strsave(iptr->isn_arg.string); - ++ectx->ec_stack.ga_len; - break; - } - } } if (di == NULL) { SOURCING_LNUM = iptr->isn_lnum; ! semsg(_(e_undefined_variable_char_str), namespace, iptr->isn_arg.string); goto on_error; } --- 2240,2258 ---- iptr->isn_arg.string, TRUE); if (did_emsg) goto on_error; } if (di == NULL) { SOURCING_LNUM = iptr->isn_lnum; ! if (vim_strchr(iptr->isn_arg.string, ! AUTOLOAD_CHAR) != NULL) ! // no check if the item exists in the script but ! // isn't exported, it is too complicated ! semsg(_(e_item_not_found_in_script_str), ! iptr->isn_arg.string); ! else ! semsg(_(e_undefined_variable_char_str), namespace, iptr->isn_arg.string); goto on_error; } *** ../vim-8.2.4136/src/vim9script.c 2022-01-18 16:25:58.618309943 +0000 --- src/vim9script.c 2022-01-18 17:10:23.319140985 +0000 *************** *** 707,728 **** sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); } *ufunc = find_func(funcname, FALSE); - if (funcname != buffer) - vim_free(funcname); if (*ufunc == NULL) { if (verbose) ! semsg(_(e_item_not_found_in_script_str), name); ! return -1; } else if (((*ufunc)->uf_flags & FC_EXPORT) == 0) { if (verbose) semsg(_(e_item_not_exported_in_script_str), name); *ufunc = NULL; - return -1; } } return idx; --- 707,742 ---- sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); } *ufunc = find_func(funcname, FALSE); if (*ufunc == NULL) { if (verbose) ! { ! ufunc_T *alt_ufunc = NULL; ! ! if (script->sn_autoload_prefix != NULL) ! { ! // try find the function by the script-local name ! funcname[0] = K_SPECIAL; ! funcname[1] = KS_EXTRA; ! funcname[2] = (int)KE_SNR; ! sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); ! alt_ufunc = find_func(funcname, FALSE); ! } ! if (alt_ufunc != NULL) ! semsg(_(e_item_not_exported_in_script_str), name); ! else ! semsg(_(e_item_not_found_in_script_str), name); ! } } else if (((*ufunc)->uf_flags & FC_EXPORT) == 0) { if (verbose) semsg(_(e_item_not_exported_in_script_str), name); *ufunc = NULL; } + if (funcname != buffer) + vim_free(funcname); } return idx; *** ../vim-8.2.4136/src/testdir/test_vim9_import.vim 2022-01-18 16:25:58.618309943 +0000 --- src/testdir/test_vim9_import.vim 2022-01-18 17:39:32.997562933 +0000 *************** *** 1256,1261 **** --- 1256,1391 ---- &rtp = save_rtp enddef + def Test_import_autoload_not_exported() + mkdir('Xdir/autoload', 'p') + var save_rtp = &rtp + exe 'set rtp^=' .. getcwd() .. '/Xdir' + + # error when using an item that is not exported from an autoload script + var exportLines =<< trim END + vim9script + var notExported = 123 + def NotExport() + echo 'nop' + enddef + END + writefile(exportLines, 'Xdir/autoload/notExport1.vim') + + var lines =<< trim END + vim9script + import autoload 'notExport1.vim' + echo notExport1.notFound + END + CheckScriptFailure(lines, 'E1048: Item not found in script: notFound') + + lines =<< trim END + vim9script + import autoload 'notExport1.vim' + echo notExport1.notExported + END + CheckScriptFailure(lines, 'E1049: Item not exported in script: notExported') + + lines =<< trim END + vim9script + import autoload 'notExport1.vim' + echo notExport1.NotFunc() + END + CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc') + + lines =<< trim END + vim9script + import autoload 'notExport1.vim' + echo notExport1.NotExport() + END + CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport') + + lines =<< trim END + vim9script + import autoload 'notExport1.vim' + echo 'text'->notExport1.NotFunc() + END + CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc') + + lines =<< trim END + vim9script + import autoload 'notExport1.vim' + echo 'text'->notExport1.NotExport() + END + CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport') + + # using a :def function we use a different autoload script every time so that + # the function is compiled without the script loaded + writefile(exportLines, 'Xdir/autoload/notExport2.vim') + lines =<< trim END + vim9script + import autoload 'notExport2.vim' + def Testit() + echo notExport2.notFound + enddef + Testit() + END + CheckScriptFailure(lines, 'E1048: Item not found in script: notExport2#notFound') + + writefile(exportLines, 'Xdir/autoload/notExport3.vim') + lines =<< trim END + vim9script + import autoload 'notExport3.vim' + def Testit() + echo notExport3.notExported + enddef + Testit() + END + # don't get E1049 because it is too complicated to figure out + CheckScriptFailure(lines, 'E1048: Item not found in script: notExport3#notExported') + + writefile(exportLines, 'Xdir/autoload/notExport4.vim') + lines =<< trim END + vim9script + import autoload 'notExport4.vim' + def Testit() + echo notExport4.NotFunc() + enddef + Testit() + END + CheckScriptFailure(lines, 'E117: Unknown function: notExport4#NotFunc') + + writefile(exportLines, 'Xdir/autoload/notExport5.vim') + lines =<< trim END + vim9script + import autoload 'notExport5.vim' + def Testit() + echo notExport5.NotExport() + enddef + Testit() + END + CheckScriptFailure(lines, 'E117: Unknown function: notExport5#NotExport') + + writefile(exportLines, 'Xdir/autoload/notExport6.vim') + lines =<< trim END + vim9script + import autoload 'notExport6.vim' + def Testit() + echo 'text'->notExport6.NotFunc() + enddef + Testit() + END + CheckScriptFailure(lines, 'E117: Unknown function: notExport6#NotFunc') + + writefile(exportLines, 'Xdir/autoload/notExport7.vim') + lines =<< trim END + vim9script + import autoload 'notExport7.vim' + def Testit() + echo 'text'->notExport7.NotExport() + enddef + Testit() + END + CheckScriptFailure(lines, 'E117: Unknown function: notExport7#NotExport') + + delete('Xdir', 'rf') + &rtp = save_rtp + enddef + def Test_vim9script_autoload_call() mkdir('Xdir/autoload', 'p') var save_rtp = &rtp *** ../vim-8.2.4136/src/version.c 2022-01-18 16:25:58.618309943 +0000 --- src/version.c 2022-01-18 16:48:20.320463461 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4137, /**/ -- f y cn rd ths thn y cn hv grt jb n cmptr prgrmmng /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///