summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-01-12 17:06:27 +0000
committerBram Moolenaar <Bram@vim.org>2023-01-12 17:06:27 +0000
commita86655af84f1596f0f3ef22813724fe06f1e4809 (patch)
treebbf962d3a9b0597e34be6cecc9657241bb3346f3 /src
parenta94bd9d9396183eb7781f8d6a5a0e6e97442e9ed (diff)
patch 9.0.1185: using class from imported script not testedv9.0.1185
Problem: Using class from imported script not tested. Solution: Add tests. Implement what is missing.
Diffstat (limited to 'src')
-rw-r--r--src/evalvars.c25
-rw-r--r--src/proto/evalvars.pro1
-rw-r--r--src/testdir/test_vim9_class.vim22
-rw-r--r--src/version.c2
-rw-r--r--src/vim9class.c11
-rw-r--r--src/vim9type.c10
6 files changed, 64 insertions, 7 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index c2cb61c37a..e473e48763 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -3105,6 +3105,31 @@ eval_variable(
}
/*
+ * 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.
*/
diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro
index b8b0053422..661cb5974d 100644
--- a/src/proto/evalvars.pro
+++ b/src/proto/evalvars.pro
@@ -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);
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 74df0f4394..cf7a6c1ce2 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index e0d5bffa0b..a0fc017a03 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1185,
+/**/
1184,
/**/
1183,
diff --git a/src/vim9class.c b/src/vim9class.c
index a60e70d2a0..a1466be87d 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -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;
diff --git a/src/vim9type.c b/src/vim9type.c
index 02b674d23c..9f95a8261c 100644
--- a/src/vim9type.c
+++ b/src/vim9type.c
@@ -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)
{