]> granicus.if.org Git - vim/commitdiff
patch 9.0.1185: using class from imported script not tested v9.0.1185
authorBram Moolenaar <Bram@vim.org>
Thu, 12 Jan 2023 17:06:27 +0000 (17:06 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 12 Jan 2023 17:06:27 +0000 (17:06 +0000)
Problem:    Using class from imported script not tested.
Solution:   Add tests.  Implement what is missing.

src/evalvars.c
src/proto/evalvars.pro
src/testdir/test_vim9_class.vim
src/version.c
src/vim9class.c
src/vim9type.c

index c2cb61c37a0d01f57ec25bc44ac9df13c3588e16..e473e48763fac2ff4ff2e7de43190c962c7512be 100644 (file)
@@ -3104,6 +3104,31 @@ eval_variable(
     return ret;
 }
 
+/*
+ * Get the value of internal variable "name", also handling "import.name".
+ * Return OK or FAIL.  If OK is returned "rettv" must be cleared.
+ */
+    int
+eval_variable_import(
+    char_u     *name,
+    typval_T   *rettv)
+{
+    char_u  *s = name;
+    while (ASCII_ISALNUM(*s) || *s == '_')
+       ++s;
+    int            len = (int)(s - name);
+
+    if (eval_variable(name, len, 0, rettv, NULL, EVAL_VAR_IMPORT) == FAIL)
+       return FAIL;
+    if (rettv->v_type == VAR_ANY && *s == '.')
+    {
+       int sid = rettv->vval.v_number;
+       return eval_variable(s + 1, 0, sid, rettv, NULL, 0);
+    }
+    return OK;
+}
+
+
 /*
  * Check if variable "name[len]" is a local variable or an argument.
  * If so, "*eval_lavars_used" is set to TRUE.
index b8b0053422f3aebad57bfee648d263cd9eb15148..661cb5974d1fa1a9eaa3c02e42e2bf35e09589b9 100644 (file)
@@ -60,6 +60,7 @@ 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, scid_T sid, typval_T *rettv, dictitem_T **dip, int flags);
+int eval_variable_import(char_u *name, typval_T *rettv);
 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_also_in_script(char_u *name, hashtab_T **htp, int no_autoload);
index 74df0f4394e8ae0fa6ca839036e38ca4a5fccc8d..cf7a6c1ce2d5eb78bfadec50c3f9377457ac44e3 100644 (file)
@@ -974,5 +974,27 @@ def Test_class_extends()
   v9.CheckScriptSuccess(lines)
 enddef
 
+def Test_class_import()
+  var lines =<< trim END
+      vim9script
+      export class Animal
+        this.kind: string
+        this.name: string
+      endclass
+  END
+  writefile(lines, 'Xanimal.vim', 'D')
+
+  lines =<< trim END
+      vim9script
+      import './Xanimal.vim' as animal
+
+      var a: animal.Animal
+      a = animal.Animal.new('fish', 'Eric')
+      assert_equal('fish', a.kind)
+      assert_equal('Eric', a.name)
+  END
+  v9.CheckScriptSuccess(lines)
+enddef
+
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index e0d5bffa0b11f3a1f0aef80c774d5467f0f65f77..a0fc017a03ad6da7b791d441061a858205dd770d 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1185,
 /**/
     1184,
 /**/
index a60e70d2a05844680be097efefb2f80ab8e876bc..a1466be87d50721a052affe328cf9c49c0912085 100644 (file)
@@ -244,9 +244,13 @@ ex_class(exarg_T *eap)
     }
     char_u *name_start = arg;
 
+    // "export class" gets used when creating the class, don't use "is_export"
+    // for the items inside the class.
+    int class_export = is_export;
+    is_export = FALSE;
+
     // TODO:
     //    generics: <Tkey, Tentry>
-    //   handle "is_export" if it is set
 
     // Name for "extends BaseClass"
     char_u *extends = NULL;
@@ -558,7 +562,7 @@ early_ret:
     {
        typval_T tv;
        tv.v_type = VAR_UNKNOWN;
-       if (eval_variable(extends, 0, 0, &tv, NULL, EVAL_VAR_IMPORT) == FAIL)
+       if (eval_variable_import(extends, &tv) == FAIL)
        {
            semsg(_(e_class_name_not_found_str), extends);
            success = FALSE;
@@ -594,7 +598,7 @@ early_ret:
            char_u *impl = ((char_u **)ga_impl.ga_data)[i];
            typval_T tv;
            tv.v_type = VAR_UNKNOWN;
-           if (eval_variable(impl, 0, 0, &tv, NULL, EVAL_VAR_IMPORT) == FAIL)
+           if (eval_variable_import(impl, &tv) == FAIL)
            {
                semsg(_(e_interface_name_not_found_str), impl);
                success = FALSE;
@@ -930,6 +934,7 @@ early_ret:
        typval_T tv;
        tv.v_type = VAR_CLASS;
        tv.vval.v_class = cl;
+       is_export = class_export;
        set_var_const(cl->class_name, current_sctx.sc_sid,
                                             NULL, &tv, FALSE, ASSIGN_DECL, 0);
        return;
index 02b674d23c3e17c163c492a45a85a547952b8c35..9f95a8261c0ae32517835226bbed6f7048819218 100644 (file)
@@ -982,7 +982,9 @@ skip_type(char_u *start, int optional)
 
     if (optional && *p == '?')
        ++p;
-    while (ASCII_ISALNUM(*p) || *p == '_')
+
+    // Also skip over "." for imported classes: "import.ClassName".
+    while (ASCII_ISALNUM(*p) || *p == '_' || *p == '.')
        ++p;
 
     // Skip over "<type>"; this is permissive about white space.
@@ -1091,7 +1093,7 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
     char_u  *p = *arg;
     size_t  len;
 
-    // skip over the first word
+    // Skip over the first word.
     while (ASCII_ISALNUM(*p) || *p == '_')
        ++p;
     len = p - *arg;
@@ -1293,10 +1295,10 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
            break;
     }
 
-    // It can be a class or interface name.
+    // It can be a class or interface name, possibly imported.
     typval_T tv;
     tv.v_type = VAR_UNKNOWN;
-    if (eval_variable(*arg, (int)len, 0, &tv, NULL, EVAL_VAR_IMPORT) == OK)
+    if (eval_variable_import(*arg, &tv) == OK)
     {
        if (tv.v_type == VAR_CLASS && tv.vval.v_class != NULL)
        {