/* vi:set ts=8 sts=4 sw=4 noet:
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
* See README.txt for an overview of the Vim source code.
*/
/*
* vim9script.c: :vim9script, :import, :export and friends
*/
#include "vim.h"
#if defined(FEAT_EVAL)
# include "vim9.h"
#endif
int
in_vim9script(void)
{
// Do not go up the stack, a ":function" inside vim9script uses legacy
// syntax. "sc_version" is also set when compiling a ":def" function in
// legacy script.
return current_sctx.sc_version == SCRIPT_VERSION_VIM9
|| (cmdmod.cmod_flags & CMOD_VIM9CMD);
}
/*
* ":vim9script".
*/
void
ex_vim9script(exarg_T *eap UNUSED)
{
#ifdef FEAT_EVAL
int sid = current_sctx.sc_sid;
scriptitem_T *si;
if (!getline_equal(eap->getline, eap->cookie, getsourceline))
{
emsg(_(e_vim9script_can_only_be_used_in_script));
return;
}
si = SCRIPT_ITEM(sid);
if (si->sn_state == SN_STATE_HAD_COMMAND)
{
emsg(_(e_vim9script_must_be_first_command_in_script));
return;
}
if (!IS_WHITE_OR_NUL(*eap->arg) && STRCMP(eap->arg, "noclear") != 0)
{
semsg(_(e_invarg2), eap->arg);
return;
}
if (si->sn_state == SN_STATE_RELOAD && IS_WHITE_OR_NUL(*eap->arg))
{
hashtab_T *ht = &SCRIPT_VARS(sid);
// Reloading a script without the "noclear" argument: clear
// script-local variables and functions.
hashtab_free_contents(ht);
hash_init(ht);
delete_script_functions(sid);
// old imports and script variables are no longer valid
free_imports_and_script_vars(sid);
}
si->sn_state = SN_STATE_HAD_COMMAND;
current_sctx.sc_version = SCRIPT_VERSION_VIM9;
si->sn_version = SCRIPT_VERSION_VIM9;
if (STRCMP(p_cpo, CPO_VIM) != 0)
{
si->sn_save_cpo = vim_strsave(p_cpo);
set_option_value((char_u *)"cpo", 0L, (char_u *)CPO_VIM, 0);
}
#else
// No check for this being the first command, it doesn't matter.
current_sctx.sc_version = SCRIPT_VERSION_VIM9;
#endif
}
/*
* When in Vim9 script give an error and return FAIL.
*/
int
not_in_vim9(exarg_T *eap)
{
if (in_vim9script())
switch (eap->cmdidx)
{
case CMD_k:
if (eap->addr_count > 0)
{
emsg(_(e_norange));
return FAIL;
}
// FALLTHROUGH
case CMD_append:
case CMD_change:
case CMD_insert:
case CMD_t:
case CMD_xit:
semsg(_(e_command_not_supported_in_vim9_script_missing_var_str), eap->cmd);
return FAIL;
default: break;
}
return OK;
}
/*
* Return TRUE if "p" points at a "#". Does not check for white space.
*/
int
vim9_comment_start(char_u *p)
{
return p[0] == '#';
}
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* ":export let Name: type"
* ":export const Name: type"
* ":export def Name(..."
* ":export class Name ..."
*/
void
ex_export(exarg_T *eap)
{
if (!in_vim9script())
{
emsg(_(e_export_can_only_be_used_in_vim9script));
return;
}
eap->cmd = eap->arg;
(void)find_ex_command(eap, NULL, lookup_scriptvar, NULL);
switch (eap->cmdidx)
{
case CMD_let:
case CMD_var:
case CMD_final:
case CMD_const:
case CMD_def:
// 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)
{
emsg(_(e_export_with_invalid_argument));
is_export = FALSE;
}
break;
default:
emsg(_(e_invalid_command_after_export));
break;
}
}
/*
* Add a new imported item entry to the current script.
*/
static imported_T *
new_imported(garray_T *gap)
{
if (ga_grow(gap, 1) == OK)
return ((imported_T *)gap->ga_data + gap->ga_len++);
return NULL;
}
/*
* Free all imported items in script "sid".
*/
void
free_imports_and_script_vars(int sid)
{
scriptitem_T *si = SCRIPT_ITEM(sid);
int idx;
for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
{
imported_T *imp = ((imported_T *)si->sn_imports.ga_data) + idx;
vim_free(imp->imp_name);
}
ga_clear(&si->sn_imports);
free_all_script_vars(si);
clear_type_list(&si->sn_type_list);
}
/*
* Mark all imports as possible to redefine. Used when a script is loaded
* again but not cleared.
*/
void
mark_imports_for_reload(int sid)
{
scriptitem_T *si = SCRIPT_ITEM(sid);
int idx;
for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
{
imported_T *imp = ((imported_T