Mercurial > vim
diff src/eval.c @ 26980:8796f1384750 v8.2.4019
patch 8.2.4019: Vim9: import mechanism is too complicated
Commit: https://github.com/vim/vim/commit/d5f400c607182db6d4fbe2964471d796277f67e8
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jan 6 21:10:28 2022 +0000
patch 8.2.4019: Vim9: import mechanism is too complicated
Problem: Vim9: import mechanism is too complicated.
Solution: Do not use the Javascript mechanism but a much simpler one.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 06 Jan 2022 22:15:04 +0100 |
parents | 11ee2667a09a |
children | 4b8d836db103 |
line wrap: on
line diff
--- a/src/eval.c +++ b/src/eval.c @@ -56,7 +56,6 @@ static int eval7_leader(typval_T *rettv, static int free_unref_items(int copyID); static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); -static char_u *eval_next_line(evalarg_T *evalarg); /* * Return "n1" divided by "n2", taking care of dividing by zero. @@ -922,9 +921,37 @@ get_lval( } } } + if (lp->ll_name == NULL) + return p; + + if (*p == '.' && in_vim9script()) + { + imported_T *import = find_imported(lp->ll_name, p - lp->ll_name, NULL); + if (import != NULL) + { + ufunc_T *ufunc; + type_T *type; + + lp->ll_sid = import->imp_sid; + lp->ll_name = skipwhite(p + 1); + p = find_name_end(lp->ll_name, NULL, NULL, fne_flags); + lp->ll_name_end = p; + + // check the item is exported + cc = *p; + *p = NUL; + if (find_exported(import->imp_sid, lp->ll_name, &ufunc, &type, + NULL, TRUE) == -1) + { + *p = cc; + return FAIL; + } + *p = cc; + } + } // Without [idx] or .key we are done. - if ((*p != '[' && *p != '.') || lp->ll_name == NULL) + if ((*p != '[' && *p != '.')) return p; if (in_vim9script() && lval_root != NULL) @@ -997,7 +1024,7 @@ get_lval( && lp->ll_tv == &v->di_tv && ht != NULL && ht == get_script_local_ht()) { - svar_T *sv = find_typval_in_script(lp->ll_tv); + svar_T *sv = find_typval_in_script(lp->ll_tv, 0); // Vim9 script local variable: get the type if (sv != NULL) @@ -1359,13 +1386,13 @@ set_var_lval( // handle +=, -=, *=, /=, %= and .= di = NULL; if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name), - &tv, &di, EVAL_VAR_VERBOSE) == OK) + lp->ll_sid, &tv, &di, EVAL_VAR_VERBOSE) == OK) { if ((di == NULL || (!var_check_ro(di->di_flags, lp->ll_name, FALSE) && !tv_check_lock(&di->di_tv, lp->ll_name, FALSE))) && tv_op(&tv, rettv, op) == OK) - set_var_const(lp->ll_name, NULL, &tv, FALSE, + set_var_const(lp->ll_name, lp->ll_sid, NULL, &tv, FALSE, ASSIGN_NO_DECL, 0); clear_tv(&tv); } @@ -1375,7 +1402,7 @@ set_var_lval( if (lp->ll_type != NULL && check_typval_arg_type(lp->ll_type, rettv, NULL, 0) == FAIL) return; - set_var_const(lp->ll_name, lp->ll_type, rettv, copy, + set_var_const(lp->ll_name, lp->ll_sid, lp->ll_type, rettv, copy, flags, var_idx); } *endp = cc; @@ -1389,7 +1416,7 @@ set_var_lval( if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) && (flags & ASSIGN_FOR_LOOP) == 0) { - emsg(_("E996: Cannot lock a range")); + emsg(_(e_cannot_lock_range)); return; } @@ -1404,7 +1431,7 @@ set_var_lval( if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) && (flags & ASSIGN_FOR_LOOP) == 0) { - emsg(_("E996: Cannot lock a list or dict")); + emsg(_(e_cannot_lock_list_or_dict)); return; } @@ -2089,7 +2116,7 @@ getline_peek_skip_comments(evalarg_T *ev * FALSE. * "arg" must point somewhere inside a line, not at the start. */ - static char_u * + char_u * eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext) { char_u *p = skipwhite(arg); @@ -2120,7 +2147,7 @@ eval_next_non_blank(char_u *arg, evalarg * To be called after eval_next_non_blank() sets "getnext" to TRUE. * Only called for Vim9 script. */ - static char_u * + char_u * eval_next_line(evalarg_T *evalarg) { garray_T *gap = &evalarg->eval_ga; @@ -2236,13 +2263,28 @@ eval0( exarg_T *eap, evalarg_T *evalarg) { + return eval0_retarg(arg, rettv, eap, evalarg, NULL); +} + +/* + * Like eval0() but when "retarg" is not NULL store the pointer to after the + * expression and don't check what comes after the expression. + */ + int +eval0_retarg( + char_u *arg, + typval_T *rettv, + exarg_T *eap, + evalarg_T *evalarg, + char_u **retarg) +{ int ret; char_u *p; char_u *expr_end; int did_emsg_before = did_emsg; int called_emsg_before = called_emsg; int flags = evalarg == NULL ? 0 : evalarg->eval_flags; - int check_for_end = TRUE; + int check_for_end = retarg == NULL; int end_error = FALSE; p = skipwhite(arg); @@ -2253,7 +2295,7 @@ eval0( // In Vim9 script a command block is not split at NL characters for // commands using an expression argument. Skip over a '#' comment to check // for a following NL. Require white space before the '#'. - if (in_vim9script() && p > expr_end) + if (in_vim9script() && p > expr_end && retarg == NULL) while (*p == '#') { char_u *nl = vim_strchr(p, NL); @@ -2298,7 +2340,9 @@ eval0( return FAIL; } - if (check_for_end && eap != NULL) + if (retarg != NULL) + *retarg = p; + else if (check_for_end && eap != NULL) set_nextcmd(eap, p); return ret; @@ -3669,7 +3713,7 @@ eval7( ret = OK; } else - ret = eval_variable(s, len, rettv, NULL, + ret = eval_variable(s, len, 0, rettv, NULL, EVAL_VAR_VERBOSE + EVAL_VAR_IMPORT); } else @@ -5887,7 +5931,7 @@ handle_subscript( ufunc_T *ufunc; type_T *type; - // Found script from "import * as {name}", script item name must + // Found script from "import {name} as name", script item name must // follow. if (**arg != '.') { @@ -5934,6 +5978,7 @@ handle_subscript( rettv->v_type = VAR_FUNC; rettv->vval.v_string = vim_strsave(ufunc->uf_name); } + continue; } if ((**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC