patch 9.0.1982: vim9: clean up from v9.0.1955
Problem: vim9: clean up from v9.0.1955
Solution: Fix a few remaining issues, improve error message
- Use `cl_exec`, the executing class, to check permissions in `get_lval()`.
- Handle lockvar of script variable from class.
- Add 'in class "Xxx"' to e_cannot_access_private_variable_str.
closes: #13222
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Ernie Rael <errael@raelity.com>
diff --git a/src/vim9cmds.c b/src/vim9cmds.c
index 0d6dc01..0be2077 100644
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -212,11 +212,20 @@
if (p[1] != ':')
{
char_u *end = find_name_end(p, NULL, NULL, FNE_CHECK_START);
- // If name is is locally accessible, except for local var,
+
+ // The most important point is that something like
+ // name[idx].member... needs to be resolved at runtime, get_lval(),
+ // starting from the root "name".
+
+ // These checks are reminiscent of the variable_exists function.
+ // But most of the matches require special handling.
+
+ // If bare name is is locally accessible, except for local var,
// then put it on the stack to use with ISN_LOCKUNLOCK.
// This could be v.memb, v[idx_key]; bare class variable,
- // function arg. The local variable on the stack, will be passed
- // to ex_lockvar() indirectly.
+ // function arg. The item on the stack, will be passed
+ // to ex_lockvar() indirectly and be used as the root for get_lval.
+ // A bare script variable name needs no special handling.
char_u *name = NULL;
int len = end - p;
@@ -233,7 +242,7 @@
// Push the local on the stack, could be "this".
name = p;
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... lookup_local: name %s", name);
+ ch_log(NULL, "LKVAR: ... lookup_local: name %s", name);
#endif
}
if (name == NULL)
@@ -247,7 +256,7 @@
name = cl->class_name;
len = STRLEN(name);
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... cctx_class_member: name %s",
+ ch_log(NULL, "LKVAR: ... cctx_class_member: name %s",
name);
#endif
}
@@ -255,23 +264,33 @@
}
if (name == NULL)
{
- int idx;
- type_T *type;
// Can lockvar any function arg.
- // TODO: test arg[idx]/arg.member
- if (arg_exists(p, len, &idx, &type, NULL, cctx) == OK)
+ if (arg_exists(p, len, NULL, NULL, NULL, cctx) == OK)
{
name = p;
is_arg = TRUE;
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... arg_exists: name %s", name);
+ ch_log(NULL, "LKVAR: ... arg_exists: name %s", name);
+#endif
+ }
+ }
+ if (name == NULL)
+ {
+ // No special handling for a bare script variable; but
+ // if followed by '[' or '.', it's a root for get_lval().
+ if (script_var_exists(p, len, cctx, NULL) == OK
+ && (*end == '.' || *end == '['))
+ {
+ name = p;
+#ifdef LOG_LOCKVAR
+ ch_log(NULL, "LKVAR: ... script_var_exists: name %s", name);
#endif
}
}
if (name != NULL)
{
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... INS_LOCKUNLOCK %s", name);
+ ch_log(NULL, "LKVAR: ... INS_LOCKUNLOCK %s", name);
#endif
if (compile_load(&name, name + len, cctx, FALSE, FALSE) == FAIL)
return FAIL;
@@ -292,7 +311,7 @@
else
vim_snprintf((char *)buf, len, "%s %d %s", cmd, deep, p);
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... buf %s", buf);
+ ch_log(NULL, "LKVAR: ... buf %s", buf);
#endif
if (isn == ISN_LOCKUNLOCK)
ret = generate_LOCKUNLOCK(cctx, buf, is_arg);