mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.0.1127: no error if function argument shadows class member
Problem: No error if function argument shadows class member. Solution: Give an error for shadowing a class member.
This commit is contained in:
parent
fc966c19f8
commit
6acf757c6a
@ -6,7 +6,7 @@ void ex_enum(exarg_T *eap);
|
|||||||
void ex_type(exarg_T *eap);
|
void ex_type(exarg_T *eap);
|
||||||
int class_object_index(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int verbose);
|
int class_object_index(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int verbose);
|
||||||
ufunc_T *find_class_func(char_u **arg);
|
ufunc_T *find_class_func(char_u **arg);
|
||||||
int class_member_exists(char_u *name, class_T **cl_ret, int *idx_ret, cctx_T *cctx);
|
int class_member_index(char_u *name, size_t len, class_T **cl_ret, cctx_T *cctx);
|
||||||
void copy_object(typval_T *from, typval_T *to);
|
void copy_object(typval_T *from, typval_T *to);
|
||||||
void object_unref(object_T *obj);
|
void object_unref(object_T *obj);
|
||||||
void copy_class(typval_T *from, typval_T *to);
|
void copy_class(typval_T *from, typval_T *to);
|
||||||
|
@ -367,7 +367,8 @@ def Test_class_object_member_access()
|
|||||||
v9.CheckScriptFailure(lines, 'E1041:')
|
v9.CheckScriptFailure(lines, 'E1041:')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_class_member_access()
|
def Test_class_member()
|
||||||
|
# check access rules
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
class TextPos
|
class TextPos
|
||||||
@ -401,6 +402,38 @@ def Test_class_member_access()
|
|||||||
assert_equal(17, TextPos.anybody)
|
assert_equal(17, TextPos.anybody)
|
||||||
END
|
END
|
||||||
v9.CheckScriptSuccess(lines)
|
v9.CheckScriptSuccess(lines)
|
||||||
|
|
||||||
|
# check shadowing
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
|
||||||
|
class Some
|
||||||
|
static count = 0
|
||||||
|
def Method(count: number)
|
||||||
|
echo count
|
||||||
|
enddef
|
||||||
|
endclass
|
||||||
|
|
||||||
|
var s = Some.new()
|
||||||
|
s.Method(7)
|
||||||
|
END
|
||||||
|
v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
|
||||||
|
class Some
|
||||||
|
static count = 0
|
||||||
|
def Method(arg: number)
|
||||||
|
var count = 3
|
||||||
|
echo arg count
|
||||||
|
enddef
|
||||||
|
endclass
|
||||||
|
|
||||||
|
var s = Some.new()
|
||||||
|
s.Method(7)
|
||||||
|
END
|
||||||
|
v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_class_function()
|
def Test_class_function()
|
||||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1127,
|
||||||
/**/
|
/**/
|
||||||
1126,
|
1126,
|
||||||
/**/
|
/**/
|
||||||
|
@ -358,11 +358,12 @@ ex_class(exarg_T *eap)
|
|||||||
ufunc_T *uf = define_function(&ea, NULL, &lines_to_free, TRUE);
|
ufunc_T *uf = define_function(&ea, NULL, &lines_to_free, TRUE);
|
||||||
ga_clear_strings(&lines_to_free);
|
ga_clear_strings(&lines_to_free);
|
||||||
|
|
||||||
// TODO: how about errors?
|
if (uf != NULL)
|
||||||
|
{
|
||||||
int is_new = STRNCMP(uf->uf_name, "new", 3) == 0;
|
int is_new = STRNCMP(uf->uf_name, "new", 3) == 0;
|
||||||
garray_T *fgap = has_static || is_new
|
garray_T *fgap = has_static || is_new
|
||||||
? &classfunctions : &objmethods;
|
? &classfunctions : &objmethods;
|
||||||
if (uf != NULL && ga_grow(fgap, 1) == OK)
|
if (ga_grow(fgap, 1) == OK)
|
||||||
{
|
{
|
||||||
if (is_new)
|
if (is_new)
|
||||||
uf->uf_flags |= FC_NEW;
|
uf->uf_flags |= FC_NEW;
|
||||||
@ -371,6 +372,7 @@ ex_class(exarg_T *eap)
|
|||||||
++fgap->ga_len;
|
++fgap->ga_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// class members
|
// class members
|
||||||
else if (has_static)
|
else if (has_static)
|
||||||
@ -863,32 +865,30 @@ fail_after_eval:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If "cctx->ctx_ufunc" indicates we are in a class, check if "name" is a class
|
* If "name[len]" is a class member in cctx->ctx_ufunc->uf_class return the
|
||||||
* member. If it is then return TRUE and set "cl_ret" and "idx_ret".
|
* index in class.class_class_members[].
|
||||||
|
* If "cl_ret" is not NULL set it to the class.
|
||||||
|
* Otherwise return -1;
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
class_member_exists(
|
class_member_index(char_u *name, size_t len, class_T **cl_ret, cctx_T *cctx)
|
||||||
char_u *name,
|
|
||||||
class_T **cl_ret,
|
|
||||||
int *idx_ret,
|
|
||||||
cctx_T *cctx)
|
|
||||||
{
|
{
|
||||||
if (cctx->ctx_ufunc == NULL || cctx->ctx_ufunc->uf_class == NULL)
|
if (cctx == NULL || cctx->ctx_ufunc == NULL
|
||||||
return FALSE;
|
|| cctx->ctx_ufunc->uf_class == NULL)
|
||||||
|
return -1;
|
||||||
class_T *cl = cctx->ctx_ufunc->uf_class;
|
class_T *cl = cctx->ctx_ufunc->uf_class;
|
||||||
|
|
||||||
for (int idx = 0; idx < cl->class_class_member_count; ++idx)
|
for (int i = 0; i < cl->class_class_member_count; ++i)
|
||||||
{
|
{
|
||||||
ocmember_T *m = &cl->class_class_members[idx];
|
ocmember_T *m = &cl->class_class_members[i];
|
||||||
if (STRCMP(m->ocm_name, name) == 0)
|
if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL)
|
||||||
{
|
{
|
||||||
|
if (cl_ret != NULL)
|
||||||
*cl_ret = cl;
|
*cl_ret = cl;
|
||||||
*idx_ret = idx;
|
return i;
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -301,28 +301,6 @@ script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If "name" is a class member in cctx->ctx_ufunc->uf_class return the index in
|
|
||||||
* class.class_class_members[].
|
|
||||||
* Otherwise return -1;
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
class_member_index(char_u *name, size_t len, cctx_T *cctx)
|
|
||||||
{
|
|
||||||
if (cctx == NULL || cctx->ctx_ufunc == NULL
|
|
||||||
|| cctx->ctx_ufunc->uf_class == NULL)
|
|
||||||
return -1;
|
|
||||||
class_T *cl = cctx->ctx_ufunc->uf_class;
|
|
||||||
for (int i = 0; i < cl->class_class_member_count; ++i)
|
|
||||||
{
|
|
||||||
ocmember_T *m = &cl->class_class_members[i];
|
|
||||||
if (STRNCMP(name, m->ocm_name, len) == 0
|
|
||||||
&& m->ocm_name[len] == NUL)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if "name" is a local variable, argument, script variable or
|
* Return TRUE if "name" is a local variable, argument, script variable or
|
||||||
* imported.
|
* imported.
|
||||||
@ -338,7 +316,7 @@ variable_exists(char_u *name, size_t len, cctx_T *cctx)
|
|||||||
&& (cctx->ctx_ufunc->uf_flags & FC_OBJECT)
|
&& (cctx->ctx_ufunc->uf_flags & FC_OBJECT)
|
||||||
&& STRNCMP(name, "this", 4) == 0)))
|
&& STRNCMP(name, "this", 4) == 0)))
|
||||||
|| script_var_exists(name, len, cctx, NULL) == OK
|
|| script_var_exists(name, len, cctx, NULL) == OK
|
||||||
|| class_member_index(name, len, cctx) >= 0
|
|| class_member_index(name, len, NULL, cctx) >= 0
|
||||||
|| find_imported(name, len, FALSE) != NULL;
|
|| find_imported(name, len, FALSE) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,9 +354,6 @@ check_defined(
|
|||||||
if (len == 1 && *p == '_')
|
if (len == 1 && *p == '_')
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
if (class_member_index(p, len, cctx) >= 0)
|
|
||||||
return OK;
|
|
||||||
|
|
||||||
if (script_var_exists(p, len, cctx, cstack) == OK)
|
if (script_var_exists(p, len, cctx, cstack) == OK)
|
||||||
{
|
{
|
||||||
if (is_arg)
|
if (is_arg)
|
||||||
@ -388,6 +363,15 @@ check_defined(
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (class_member_index(p, len, NULL, cctx) >= 0)
|
||||||
|
{
|
||||||
|
if (is_arg)
|
||||||
|
semsg(_(e_argument_already_declared_in_class_str), p);
|
||||||
|
else
|
||||||
|
semsg(_(e_variable_already_declared_in_class_str), p);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
p[len] = NUL;
|
p[len] = NUL;
|
||||||
if ((cctx != NULL
|
if ((cctx != NULL
|
||||||
&& (lookup_local(p, len, NULL, cctx) == OK
|
&& (lookup_local(p, len, NULL, cctx) == OK
|
||||||
@ -1592,8 +1576,14 @@ compile_lhs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((lhs->lhs_classmember_idx = class_member_index(
|
else if ((lhs->lhs_classmember_idx = class_member_index(
|
||||||
var_start, lhs->lhs_varlen, cctx)) >= 0)
|
var_start, lhs->lhs_varlen, NULL, cctx)) >= 0)
|
||||||
{
|
{
|
||||||
|
if (is_decl)
|
||||||
|
{
|
||||||
|
semsg(_(e_variable_already_declared_in_class_str),
|
||||||
|
lhs->lhs_name);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
lhs->lhs_dest = dest_class_member;
|
lhs->lhs_dest = dest_class_member;
|
||||||
lhs->lhs_class = cctx->ctx_ufunc->uf_class;
|
lhs->lhs_class = cctx->ctx_ufunc->uf_class;
|
||||||
}
|
}
|
||||||
|
@ -603,7 +603,7 @@ compile_load(
|
|||||||
else
|
else
|
||||||
gen_load = TRUE;
|
gen_load = TRUE;
|
||||||
}
|
}
|
||||||
else if (class_member_exists(name, &cl, &idx, cctx))
|
else if ((idx = class_member_index(*arg, len, &cl, cctx)) >= 0)
|
||||||
{
|
{
|
||||||
res = generate_CLASSMEMBER(cctx, TRUE, cl, idx);
|
res = generate_CLASSMEMBER(cctx, TRUE, cl, idx);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user