To: vim_dev@googlegroups.com Subject: Patch 8.2.1068 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1068 Problem: Vim9: no line break allowed inside a dict. Solution: Handle line break inside a dict in Vim9 script. Files: src/eval.c, src/dict.c, src/proto/dict.pro, src/vim9compile.c, src/testdir/test_vim9_expr.vim *** ../vim-8.2.1067/src/eval.c 2020-06-27 13:11:46.863462713 +0200 --- src/eval.c 2020-06-27 13:49:56.327406666 +0200 *************** *** 2787,2793 **** case '#': if ((*arg)[1] == '{') { ++*arg; ! ret = eval_dict(arg, rettv, flags, TRUE); } else ret = NOTDONE; --- 2787,2793 ---- case '#': if ((*arg)[1] == '{') { ++*arg; ! ret = eval_dict(arg, rettv, evalarg, TRUE); } else ret = NOTDONE; *************** *** 2799,2805 **** */ case '{': ret = get_lambda_tv(arg, rettv, evaluate); if (ret == NOTDONE) ! ret = eval_dict(arg, rettv, flags, FALSE); break; /* --- 2799,2805 ---- */ case '{': ret = get_lambda_tv(arg, rettv, evaluate); if (ret == NOTDONE) ! ret = eval_dict(arg, rettv, evalarg, FALSE); break; /* *** ../vim-8.2.1067/src/dict.c 2020-06-24 18:37:28.355249390 +0200 --- src/dict.c 2020-06-27 14:09:58.023658054 +0200 *************** *** 792,801 **** * Return OK or FAIL. Returns NOTDONE for {expr}. */ int ! eval_dict(char_u **arg, typval_T *rettv, int flags, int literal) { ! int evaluate = flags & EVAL_EVALUATE; ! evalarg_T evalarg; dict_T *d = NULL; typval_T tvkey; typval_T tv; --- 792,801 ---- * Return OK or FAIL. Returns NOTDONE for {expr}. */ int ! eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal) { ! int evaluate = evalarg == NULL ? FALSE ! : evalarg->eval_flags & EVAL_EVALUATE; dict_T *d = NULL; typval_T tvkey; typval_T tv; *************** *** 804,812 **** char_u *start = skipwhite(*arg + 1); char_u buf[NUMBUFLEN]; int vim9script = current_sctx.sc_version == SCRIPT_VERSION_VIM9; ! ! CLEAR_FIELD(evalarg); ! evalarg.eval_flags = flags; /* * First check if it's not a curly-braces thing: {expr}. --- 804,811 ---- char_u *start = skipwhite(*arg + 1); char_u buf[NUMBUFLEN]; int vim9script = current_sctx.sc_version == SCRIPT_VERSION_VIM9; ! int had_comma; ! int getnext; /* * First check if it's not a curly-braces thing: {expr}. *************** *** 833,843 **** tv.v_type = VAR_UNKNOWN; *arg = skipwhite(*arg + 1); while (**arg != '}' && **arg != NUL) { if ((literal ? get_literal_key(arg, &tvkey) ! : eval1(arg, &tvkey, &evalarg)) == FAIL) // recursive! goto failret; if (**arg != ':') --- 832,845 ---- tv.v_type = VAR_UNKNOWN; *arg = skipwhite(*arg + 1); + eval_next_non_blank(*arg, evalarg, &getnext); + if (getnext) + *arg = eval_next_line(evalarg); while (**arg != '}' && **arg != NUL) { if ((literal ? get_literal_key(arg, &tvkey) ! : eval1(arg, &tvkey, evalarg)) == FAIL) // recursive! goto failret; if (**arg != ':') *************** *** 857,865 **** goto failret; } } *arg = skipwhite(*arg + 1); ! if (eval1(arg, &tv, &evalarg) == FAIL) // recursive! { if (evaluate) clear_tv(&tvkey); --- 859,875 ---- goto failret; } } + if (vim9script && (*arg)[1] != NUL && !VIM_ISWHITE((*arg)[1])) + { + semsg(_(e_white_after), ":"); + goto failret; + } *arg = skipwhite(*arg + 1); ! eval_next_non_blank(*arg, evalarg, &getnext); ! if (getnext) ! *arg = eval_next_line(evalarg); ! if (eval1(arg, &tv, evalarg) == FAIL) // recursive! { if (evaluate) clear_tv(&tvkey); *************** *** 887,901 **** } clear_tv(&tvkey); if (**arg == '}') break; ! if (**arg != ',') { if (evaluate) semsg(_(e_missing_dict_comma), *arg); goto failret; } - *arg = skipwhite(*arg + 1); } if (**arg != '}') --- 897,926 ---- } clear_tv(&tvkey); + // the comma must come after the value + had_comma = **arg == ','; + if (had_comma) + { + if (vim9script && (*arg)[1] != NUL && !VIM_ISWHITE((*arg)[1])) + { + semsg(_(e_white_after), ","); + goto failret; + } + *arg = skipwhite(*arg + 1); + } + + // the "}" can be on the next line + eval_next_non_blank(*arg, evalarg, &getnext); + if (getnext) + *arg = eval_next_line(evalarg); if (**arg == '}') break; ! if (!had_comma) { if (evaluate) semsg(_(e_missing_dict_comma), *arg); goto failret; } } if (**arg != '}') *** ../vim-8.2.1067/src/proto/dict.pro 2020-05-10 15:24:41.388262074 +0200 --- src/proto/dict.pro 2020-06-27 13:52:05.467510250 +0200 *************** *** 32,38 **** varnumber_T dict_get_number_def(dict_T *d, char_u *key, int def); varnumber_T dict_get_number_check(dict_T *d, char_u *key); char_u *dict2string(typval_T *tv, int copyID, int restore_copyID); ! int eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal); void dict_extend(dict_T *d1, dict_T *d2, char_u *action); dictitem_T *dict_lookup(hashitem_T *hi); int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive); --- 32,38 ---- varnumber_T dict_get_number_def(dict_T *d, char_u *key, int def); varnumber_T dict_get_number_check(dict_T *d, char_u *key); char_u *dict2string(typval_T *tv, int copyID, int restore_copyID); ! int eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal); void dict_extend(dict_T *d1, dict_T *d2, char_u *action); dictitem_T *dict_lookup(hashitem_T *hi); int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive); *** ../vim-8.2.1067/src/vim9compile.c 2020-06-26 22:46:23.233370940 +0200 --- src/vim9compile.c 2020-06-27 13:51:24.907470679 +0200 *************** *** 2996,3002 **** { // Can be "#{a: 1}->Func()". ++p; ! if (eval_dict(&p, &rettv, 0, TRUE) == FAIL) p = arg; } else if (p == arg && *arg == '{') --- 2996,3002 ---- { // Can be "#{a: 1}->Func()". ++p; ! if (eval_dict(&p, &rettv, NULL, TRUE) == FAIL) p = arg; } else if (p == arg && *arg == '{') *************** *** 3006,3012 **** // Can be "{x -> ret}()". // Can be "{'a': 1}->Func()". if (ret == NOTDONE) ! ret = eval_dict(&p, &rettv, 0, FALSE); if (ret != OK) p = arg; } --- 3006,3012 ---- // Can be "{x -> ret}()". // Can be "{'a': 1}->Func()". if (ret == NOTDONE) ! ret = eval_dict(&p, &rettv, NULL, FALSE); if (ret != OK) p = arg; } *** ../vim-8.2.1067/src/testdir/test_vim9_expr.vim 2020-06-27 13:11:46.863462713 +0200 --- src/testdir/test_vim9_expr.vim 2020-06-27 14:10:59.803083661 +0200 *************** *** 1002,1007 **** --- 1002,1013 ---- assert_equal([11, 22], l) END CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + let l = [11,22] + END + CheckScriptFailure(lines, 'E1069:') enddef def Test_expr7_lambda() *************** *** 1034,1039 **** --- 1040,1079 ---- call CheckDefExecFailure(["let x = g:dict_empty.member"], 'E716:') enddef + def Test_expr7_dict_vim9script() + let lines =<< trim END + vim9script + let d = { + 'one': + 1, + 'two': 2, + } + assert_equal({'one': 1, 'two': 2}, d) + END + CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + let d = #{one: 1, + two: 2, + } + assert_equal({'one': 1, 'two': 2}, d) + END + CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + let d = #{one:1, two: 2} + END + CheckScriptFailure(lines, 'E1069:') + + lines =<< trim END + vim9script + let d = #{one: 1,two: 2} + END + CheckScriptFailure(lines, 'E1069:') + enddef + def Test_expr_member() assert_equal(1, g:dict_one.one) let d: dict = g:dict_one *** ../vim-8.2.1067/src/version.c 2020-06-27 13:11:46.863462713 +0200 --- src/version.c 2020-06-27 14:11:23.710872985 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1068, /**/ -- Behold the warranty! The bold print giveth and the fine print taketh. /// 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 ///