Patch 8.2.3178
Problem:    Vim9: the file name of an :import cannot be an expression.
Solution:   Accept an expression that results in a string.  Do not support
            :import in a function.
Files:      runtime/doc/vim9.txt, src/vim9script.c, src/vim9compile.c,
            src/testdir/test_vim9_script.vim


*** ../vim-8.2.3177/runtime/doc/vim9.txt        2021-06-12 14:52:35.953230564 
+0200
--- runtime/doc/vim9.txt        2021-07-18 18:03:38.334326980 +0200
***************
*** 1306,1311 ****
--- 1363,1371 ----
  `:import` can also be used in legacy Vim script.  The imported items still
  become script-local, even when the "s:" prefix is not given.
  
+ `:import` can not be used in a function.  Imported items are intended to exist
+ at the script level and only imported once.
+ 
  The script name after `import` can be:
  - A relative path, starting "." or "..".  This finds a file relative to the
    location of the script file itself.  This is useful to split up a large
***************
*** 1315,1320 ****
--- 1375,1381 ----
  - A path not being relative or absolute.  This will be found in the
    "import" subdirectories of 'runtimepath' entries.  The name will usually be
    longer and unique, to avoid loading the wrong file.
+   Note that "after/import" is not used.
  
  Once a vim9 script file has been imported, the result is cached and used the
  next time the same script is imported.  It will not be read again.
*** ../vim-8.2.3177/src/vim9script.c    2021-07-08 21:38:45.339232318 +0200
--- src/vim9script.c    2021-07-18 17:43:46.896511720 +0200
***************
*** 412,417 ****
--- 412,418 ----
      garray_T  names;
      garray_T  as_names;
  
+     tv.v_type = VAR_UNKNOWN;
      ga_init2(&names, sizeof(char_u *), 10);
      ga_init2(&as_names, sizeof(char_u *), 10);
      if (*arg == '{')
***************
*** 496,509 ****
        goto erret;
      }
  
      arg = skipwhite_and_linebreak(arg + 4, evalarg);
!     tv.v_type = VAR_UNKNOWN;
!     // TODO: should we accept any expression?
!     if (*arg == '\'')
!       ret = eval_lit_string(&arg, &tv, TRUE);
!     else if (*arg == '"')
!       ret = eval_string(&arg, &tv, TRUE);
!     if (ret == FAIL || tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
      {
        emsg(_(e_invalid_string_after_from));
        goto erret;
--- 497,510 ----
        goto erret;
      }
  
+     // The name of the file can be an expression, which must evaluate to a
+     // string.
      arg = skipwhite_and_linebreak(arg + 4, evalarg);
!     ret = eval0(arg, &tv, NULL, evalarg);
!     if (ret == FAIL)
!       goto erret;
!     if (tv.v_type != VAR_STRING
!                      || tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
      {
        emsg(_(e_invalid_string_after_from));
        goto erret;
***************
*** 524,533 ****
        len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
        from_name = alloc((int)len);
        if (from_name == NULL)
-       {
-           clear_tv(&tv);
            goto erret;
-       }
        vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
        add_pathsep(from_name);
        STRCAT(from_name, tv.vval.v_string);
--- 525,531 ----
***************
*** 550,556 ****
        from_name = alloc((int)len);
        if (from_name == NULL)
        {
-           clear_tv(&tv);
            goto erret;
        }
        vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string);
--- 548,553 ----
***************
*** 561,570 ****
      if (res == FAIL || sid <= 0)
      {
        semsg(_(e_could_not_import_str), tv.vval.v_string);
-       clear_tv(&tv);
        goto erret;
      }
-     clear_tv(&tv);
  
      if (*arg_start == '*')
      {
--- 558,565 ----
***************
*** 669,674 ****
--- 664,670 ----
        }
      }
  erret:
+     clear_tv(&tv);
      ga_clear_strings(&names);
      ga_clear_strings(&as_names);
      return cmd_end;
*** ../vim-8.2.3177/src/vim9compile.c   2021-07-17 21:24:52.063911244 +0200
--- src/vim9compile.c   2021-07-18 18:05:37.366071470 +0200
***************
*** 4335,4341 ****
                    semsg(_(e_missing_paren), *arg);
                    return FAIL;
                }
-               // TODO: base value may not be the first argument
                if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL)
                    return FAIL;
            }
--- 4335,4340 ----
***************
*** 7294,7308 ****
  }
  
  /*
-  * Compile an :import command.
-  */
-     static char_u *
- compile_import(char_u *arg, cctx_T *cctx)
- {
-     return handle_import(arg, &cctx->ctx_imports, 0, NULL, cctx);
- }
- 
- /*
   * generate a jump to the ":endif"/":endfor"/":endwhile"/":finally"/":endtry".
   */
      static int
--- 7293,7298 ----
***************
*** 9638,9644 ****
                    break;
  
            case CMD_import:
!                   line = compile_import(p, &cctx);
                    break;
  
            case CMD_if:
--- 9628,9635 ----
                    break;
  
            case CMD_import:
!                   emsg(_(e_import_can_only_be_used_in_script));
!                   line = NULL;
                    break;
  
            case CMD_if:
*** ../vim-8.2.3177/src/testdir/test_vim9_script.vim    2021-07-18 
17:08:47.028125894 +0200
--- src/testdir/test_vim9_script.vim    2021-07-18 18:17:42.808680143 +0200
***************
*** 1085,1091 ****
      enddef
      g:funcref_result = GetExported()
  
!     import {exp_name} from './Xexport.vim'
      g:imported_name = exp_name
      exp_name ..= ' Doe'
      g:imported_name_appended = exp_name
--- 1085,1093 ----
      enddef
      g:funcref_result = GetExported()
  
!     var dir = './'
!     var ext = ".vim"
!     import {exp_name} from dir .. 'Xexport' .. ext
      g:imported_name = exp_name
      exp_name ..= ' Doe'
      g:imported_name_appended = exp_name
***************
*** 1148,1173 ****
    unlet g:imported_func
    delete('Ximport_lbr.vim')
  
-   # import inside :def function
-   var import_in_def_lines =<< trim END
-     vim9script
-     def ImportInDef()
-       import exported from './Xexport.vim'
-       g:imported = exported
-       exported += 7
-       g:imported_added = exported
-     enddef
-     ImportInDef()
-   END
-   writefile(import_in_def_lines, 'Ximport2.vim')
-   source Ximport2.vim
-   # TODO: this should be 9879
-   assert_equal(9876, g:imported)
-   assert_equal(9883, g:imported_added)
-   unlet g:imported
-   unlet g:imported_added
-   delete('Ximport2.vim')
- 
    var import_star_as_lines =<< trim END
      vim9script
      import * as Export from './Xexport.vim'
--- 1150,1155 ----
***************
*** 1181,1188 ****
    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
--- 1163,1171 ----
    END
    writefile(import_star_as_lines, 'Ximport.vim')
    source Ximport.vim
!   # FIXME: this should be 9881
!   assert_equal(9876, g:imported_def)
!   assert_equal(9876, g:imported_script)
  
    var import_star_as_lines_no_dot =<< trim END
      vim9script
***************
*** 1257,1263 ****
    END
    writefile(import_star_as_lbr_lines, 'Ximport.vim')
    source Ximport.vim
!   assert_equal(9883, g:imported)
  
    var import_star_lines =<< trim END
      vim9script
--- 1240,1246 ----
    END
    writefile(import_star_as_lbr_lines, 'Ximport.vim')
    source Ximport.vim
!   assert_equal(9876, g:imported)
  
    var import_star_lines =<< trim END
      vim9script
***************
*** 1345,1351 ****
      import name from Xexport.vim
    END
    writefile(import_invalid_string_lines, 'Ximport.vim')
!   assert_fails('source Ximport.vim', 'E1071:', '', 2, 'Ximport.vim')
  
    var import_wrong_name_lines =<< trim END
      vim9script
--- 1328,1334 ----
      import name from Xexport.vim
    END
    writefile(import_invalid_string_lines, 'Ximport.vim')
!   assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')
  
    var import_wrong_name_lines =<< trim END
      vim9script
***************
*** 1659,1680 ****
    source Xreload.vim
    source Xreload.vim
  
-   var testlines =<< trim END
-     vim9script
-     def TheFunc()
-       import GetValtwo from './Xreload.vim'
-       assert_equal(222, GetValtwo())
-     enddef
-     TheFunc()
-   END
-   writefile(testlines, 'Ximport.vim')
-   source Ximport.vim
- 
-   # Test that when not using "morelines" GetValtwo() and valtwo are still
-   # defined, because import doesn't reload a script.
-   writefile(lines, 'Xreload.vim')
-   source Ximport.vim
- 
    # cannot declare a var twice
    lines =<< trim END
      vim9script
--- 1642,1647 ----
*** ../vim-8.2.3177/src/version.c       2021-07-18 17:08:47.032125889 +0200
--- src/version.c       2021-07-18 18:04:16.594243503 +0200
***************
*** 757,758 ****
--- 757,760 ----
  {   /* Add new patch number below this line */
+ /**/
+     3178,
  /**/

-- 
If Microsoft would build a car...
... Occasionally your car would die on the freeway for no
reason. You would have to pull over to the side of the road,
close all of the car windows, shut it off, restart it, and
reopen the windows before you could continue. For some reason
you would simply accept this.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/202107181622.16IGM4hg2783536%40masaka.moolenaar.net.

Raspunde prin e-mail lui