forked from aniani/vim
patch 8.2.2597: Vim9: "import * as" does not work at script level
Problem: Vim9: "import * as" does not work at script level. Solution: Implement using an imported namespace.
This commit is contained in:
parent
41cd80335c
commit
cb4e80fab9
@ -373,3 +373,5 @@ EXTERN char e_argument_name_shadows_existing_variable_str[]
|
|||||||
INIT(= N_("E1167: Argument name shadows existing variable: %s"));
|
INIT(= N_("E1167: Argument name shadows existing variable: %s"));
|
||||||
EXTERN char e_argument_already_declared_in_script_str[]
|
EXTERN char e_argument_already_declared_in_script_str[]
|
||||||
INIT(= N_("E1168: Argument already declared in the script: %s"));
|
INIT(= N_("E1168: Argument already declared in the script: %s"));
|
||||||
|
EXTERN char e_import_as_name_not_supported_here[]
|
||||||
|
INIT(= N_("E1169: 'import * as {name}' not supported here"));
|
||||||
|
62
src/eval.c
62
src/eval.c
@ -1370,7 +1370,7 @@ set_var_lval(
|
|||||||
// handle +=, -=, *=, /=, %= and .=
|
// handle +=, -=, *=, /=, %= and .=
|
||||||
di = NULL;
|
di = NULL;
|
||||||
if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
|
if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
|
||||||
&tv, &di, TRUE, FALSE) == OK)
|
&tv, &di, EVAL_VAR_VERBOSE) == OK)
|
||||||
{
|
{
|
||||||
if ((di == NULL
|
if ((di == NULL
|
||||||
|| (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
|
|| (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
|
||||||
@ -3500,7 +3500,8 @@ eval7(
|
|||||||
ret = OK;
|
ret = OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = eval_variable(s, len, rettv, NULL, TRUE, FALSE);
|
ret = eval_variable(s, len, rettv, NULL,
|
||||||
|
EVAL_VAR_VERBOSE + EVAL_VAR_IMPORT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5760,6 +5761,63 @@ handle_subscript(
|
|||||||
check_white = FALSE;
|
check_white = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rettv->v_type == VAR_ANY)
|
||||||
|
{
|
||||||
|
char_u *exp_name;
|
||||||
|
int cc;
|
||||||
|
int idx;
|
||||||
|
ufunc_T *ufunc;
|
||||||
|
type_T *type;
|
||||||
|
|
||||||
|
// Found script from "import * as {name}", script item name must
|
||||||
|
// follow.
|
||||||
|
if (**arg != '.')
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
semsg(_(e_expected_str_but_got_str), "'.'", *arg);
|
||||||
|
ret = FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++*arg;
|
||||||
|
if (IS_WHITE_OR_NUL(**arg))
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
emsg(_(e_no_white_space_allowed_after_dot));
|
||||||
|
ret = FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// isolate the name
|
||||||
|
exp_name = *arg;
|
||||||
|
while (eval_isnamec(**arg))
|
||||||
|
++*arg;
|
||||||
|
cc = **arg;
|
||||||
|
**arg = NUL;
|
||||||
|
|
||||||
|
idx = find_exported(rettv->vval.v_number, exp_name, &ufunc, &type,
|
||||||
|
evalarg->eval_cctx, verbose);
|
||||||
|
**arg = cc;
|
||||||
|
*arg = skipwhite(*arg);
|
||||||
|
|
||||||
|
if (idx < 0 && ufunc == NULL)
|
||||||
|
{
|
||||||
|
ret = FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (idx >= 0)
|
||||||
|
{
|
||||||
|
scriptitem_T *si = SCRIPT_ITEM(rettv->vval.v_number);
|
||||||
|
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
|
||||||
|
|
||||||
|
copy_tv(sv->sv_tv, rettv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_FUNC;
|
||||||
|
rettv->vval.v_string = vim_strsave(ufunc->uf_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
|
if ((**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
|
||||||
|| rettv->v_type == VAR_PARTIAL))
|
|| rettv->v_type == VAR_PARTIAL))
|
||||||
&& (!check_white || !VIM_ISWHITE(*(*arg - 1))))
|
&& (!check_white || !VIM_ISWHITE(*(*arg - 1))))
|
||||||
|
@ -1219,7 +1219,8 @@ list_arg_vars(exarg_T *eap, char_u *arg, int *first)
|
|||||||
arg = skipwhite(arg);
|
arg = skipwhite(arg);
|
||||||
if (tofree != NULL)
|
if (tofree != NULL)
|
||||||
name = tofree;
|
name = tofree;
|
||||||
if (eval_variable(name, len, &tv, NULL, TRUE, FALSE) == FAIL)
|
if (eval_variable(name, len, &tv, NULL,
|
||||||
|
EVAL_VAR_VERBOSE) == FAIL)
|
||||||
error = TRUE;
|
error = TRUE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2539,6 +2540,8 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the value of internal variable "name".
|
* Get the value of internal variable "name".
|
||||||
|
* If "flags" has EVAL_VAR_IMPORT may return a VAR_ANY with v_number set to the
|
||||||
|
* imported script ID.
|
||||||
* Return OK or FAIL. If OK is returned "rettv" must be cleared.
|
* Return OK or FAIL. If OK is returned "rettv" must be cleared.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -2547,12 +2550,11 @@ eval_variable(
|
|||||||
int len, // length of "name"
|
int len, // length of "name"
|
||||||
typval_T *rettv, // NULL when only checking existence
|
typval_T *rettv, // NULL when only checking existence
|
||||||
dictitem_T **dip, // non-NULL when typval's dict item is needed
|
dictitem_T **dip, // non-NULL when typval's dict item is needed
|
||||||
int verbose, // may give error message
|
int flags) // EVAL_VAR_ flags
|
||||||
int no_autoload) // do not use script autoloading
|
|
||||||
{
|
{
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
typval_T *tv = NULL;
|
typval_T *tv = NULL;
|
||||||
int foundFunc = FALSE;
|
int found = FALSE;
|
||||||
dictitem_T *v;
|
dictitem_T *v;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
@ -2561,7 +2563,7 @@ eval_variable(
|
|||||||
name[len] = NUL;
|
name[len] = NUL;
|
||||||
|
|
||||||
// Check for user-defined variables.
|
// Check for user-defined variables.
|
||||||
v = find_var(name, NULL, no_autoload);
|
v = find_var(name, NULL, flags & EVAL_VAR_NOAUTOLOAD);
|
||||||
if (v != NULL)
|
if (v != NULL)
|
||||||
{
|
{
|
||||||
tv = &v->di_tv;
|
tv = &v->di_tv;
|
||||||
@ -2581,7 +2583,7 @@ eval_variable(
|
|||||||
{
|
{
|
||||||
if (import->imp_funcname != NULL)
|
if (import->imp_funcname != NULL)
|
||||||
{
|
{
|
||||||
foundFunc = TRUE;
|
found = TRUE;
|
||||||
if (rettv != NULL)
|
if (rettv != NULL)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_FUNC;
|
rettv->v_type = VAR_FUNC;
|
||||||
@ -2590,8 +2592,21 @@ eval_variable(
|
|||||||
}
|
}
|
||||||
else if (import->imp_flags & IMP_FLAGS_STAR)
|
else if (import->imp_flags & IMP_FLAGS_STAR)
|
||||||
{
|
{
|
||||||
emsg("Sorry, 'import * as X' not implemented yet");
|
if ((flags & EVAL_VAR_IMPORT) == 0)
|
||||||
ret = FAIL;
|
{
|
||||||
|
if (flags & EVAL_VAR_VERBOSE)
|
||||||
|
emsg(_(e_import_as_name_not_supported_here));
|
||||||
|
ret = FAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rettv != NULL)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_ANY;
|
||||||
|
rettv->vval.v_number = import->imp_sid;
|
||||||
|
}
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2607,7 +2622,7 @@ eval_variable(
|
|||||||
|
|
||||||
if (ufunc != NULL)
|
if (ufunc != NULL)
|
||||||
{
|
{
|
||||||
foundFunc = TRUE;
|
found = TRUE;
|
||||||
if (rettv != NULL)
|
if (rettv != NULL)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_FUNC;
|
rettv->v_type = VAR_FUNC;
|
||||||
@ -2617,11 +2632,11 @@ eval_variable(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundFunc)
|
if (!found)
|
||||||
{
|
{
|
||||||
if (tv == NULL)
|
if (tv == NULL)
|
||||||
{
|
{
|
||||||
if (rettv != NULL && verbose)
|
if (rettv != NULL && (flags & EVAL_VAR_VERBOSE))
|
||||||
semsg(_(e_undefined_variable_str), name);
|
semsg(_(e_undefined_variable_str), name);
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
}
|
}
|
||||||
@ -3695,7 +3710,8 @@ var_exists(char_u *var)
|
|||||||
{
|
{
|
||||||
if (tofree != NULL)
|
if (tofree != NULL)
|
||||||
name = tofree;
|
name = tofree;
|
||||||
n = (eval_variable(name, len, &tv, NULL, FALSE, TRUE) == OK);
|
n = (eval_variable(name, len, &tv, NULL,
|
||||||
|
EVAL_VAR_NOAUTOLOAD + EVAL_VAR_IMPORT) == OK);
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
// handle d.key, l[idx], f(expr)
|
// handle d.key, l[idx], f(expr)
|
||||||
|
@ -56,7 +56,7 @@ void set_reg_var(int c);
|
|||||||
char_u *v_exception(char_u *oldval);
|
char_u *v_exception(char_u *oldval);
|
||||||
char_u *v_throwpoint(char_u *oldval);
|
char_u *v_throwpoint(char_u *oldval);
|
||||||
char_u *set_cmdarg(exarg_T *eap, char_u *oldarg);
|
char_u *set_cmdarg(exarg_T *eap, char_u *oldarg);
|
||||||
int eval_variable(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload);
|
int eval_variable(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int flags);
|
||||||
void check_vars(char_u *name, int len);
|
void check_vars(char_u *name, int len);
|
||||||
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
|
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
|
||||||
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
|
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
|
||||||
|
@ -7,7 +7,7 @@ void ex_export(exarg_T *eap);
|
|||||||
void free_imports_and_script_vars(int sid);
|
void free_imports_and_script_vars(int sid);
|
||||||
void mark_imports_for_reload(int sid);
|
void mark_imports_for_reload(int sid);
|
||||||
void ex_import(exarg_T *eap);
|
void ex_import(exarg_T *eap);
|
||||||
int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, cctx_T *cctx);
|
int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, cctx_T *cctx, int verbose);
|
||||||
char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, evalarg_T *evalarg, void *cctx);
|
char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, evalarg_T *evalarg, void *cctx);
|
||||||
char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg);
|
char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg);
|
||||||
void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T *tv, type_T **type);
|
void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T *tv, type_T **type);
|
||||||
|
@ -1031,13 +1031,17 @@ def Test_vim9_import_export()
|
|||||||
vim9script
|
vim9script
|
||||||
import * as Export from './Xexport.vim'
|
import * as Export from './Xexport.vim'
|
||||||
def UseExport()
|
def UseExport()
|
||||||
g:imported = Export.exported
|
g:imported_def = Export.exported
|
||||||
enddef
|
enddef
|
||||||
|
g:imported_script = Export.exported
|
||||||
|
assert_equal(1, exists('Export.exported'))
|
||||||
|
assert_equal(0, exists('Export.notexported'))
|
||||||
UseExport()
|
UseExport()
|
||||||
END
|
END
|
||||||
writefile(import_star_as_lines, 'Ximport.vim')
|
writefile(import_star_as_lines, 'Ximport.vim')
|
||||||
source Ximport.vim
|
source Ximport.vim
|
||||||
assert_equal(9883, g:imported)
|
assert_equal(9883, g:imported_def)
|
||||||
|
assert_equal(9883, g:imported_script)
|
||||||
|
|
||||||
var import_star_as_lines_no_dot =<< trim END
|
var import_star_as_lines_no_dot =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
@ -1072,6 +1076,22 @@ def Test_vim9_import_export()
|
|||||||
writefile(import_star_as_duplicated, 'Ximport.vim')
|
writefile(import_star_as_duplicated, 'Ximport.vim')
|
||||||
assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim')
|
assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim')
|
||||||
|
|
||||||
|
var import_star_as_lines_script_no_dot =<< trim END
|
||||||
|
vim9script
|
||||||
|
import * as Export from './Xexport.vim'
|
||||||
|
g:imported_script = Export exported
|
||||||
|
END
|
||||||
|
writefile(import_star_as_lines_script_no_dot, 'Ximport.vim')
|
||||||
|
assert_fails('source Ximport.vim', 'E1029:')
|
||||||
|
|
||||||
|
var import_star_as_lines_script_space_after_dot =<< trim END
|
||||||
|
vim9script
|
||||||
|
import * as Export from './Xexport.vim'
|
||||||
|
g:imported_script = Export. exported
|
||||||
|
END
|
||||||
|
writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim')
|
||||||
|
assert_fails('source Ximport.vim', 'E1074:')
|
||||||
|
|
||||||
var import_star_as_lines_missing_name =<< trim END
|
var import_star_as_lines_missing_name =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
import * as Export from './Xexport.vim'
|
import * as Export from './Xexport.vim'
|
||||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2597,
|
||||||
/**/
|
/**/
|
||||||
2596,
|
2596,
|
||||||
/**/
|
/**/
|
||||||
|
@ -2702,4 +2702,9 @@ long elapsed(DWORD start_tick);
|
|||||||
#define MCH_DELAY_IGNOREINPUT 1
|
#define MCH_DELAY_IGNOREINPUT 1
|
||||||
#define MCH_DELAY_SETTMODE 2
|
#define MCH_DELAY_SETTMODE 2
|
||||||
|
|
||||||
|
// Flags for eval_variable().
|
||||||
|
#define EVAL_VAR_VERBOSE 1 // may give error message
|
||||||
|
#define EVAL_VAR_NOAUTOLOAD 2 // do not use script autoloading
|
||||||
|
#define EVAL_VAR_IMPORT 4 // may return special variable for import
|
||||||
|
|
||||||
#endif // VIM__H
|
#endif // VIM__H
|
||||||
|
@ -1765,7 +1765,7 @@ call_def_function(
|
|||||||
goto failed;
|
goto failed;
|
||||||
SOURCING_LNUM = iptr->isn_lnum;
|
SOURCING_LNUM = iptr->isn_lnum;
|
||||||
if (eval_variable(name, (int)STRLEN(name),
|
if (eval_variable(name, (int)STRLEN(name),
|
||||||
STACK_TV_BOT(0), NULL, TRUE, FALSE) == FAIL)
|
STACK_TV_BOT(0), NULL, EVAL_VAR_VERBOSE) == FAIL)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
++ectx.ec_stack.ga_len;
|
++ectx.ec_stack.ga_len;
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,8 @@ find_exported(
|
|||||||
char_u *name,
|
char_u *name,
|
||||||
ufunc_T **ufunc,
|
ufunc_T **ufunc,
|
||||||
type_T **type,
|
type_T **type,
|
||||||
cctx_T *cctx)
|
cctx_T *cctx,
|
||||||
|
int verbose)
|
||||||
{
|
{
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
svar_T *sv;
|
svar_T *sv;
|
||||||
@ -271,7 +272,8 @@ find_exported(
|
|||||||
sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
|
sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
|
||||||
if (!sv->sv_export)
|
if (!sv->sv_export)
|
||||||
{
|
{
|
||||||
semsg(_(e_item_not_exported_in_script_str), name);
|
if (verbose)
|
||||||
|
semsg(_(e_item_not_exported_in_script_str), name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*type = sv->sv_type;
|
*type = sv->sv_type;
|
||||||
@ -301,7 +303,8 @@ find_exported(
|
|||||||
|
|
||||||
if (*ufunc == NULL)
|
if (*ufunc == NULL)
|
||||||
{
|
{
|
||||||
semsg(_(e_item_not_found_in_script_str), name);
|
if (verbose)
|
||||||
|
semsg(_(e_item_not_found_in_script_str), name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -532,7 +535,7 @@ handle_import(
|
|||||||
ufunc_T *ufunc = NULL;
|
ufunc_T *ufunc = NULL;
|
||||||
type_T *type;
|
type_T *type;
|
||||||
|
|
||||||
idx = find_exported(sid, name, &ufunc, &type, cctx);
|
idx = find_exported(sid, name, &ufunc, &type, cctx, TRUE);
|
||||||
|
|
||||||
if (idx < 0 && ufunc == NULL)
|
if (idx < 0 && ufunc == NULL)
|
||||||
goto erret;
|
goto erret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user