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