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<number> = 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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202006271212.05RCCHX1037672%40masaka.moolenaar.net.

Raspunde prin e-mail lui