Patch 8.2.0527
Problem:    Vim9: function types insufficiently tested.
Solution:   Add more tests.  Fix white space check.  Add "test_vim9" target.
Files:      src/vim9compile.c, src/testdir/test_vim9_func.vim, src/Makefile,
            src/testdir/Makefile, src/testdir/Make_all.mak


*** ../vim-8.2.0526/src/vim9compile.c   2020-04-06 22:12:57.145652827 +0200
--- src/vim9compile.c   2020-04-07 20:33:18.943457072 +0200
***************
*** 314,319 ****
--- 314,324 ----
      // recognize commonly used types
      if (argcount <= 0)
      {
+       if (ret_type == &t_unknown)
+       {
+           // (argcount == 0) is not possible
+           return &t_func_unknown;
+       }
        if (ret_type == &t_void)
        {
            if (argcount == 0)
***************
*** 350,355 ****
--- 355,361 ----
        return &t_any;
      type->tt_type = VAR_FUNC;
      type->tt_member = ret_type;
+     type->tt_argcount = argcount;
      type->tt_args = NULL;
      return type;
  }
***************
*** 1589,1595 ****
            if (len == 4 && STRNCMP(*arg, "func", len) == 0)
            {
                type_T  *type;
!               type_T  *ret_type = &t_any;
                int     argcount = -1;
                int     flags = 0;
                int     first_optional = -1;
--- 1595,1601 ----
            if (len == 4 && STRNCMP(*arg, "func", len) == 0)
            {
                type_T  *type;
!               type_T  *ret_type = &t_unknown;
                int     argcount = -1;
                int     flags = 0;
                int     first_optional = -1;
***************
*** 1657,1663 ****
                {
                    // parse return type
                    ++*arg;
!                   if (!VIM_ISWHITE(*p))
                        semsg(_(e_white_after), ":");
                    *arg = skipwhite(*arg);
                    ret_type = parse_type(arg, type_gap);
--- 1663,1669 ----
                {
                    // parse return type
                    ++*arg;
!                   if (!VIM_ISWHITE(**arg))
                        semsg(_(e_white_after), ":");
                    *arg = skipwhite(*arg);
                    ret_type = parse_type(arg, type_gap);
***************
*** 2405,2411 ****
  {
      int ret = OK;
  
!     if (expected->tt_type != VAR_UNKNOWN && expected->tt_type != VAR_ANY)
      {
        if (expected->tt_type != actual->tt_type)
        {
--- 2411,2420 ----
  {
      int ret = OK;
  
!     // When expected is "unknown" we accept any actual type.
!     // When expected is "any" we accept any actual type except "void".
!     if (expected->tt_type != VAR_UNKNOWN
!           && (expected->tt_type != VAR_ANY || actual->tt_type == VAR_VOID))
      {
        if (expected->tt_type != actual->tt_type)
        {
***************
*** 2421,2428 ****
        }
        else if (expected->tt_type == VAR_FUNC)
        {
!           if (expected->tt_member != &t_any
!                                         && expected->tt_member != &t_unknown)
                ret = check_type(expected->tt_member, actual->tt_member, FALSE);
            if (ret == OK && expected->tt_argcount != -1
                    && (actual->tt_argcount < expected->tt_min_argcount
--- 2430,2436 ----
        }
        else if (expected->tt_type == VAR_FUNC)
        {
!           if (expected->tt_member != &t_unknown)
                ret = check_type(expected->tt_member, actual->tt_member, FALSE);
            if (ret == OK && expected->tt_argcount != -1
                    && (actual->tt_argcount < expected->tt_min_argcount
***************
*** 4044,4079 ****
        if (r == FAIL)
            goto theend;
  
!       stack = &cctx->ctx_type_stack;
!       stacktype = stack->ga_len == 0 ? &t_void
!                             : ((type_T **)stack->ga_data)[stack->ga_len - 1];
!       if (idx >= 0 && (is_decl || !has_type))
        {
!           lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
!           if (new_local && !has_type)
            {
!               if (stacktype->tt_type == VAR_VOID)
!               {
!                   emsg(_("E1031: Cannot use void value"));
!                   goto theend;
!               }
!               else
                {
!                   // An empty list or dict has a &t_void member, for a
!                   // variable that implies &t_any.
!                   if (stacktype == &t_list_empty)
!                       lvar->lv_type = &t_list_any;
!                   else if (stacktype == &t_dict_empty)
!                       lvar->lv_type = &t_dict_any;
                    else
!                       lvar->lv_type = stacktype;
                }
            }
!           else if (need_type(stacktype, lvar->lv_type, -1, cctx) == FAIL)
                goto theend;
        }
-       else if (*p != '=' && check_type(type, stacktype, TRUE) == FAIL)
-           goto theend;
      }
      else if (cmdidx == CMD_const)
      {
--- 4052,4090 ----
        if (r == FAIL)
            goto theend;
  
!       if (cctx->ctx_skip != TRUE)
        {
!           stack = &cctx->ctx_type_stack;
!           stacktype = stack->ga_len == 0 ? &t_void
!                             : ((type_T **)stack->ga_data)[stack->ga_len - 1];
!           if (idx >= 0 && (is_decl || !has_type))
            {
!               lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
!               if (new_local && !has_type)
                {
!                   if (stacktype->tt_type == VAR_VOID)
!                   {
!                       emsg(_("E1031: Cannot use void value"));
!                       goto theend;
!                   }
                    else
!                   {
!                       // An empty list or dict has a &t_void member, for a
!                       // variable that implies &t_any.
!                       if (stacktype == &t_list_empty)
!                           lvar->lv_type = &t_list_any;
!                       else if (stacktype == &t_dict_empty)
!                           lvar->lv_type = &t_dict_any;
!                       else
!                           lvar->lv_type = stacktype;
!                   }
                }
+               else if (need_type(stacktype, lvar->lv_type, -1, cctx) == FAIL)
+                   goto theend;
            }
!           else if (*p != '=' && check_type(type, stacktype, TRUE) == FAIL)
                goto theend;
        }
      }
      else if (cmdidx == CMD_const)
      {
*** ../vim-8.2.0526/src/testdir/test_vim9_func.vim      2020-04-06 
21:35:02.464237765 +0200
--- src/testdir/test_vim9_func.vim      2020-04-06 23:44:45.188546833 +0200
***************
*** 373,378 ****
--- 373,383 ----
    return 1234
  enddef
  
+ def FuncNoArgRetString(): string
+   funcResult = 45
+   return 'text'
+ enddef
+ 
  def FuncOneArgNoRet(arg: number)
    funcResult = arg
  enddef
***************
*** 382,387 ****
--- 387,396 ----
    return arg
  enddef
  
+ def FuncOneArgRetString(arg: string): string
+   return arg
+ enddef
+ 
  def FuncOneArgRetAny(arg: any): any
    return arg
  enddef
***************
*** 415,420 ****
--- 424,455 ----
    assert_equal(13, funcResult)
  enddef
  
+ def Test_func_type_part()
+   let RefVoid: func: void
+   RefVoid = FuncNoArgNoRet
+   RefVoid = FuncOneArgNoRet
+   CheckDefFailure(['let RefVoid: func: void', 'RefVoid = 
FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): 
number')
+   CheckDefFailure(['let RefVoid: func: void', 'RefVoid = 
FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): 
string')
+ 
+   let RefAny: func(): any
+   RefAny = FuncNoArgRetNumber
+   RefAny = FuncNoArgRetString
+   CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 
'E1013: type mismatch, expected func(): any but got func()')
+   CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 
'E1013: type mismatch, expected func(): any but got func(number)')
+ 
+   let RefNr: func: number
+   RefNr = FuncNoArgRetNumber
+   RefNr = FuncOneArgRetNumber
+   CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 
'E1013: type mismatch, expected func(): number but got func()')
+   CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 
'E1013: type mismatch, expected func(): number but got func(): string')
+ 
+   let RefStr: func: string
+   RefStr = FuncNoArgRetString
+   RefStr = FuncOneArgRetString
+   CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 
'E1013: type mismatch, expected func(): string but got func()')
+   CheckDefFailure(['let RefStr: func: string', 'RefStr = 
FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got 
func(): number')
+ enddef
+ 
  def Test_func_type_fails()
    CheckDefFailure(['let ref1: func()'], 'E704:')
  
*** ../vim-8.2.0526/src/Makefile        2020-04-05 20:20:40.100596581 +0200
--- src/Makefile        2020-04-07 20:40:46.881763609 +0200
***************
*** 2301,2307 ****
  #     export TEST_FILTER=Test_terminal_wipe_buffer
  # A partial match also works:
  #     export TEST_FILTER=wipe_buffer
! $(NEW_TESTS):
        cd testdir; $(MAKE) $@ VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) 
SCRIPTSOURCE=../$(SCRIPTSOURCE)
  
  newtests:
--- 2301,2307 ----
  #     export TEST_FILTER=Test_terminal_wipe_buffer
  # A partial match also works:
  #     export TEST_FILTER=wipe_buffer
! $(NEW_TESTS) test_vim9:
        cd testdir; $(MAKE) $@ VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) 
SCRIPTSOURCE=../$(SCRIPTSOURCE)
  
  newtests:
*** ../vim-8.2.0526/src/testdir/Makefile        2020-02-20 22:34:59.264986542 
+0100
--- src/testdir/Makefile        2020-04-07 20:49:29.091821932 +0200
***************
*** 78,83 ****
--- 78,93 ----
        @if test -f test.log; then \
                exit 1; \
        fi
+ 
+ # Run only tests specific for Vim9 script
+ test_vim9:
+       rm -f test_vim9_*.res test.log messages
+       @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile $(TEST_VIM9_RES) 
VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE)
+       @cat messages
+       @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile report 
VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE)
+       @if test -f test.log; then \
+               exit 1; \
+       fi
  
  RM_ON_RUN = test.out X* viminfo
  RM_ON_START = tiny.vim small.vim mbyte.vim mzscheme.vim test.ok benchmark.out
*** ../vim-8.2.0526/src/testdir/Make_all.mak    2020-04-05 23:04:53.664241873 
+0200
--- src/testdir/Make_all.mak    2020-04-07 20:39:22.066081532 +0200
***************
*** 43,48 ****
--- 43,61 ----
  # Tests for the GUI.
  SCRIPTS_GUI =
  
+ # Tests for Vim9 script.
+ TEST_VIM9 = \
+       test_vim9_disassemble \
+       test_vim9_expr \
+       test_vim9_func \
+       test_vim9_script
+ 
+ TEST_VIM9_RES = \
+       test_vim9_disassemble.res \
+       test_vim9_expr.res \
+       test_vim9_func.res \
+       test_vim9_script.res
+ 
  # Individual tests, including the ones part of test_alot.
  # Please keep sorted up to test_alot.
  NEW_TESTS = \
***************
*** 272,281 ****
        test_utf8 \
        test_utf8_comparisons \
        test_vartabs \
!       test_vim9_disassemble \
!       test_vim9_expr \
!       test_vim9_func \
!       test_vim9_script \
        test_viminfo \
        test_vimscript \
        test_virtualedit \
--- 285,291 ----
        test_utf8 \
        test_utf8_comparisons \
        test_vartabs \
!       $(TEST_VIM9) \
        test_viminfo \
        test_vimscript \
        test_virtualedit \
***************
*** 482,491 ****
        test_user_func.res \
        test_usercommands.res \
        test_vartabs.res \
!       test_vim9_disassemble.res \
!       test_vim9_expr.res \
!       test_vim9_func.res \
!       test_vim9_script.res \
        test_viminfo.res \
        test_vimscript.res \
        test_virtualedit.res \
--- 492,498 ----
        test_user_func.res \
        test_usercommands.res \
        test_vartabs.res \
!       $(TEST_VIM9_RES) \
        test_viminfo.res \
        test_vimscript.res \
        test_virtualedit.res \
*** ../vim-8.2.0526/src/version.c       2020-04-07 19:57:26.043208340 +0200
--- src/version.c       2020-04-07 20:50:30.695593979 +0200
***************
*** 740,741 ****
--- 740,743 ----
  {   /* Add new patch number below this line */
+ /**/
+     527,
  /**/

-- 
Zen Microsystems: we're the om in .commmmmmmmm

 /// 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/202004071854.037IsYTu012095%40masaka.moolenaar.net.

Raspunde prin e-mail lui