]> granicus.if.org Git - vim/commitdiff
patch 8.2.4102: Vim9: import cannot be used after method v8.2.4102
authorBram Moolenaar <Bram@vim.org>
Sat, 15 Jan 2022 21:08:19 +0000 (21:08 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 15 Jan 2022 21:08:19 +0000 (21:08 +0000)
Problem:    Vim9: import cannot be used after method.
Solution:   Recognize an imported function name. (closes #9496)

src/eval.c
src/testdir/test_vim9_import.vim
src/version.c

index 08804c09243c1d55fc7425623413fe2242f56aef..5588abd026048fd7b571464ae67cf5811bbf648a 100644 (file)
@@ -3949,7 +3949,7 @@ eval_method(
     long       len;
     char_u     *alias;
     typval_T   base = *rettv;
-    int                ret;
+    int                ret = OK;
     int                evaluate = evalarg != NULL
                                      && (evalarg->eval_flags & EVAL_EVALUATE);
 
@@ -3968,22 +3968,87 @@ eval_method(
     }
     else
     {
-       *arg = skipwhite(*arg);
-       if (**arg != '(')
+       if (**arg == '.')
        {
-           if (verbose)
-               semsg(_(e_missing_parenthesis_str), name);
-           ret = FAIL;
+           int         len2;
+           char_u      *fname;
+           int         idx;
+           imported_T  *import = find_imported(name, len,
+                                                    TRUE, evalarg->eval_cctx);
+           type_T      *type;
+
+           // value->import.func()
+           if (import != NULL)
+           {
+               name = NULL;
+               ++*arg;
+               fname = *arg;
+               len2 = get_name_len(arg, &alias, evaluate, TRUE);
+               if (len2 <= 0)
+               {
+                   emsg(_(e_missing_name_after_dot));
+                   ret = FAIL;
+               }
+               else
+               {
+                   int     cc = fname[len2];
+                   ufunc_T *ufunc;
+
+                   fname[len2] = NUL;
+                   idx = find_exported(import->imp_sid, fname, &ufunc, &type,
+                                                 evalarg->eval_cctx, verbose);
+                   fname[len2] = cc;
+
+                   if (idx >= 0)
+                   {
+                       scriptitem_T    *si = SCRIPT_ITEM(import->imp_sid);
+                       svar_T          *sv =
+                                    ((svar_T *)si->sn_var_vals.ga_data) + idx;
+
+                       if (sv->sv_tv->v_type == VAR_FUNC
+                                          && sv->sv_tv->vval.v_string != NULL)
+                       {
+                           name = sv->sv_tv->vval.v_string;
+                           len = STRLEN(name);
+                       }
+                       else
+                       {
+                           // TODO: how about a partial?
+                           semsg(_(e_not_callable_type_str), fname);
+                           ret = FAIL;
+                       }
+                   }
+                   else if (ufunc != NULL)
+                   {
+                       name = ufunc->uf_name;
+                       len = STRLEN(name);
+                   }
+                   else
+                       ret = FAIL;
+               }
+           }
        }
-       else if (VIM_ISWHITE((*arg)[-1]))
+
+       if (ret == OK)
        {
-           if (verbose)
-               emsg(_(e_no_white_space_allowed_before_parenthesis));
-           ret = FAIL;
-       }
-       else
-           ret = eval_func(arg, evalarg, name, len, rettv,
+           *arg = skipwhite(*arg);
+
+           if (**arg != '(')
+           {
+               if (verbose)
+                   semsg(_(e_missing_parenthesis_str), name);
+               ret = FAIL;
+           }
+           else if (VIM_ISWHITE((*arg)[-1]))
+           {
+               if (verbose)
+                   emsg(_(e_no_white_space_allowed_before_parenthesis));
+               ret = FAIL;
+           }
+           else
+               ret = eval_func(arg, evalarg, name, len, rettv,
                                          evaluate ? EVAL_EVALUATE : 0, &base);
+       }
     }
 
     // Clear the funcref afterwards, so that deleting it while
index f5e449714f179037c98962fd8de9f6452c28ad31..79e572896b296a9f209bc62c48e47f19e2fc7b40 100644 (file)
@@ -27,6 +27,10 @@ let s:export_script_lines =<< trim END
     exported += 5
   enddef
   export final theList = [1]
+  export def AddSome(s: string): string
+    return s .. 'some'
+  enddef
+  export var AddRef = AddSome
 END
 
 def Undo_export_script_lines()
@@ -70,6 +74,9 @@ def Test_vim9_import_export()
 
     expo.theList->add(2)
     assert_equal([1, 2], expo.theList)
+
+    assert_equal('andthensome', 'andthen'->expo.AddSome())
+    assert_equal('awesome', 'awe'->expo.AddRef())
   END
   writefile(import_script_lines, 'Ximport.vim')
   source Ximport.vim
index e6bcb1ba3be1917065698cd77f2a67a82cbb820d..dd97a716ec4ca15e54791ace4ae0c47f618da3c3 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4102,
 /**/
     4101,
 /**/