summaryrefslogtreecommitdiffstats
path: root/src/evalfunc.c
diff options
context:
space:
mode:
authorErnie Rael <errael@raelity.com>2023-10-14 11:25:04 +0200
committerChristian Brabandt <cb@256bit.org>2023-10-14 11:25:04 +0200
commit0f058d13206665bad37c7d42834cfa0075f50239 (patch)
tree75929a5f6eb9fc5d4b3fa5008d701569e2a5dbf6 /src/evalfunc.c
parent2bbd0d30eebdea66c0da3895e83d999ed6ad83fb (diff)
patch 9.0.2020: Vim9: islocked() needs more workv9.0.2020
Problem: Vim9: islocked() needs more work Solution: rework islocked() and remove sync_root from get_lval() closes: #13329 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Ernie Rael <errael@raelity.com>
Diffstat (limited to 'src/evalfunc.c')
-rw-r--r--src/evalfunc.c58
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;