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);