Patch 8.2.2449
Problem:    Vim9: flatten() always changes the list type.
Solution:   Disallow using flatten() and add flattennew().
Files:      runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/evalfunc.c,
            src/list.c, src/proto/list.pro, src/errors.h, src/vim9compile.c,
            src/testdir/test_flatten.vim, src/testdir/test_vim9_builtin.vim


*** ../vim-8.2.2448/runtime/doc/eval.txt        2021-01-31 17:02:06.250490190 
+0100
--- runtime/doc/eval.txt        2021-02-01 19:48:59.899320314 +0100
***************
*** 2549,2554 ****
--- 2549,2556 ----
  findfile({name} [, {path} [, {count}]])
                                String  find file {name} in {path}
  flatten({list} [, {maxdepth}])        List    flatten {list} up to {maxdepth} 
levels
+ flattennew({list} [, {maxdepth}])
+                               List    flatten a copy of {list}
  float2nr({expr})              Number  convert Float {expr} to a Number
  floor({expr})                 Float   round {expr} down
  fmod({expr1}, {expr2})                Float   remainder of {expr1} / {expr2}
***************
*** 4712,4719 ****
                Flatten {list} up to {maxdepth} levels.  Without {maxdepth}
                the result is a |List| without nesting, as if {maxdepth} is
                a very large number.
!               The {list} is changed in place, make a copy first if you do
                not want that.
                                                                *E900*
                {maxdepth} means how deep in nested lists changes are made.
                {list} is not modified when {maxdepth} is 0.
--- 4714,4723 ----
                Flatten {list} up to {maxdepth} levels.  Without {maxdepth}
                the result is a |List| without nesting, as if {maxdepth} is
                a very large number.
!               The {list} is changed in place, use |flattennew()| if you do
                not want that.
+               In Vim9 script flatten() cannot be used, you must always use
+               |flattennew()|.
                                                                *E900*
                {maxdepth} means how deep in nested lists changes are made.
                {list} is not modified when {maxdepth} is 0.
***************
*** 4727,4732 ****
--- 4731,4740 ----
                        :echo flatten([1, [2, [3, 4]], 5], 1)
  <                     [1, 2, [3, 4], 5]
  
+ flattennew({list} [, {maxdepth}])                     *flattennew()*
+               Like |flatten()| but first make a copy of {list}.
+ 
+ 
  float2nr({expr})                                      *float2nr()*
                Convert {expr} to a Number by omitting the part after the
                decimal point.
*** ../vim-8.2.2448/runtime/doc/usr_41.txt      2021-01-31 17:02:06.266490126 
+0100
--- runtime/doc/usr_41.txt      2021-02-01 19:49:35.455237261 +0100
***************
*** 665,670 ****
--- 665,671 ----
        count()                 count number of times a value appears in a List
        repeat()                repeat a List multiple times
        flatten()               flatten a List
+       flattennew()            flatten a copy of a List
  
  Dictionary manipulation:                              *dict-functions*
        get()                   get an entry without an error for a wrong key
*** ../vim-8.2.2448/src/evalfunc.c      2021-01-31 20:48:55.162175817 +0100
--- src/evalfunc.c      2021-02-01 19:50:24.523120307 +0100
***************
*** 954,959 ****
--- 954,961 ----
                        ret_string,         f_findfile},
      {"flatten",               1, 2, FEARG_1,      NULL,
                        ret_list_any,       f_flatten},
+     {"flattennew",    1, 2, FEARG_1,      NULL,
+                       ret_list_any,       f_flattennew},
      {"float2nr",      1, 1, FEARG_1,      NULL,
                        ret_number,         FLOAT_FUNC(f_float2nr)},
      {"floor",         1, 1, FEARG_1,      NULL,
*** ../vim-8.2.2448/src/list.c  2021-01-31 17:48:26.358330166 +0100
--- src/list.c  2021-02-01 20:03:02.281100687 +0100
***************
*** 740,746 ****
   * It does nothing if "maxdepth" is 0.
   * Returns FAIL when out of memory.
   */
!     static int
  list_flatten(list_T *list, long maxdepth)
  {
      listitem_T        *item;
--- 740,746 ----
   * It does nothing if "maxdepth" is 0.
   * Returns FAIL when out of memory.
   */
!     static void
  list_flatten(list_T *list, long maxdepth)
  {
      listitem_T        *item;
***************
*** 748,754 ****
      int               n;
  
      if (maxdepth == 0)
!       return OK;
      CHECK_LIST_MATERIALIZE(list);
  
      n = 0;
--- 748,754 ----
      int               n;
  
      if (maxdepth == 0)
!       return;
      CHECK_LIST_MATERIALIZE(list);
  
      n = 0;
***************
*** 757,763 ****
      {
        fast_breakcheck();
        if (got_int)
!           return FAIL;
  
        if (item->li_tv.v_type == VAR_LIST)
        {
--- 757,763 ----
      {
        fast_breakcheck();
        if (got_int)
!           return;
  
        if (item->li_tv.v_type == VAR_LIST)
        {
***************
*** 765,771 ****
  
            vimlist_remove(list, item, item);
            if (list_extend(list, item->li_tv.vval.v_list, next) == FAIL)
!               return FAIL;
            clear_tv(&item->li_tv);
            tofree = item;
  
--- 765,771 ----
  
            vimlist_remove(list, item, item);
            if (list_extend(list, item->li_tv.vval.v_list, next) == FAIL)
!               return;
            clear_tv(&item->li_tv);
            tofree = item;
  
***************
*** 787,801 ****
            item = item->li_next;
        }
      }
- 
-     return OK;
  }
  
  /*
!  * "flatten(list[, {maxdepth}])" function
   */
!     void
! f_flatten(typval_T *argvars, typval_T *rettv)
  {
      list_T  *l;
      long    maxdepth;
--- 787,799 ----
            item = item->li_next;
        }
      }
  }
  
  /*
!  * "flatten()" and "flattennew()" functions
   */
!     static void
! flatten_common(typval_T *argvars, typval_T *rettv, int make_copy)
  {
      list_T  *l;
      long    maxdepth;
***************
*** 822,831 ****
      }
  
      l = argvars[0].vval.v_list;
!     if (l != NULL && !value_check_lock(l->lv_lock,
!                                     (char_u *)N_("flatten() argument"), TRUE)
!                && list_flatten(l, maxdepth) == OK)
!       copy_tv(&argvars[0], rettv);
  }
  
  /*
--- 820,867 ----
      }
  
      l = argvars[0].vval.v_list;
!     rettv->v_type = VAR_LIST;
!     rettv->vval.v_list = l;
!     if (l == NULL)
!       return;
! 
!     if (make_copy)
!     {
!       l = list_copy(l, TRUE, get_copyID());
!       rettv->vval.v_list = l;
!       if (l == NULL)
!           return;
!     }
!     else
!     {
!       if (value_check_lock(l->lv_lock,
!                                    (char_u *)N_("flatten() argument"), TRUE))
!           return;
!       ++l->lv_refcount;
!     }
! 
!     list_flatten(l, maxdepth);
! }
! 
! /*
!  * "flatten(list[, {maxdepth}])" function
!  */
!     void
! f_flatten(typval_T *argvars, typval_T *rettv)
! {
!     if (in_vim9script())
!       emsg(_(e_cannot_use_flatten_in_vim9_script));
!     else
!       flatten_common(argvars, rettv, FALSE);
! }
! 
! /*
!  * "flattennew(list[, {maxdepth}])" function
!  */
!     void
! f_flattennew(typval_T *argvars, typval_T *rettv)
! {
!     flatten_common(argvars, rettv, TRUE);
  }
  
  /*
*** ../vim-8.2.2448/src/proto/list.pro  2021-01-13 21:46:53.832589880 +0100
--- src/proto/list.pro  2021-02-01 19:54:08.770557406 +0100
***************
*** 31,36 ****
--- 31,37 ----
  int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
  void list_insert(list_T *l, listitem_T *ni, listitem_T *item);
  void f_flatten(typval_T *argvars, typval_T *rettv);
+ void f_flattennew(typval_T *argvars, typval_T *rettv);
  int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
  int list_concat(list_T *l1, list_T *l2, typval_T *tv);
  list_T *list_slice(list_T *ol, long n1, long n2);
*** ../vim-8.2.2448/src/errors.h        2021-01-31 22:18:21.977811108 +0100
--- src/errors.h        2021-02-01 19:54:23.870518098 +0100
***************
*** 351,353 ****
--- 351,355 ----
        INIT(= N_("E1156: Cannot change the argument list recursively"));
  EXTERN char e_missing_return_type[]
        INIT(= N_("E1157: Missing return type"));
+ EXTERN char e_cannot_use_flatten_in_vim9_script[]
+       INIT(= N_("E1158: Cannot use flatten() in Vim9 script"));
*** ../vim-8.2.2448/src/vim9compile.c   2021-01-31 21:47:39.036783041 +0100
--- src/vim9compile.c   2021-02-01 20:11:35.063630218 +0100
***************
*** 2900,2905 ****
--- 2900,2911 ----
        idx = find_internal_func(name);
        if (idx >= 0)
        {
+           if (STRCMP(name, "flatten") == 0)
+           {
+               emsg(_(e_cannot_use_flatten_in_vim9_script));
+               goto theend;
+           }
+ 
            if (STRCMP(name, "add") == 0 && argcount == 2)
            {
                garray_T    *stack = &cctx->ctx_type_stack;
*** ../vim-8.2.2448/src/testdir/test_flatten.vim        2020-08-12 
18:50:31.879655802 +0200
--- src/testdir/test_flatten.vim        2021-02-01 20:06:39.924481595 +0100
***************
*** 81,84 ****
--- 81,93 ----
    call assert_equal([2, l:x], l:y)
  endfunc
  
+ func Test_flattennew()
+   let l = [1, [2, [3, 4]], 5]
+   call assert_equal([1, 2, 3, 4, 5], flattennew(l))
+   call assert_equal([1, [2, [3, 4]], 5], l)
+ 
+   call assert_equal([1, 2, [3, 4], 5], flattennew(l, 1))
+   call assert_equal([1, [2, [3, 4]], 5], l)
+ endfunc
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.2448/src/testdir/test_vim9_builtin.vim   2021-01-31 
20:48:55.162175817 +0100
--- src/testdir/test_vim9_builtin.vim   2021-02-01 20:09:18.728024772 +0100
***************
*** 382,387 ****
--- 382,404 ----
    CheckDefExecFailure(['echo findfile("")'], 'E1142:')
  enddef
  
+ def Test_flattennew()
+   var lines =<< trim END
+       var l = [1, [2, [3, 4]], 5]
+       call assert_equal([1, 2, 3, 4, 5], flattennew(l))
+       call assert_equal([1, [2, [3, 4]], 5], l)
+ 
+       call assert_equal([1, 2, [3, 4], 5], flattennew(l, 1))
+       call assert_equal([1, [2, [3, 4]], 5], l)
+   END
+   CheckDefAndScriptSuccess(lines)
+ 
+   lines =<< trim END
+       echo flatten([1, 2, 3])
+   END
+   CheckDefAndScriptFailure(lines, 'E1158:')
+ enddef
+ 
  def Test_fnamemodify()
    CheckDefSuccess(['echo fnamemodify(test_null_string(), ":p")'])
    CheckDefSuccess(['echo fnamemodify("", ":p")'])
*** ../vim-8.2.2448/src/version.c       2021-02-01 19:31:43.969603658 +0100
--- src/version.c       2021-02-01 19:51:03.851024757 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2449,
  /**/

-- 
Facepalm reply #9: "Speed up, you can drive 80 here" "Why, the cars behind us
are also driving 60"

 /// 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/202102011915.111JFKhP1304916%40masaka.moolenaar.net.

Raspunde prin e-mail lui