Patch 8.2.4137
Problem:    Vim9: calling import with and without method is inconsistent.
Solution:   Set a flag that a parenthsis follows to compile_load_scriptvar().
            Add some more tests.  Improve error message.
Files:      src/vim9expr.c, src/vim9execute.c, src/vim9script.c,
            src/testdir/test_vim9_import.vim


*** ../vim-8.2.4136/src/vim9expr.c      2022-01-17 20:50:36.491316623 +0000
--- src/vim9expr.c      2022-01-18 16:51:42.168358403 +0000
***************
*** 21,26 ****
--- 21,29 ----
  # include "vim9.h"
  #endif
  
+ // flag passed from compile_subscript() to compile_load_scriptvar()
+ static int paren_follows_after_expr = 0;
+ 
  /*
   * Generate code for any ppconst entries.
   */
***************
*** 277,283 ****
        int     done = FALSE;
        int     res = OK;
  
-       // TODO: if this is an autoload import do something else.
        // Need to lookup the member.
        if (*p != '.')
        {
--- 280,285 ----
***************
*** 306,312 ****
  
            // autoload script must be loaded later, access by the autoload
            // name.
!           if (cc == '(')
                res = generate_PUSHFUNC(cctx, auto_name, &t_func_any);
            else
                res = generate_LOAD(cctx, ISN_LOADG, 0, auto_name, &t_any);
--- 308,314 ----
  
            // autoload script must be loaded later, access by the autoload
            // name.
!           if (cc == '(' || paren_follows_after_expr)
                res = generate_PUSHFUNC(cctx, auto_name, &t_func_any);
            else
                res = generate_LOAD(cctx, ISN_LOADG, 0, auto_name, &t_any);
***************
*** 1736,1747 ****
--- 1738,1756 ----
                    int save_len = cctx->ctx_ufunc->uf_lines.ga_len;
  
                    *paren = NUL;
+ 
+                   // instead of using LOADG for "import.Func" use PUSHFUNC
+                   ++paren_follows_after_expr;
+ 
                    // do not look in the next line
                    cctx->ctx_ufunc->uf_lines.ga_len = 1;
+ 
                    fail = compile_expr8(arg, cctx, ppconst) == FAIL
                                                    || *skipwhite(*arg) != NUL;
                    *paren = '(';
+                   --paren_follows_after_expr;
                    cctx->ctx_ufunc->uf_lines.ga_len = save_len;
+ 
                    if (fail)
                    {
                        semsg(_(e_invalid_expression_str), pstart);
*** ../vim-8.2.4136/src/vim9execute.c   2022-01-18 12:58:24.726772997 +0000
--- src/vim9execute.c   2022-01-18 17:29:48.517038067 +0000
***************
*** 2240,2272 ****
                                                   iptr->isn_arg.string, TRUE);
                        if (did_emsg)
                            goto on_error;
-                       if (di == NULL)
-                       {
-                           isn_T   *next = &ectx->ec_instr[ectx->ec_iidx];
- 
-                           // When compiling "script.Func()" when "script" is
-                           // an autoload import then this results in
-                           // "LOADG script#Func" because we don't know if it
-                           // is a funcref variable or a function name.  In
-                           // that case a PCALL follows, push the function
-                           // name instead.
-                           if (next->isn_type == ISN_PCALL)
-                           {
-                               tv = STACK_TV_BOT(0);
-                               tv->v_type = VAR_FUNC;
-                               tv->v_lock = 0;
-                               tv->vval.v_string =
-                                            vim_strsave(iptr->isn_arg.string);
-                               ++ectx->ec_stack.ga_len;
-                               break;
-                           }
-                       }
                    }
  
                    if (di == NULL)
                    {
                        SOURCING_LNUM = iptr->isn_lnum;
!                       semsg(_(e_undefined_variable_char_str),
                                             namespace, iptr->isn_arg.string);
                        goto on_error;
                    }
--- 2240,2258 ----
                                                   iptr->isn_arg.string, TRUE);
                        if (did_emsg)
                            goto on_error;
                    }
  
                    if (di == NULL)
                    {
                        SOURCING_LNUM = iptr->isn_lnum;
!                       if (vim_strchr(iptr->isn_arg.string,
!                                                       AUTOLOAD_CHAR) != NULL)
!                           // no check if the item exists in the script but
!                           // isn't exported, it is too complicated
!                           semsg(_(e_item_not_found_in_script_str),
!                                                        iptr->isn_arg.string);
!                       else
!                           semsg(_(e_undefined_variable_char_str),
                                             namespace, iptr->isn_arg.string);
                        goto on_error;
                    }
*** ../vim-8.2.4136/src/vim9script.c    2022-01-18 16:25:58.618309943 +0000
--- src/vim9script.c    2022-01-18 17:10:23.319140985 +0000
***************
*** 707,728 ****
            sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name);
        }
        *ufunc = find_func(funcname, FALSE);
-       if (funcname != buffer)
-           vim_free(funcname);
  
        if (*ufunc == NULL)
        {
            if (verbose)
!               semsg(_(e_item_not_found_in_script_str), name);
!           return -1;
        }
        else if (((*ufunc)->uf_flags & FC_EXPORT) == 0)
        {
            if (verbose)
                semsg(_(e_item_not_exported_in_script_str), name);
            *ufunc = NULL;
-           return -1;
        }
      }
  
      return idx;
--- 707,742 ----
            sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name);
        }
        *ufunc = find_func(funcname, FALSE);
  
        if (*ufunc == NULL)
        {
            if (verbose)
!           {
!               ufunc_T *alt_ufunc = NULL;
! 
!               if (script->sn_autoload_prefix != NULL)
!               {
!                   // try find the function by the script-local name
!                   funcname[0] = K_SPECIAL;
!                   funcname[1] = KS_EXTRA;
!                   funcname[2] = (int)KE_SNR;
!                   sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name);
!                   alt_ufunc = find_func(funcname, FALSE);
!               }
!               if (alt_ufunc != NULL)
!                   semsg(_(e_item_not_exported_in_script_str), name);
!               else
!                   semsg(_(e_item_not_found_in_script_str), name);
!           }
        }
        else if (((*ufunc)->uf_flags & FC_EXPORT) == 0)
        {
            if (verbose)
                semsg(_(e_item_not_exported_in_script_str), name);
            *ufunc = NULL;
        }
+       if (funcname != buffer)
+           vim_free(funcname);
      }
  
      return idx;
*** ../vim-8.2.4136/src/testdir/test_vim9_import.vim    2022-01-18 
16:25:58.618309943 +0000
--- src/testdir/test_vim9_import.vim    2022-01-18 17:39:32.997562933 +0000
***************
*** 1256,1261 ****
--- 1256,1391 ----
    &rtp = save_rtp
  enddef
  
+ def Test_import_autoload_not_exported()
+   mkdir('Xdir/autoload', 'p')
+   var save_rtp = &rtp
+   exe 'set rtp^=' .. getcwd() .. '/Xdir'
+ 
+   # error when using an item that is not exported from an autoload script
+   var exportLines =<< trim END
+       vim9script
+       var notExported = 123
+       def NotExport()
+         echo 'nop'
+       enddef
+   END
+   writefile(exportLines, 'Xdir/autoload/notExport1.vim')
+ 
+   var lines =<< trim END
+       vim9script
+       import autoload 'notExport1.vim'
+       echo notExport1.notFound
+   END
+   CheckScriptFailure(lines, 'E1048: Item not found in script: notFound')
+ 
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport1.vim'
+       echo notExport1.notExported
+   END
+   CheckScriptFailure(lines, 'E1049: Item not exported in script: notExported')
+ 
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport1.vim'
+       echo notExport1.NotFunc()
+   END
+   CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc')
+ 
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport1.vim'
+       echo notExport1.NotExport()
+   END
+   CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport')
+ 
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport1.vim'
+       echo 'text'->notExport1.NotFunc()
+   END
+   CheckScriptFailure(lines, 'E1048: Item not found in script: NotFunc')
+ 
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport1.vim'
+       echo 'text'->notExport1.NotExport()
+   END
+   CheckScriptFailure(lines, 'E1049: Item not exported in script: NotExport')
+ 
+   # using a :def function we use a different autoload script every time so 
that
+   # the function is compiled without the script loaded
+   writefile(exportLines, 'Xdir/autoload/notExport2.vim')
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport2.vim'
+       def Testit()
+         echo notExport2.notFound
+       enddef
+       Testit()
+   END
+   CheckScriptFailure(lines, 'E1048: Item not found in script: 
notExport2#notFound')
+ 
+   writefile(exportLines, 'Xdir/autoload/notExport3.vim')
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport3.vim'
+       def Testit()
+         echo notExport3.notExported
+       enddef
+       Testit()
+   END
+   # don't get E1049 because it is too complicated to figure out
+   CheckScriptFailure(lines, 'E1048: Item not found in script: 
notExport3#notExported')
+ 
+   writefile(exportLines, 'Xdir/autoload/notExport4.vim')
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport4.vim'
+       def Testit()
+         echo notExport4.NotFunc()
+       enddef
+       Testit()
+   END
+   CheckScriptFailure(lines, 'E117: Unknown function: notExport4#NotFunc')
+ 
+   writefile(exportLines, 'Xdir/autoload/notExport5.vim')
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport5.vim'
+       def Testit()
+         echo notExport5.NotExport()
+       enddef
+       Testit()
+   END
+   CheckScriptFailure(lines, 'E117: Unknown function: notExport5#NotExport')
+ 
+   writefile(exportLines, 'Xdir/autoload/notExport6.vim')
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport6.vim'
+       def Testit()
+         echo 'text'->notExport6.NotFunc()
+       enddef
+       Testit()
+   END
+   CheckScriptFailure(lines, 'E117: Unknown function: notExport6#NotFunc')
+ 
+   writefile(exportLines, 'Xdir/autoload/notExport7.vim')
+   lines =<< trim END
+       vim9script
+       import autoload 'notExport7.vim'
+       def Testit()
+         echo 'text'->notExport7.NotExport()
+       enddef
+       Testit()
+   END
+   CheckScriptFailure(lines, 'E117: Unknown function: notExport7#NotExport')
+ 
+   delete('Xdir', 'rf')
+   &rtp = save_rtp
+ enddef
+ 
  def Test_vim9script_autoload_call()
    mkdir('Xdir/autoload', 'p')
    var save_rtp = &rtp
*** ../vim-8.2.4136/src/version.c       2022-01-18 16:25:58.618309943 +0000
--- src/version.c       2022-01-18 16:48:20.320463461 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4137,
  /**/

-- 
    f y cn rd ths thn y cn hv grt jb n cmptr prgrmmng

 /// 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/20220118174347.CC7C91C044E%40moolenaar.net.

Raspunde prin e-mail lui