Patch 8.2.5026
Problem:    Vim9: a few lines not covered by tests.
Solution:   Delete dead code.  Add a few test cases. make "12->func()" work.
Files:      src/vim9type.c, src/ex_docmd.c, src/proto/ex_docmd.pro,
            src/vim9compile.c, src/testdir/test_vim9_assign.vim,
            src/testdir/test_vim9_func.vim


*** ../vim-8.2.5025/src/vim9type.c      2022-05-22 13:45:47.749779044 +0100
--- src/vim9type.c      2022-05-26 22:21:46.262567229 +0100
***************
*** 244,291 ****
  
  /*
   * Get a function type, based on the return type "ret_type".
!  * If "argcount" is -1 or 0 a predefined type can be used.
!  * If "argcount" > 0 always create a new type, so that arguments can be added.
   */
      type_T *
  get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
  {
      // recognize commonly used types
!     if (argcount <= 0)
      {
!       if (ret_type == &t_unknown || ret_type == NULL)
!       {
!           // (argcount == 0) is not possible
!           return &t_func_unknown;
!       }
!       if (ret_type == &t_void)
!       {
!           if (argcount == 0)
!               return &t_func_0_void;
!           else
!               return &t_func_void;
!       }
!       if (ret_type == &t_any)
!       {
!           if (argcount == 0)
!               return &t_func_0_any;
!           else
!               return &t_func_any;
!       }
!       if (ret_type == &t_number)
!       {
!           if (argcount == 0)
!               return &t_func_0_number;
!           else
!               return &t_func_number;
!       }
!       if (ret_type == &t_string)
!       {
!           if (argcount == 0)
!               return &t_func_0_string;
!           else
!               return &t_func_string;
!       }
      }
  
      return alloc_func_type(ret_type, argcount, type_gap);
--- 244,287 ----
  
  /*
   * Get a function type, based on the return type "ret_type".
!  * "argcount" must be -1 or 0, a predefined type can be used.
   */
      type_T *
  get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
  {
      // recognize commonly used types
!     if (ret_type == &t_unknown || ret_type == NULL)
      {
!       // (argcount == 0) is not possible
!       return &t_func_unknown;
!     }
!     if (ret_type == &t_void)
!     {
!       if (argcount == 0)
!           return &t_func_0_void;
!       else
!           return &t_func_void;
!     }
!     if (ret_type == &t_any)
!     {
!       if (argcount == 0)
!           return &t_func_0_any;
!       else
!           return &t_func_any;
!     }
!     if (ret_type == &t_number)
!     {
!       if (argcount == 0)
!           return &t_func_0_number;
!       else
!           return &t_func_number;
!     }
!     if (ret_type == &t_string)
!     {
!       if (argcount == 0)
!           return &t_func_0_string;
!       else
!           return &t_func_string;
      }
  
      return alloc_func_type(ret_type, argcount, type_gap);
***************
*** 541,547 ****
  {
      if (tv->v_type == VAR_LIST)  // e.g. for v:oldfiles
        return &t_list_string;
!     if (tv->v_type == VAR_DICT)  // e.g. for v:completed_item
        return &t_dict_any;
      return typval2type(tv, get_copyID(), type_gap, TVTT_DO_MEMBER);
  }
--- 537,543 ----
  {
      if (tv->v_type == VAR_LIST)  // e.g. for v:oldfiles
        return &t_list_string;
!     if (tv->v_type == VAR_DICT)  // e.g. for v:event
        return &t_dict_any;
      return typval2type(tv, get_copyID(), type_gap, TVTT_DO_MEMBER);
  }
***************
*** 1441,1446 ****
--- 1437,1443 ----
  type_name(type_T *type, char **tofree)
  {
      char *name;
+     char *arg_free = NULL;
  
      *tofree = NULL;
      if (type == NULL)
***************
*** 1469,1481 ****
  
        ga_init2(&ga, 1, 100);
        if (ga_grow(&ga, 20) == FAIL)
!           return "[unknown]";
        STRCPY(ga.ga_data, "func(");
        ga.ga_len += 5;
  
        for (i = 0; i < type->tt_argcount; ++i)
        {
-           char *arg_free = NULL;
            char *arg_type;
            int  len;
  
--- 1466,1477 ----
  
        ga_init2(&ga, 1, 100);
        if (ga_grow(&ga, 20) == FAIL)
!           goto failed;
        STRCPY(ga.ga_data, "func(");
        ga.ga_len += 5;
  
        for (i = 0; i < type->tt_argcount; ++i)
        {
            char *arg_type;
            int  len;
  
***************
*** 1490,1506 ****
            }
            len = (int)STRLEN(arg_type);
            if (ga_grow(&ga, len + 8) == FAIL)
!           {
!               vim_free(arg_free);
!               ga_clear(&ga);
!               return "[unknown]";
!           }
            if (varargs && i == type->tt_argcount - 1)
                ga_concat(&ga, (char_u *)"...");
            else if (i >= type->tt_min_argcount)
                *((char *)ga.ga_data + ga.ga_len++) = '?';
            ga_concat(&ga, (char_u *)arg_type);
!           vim_free(arg_free);
        }
        if (type->tt_argcount < 0)
            // any number of arguments
--- 1486,1498 ----
            }
            len = (int)STRLEN(arg_type);
            if (ga_grow(&ga, len + 8) == FAIL)
!               goto failed;
            if (varargs && i == type->tt_argcount - 1)
                ga_concat(&ga, (char_u *)"...");
            else if (i >= type->tt_min_argcount)
                *((char *)ga.ga_data + ga.ga_len++) = '?';
            ga_concat(&ga, (char_u *)arg_type);
!           VIM_CLEAR(arg_free);
        }
        if (type->tt_argcount < 0)
            // any number of arguments
***************
*** 1516,1532 ****
  
            len = (int)STRLEN(ret_name) + 4;
            if (ga_grow(&ga, len) == FAIL)
!           {
!               vim_free(ret_free);
!               ga_clear(&ga);
!               return "[unknown]";
!           }
            STRCPY((char *)ga.ga_data + ga.ga_len, "): ");
            STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name);
            vim_free(ret_free);
        }
        *tofree = ga.ga_data;
        return ga.ga_data;
      }
  
      return name;
--- 1508,1525 ----
  
            len = (int)STRLEN(ret_name) + 4;
            if (ga_grow(&ga, len) == FAIL)
!               goto failed;
            STRCPY((char *)ga.ga_data + ga.ga_len, "): ");
            STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name);
            vim_free(ret_free);
        }
        *tofree = ga.ga_data;
        return ga.ga_data;
+ 
+ failed:
+       vim_free(arg_free);
+       ga_clear(&ga);
+       return "[unknown]";
      }
  
      return name;
*** ../vim-8.2.5025/src/ex_docmd.c      2022-05-17 13:14:19.800706270 +0100
--- src/ex_docmd.c      2022-05-26 21:38:23.839998845 +0100
***************
*** 3507,3512 ****
--- 3507,3524 ----
  }
  
  /*
+  * Return TRUE if "cmd" starts with "123->", a number followed by a method
+  * call.
+  */
+     int
+ number_method(char_u *cmd)
+ {
+     char_u *p = skipdigits(cmd);
+ 
+     return p > cmd && (p = skipwhite(p))[0] == '-' && p[1] == '>';
+ }
+ 
+ /*
   * Find an Ex command by its name, either built-in or user.
   * Start of the name can be found at eap->cmd.
   * Sets eap->cmdidx and returns a pointer to char after the command name.
***************
*** 3716,3721 ****
--- 3728,3740 ----
            }
        }
  
+       // 1234->func() is a method call
+       if (number_method(eap->cmd))
+       {
+           eap->cmdidx = CMD_eval;
+           return eap->cmd;
+       }
+ 
        // "g:", "s:" and "l:" are always assumed to be a variable, thus start
        // an expression.  A global/substitute/list command needs to use a
        // longer name.
*** ../vim-8.2.5025/src/proto/ex_docmd.pro      2022-04-28 17:52:19.532130311 
+0100
--- src/proto/ex_docmd.pro      2022-05-26 21:38:28.171998368 +0100
***************
*** 17,22 ****
--- 17,23 ----
  void undo_cmdmod(cmdmod_T *cmod);
  int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
  char_u *skip_option_env_lead(char_u *start);
+ int number_method(char_u *cmd);
  char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, 
size_t, int cmd, cctx_T *), cctx_T *cctx);
  int modifier_len(char_u *cmd);
  int cmd_exists(char_u *name);
*** ../vim-8.2.5025/src/vim9compile.c   2022-05-25 19:15:06.382288150 +0100
--- src/vim9compile.c   2022-05-26 21:38:51.303995575 +0100
***************
*** 3001,3006 ****
--- 3001,3007 ----
         * 0z1234->func() should not be confused with a zero line number
         * "++nr" and "--nr" are eval commands
         * in "$ENV->func()" the "$" is not a range
+        * "123->func()" is a method call
         */
        cmd = ea.cmd;
        if ((*cmd != '$' || starts_with_colon)
***************
*** 3008,3014 ****
                    || !(*cmd == '\''
                        || (cmd[0] == '0' && cmd[1] == 'z')
                        || (cmd[0] != NUL && cmd[0] == cmd[1]
!                                           && (*cmd == '+' || *cmd == '-')))))
        {
            ea.cmd = skip_range(ea.cmd, TRUE, NULL);
            if (ea.cmd > cmd)
--- 3009,3016 ----
                    || !(*cmd == '\''
                        || (cmd[0] == '0' && cmd[1] == 'z')
                        || (cmd[0] != NUL && cmd[0] == cmd[1]
!                                           && (*cmd == '+' || *cmd == '-'))
!                       || number_method(cmd))))
        {
            ea.cmd = skip_range(ea.cmd, TRUE, NULL);
            if (ea.cmd > cmd)
*** ../vim-8.2.5025/src/testdir/test_vim9_assign.vim    2022-05-26 
19:54:02.187958880 +0100
--- src/testdir/test_vim9_assign.vim    2022-05-26 22:17:30.766753420 +0100
***************
*** 1121,1126 ****
--- 1121,1129 ----
    var dict4: dict<any> = {one: 1, two: '2'}
    var dict5: dict<blob> = {one: 0z01, two: 0z02}
  
+   # check the type is OK
+   var events: dict<string> = v:event
+ 
    # overwrite
    dict3['key'] = 'another'
    assert_equal(dict3, {key: 'another'})
***************
*** 2105,2110 ****
--- 2108,2139 ----
        va foo = 123
    END
    v9.CheckDefAndScriptFailure(lines, 'E1065:', 1)
+ 
+   lines =<< trim END
+       var foo: func(number
+   END
+   v9.CheckDefAndScriptFailure(lines, 'E110:', 1)
+ 
+   lines =<< trim END
+       var foo: func(number): func(
+   END
+   v9.CheckDefAndScriptFailure(lines, 'E110:', 1)
+ 
+   for type in ['num_ber',
+                'anys', 'ani',
+                'bools', 'boel',
+                'blobs', 'blub',
+                'channels', 'channol',
+                'dicts', 'duct',
+                'floats', 'floot',
+                'funcs', 'funk',
+                'jobs', 'jop',
+                'lists', 'last'
+                'numbers', 'numbar',
+                'strings', 'strung',
+                'voids', 'viod']
+     v9.CheckDefAndScriptFailure([$'var foo: {type}'], 'E1010:', 1)
+   endfor
  enddef
  
  def Test_var_declaration_inferred()
***************
*** 2118,2123 ****
--- 2147,2180 ----
        echo GetList()->extend(['x'])
    END
    v9.CheckScriptFailure(lines, 'E1013:', 6)
+ 
+   lines =<< trim END
+       vim9script
+       def GetNr(): number
+         return 5
+       enddef
+       def TestOne()
+         var some = [function('len'), GetNr]
+         g:res = typename(some)
+       enddef
+       TestOne()
+       assert_equal('list<func(): number>', g:res)
+ 
+       def TestTwo()
+         var some = [function('len'), GetNr]
+         g:res = typename(some)
+       enddef
+       TestTwo()
+       assert_equal('list<func(): number>', g:res)
+       unlet g:res
+ 
+       # FIXME: why is the type different?
+       var first = [function('len'), GetNr]
+       assert_equal('list<func(...): number>', typename(first))
+       var second = [GetNr, function('len')]
+       assert_equal('list<func(...): number>', typename(second))
+   END
+   v9.CheckScriptSuccess(lines)
  enddef
  
  def Test_script_local_in_legacy()
*** ../vim-8.2.5025/src/testdir/test_vim9_func.vim      2022-05-22 
13:45:47.749779044 +0100
--- src/testdir/test_vim9_func.vim      2022-05-26 21:27:44.140391584 +0100
***************
*** 4051,4056 ****
--- 4051,4113 ----
      echo [0, 1, 2]->map((_) => 123)
    END
    v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too 
many'], 1)
+ 
+   lines =<< trim END
+       vim9script
+       def OneArgument(arg: string)
+         echo arg
+       enddef
+       var Ref = OneArgument
+       Ref('a', 'b')
+   END
+   v9.CheckScriptFailure(lines, 'E118:')
+ enddef
+ 
+ def Test_funcref_with_base()
+   var lines =<< trim END
+       vim9script
+       def TwoArguments(str: string, nr: number)
+         echo str nr
+       enddef
+       var Ref = TwoArguments
+       Ref('a', 12)
+       'b'->Ref(34)
+   END
+   v9.CheckScriptSuccess(lines)
+ 
+   lines =<< trim END
+       vim9script
+       def TwoArguments(str: string, nr: number)
+         echo str nr
+       enddef
+       var Ref = TwoArguments
+       'a'->Ref('b')
+   END
+   v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected 
number but got string', 6)
+ 
+   lines =<< trim END
+       vim9script
+       def TwoArguments(str: string, nr: number)
+         echo str nr
+       enddef
+       var Ref = TwoArguments
+       123->Ref(456)
+   END
+   v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected 
string but got number')
+ 
+   lines =<< trim END
+       vim9script
+       def TwoArguments(nr: number, str: string)
+         echo str nr
+       enddef
+       var Ref = TwoArguments
+       123->Ref('b')
+       def AndNowCompiled()
+         456->Ref('x')
+       enddef
+       AndNowCompiled()
+   END
+   v9.CheckScriptSuccess(lines)
  enddef
  
  def Test_closing_brace_at_start_of_line()
*** ../vim-8.2.5025/src/version.c       2022-05-26 19:54:02.187958880 +0100
--- src/version.c       2022-05-26 20:41:11.850465465 +0100
***************
*** 736,737 ****
--- 736,739 ----
  {   /* Add new patch number below this line */
+ /**/
+     5026,
  /**/

-- 
Luxury. We used to have to get out of the lake at three o'clock in the 
morning, clean the lake, eat a handful of hot gravel, go to work at the 
mill every day for tuppence a month, come home, and Dad would beat us 
around the head and neck with a broken bottle, if we were LUCKY!

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20220526212524.2DD3E1C0B4C%40moolenaar.net.

Raspunde prin e-mail lui