Patch 8.2.2597
Problem:    Vim9: "import * as" does not work at script level.
Solution:   Implement using an imported namespace.
Files:      src/vim.h, src/eval.c, src/evalvars.c, src/proto/evalvars.pro,
            src/vim9execute.c, src/errors.h, src/vim9script.c,
            src/proto/vim9script.pro, src/testdir/test_vim9_script.vim


*** ../vim-8.2.2596/src/vim.h   2021-03-10 13:39:46.318350557 +0100
--- src/vim.h   2021-03-13 19:57:01.831161138 +0100
***************
*** 2702,2705 ****
--- 2702,2710 ----
  #define MCH_DELAY_IGNOREINPUT 1
  #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
*** ../vim-8.2.2596/src/eval.c  2021-03-06 18:18:15.370336953 +0100
--- src/eval.c  2021-03-13 20:55:08.555780587 +0100
***************
*** 1370,1376 ****
            // handle +=, -=, *=, /=, %= and .=
            di = NULL;
            if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
!                                            &tv, &di, TRUE, FALSE) == OK)
            {
                if ((di == NULL
                         || (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
--- 1370,1376 ----
            // handle +=, -=, *=, /=, %= and .=
            di = NULL;
            if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
!                                            &tv, &di, EVAL_VAR_VERBOSE) == OK)
            {
                if ((di == NULL
                         || (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
***************
*** 3500,3506 ****
                    ret = OK;
                }
                else
!                   ret = eval_variable(s, len, rettv, NULL, TRUE, FALSE);
            }
            else
            {
--- 3500,3507 ----
                    ret = OK;
                }
                else
!                   ret = eval_variable(s, len, rettv, NULL,
!                                          EVAL_VAR_VERBOSE + EVAL_VAR_IMPORT);
            }
            else
            {
***************
*** 5760,5765 ****
--- 5761,5823 ----
            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
                            || rettv->v_type == VAR_PARTIAL))
                    && (!check_white || !VIM_ISWHITE(*(*arg - 1))))
*** ../vim-8.2.2596/src/evalvars.c      2021-03-08 20:47:09.733874887 +0100
--- src/evalvars.c      2021-03-13 20:49:53.628437349 +0100
***************
*** 1219,1225 ****
                arg = skipwhite(arg);
                if (tofree != NULL)
                    name = tofree;
!               if (eval_variable(name, len, &tv, NULL, TRUE, FALSE) == FAIL)
                    error = TRUE;
                else
                {
--- 1219,1226 ----
                arg = skipwhite(arg);
                if (tofree != NULL)
                    name = tofree;
!               if (eval_variable(name, len, &tv, NULL,
!                                                    EVAL_VAR_VERBOSE) == FAIL)
                    error = TRUE;
                else
                {
***************
*** 2539,2544 ****
--- 2540,2547 ----
  
  /*
   * 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.
   */
      int
***************
*** 2547,2558 ****
      int               len,            // length of "name"
      typval_T  *rettv,         // NULL when only checking existence
      dictitem_T        **dip,          // non-NULL when typval's dict item is 
needed
!     int               verbose,        // may give error message
!     int               no_autoload)    // do not use script autoloading
  {
      int               ret = OK;
      typval_T  *tv = NULL;
!     int               foundFunc = FALSE;
      dictitem_T        *v;
      int               cc;
  
--- 2550,2560 ----
      int               len,            // length of "name"
      typval_T  *rettv,         // NULL when only checking existence
      dictitem_T        **dip,          // non-NULL when typval's dict item is 
needed
!     int               flags)          // EVAL_VAR_ flags
  {
      int               ret = OK;
      typval_T  *tv = NULL;
!     int               found = FALSE;
      dictitem_T        *v;
      int               cc;
  
***************
*** 2561,2567 ****
      name[len] = NUL;
  
      // Check for user-defined variables.
!     v = find_var(name, NULL, no_autoload);
      if (v != NULL)
      {
        tv = &v->di_tv;
--- 2563,2569 ----
      name[len] = NUL;
  
      // Check for user-defined variables.
!     v = find_var(name, NULL, flags & EVAL_VAR_NOAUTOLOAD);
      if (v != NULL)
      {
        tv = &v->di_tv;
***************
*** 2581,2587 ****
        {
            if (import->imp_funcname != NULL)
            {
!               foundFunc = TRUE;
                if (rettv != NULL)
                {
                    rettv->v_type = VAR_FUNC;
--- 2583,2589 ----
        {
            if (import->imp_funcname != NULL)
            {
!               found = TRUE;
                if (rettv != NULL)
                {
                    rettv->v_type = VAR_FUNC;
***************
*** 2590,2597 ****
            }
            else if (import->imp_flags & IMP_FLAGS_STAR)
            {
!               emsg("Sorry, 'import * as X' not implemented yet");
!               ret = FAIL;
            }
            else
            {
--- 2592,2612 ----
            }
            else if (import->imp_flags & IMP_FLAGS_STAR)
            {
!               if ((flags & EVAL_VAR_IMPORT) == 0)
!               {
!                   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
            {
***************
*** 2607,2613 ****
  
            if (ufunc != NULL)
            {
!               foundFunc = TRUE;
                if (rettv != NULL)
                {
                    rettv->v_type = VAR_FUNC;
--- 2622,2628 ----
  
            if (ufunc != NULL)
            {
!               found = TRUE;
                if (rettv != NULL)
                {
                    rettv->v_type = VAR_FUNC;
***************
*** 2617,2627 ****
        }
      }
  
!     if (!foundFunc)
      {
        if (tv == NULL)
        {
!           if (rettv != NULL && verbose)
                semsg(_(e_undefined_variable_str), name);
            ret = FAIL;
        }
--- 2632,2642 ----
        }
      }
  
!     if (!found)
      {
        if (tv == NULL)
        {
!           if (rettv != NULL && (flags & EVAL_VAR_VERBOSE))
                semsg(_(e_undefined_variable_str), name);
            ret = FAIL;
        }
***************
*** 3695,3701 ****
      {
        if (tofree != NULL)
            name = tofree;
!       n = (eval_variable(name, len, &tv, NULL, FALSE, TRUE) == OK);
        if (n)
        {
            // handle d.key, l[idx], f(expr)
--- 3710,3717 ----
      {
        if (tofree != NULL)
            name = tofree;
!       n = (eval_variable(name, len, &tv, NULL,
!                                EVAL_VAR_NOAUTOLOAD + EVAL_VAR_IMPORT) == OK);
        if (n)
        {
            // handle d.key, l[idx], f(expr)
*** ../vim-8.2.2596/src/proto/evalvars.pro      2021-03-03 21:22:37.178739531 
+0100
--- src/proto/evalvars.pro      2021-03-13 20:12:00.957184043 +0100
***************
*** 56,62 ****
  char_u *v_exception(char_u *oldval);
  char_u *v_throwpoint(char_u *oldval);
  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);
  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_in_ht(hashtab_T *ht, int htname, char_u *varname, int 
no_autoload);
--- 56,62 ----
  char_u *v_exception(char_u *oldval);
  char_u *v_throwpoint(char_u *oldval);
  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 flags);
  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_in_ht(hashtab_T *ht, int htname, char_u *varname, int 
no_autoload);
*** ../vim-8.2.2596/src/vim9execute.c   2021-03-08 21:47:09.664648818 +0100
--- src/vim9execute.c   2021-03-13 20:05:46.021989741 +0100
***************
*** 1765,1771 ****
                        goto failed;
                    SOURCING_LNUM = iptr->isn_lnum;
                    if (eval_variable(name, (int)STRLEN(name),
!                                 STACK_TV_BOT(0), NULL, TRUE, FALSE) == FAIL)
                        goto on_error;
                    ++ectx.ec_stack.ga_len;
                }
--- 1765,1771 ----
                        goto failed;
                    SOURCING_LNUM = iptr->isn_lnum;
                    if (eval_variable(name, (int)STRLEN(name),
!                             STACK_TV_BOT(0), NULL, EVAL_VAR_VERBOSE) == FAIL)
                        goto on_error;
                    ++ectx.ec_stack.ga_len;
                }
*** ../vim-8.2.2596/src/errors.h        2021-02-28 16:55:07.513026844 +0100
--- src/errors.h        2021-03-13 20:02:53.554367234 +0100
***************
*** 373,375 ****
--- 373,377 ----
        INIT(= N_("E1167: Argument name shadows existing variable: %s"));
  EXTERN char e_argument_already_declared_in_script_str[]
        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"));
*** ../vim-8.2.2596/src/vim9script.c    2021-03-10 13:39:46.322350547 +0100
--- src/vim9script.c    2021-03-13 20:54:50.315818631 +0100
***************
*** 257,263 ****
        char_u      *name,
        ufunc_T     **ufunc,
        type_T      **type,
!       cctx_T      *cctx)
  {
      int               idx = -1;
      svar_T    *sv;
--- 257,264 ----
        char_u      *name,
        ufunc_T     **ufunc,
        type_T      **type,
!       cctx_T      *cctx,
!       int         verbose)
  {
      int               idx = -1;
      svar_T    *sv;
***************
*** 271,277 ****
        sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
        if (!sv->sv_export)
        {
!           semsg(_(e_item_not_exported_in_script_str), name);
            return -1;
        }
        *type = sv->sv_type;
--- 272,279 ----
        sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
        if (!sv->sv_export)
        {
!           if (verbose)
!               semsg(_(e_item_not_exported_in_script_str), name);
            return -1;
        }
        *type = sv->sv_type;
***************
*** 301,307 ****
  
        if (*ufunc == NULL)
        {
!           semsg(_(e_item_not_found_in_script_str), name);
            return -1;
        }
      }
--- 303,310 ----
  
        if (*ufunc == NULL)
        {
!           if (verbose)
!               semsg(_(e_item_not_found_in_script_str), name);
            return -1;
        }
      }
***************
*** 532,538 ****
            ufunc_T     *ufunc = NULL;
            type_T      *type;
  
!           idx = find_exported(sid, name, &ufunc, &type, cctx);
  
            if (idx < 0 && ufunc == NULL)
                goto erret;
--- 535,541 ----
            ufunc_T     *ufunc = NULL;
            type_T      *type;
  
!           idx = find_exported(sid, name, &ufunc, &type, cctx, TRUE);
  
            if (idx < 0 && ufunc == NULL)
                goto erret;
*** ../vim-8.2.2596/src/proto/vim9script.pro    2021-02-11 21:19:30.522147936 
+0100
--- src/proto/vim9script.pro    2021-03-13 20:54:02.211918980 +0100
***************
*** 7,13 ****
  void free_imports_and_script_vars(int sid);
  void mark_imports_for_reload(int sid);
  void ex_import(exarg_T *eap);
! int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, 
cctx_T *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);
  void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T 
*tv, type_T **type);
--- 7,13 ----
  void free_imports_and_script_vars(int sid);
  void mark_imports_for_reload(int sid);
  void ex_import(exarg_T *eap);
! 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 *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);
*** ../vim-8.2.2596/src/testdir/test_vim9_script.vim    2021-03-10 
14:00:15.571489906 +0100
--- src/testdir/test_vim9_script.vim    2021-03-13 20:51:35.688224516 +0100
***************
*** 1031,1043 ****
      vim9script
      import * as Export from './Xexport.vim'
      def UseExport()
!       g:imported = Export.exported
      enddef
      UseExport()
    END
    writefile(import_star_as_lines, 'Ximport.vim')
    source Ximport.vim
!   assert_equal(9883, g:imported)
  
    var import_star_as_lines_no_dot =<< trim END
      vim9script
--- 1031,1047 ----
      vim9script
      import * as Export from './Xexport.vim'
      def UseExport()
!       g:imported_def = Export.exported
      enddef
+     g:imported_script = Export.exported
+     assert_equal(1, exists('Export.exported'))
+     assert_equal(0, exists('Export.notexported'))
      UseExport()
    END
    writefile(import_star_as_lines, 'Ximport.vim')
    source Ximport.vim
!   assert_equal(9883, g:imported_def)
!   assert_equal(9883, g:imported_script)
  
    var import_star_as_lines_no_dot =<< trim END
      vim9script
***************
*** 1072,1077 ****
--- 1076,1097 ----
    writefile(import_star_as_duplicated, '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
      vim9script
      import * as Export from './Xexport.vim'
*** ../vim-8.2.2596/src/version.c       2021-03-13 15:47:51.577753545 +0100
--- src/version.c       2021-03-13 19:39:18.049496738 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2597,
  /**/

-- 
BEDEVERE: Wait.  Wait ... tell me, what also floats on water?
ALL:      Bread?  No, no, no.  Apples .... gravy ... very small rocks ...
ARTHUR:   A duck.
                 "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/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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/202103131957.12DJvmmu060616%40masaka.moolenaar.net.

Raspunde prin e-mail lui