Patch 9.0.0687

6 views
Skip to first unread message

Bram Moolenaar

unread,
Oct 7, 2022, 12:28:19 PM10/7/22
to vim...@googlegroups.com

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 -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages