To: vim_dev@googlegroups.com Subject: Patch 8.2.1510 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1510 Problem: Using "var" in a :def function may refer to a legacy Vim script variable. Solution: Require using "s:" to refer to a legacy Vim script variable. (closes #6771) Files: src/vim9compile.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.1509/src/vim9compile.c 2020-08-21 22:36:43.662719906 +0200 --- src/vim9compile.c 2020-08-22 18:54:08.557602751 +0200 *************** *** 260,274 **** /* * Lookup a variable in the current script. * Returns OK or FAIL. */ static int ! lookup_script(char_u *name, size_t len) { int cc; hashtab_T *ht = &SCRIPT_VARS(current_sctx.sc_sid); dictitem_T *di; cc = name[len]; name[len] = NUL; di = find_var_in_ht(ht, 0, name, TRUE); --- 260,279 ---- /* * Lookup a variable in the current script. + * If "vim9script" is TRUE the script must be Vim9 script. Used for "var" + * without "s:". * Returns OK or FAIL. */ static int ! lookup_script(char_u *name, size_t len, int vim9script) { int cc; hashtab_T *ht = &SCRIPT_VARS(current_sctx.sc_sid); dictitem_T *di; + if (vim9script && SCRIPT_ITEM(current_sctx.sc_sid)->sn_version + != SCRIPT_VERSION_VIM9) + return FAIL; cc = name[len]; name[len] = NUL; di = find_var_in_ht(ht, 0, name, TRUE); *************** *** 287,293 **** int c = p[len]; p[len] = NUL; ! if (lookup_script(p, len) == OK || (cctx != NULL && (lookup_local(p, len, cctx) != NULL || lookup_arg(p, len, NULL, NULL, NULL, cctx) == OK)) --- 292,298 ---- int c = p[len]; p[len] = NUL; ! if (lookup_script(p, len, FALSE) == OK || (cctx != NULL && (lookup_local(p, len, cctx) != NULL || lookup_arg(p, len, NULL, NULL, NULL, cctx) == OK)) *************** *** 2145,2159 **** else { // "var" can be script-local even without using "s:" if it ! // already exists. ! if (SCRIPT_ITEM(current_sctx.sc_sid)->sn_version ! == SCRIPT_VERSION_VIM9 ! || lookup_script(*arg, len) == OK) ! res = compile_load_scriptvar(cctx, name, *arg, &end, ! FALSE); // When the name starts with an uppercase letter or "x:" it // can be a user defined function. if (res == FAIL && (ASCII_ISUPPER(*name) || name[1] == ':')) res = generate_funcref(cctx, name); } --- 2150,2163 ---- else { // "var" can be script-local even without using "s:" if it ! // already exists in a Vim9 script or when it's imported. ! if (lookup_script(*arg, len, TRUE) == OK ! || find_imported(name, 0, cctx) != NULL) ! res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE); // When the name starts with an uppercase letter or "x:" it // can be a user defined function. + // TODO: this is just guessing if (res == FAIL && (ASCII_ISUPPER(*name) || name[1] == ':')) res = generate_funcref(cctx, name); } *************** *** 4697,4704 **** int script_namespace = varlen > 1 && STRNCMP(var_start, "s:", 2) == 0; int script_var = (script_namespace ! ? lookup_script(var_start + 2, varlen - 2) ! : lookup_script(var_start, varlen)) == OK; imported_T *import = find_imported(var_start, varlen, cctx); --- 4701,4708 ---- int script_namespace = varlen > 1 && STRNCMP(var_start, "s:", 2) == 0; int script_var = (script_namespace ! ? lookup_script(var_start + 2, varlen - 2, FALSE) ! : lookup_script(var_start, varlen, TRUE)) == OK; imported_T *import = find_imported(var_start, varlen, cctx); *************** *** 6637,6643 **** || lookup_local(ea.cmd, len, &cctx) != NULL || lookup_arg(ea.cmd, len, NULL, NULL, NULL, &cctx) == OK ! || lookup_script(ea.cmd, len) == OK || find_imported(ea.cmd, len, &cctx) != NULL) { line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx); --- 6641,6647 ---- || lookup_local(ea.cmd, len, &cctx) != NULL || lookup_arg(ea.cmd, len, NULL, NULL, NULL, &cctx) == OK ! || lookup_script(ea.cmd, len, FALSE) == OK || find_imported(ea.cmd, len, &cctx) != NULL) { line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx); *** ../vim-8.2.1509/src/testdir/test_vim9_func.vim 2020-08-22 15:06:29.420409081 +0200 --- src/testdir/test_vim9_func.vim 2020-08-22 18:32:02.197128398 +0200 *************** *** 829,858 **** let s:funcResult = 0 def FuncNoArgNoRet() ! funcResult = 11 enddef def FuncNoArgRetNumber(): number ! funcResult = 22 return 1234 enddef def FuncNoArgRetString(): string ! funcResult = 45 return 'text' enddef def FuncOneArgNoRet(arg: number) ! funcResult = arg enddef def FuncOneArgRetNumber(arg: number): number ! funcResult = arg return arg enddef def FuncTwoArgNoRet(one: bool, two: number) ! funcResult = two enddef def FuncOneArgRetString(arg: string): string --- 829,858 ---- let s:funcResult = 0 def FuncNoArgNoRet() ! s:funcResult = 11 enddef def FuncNoArgRetNumber(): number ! s:funcResult = 22 return 1234 enddef def FuncNoArgRetString(): string ! s:funcResult = 45 return 'text' enddef def FuncOneArgNoRet(arg: number) ! s:funcResult = arg enddef def FuncOneArgRetNumber(arg: number): number ! s:funcResult = arg return arg enddef def FuncTwoArgNoRet(one: bool, two: number) ! s:funcResult = two enddef def FuncOneArgRetString(arg: string): string *************** *** 865,895 **** def Test_func_type() let Ref1: func() ! funcResult = 0 Ref1 = FuncNoArgNoRet Ref1() ! assert_equal(11, funcResult) let Ref2: func ! funcResult = 0 Ref2 = FuncNoArgNoRet Ref2() ! assert_equal(11, funcResult) ! funcResult = 0 Ref2 = FuncOneArgNoRet Ref2(12) ! assert_equal(12, funcResult) ! funcResult = 0 Ref2 = FuncNoArgRetNumber assert_equal(1234, Ref2()) ! assert_equal(22, funcResult) ! funcResult = 0 Ref2 = FuncOneArgRetNumber assert_equal(13, Ref2(13)) ! assert_equal(13, funcResult) enddef def Test_repeat_return_type() --- 865,895 ---- def Test_func_type() let Ref1: func() ! s:funcResult = 0 Ref1 = FuncNoArgNoRet Ref1() ! assert_equal(11, s:funcResult) let Ref2: func ! s:funcResult = 0 Ref2 = FuncNoArgNoRet Ref2() ! assert_equal(11, s:funcResult) ! s:funcResult = 0 Ref2 = FuncOneArgNoRet Ref2(12) ! assert_equal(12, s:funcResult) ! s:funcResult = 0 Ref2 = FuncNoArgRetNumber assert_equal(1234, Ref2()) ! assert_equal(22, s:funcResult) ! s:funcResult = 0 Ref2 = FuncOneArgRetNumber assert_equal(13, Ref2(13)) ! assert_equal(13, s:funcResult) enddef def Test_repeat_return_type() *** ../vim-8.2.1509/src/version.c 2020-08-22 17:21:10.250012064 +0200 --- src/version.c 2020-08-22 18:54:59.981483570 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1510, /**/ -- Two fish in a tank. One says to the other: "Do you know how to drive this thing?" /// 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 ///