Patch 9.0.0687
Problem:    "export def" does not work in a nested block.
Solution:   Do not handle "export" with a separate function but in the same
            command stack. (closes #11304)
Files:      src/ex_docmd.c, src/vim9script.c, src/ex_cmds.h,
            src/testdir/test_vim9_import.vim


*** ../vim-9.0.0686/src/ex_docmd.c      2022-10-04 16:23:39.014042183 +0100
--- src/ex_docmd.c      2022-10-07 17:18:20.354476923 +0100
***************
*** 1820,1825 ****
--- 1820,1834 ----
      if (may_have_range)
        ea.cmd = skip_range(ea.cmd, TRUE, NULL);
  
+ #ifdef FEAT_EVAL
+     // Handle ":export" - it functions almost like a command modifier.
+     // ":export var Name: type"
+     // ":export def Name(..."
+     // etc.
+     if (vim9script && checkforcmd_noparen(&ea.cmd, "export", 6))
+       is_export = TRUE;
+ #endif
+ 
      if (vim9script && !may_have_range)
      {
        if (ea.cmd == cmd + 1 && *cmd == '$')
***************
*** 2496,2506 ****
      }
  #endif
  
!     if (ea.argt & EX_XFILE)
      {
!       if (expand_filename(&ea, cmdlinep, &errormsg) == FAIL)
!           goto doend;
      }
  
      /*
       * Accept buffer name.  Cannot be used at the same time with a buffer
--- 2505,2521 ----
      }
  #endif
  
!     if ((ea.argt & EX_XFILE)
!           && expand_filename(&ea, cmdlinep, &errormsg) == FAIL)
!       goto doend;
! 
! #ifdef FEAT_EVAL
!     if (is_export && (ea.argt & EX_EXPORT) == 0)
      {
!       emsg(_(e_invalid_command_after_export));
!       goto doend;
      }
+ #endif
  
      /*
       * Accept buffer name.  Cannot be used at the same time with a buffer
***************
*** 2557,2569 ****
        /*
         * Call the function to execute the builtin command.
         */
-       ea.errmsg = NULL;
        (cmdnames[ea.cmdidx].cmd_func)(&ea);
        if (ea.errmsg != NULL)
            errormsg = ea.errmsg;
      }
  
  #ifdef FEAT_EVAL
      // Set flag that any command was executed, used by ex_vim9script().
      // Not if this was a command that wasn't executed or :endif.
      if (sourcing_a_script(&ea)
--- 2572,2592 ----
        /*
         * Call the function to execute the builtin command.
         */
        (cmdnames[ea.cmdidx].cmd_func)(&ea);
        if (ea.errmsg != NULL)
            errormsg = ea.errmsg;
      }
  
  #ifdef FEAT_EVAL
+     // A command will reset "is_export" when exporting an item.  If it is 
still
+     // set something went wrong.
+     if (is_export)
+     {
+       if (errormsg == NULL)
+           errormsg = _(e_export_with_invalid_argument);
+       is_export = FALSE;
+     }
+ 
      // Set flag that any command was executed, used by ex_vim9script().
      // Not if this was a command that wasn't executed or :endif.
      if (sourcing_a_script(&ea)
***************
*** 2620,2625 ****
--- 2643,2649 ----
  
      if (did_set_expr_line)
        set_expr_line(NULL, NULL);
+     is_export = FALSE;
  #endif
  
      undo_cmdmod(&cmdmod);
*** ../vim-9.0.0686/src/vim9script.c    2022-10-07 16:00:00.757126668 +0100
--- src/vim9script.c    2022-10-07 17:10:12.814159416 +0100
***************
*** 246,294 ****
  }
  
  /*
!  * ":export let Name: type"
!  * ":export const Name: type"
!  * ":export def Name(..."
!  * ":export class Name ..."
   */
      void
! ex_export(exarg_T *eap)
  {
!     int           prev_did_emsg = did_emsg;
! 
!     if (!in_vim9script())
!     {
!       emsg(_(e_export_can_only_be_used_in_vim9script));
!       return;
!     }
! 
!     eap->cmd = eap->arg;
!     (void)find_ex_command(eap, NULL, lookup_scriptitem, NULL);
!     switch (eap->cmdidx)
!     {
!       case CMD_var:
!       case CMD_final:
!       case CMD_const:
!       case CMD_def:
!       case CMD_function:
!       // case CMD_class:
!           is_export = TRUE;
!           do_cmdline(eap->cmd, eap->getline, eap->cookie,
!                                               DOCMD_VERBOSE + DOCMD_NOWAIT);
! 
!           // The command will reset "is_export" when exporting an item.
!           if (is_export)
!           {
!               if (did_emsg == prev_did_emsg)
!                   emsg(_(e_export_with_invalid_argument));
!               is_export = FALSE;
!           }
!           break;
!       default:
!           if (did_emsg == prev_did_emsg)
!               emsg(_(e_invalid_command_after_export));
!           break;
!     }
  }
  
  /*
--- 246,258 ----
  }
  
  /*
!  * ":export cmd"
   */
      void
! ex_export(exarg_T *eap UNUSED)
  {
!     // can only get here when "export" wasn't caught in do_cmdline()
!     emsg(_(e_export_can_only_be_used_in_vim9script));
  }
  
  /*
*** ../vim-9.0.0686/src/ex_cmds.h       2022-10-07 14:31:04.320852668 +0100
--- src/ex_cmds.h       2022-10-07 17:05:00.691039541 +0100
***************
*** 59,64 ****
--- 59,65 ----
  #define EX_KEEPSCRIPT  0x4000000  // keep sctx of where command was invoked
  #define EX_EXPR_ARG    0x8000000  // argument is an expression
  #define EX_WHOLE      0x10000000  // command name cannot be shortened in Vim9
+ #define EX_EXPORT     0x20000000  // command can be used after :export
  
  #define EX_FILES (EX_XFILE | EX_EXTRA)        // multiple extra files allowed
  #define EX_FILE1 (EX_FILES | EX_NOSPC)        // 1 file, defaults to current 
file
***************
*** 354,360 ****
        EX_RANGE|EX_COUNT|EX_TRLBAR|EX_BANG,
        ADDR_UNSIGNED),
  EXCMD(CMD_class,      "class",        ex_ni,
!       EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_close,      "close",        ex_close,
        EX_BANG|EX_RANGE|EX_COUNT|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
--- 355,361 ----
        EX_RANGE|EX_COUNT|EX_TRLBAR|EX_BANG,
        ADDR_UNSIGNED),
  EXCMD(CMD_class,      "class",        ex_ni,
!       EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT,
        ADDR_NONE),
  EXCMD(CMD_close,      "close",        ex_close,
        EX_BANG|EX_RANGE|EX_COUNT|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
***************
*** 414,420 ****
        EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_const,      "const",        ex_let,
!       
EX_EXTRA|EX_BANG|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE,
        ADDR_NONE),
  EXCMD(CMD_copen,      "copen",        ex_copen,
        EX_RANGE|EX_COUNT|EX_TRLBAR,
--- 415,421 ----
        EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_const,      "const",        ex_let,
!       
EX_EXTRA|EX_BANG|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE|EX_EXPORT,
        ADDR_NONE),
  EXCMD(CMD_copen,      "copen",        ex_copen,
        EX_RANGE|EX_COUNT|EX_TRLBAR,
***************
*** 462,468 ****
        EX_RANGE|EX_ZEROR|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
        ADDR_OTHER),
  EXCMD(CMD_def,                "def",          ex_function,
!       EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_defcompile, "defcompile",   ex_defcompile,
        EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_TRLBAR|EX_EXTRA,
--- 463,469 ----
        EX_RANGE|EX_ZEROR|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
        ADDR_OTHER),
  EXCMD(CMD_def,                "def",          ex_function,
!       EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT,
        ADDR_NONE),
  EXCMD(CMD_defcompile, "defcompile",   ex_defcompile,
        EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_TRLBAR|EX_EXTRA,
***************
*** 594,600 ****
        EX_BANG|EX_TRLBAR,
        ADDR_NONE),
  EXCMD(CMD_enum,               "enum",         ex_ni,
!       EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_eval,               "eval",         ex_eval,
        EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
--- 595,601 ----
        EX_BANG|EX_TRLBAR,
        ADDR_NONE),
  EXCMD(CMD_enum,               "enum",         ex_ni,
!       EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT,
        ADDR_NONE),
  EXCMD(CMD_eval,               "eval",         ex_eval,
        EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
***************
*** 630,636 ****
        EX_RANGE|EX_BANG|EX_FILE1|EX_CMDARG|EX_ARGOPT|EX_TRLBAR|EX_NEEDARG,
        ADDR_OTHER),
  EXCMD(CMD_final,      "final",        ex_let,
!       EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE,
        ADDR_NONE),
  EXCMD(CMD_finally,    "finally",      ex_finally,
        EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE,
--- 631,637 ----
        EX_RANGE|EX_BANG|EX_FILE1|EX_CMDARG|EX_ARGOPT|EX_TRLBAR|EX_NEEDARG,
        ADDR_OTHER),
  EXCMD(CMD_final,      "final",        ex_let,
!       EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE|EX_EXPORT,
        ADDR_NONE),
  EXCMD(CMD_finally,    "finally",      ex_finally,
        EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE,
***************
*** 663,669 ****
        EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_function,   "function",     ex_function,
!       EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_global,     "global",       ex_global,
        
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_EXTRA|EX_DFLALL|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
--- 664,670 ----
        EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_function,   "function",     ex_function,
!       EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT,
        ADDR_NONE),
  EXCMD(CMD_global,     "global",       ex_global,
        
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_EXTRA|EX_DFLALL|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
***************
*** 1665,1671 ****
        EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_type,               "type",         ex_ni,
!       EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_undo,               "undo",         ex_undo,
        EX_RANGE|EX_COUNT|EX_ZEROR|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
--- 1666,1672 ----
        EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_type,               "type",         ex_ni,
!       EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT,
        ADDR_NONE),
  EXCMD(CMD_undo,               "undo",         ex_undo,
        EX_RANGE|EX_COUNT|EX_ZEROR|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
***************
*** 1704,1710 ****
        
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_DFLALL|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
        ADDR_LINES),
  EXCMD(CMD_var,                "var",          ex_var,
!       
EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE,
        ADDR_NONE),
  EXCMD(CMD_version,    "version",      ex_version,
        EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
--- 1705,1711 ----
        
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_DFLALL|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
        ADDR_LINES),
  EXCMD(CMD_var,                "var",          ex_var,
!       
EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE|EX_EXPORT,
        ADDR_NONE),
  EXCMD(CMD_version,    "version",      ex_version,
        EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
*** ../vim-9.0.0686/src/testdir/test_vim9_import.vim    2022-09-03 
12:09:02.530363340 +0100
--- src/testdir/test_vim9_import.vim    2022-10-07 17:23:11.563142366 +0100
***************
*** 452,457 ****
--- 452,472 ----
    delete('Xlib.vim')
  enddef
  
+ def Test_export_closure()
+   # tests that the closure in block can be compiled, not the import part
+   var lines =<< trim END
+       vim9script
+       {
+         var foo = 42
+         export def Bar(): number
+           return foo
+         enddef
+       }
+       assert_equal(42, Bar())
+   END
+   v9.CheckScriptSuccess(lines)
+ enddef
+ 
  def Test_import_duplicate_function()
    # Function Hover() exists in both scripts, partial should refer to the right
    # one.
***************
*** 1513,1519 ****
    v9.CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
    v9.CheckScriptFailure(['vim9script', 'export function /a1b2c3'], 'E1044:')
  
!   assert_fails('export something', 'E1043:')
  enddef
  
  func Test_import_fails_without_script()
--- 1528,1534 ----
    v9.CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
    v9.CheckScriptFailure(['vim9script', 'export function /a1b2c3'], 'E1044:')
  
!   assert_fails('export echo 1', 'E1043:')
  enddef
  
  func Test_import_fails_without_script()
*** ../vim-9.0.0686/src/version.c       2022-10-07 16:28:43.522256458 +0100
--- src/version.c       2022-10-07 17:25:09.351256660 +0100
***************
*** 701,702 ****
--- 701,704 ----
  {   /* Add new patch number below this line */
+ /**/
+     687,
  /**/

-- 
ARTHUR:      Who are you?
TALL KNIGHT: We are the Knights Who Say "Ni"!
BEDEVERE:    No!  Not the Knights Who Say "Ni"!
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// 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/20221007162806.C07EB1C0592%40moolenaar.net.

Raspunde prin e-mail lui