To: vim_dev@googlegroups.com Subject: Patch 8.1.1722 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.1722 Problem: Error when scriptversion is 2 a making a dictionary access. Solution: Parse the subscript even when not evaluating the sub-expression. (closes #4704) Files: src/eval.c, src/testdir/test_eval_stuff.vim *** ../vim-8.1.1721/src/eval.c 2019-07-16 22:03:28.906863140 +0200 --- src/eval.c 2019-07-20 20:55:31.946250610 +0200 *************** *** 1486,1492 **** /* * Assign the typevalue "tv" to the variable or variables at "arg_start". * Handles both "var" with any type and "[var, var; var]" with a list type. ! * When "nextchars" is not NULL it points to a string with characters that * must appear after the variable(s). Use "+", "-" or "." for add, subtract * or concatenate. * Returns OK or FAIL; --- 1486,1492 ---- /* * Assign the typevalue "tv" to the variable or variables at "arg_start". * Handles both "var" with any type and "[var, var; var]" with a list type. ! * When "op" is not NULL it points to a string with characters that * must appear after the variable(s). Use "+", "-" or "." for add, subtract * or concatenate. * Returns OK or FAIL; *************** *** 1499,1505 **** int semicolon, // from skip_var_list() int var_count, // from skip_var_list() int is_const, // lock variables for const ! char_u *nextchars) { char_u *arg = arg_start; list_T *l; --- 1499,1505 ---- int semicolon, // from skip_var_list() int var_count, // from skip_var_list() int is_const, // lock variables for const ! char_u *op) { char_u *arg = arg_start; list_T *l; *************** *** 1512,1518 **** /* * ":let var = expr" or ":for var in list" */ ! if (ex_let_one(arg, tv, copy, is_const, nextchars, nextchars) == NULL) return FAIL; return OK; } --- 1512,1518 ---- /* * ":let var = expr" or ":for var in list" */ ! if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) return FAIL; return OK; } *************** *** 1543,1549 **** { arg = skipwhite(arg + 1); arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, ! (char_u *)",;]", nextchars); item = item->li_next; if (arg == NULL) return FAIL; --- 1543,1549 ---- { arg = skipwhite(arg + 1); arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, ! (char_u *)",;]", op); item = item->li_next; if (arg == NULL) return FAIL; *************** *** 1568,1574 **** l->lv_refcount = 1; arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, is_const, ! (char_u *)"]", nextchars); clear_tv(<v); if (arg == NULL) return FAIL; --- 1568,1574 ---- l->lv_refcount = 1; arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, is_const, ! (char_u *)"]", op); clear_tv(<v); if (arg == NULL) return FAIL; *************** *** 7355,7363 **** int len; typval_T functv; while (ret == OK && (**arg == '[' ! || (**arg == '.' && rettv->v_type == VAR_DICT) || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL))) && !VIM_ISWHITE(*(*arg - 1))) --- 7355,7368 ---- int len; typval_T functv; + // "." is ".name" lookup when we found a dict or when evaluating and + // scriptversion is at least 2, where string concatenation is "..". while (ret == OK && (**arg == '[' ! || (**arg == '.' && (rettv->v_type == VAR_DICT ! || (!evaluate ! && (*arg)[1] != '.' ! && current_sctx.sc_version >= 2))) || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL))) && !VIM_ISWHITE(*(*arg - 1))) *** ../vim-8.1.1721/src/testdir/test_eval_stuff.vim 2019-06-14 14:39:44.553975948 +0200 --- src/testdir/test_eval_stuff.vim 2019-07-20 20:32:51.939062672 +0200 *************** *** 176,181 **** --- 176,188 ---- call assert_true(v:versionlong > 8011525) endfunc + func Test_dict_access_scriptversion2() + let l:x = {'foo': 1} + + call assert_false(0 && l:x.foo) + call assert_true(1 && l:x.foo) + endfunc + func Test_scriptversion() call writefile(['scriptversion 9'], 'Xversionscript') call assert_fails('source Xversionscript', 'E999:') *** ../vim-8.1.1721/src/version.c 2019-07-20 19:14:46.210396115 +0200 --- src/version.c 2019-07-20 21:00:50.143969149 +0200 *************** *** 779,780 **** --- 779,782 ---- { /* Add new patch number below this line */ + /**/ + 1722, /**/ -- TERRY GILLIAM PLAYED: PATSY (ARTHUR'S TRUSTY STEED), THE GREEN KNIGHT SOOTHSAYER, BRIDGEKEEPER, SIR GAWAIN (THE FIRST TO BE KILLED BY THE RABBIT) "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// 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 ///