comparison src/vim9cmds.c @ 33456:4a62e78803db v9.0.1982

patch 9.0.1982: vim9: clean up from v9.0.1955 Commit: https://github.com/vim/vim/commit/64885645e76b301a6c34fe762c4e29c7a0f63881 Author: Ernie Rael <errael@raelity.com> Date: Wed Oct 4 20:16:22 2023 +0200 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>
author Christian Brabandt <cb@256bit.org>
date Wed, 04 Oct 2023 20:30:03 +0200
parents 016d8f863230
children f61713271934
comparison
equal deleted inserted replaced
33455:d1dddc5cb66e 33456:4a62e78803db
210 210
211 // Cannot use :lockvar and :unlockvar on local variables. 211 // Cannot use :lockvar and :unlockvar on local variables.
212 if (p[1] != ':') 212 if (p[1] != ':')
213 { 213 {
214 char_u *end = find_name_end(p, NULL, NULL, FNE_CHECK_START); 214 char_u *end = find_name_end(p, NULL, NULL, FNE_CHECK_START);
215 // If name is is locally accessible, except for local var, 215
216 // The most important point is that something like
217 // name[idx].member... needs to be resolved at runtime, get_lval(),
218 // starting from the root "name".
219
220 // These checks are reminiscent of the variable_exists function.
221 // But most of the matches require special handling.
222
223 // If bare name is is locally accessible, except for local var,
216 // then put it on the stack to use with ISN_LOCKUNLOCK. 224 // then put it on the stack to use with ISN_LOCKUNLOCK.
217 // This could be v.memb, v[idx_key]; bare class variable, 225 // This could be v.memb, v[idx_key]; bare class variable,
218 // function arg. The local variable on the stack, will be passed 226 // function arg. The item on the stack, will be passed
219 // to ex_lockvar() indirectly. 227 // to ex_lockvar() indirectly and be used as the root for get_lval.
228 // A bare script variable name needs no special handling.
220 229
221 char_u *name = NULL; 230 char_u *name = NULL;
222 int len = end - p; 231 int len = end - p;
223 232
224 if (lookup_local(p, len, NULL, cctx) == OK) 233 if (lookup_local(p, len, NULL, cctx) == OK)
231 return FAIL; 240 return FAIL;
232 } 241 }
233 // Push the local on the stack, could be "this". 242 // Push the local on the stack, could be "this".
234 name = p; 243 name = p;
235 #ifdef LOG_LOCKVAR 244 #ifdef LOG_LOCKVAR
236 ch_log(NULL, "LKVAR: compile... lookup_local: name %s", name); 245 ch_log(NULL, "LKVAR: ... lookup_local: name %s", name);
237 #endif 246 #endif
238 } 247 }
239 if (name == NULL) 248 if (name == NULL)
240 { 249 {
241 class_T *cl; 250 class_T *cl;
245 { 254 {
246 // Push the class of the bare class variable name 255 // Push the class of the bare class variable name
247 name = cl->class_name; 256 name = cl->class_name;
248 len = STRLEN(name); 257 len = STRLEN(name);
249 #ifdef LOG_LOCKVAR 258 #ifdef LOG_LOCKVAR
250 ch_log(NULL, "LKVAR: compile... cctx_class_member: name %s", 259 ch_log(NULL, "LKVAR: ... cctx_class_member: name %s",
251 name); 260 name);
252 #endif 261 #endif
253 } 262 }
254 } 263 }
255 } 264 }
256 if (name == NULL) 265 if (name == NULL)
257 { 266 {
258 int idx;
259 type_T *type;
260 // Can lockvar any function arg. 267 // Can lockvar any function arg.
261 // TODO: test arg[idx]/arg.member 268 if (arg_exists(p, len, NULL, NULL, NULL, cctx) == OK)
262 if (arg_exists(p, len, &idx, &type, NULL, cctx) == OK)
263 { 269 {
264 name = p; 270 name = p;
265 is_arg = TRUE; 271 is_arg = TRUE;
266 #ifdef LOG_LOCKVAR 272 #ifdef LOG_LOCKVAR
267 ch_log(NULL, "LKVAR: compile... arg_exists: name %s", name); 273 ch_log(NULL, "LKVAR: ... arg_exists: name %s", name);
268 #endif 274 #endif
269 } 275 }
270 } 276 }
277 if (name == NULL)
278 {
279 // No special handling for a bare script variable; but
280 // if followed by '[' or '.', it's a root for get_lval().
281 if (script_var_exists(p, len, cctx, NULL) == OK
282 && (*end == '.' || *end == '['))
283 {
284 name = p;
285 #ifdef LOG_LOCKVAR
286 ch_log(NULL, "LKVAR: ... script_var_exists: name %s", name);
287 #endif
288 }
289 }
271 if (name != NULL) 290 if (name != NULL)
272 { 291 {
273 #ifdef LOG_LOCKVAR 292 #ifdef LOG_LOCKVAR
274 ch_log(NULL, "LKVAR: compile... INS_LOCKUNLOCK %s", name); 293 ch_log(NULL, "LKVAR: ... INS_LOCKUNLOCK %s", name);
275 #endif 294 #endif
276 if (compile_load(&name, name + len, cctx, FALSE, FALSE) == FAIL) 295 if (compile_load(&name, name + len, cctx, FALSE, FALSE) == FAIL)
277 return FAIL; 296 return FAIL;
278 isn = ISN_LOCKUNLOCK; 297 isn = ISN_LOCKUNLOCK;
279 } 298 }
290 if (deep < 0) 309 if (deep < 0)
291 vim_snprintf((char *)buf, len, "%s! %s", cmd, p); 310 vim_snprintf((char *)buf, len, "%s! %s", cmd, p);
292 else 311 else
293 vim_snprintf((char *)buf, len, "%s %d %s", cmd, deep, p); 312 vim_snprintf((char *)buf, len, "%s %d %s", cmd, deep, p);
294 #ifdef LOG_LOCKVAR 313 #ifdef LOG_LOCKVAR
295 ch_log(NULL, "LKVAR: compile... buf %s", buf); 314 ch_log(NULL, "LKVAR: ... buf %s", buf);
296 #endif 315 #endif
297 if (isn == ISN_LOCKUNLOCK) 316 if (isn == ISN_LOCKUNLOCK)
298 ret = generate_LOCKUNLOCK(cctx, buf, is_arg); 317 ret = generate_LOCKUNLOCK(cctx, buf, is_arg);
299 else 318 else
300 ret = generate_EXEC_copy(cctx, isn, buf); 319 ret = generate_EXEC_copy(cctx, isn, buf);