diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-06-27 14:11:53 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-06-27 14:11:53 +0200 |
commit | 8ea9390b78da9e34a20e7418712921397c0c1989 (patch) | |
tree | 763d4a683a512b240f7e604e518327fb7d0aa14f | |
parent | 0b1cd52ff6bf690388f892be686a91721a082e55 (diff) |
patch 8.2.1068: Vim9: no line break allowed inside a dictv8.2.1068
Problem: Vim9: no line break allowed inside a dict.
Solution: Handle line break inside a dict in Vim9 script.
-rw-r--r-- | src/dict.c | 45 | ||||
-rw-r--r-- | src/eval.c | 4 | ||||
-rw-r--r-- | src/proto/dict.pro | 2 | ||||
-rw-r--r-- | src/testdir/test_vim9_expr.vim | 40 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 4 |
6 files changed, 82 insertions, 15 deletions
diff --git a/src/dict.c b/src/dict.c index caa398deba..748a9917eb 100644 --- a/src/dict.c +++ b/src/dict.c @@ -792,10 +792,10 @@ get_literal_key(char_u **arg, typval_T *tv) * Return OK or FAIL. Returns NOTDONE for {expr}. */ int -eval_dict(char_u **arg, typval_T *rettv, int flags, int literal) +eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal) { - int evaluate = flags & EVAL_EVALUATE; - evalarg_T evalarg; + int evaluate = evalarg == NULL ? FALSE + : evalarg->eval_flags & EVAL_EVALUATE; dict_T *d = NULL; typval_T tvkey; typval_T tv; @@ -804,9 +804,8 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal) 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; + int had_comma; + int getnext; /* * First check if it's not a curly-braces thing: {expr}. @@ -833,11 +832,14 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal) 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! + : eval1(arg, &tvkey, evalarg)) == FAIL) // recursive! goto failret; if (**arg != ':') @@ -857,9 +859,17 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal) goto failret; } } + if (vim9script && (*arg)[1] != NUL && !VIM_ISWHITE((*arg)[1])) + { + semsg(_(e_white_after), ":"); + goto failret; + } *arg = skipwhite(*arg + 1); - if (eval1(arg, &tv, &evalarg) == FAIL) // recursive! + 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,15 +897,30 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal) } 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 (**arg != ',') + if (!had_comma) { if (evaluate) semsg(_(e_missing_dict_comma), *arg); goto failret; } - *arg = skipwhite(*arg + 1); } if (**arg != '}') diff --git a/src/eval.c b/src/eval.c index 4bbf65b036..0c8ab49c7f 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2787,7 +2787,7 @@ eval7( case '#': if ((*arg)[1] == '{') { ++*arg; - ret = eval_dict(arg, rettv, flags, TRUE); + ret = eval_dict(arg, rettv, evalarg, TRUE); } else ret = NOTDONE; @@ -2799,7 +2799,7 @@ eval7( */ case '{': ret = get_lambda_tv(arg, rettv, evaluate); if (ret == NOTDONE) - ret = eval_dict(arg, rettv, flags, FALSE); + ret = eval_dict(arg, rettv, evalarg, FALSE); break; /* diff --git a/src/proto/dict.pro b/src/proto/dict.pro index 45bcfbf3a9..093139f429 100644 --- a/src/proto/dict.pro +++ b/src/proto/dict.pro @@ -32,7 +32,7 @@ varnumber_T dict_get_number(dict_T *d, char_u *key); 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); +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); diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index 0976d9cdb1..30cf1b995b 100644 --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -1002,6 +1002,12 @@ def Test_expr7_list_vim9script() 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,6 +1040,40 @@ def Test_expr7_dict() 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<number> = g:dict_one diff --git a/src/version.c b/src/version.c index 0ab2b6ab43..f73afd8a1a 100644 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1068, +/**/ 1067, /**/ 1066, diff --git a/src/vim9compile.c b/src/vim9compile.c index f133a94b73..5d03e0f92c 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2996,7 +2996,7 @@ to_name_const_end(char_u *arg) { // Can be "#{a: 1}->Func()". ++p; - if (eval_dict(&p, &rettv, 0, TRUE) == FAIL) + if (eval_dict(&p, &rettv, NULL, TRUE) == FAIL) p = arg; } else if (p == arg && *arg == '{') @@ -3006,7 +3006,7 @@ to_name_const_end(char_u *arg) // Can be "{x -> ret}()". // Can be "{'a': 1}->Func()". if (ret == NOTDONE) - ret = eval_dict(&p, &rettv, 0, FALSE); + ret = eval_dict(&p, &rettv, NULL, FALSE); if (ret != OK) p = arg; } |