To: vim_dev@googlegroups.com Subject: Patch 8.2.3276 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3276 Problem: Vim9: exists() can only be evaluated at runtime. Solution: Evaluate at compile time for option name literals. (closes #8437) Files: src/vim9compile.c, src/evalfunc.c, src/proto/evalfunc.pro, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.3275/src/vim9compile.c 2021-08-02 19:10:30.961721085 +0200 --- src/vim9compile.c 2021-08-02 20:02:10.391517656 +0200 *************** *** 3395,3402 **** int is_autoload; int is_searchpair; ! // we can evaluate "has('name')" at compile time ! if (varlen == 3 && STRNCMP(*arg, "has", 3) == 0) { char_u *s = skipwhite(*arg + varlen + 1); typval_T argvars[2]; --- 3395,3404 ---- int is_autoload; int is_searchpair; ! // We can evaluate "has('name')" at compile time. ! // We can evaluate some "exists()" values at compile time. ! if ((varlen == 3 && STRNCMP(*arg, "has", 3) == 0) ! || (varlen == 6 && STRNCMP(*arg, "exists", 6) == 0)) { char_u *s = skipwhite(*arg + varlen + 1); typval_T argvars[2]; *************** *** 3408,3414 **** (void)eval_lit_string(&s, &argvars[0], TRUE); s = skipwhite(s); if (*s == ')' && argvars[0].v_type == VAR_STRING ! && !dynamic_feature(argvars[0].vval.v_string)) { typval_T *tv = &ppconst->pp_tv[ppconst->pp_used]; --- 3410,3418 ---- (void)eval_lit_string(&s, &argvars[0], TRUE); s = skipwhite(s); if (*s == ')' && argvars[0].v_type == VAR_STRING ! && ((**arg == 'h' && !dynamic_feature(argvars[0].vval.v_string)) ! || (**arg == 'e' && (*argvars[0].vval.v_string == '+' ! || *argvars[0].vval.v_string == '&')))) { typval_T *tv = &ppconst->pp_tv[ppconst->pp_used]; *************** *** 3416,3422 **** argvars[1].v_type = VAR_UNKNOWN; tv->v_type = VAR_NUMBER; tv->vval.v_number = 0; ! f_has(argvars, tv); clear_tv(&argvars[0]); ++ppconst->pp_used; return OK; --- 3420,3429 ---- argvars[1].v_type = VAR_UNKNOWN; tv->v_type = VAR_NUMBER; tv->vval.v_number = 0; ! if (**arg == 'h') ! f_has(argvars, tv); ! else ! f_exists(argvars, tv); clear_tv(&argvars[0]); ++ppconst->pp_used; return OK; *** ../vim-8.2.3275/src/evalfunc.c 2021-08-01 15:40:24.648232770 +0200 --- src/evalfunc.c 2021-08-02 19:57:01.668049213 +0200 *************** *** 49,55 **** static void f_eval(typval_T *argvars, typval_T *rettv); static void f_eventhandler(typval_T *argvars, typval_T *rettv); static void f_execute(typval_T *argvars, typval_T *rettv); - static void f_exists(typval_T *argvars, typval_T *rettv); static void f_expand(typval_T *argvars, typval_T *rettv); static void f_expandcmd(typval_T *argvars, typval_T *rettv); static void f_feedkeys(typval_T *argvars, typval_T *rettv); --- 49,54 ---- *************** *** 3521,3527 **** /* * "exists()" function */ ! static void f_exists(typval_T *argvars, typval_T *rettv) { char_u *p; --- 3520,3526 ---- /* * "exists()" function */ ! void f_exists(typval_T *argvars, typval_T *rettv) { char_u *p; *** ../vim-8.2.3275/src/proto/evalfunc.pro 2021-07-10 21:28:55.327050110 +0200 --- src/proto/evalfunc.pro 2021-08-02 19:56:54.400060990 +0200 *************** *** 18,23 **** --- 18,24 ---- win_T *get_optional_window(typval_T *argvars, int idx); void execute_redir_str(char_u *value, int value_len); void execute_common(typval_T *argvars, typval_T *rettv, int arg_off); + void f_exists(typval_T *argvars, typval_T *rettv); void f_has(typval_T *argvars, typval_T *rettv); int dynamic_feature(char_u *feature); void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv); *** ../vim-8.2.3275/src/testdir/test_vim9_builtin.vim 2021-07-31 22:03:54.508104860 +0200 --- src/testdir/test_vim9_builtin.vim 2021-08-02 20:01:15.019616717 +0200 *************** *** 790,795 **** --- 790,814 ---- def Test_exists() CheckDefAndScriptFailure2(['exists(10)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1') call assert_equal(1, exists('&tabstop')) + + if exists('+newoption') + if &newoption == 'ok' + endif + endif + if exists('&newoption') + if &newoption == 'ok' + endif + endif + if exists('+tabstop') + assert_equal(8, &tabstop) + else + assert_report('tabstop option not existing?') + endif + if exists('&tabstop') + assert_equal(8, &tabstop) + else + assert_report('tabstop option not existing?') + endif enddef def Test_expand() *** ../vim-8.2.3275/src/version.c 2021-08-02 19:10:30.961721085 +0200 --- src/version.c 2021-08-02 20:05:47.147118805 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3276, /**/ -- Not too long ago, a keyboard was something to make music with... /// 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 ///