diff options
Diffstat (limited to 'src/evalfunc.c')
-rw-r--r-- | src/evalfunc.c | 58 |
1 files changed, 19 insertions, 39 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c index 85c64a23a2..f9b81c6054 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -7325,64 +7325,48 @@ free_lval_root(lval_root_T *root) /* * This is used if executing in a method, the argument string is a - * variable/item expr/reference. If it starts with a potential class/object - * variable then return OK, may get later errors in get_lval. + * variable/item expr/reference. It may start with a potential class/object + * variable. * - * Adjust "root" as needed. Note that name may change (for example to skip - * "this") and is returned. lr_tv may be changed or freed. + * Adjust "root" as needed; lr_tv may be changed or freed. * * Always returns OK. * Free resources and return FAIL if the root should not be used. Otherwise OK. */ static int -fix_variable_reference_lval_root(lval_root_T *root, char_u **p_name) +fix_variable_reference_lval_root(lval_root_T *root, char_u *name) { - char_u *name = *p_name; - char_u *end; - dictitem_T *di; - // Only set lr_sync_root and lr_tv if the name is an object/class - // reference: object ("this.") or class because name is class variable. + // Check if lr_tv is the name of an object/class reference: name start with + // "this" or name is class variable. Clear lr_tv if neither. + int found_member = FALSE; if (root->lr_tv->v_type == VAR_OBJECT) { - if (STRNCMP("this.", name, 5) == 0) - { - name += 5; - root->lr_sync_root = TRUE; - } - else if (STRCMP("this", name) == 0) - { - name += 4; - root->lr_sync_root = TRUE; - } + if (STRNCMP("this.", name, 5) == 0 ||STRCMP("this", name) == 0) + found_member = TRUE; } - if (!root->lr_sync_root) // not object member, try class member + if (!found_member) // not object member, try class member { // Explicitly check if the name is a class member. // If it's not then do nothing. + char_u *end; for (end = name; ASCII_ISALNUM(*end) || *end == '_'; ++end) ; - if (class_member_lookup(root->lr_cl_exec, name, end - name, NULL) - != NULL) + int idx = class_member_idx(root->lr_cl_exec, name, end - name); + if (idx >= 0) { - // Using a class, so reference the class tv. - di = find_var(root->lr_cl_exec->class_name, NULL, FALSE); - if (di != NULL) - { - // replace the lr_tv - clear_tv(root->lr_tv); - copy_tv(&di->di_tv, root->lr_tv); - root->lr_sync_root = TRUE; - } + // A class variable, replace lr_tv with it + clear_tv(root->lr_tv); + copy_tv(&root->lr_cl_exec->class_members_tv[idx], root->lr_tv); + found_member = TRUE; } } - if (!root->lr_sync_root) + if (!found_member) { free_tv(root->lr_tv); root->lr_tv = NULL; // Not a member variable } - *p_name = name; // If FAIL, then must free_lval_root(root); return OK; } @@ -7415,12 +7399,8 @@ f_islocked(typval_T *argvars, typval_T *rettv) { // Almost always produces a valid lval_root since lr_cl_exec is used // for access verification, lr_tv may be set to NULL. - char_u *tname = name; - if (fix_variable_reference_lval_root(&aroot, &tname) == OK) - { - name = tname; + if (fix_variable_reference_lval_root(&aroot, name) == OK) root = &aroot; - } } lval_root_T *lval_root_save = lval_root; |