mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 9.0.2016: Vim9: assignment operators don't work for class vars
Problem: Vim9: assignment operators don't work for class vars Solution: implement it closes: #13306 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
committed by
Christian Brabandt
parent
4c8da025ef
commit
1ea428883f
@@ -1,8 +1,8 @@
|
|||||||
/* vim9class.c */
|
/* vim9class.c */
|
||||||
int object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl);
|
int object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl);
|
||||||
void ex_class(exarg_T *eap);
|
void ex_class(exarg_T *eap);
|
||||||
type_T *class_member_type(class_T *cl, int is_object, char_u *name, char_u *name_end, int *member_idx);
|
type_T *oc_member_type(class_T *cl, int is_object, char_u *name, char_u *name_end, int *member_idx);
|
||||||
type_T *class_member_type_by_idx(class_T *cl, int is_object, int member_idx);
|
type_T *oc_member_type_by_idx(class_T *cl, int is_object, int member_idx);
|
||||||
void ex_enum(exarg_T *eap);
|
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);
|
||||||
|
@@ -7431,4 +7431,50 @@ def Test_funcref_argtype_returntype_check()
|
|||||||
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
|
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
" Test for using an operator (e.g. +) with an assignment
|
||||||
|
def Test_op_and_assignment()
|
||||||
|
# Using += with a class variable
|
||||||
|
var lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
class A
|
||||||
|
public static val: list<number> = []
|
||||||
|
static def Foo(): list<number>
|
||||||
|
val += [1]
|
||||||
|
return val
|
||||||
|
enddef
|
||||||
|
endclass
|
||||||
|
def Bar(): list<number>
|
||||||
|
A.val += [2]
|
||||||
|
return A.val
|
||||||
|
enddef
|
||||||
|
assert_equal([1], A.Foo())
|
||||||
|
assert_equal([1, 2], Bar())
|
||||||
|
A.val += [3]
|
||||||
|
assert_equal([1, 2, 3], A.val)
|
||||||
|
END
|
||||||
|
v9.CheckSourceSuccess(lines)
|
||||||
|
|
||||||
|
# Using += with an object variable
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
class A
|
||||||
|
public this.val: list<number> = []
|
||||||
|
def Foo(): list<number>
|
||||||
|
this.val += [1]
|
||||||
|
return this.val
|
||||||
|
enddef
|
||||||
|
endclass
|
||||||
|
def Bar(bar_a: A): list<number>
|
||||||
|
bar_a.val += [2]
|
||||||
|
return bar_a.val
|
||||||
|
enddef
|
||||||
|
var a = A.new()
|
||||||
|
assert_equal([1], a.Foo())
|
||||||
|
assert_equal([1, 2], Bar(a))
|
||||||
|
a.val += [3]
|
||||||
|
assert_equal([1, 2, 3], a.val)
|
||||||
|
END
|
||||||
|
v9.CheckSourceSuccess(lines)
|
||||||
|
enddef
|
||||||
|
|
||||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||||
|
@@ -704,6 +704,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 */
|
||||||
|
/**/
|
||||||
|
2016,
|
||||||
/**/
|
/**/
|
||||||
2015,
|
2015,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -2032,7 +2032,7 @@ cleanup:
|
|||||||
* Set *p_m ocmmember_T if not NULL
|
* Set *p_m ocmmember_T if not NULL
|
||||||
*/
|
*/
|
||||||
type_T *
|
type_T *
|
||||||
class_member_type(
|
oc_member_type(
|
||||||
class_T *cl,
|
class_T *cl,
|
||||||
int is_object,
|
int is_object,
|
||||||
char_u *name,
|
char_u *name,
|
||||||
@@ -2060,7 +2060,7 @@ class_member_type(
|
|||||||
* Given a class or object variable index, return the variable type
|
* Given a class or object variable index, return the variable type
|
||||||
*/
|
*/
|
||||||
type_T *
|
type_T *
|
||||||
class_member_type_by_idx(
|
oc_member_type_by_idx(
|
||||||
class_T *cl,
|
class_T *cl,
|
||||||
int is_object,
|
int is_object,
|
||||||
int member_idx)
|
int member_idx)
|
||||||
|
@@ -1770,7 +1770,7 @@ compile_lhs(
|
|||||||
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;
|
||||||
lhs->lhs_type =
|
lhs->lhs_type =
|
||||||
class_member_type_by_idx(cctx->ctx_ufunc->uf_class,
|
oc_member_type_by_idx(cctx->ctx_ufunc->uf_class,
|
||||||
FALSE, lhs->lhs_classmember_idx);
|
FALSE, lhs->lhs_classmember_idx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2254,7 +2254,7 @@ compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
class_T *cl = lhs->lhs_type->tt_class;
|
class_T *cl = lhs->lhs_type->tt_class;
|
||||||
type_T *type = class_member_type(cl, TRUE, dot + 1,
|
type_T *type = oc_member_type(cl, TRUE, dot + 1,
|
||||||
lhs->lhs_end, &lhs->lhs_member_idx);
|
lhs->lhs_end, &lhs->lhs_member_idx);
|
||||||
if (lhs->lhs_member_idx < 0)
|
if (lhs->lhs_member_idx < 0)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -2275,6 +2275,22 @@ compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx)
|
|||||||
return generate_GET_ITF_MEMBER(cctx, cl, lhs->lhs_member_idx, type);
|
return generate_GET_ITF_MEMBER(cctx, cl, lhs->lhs_member_idx, type);
|
||||||
return generate_GET_OBJ_MEMBER(cctx, lhs->lhs_member_idx, type);
|
return generate_GET_OBJ_MEMBER(cctx, lhs->lhs_member_idx, type);
|
||||||
}
|
}
|
||||||
|
else if (lhs->lhs_type->tt_type == VAR_CLASS)
|
||||||
|
{
|
||||||
|
// "<classname>.value": load class variable "classname.value"
|
||||||
|
char_u *dot = vim_strchr(var_start, '.');
|
||||||
|
if (dot == NULL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
class_T *cl = lhs->lhs_type->tt_class;
|
||||||
|
ocmember_T *m = class_member_lookup(cl, dot + 1,
|
||||||
|
lhs->lhs_end - dot - 1,
|
||||||
|
&lhs->lhs_member_idx);
|
||||||
|
if (m == NULL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
return generate_CLASSMEMBER(cctx, TRUE, cl, lhs->lhs_member_idx);
|
||||||
|
}
|
||||||
|
|
||||||
compile_load_lhs(lhs, var_start, NULL, cctx);
|
compile_load_lhs(lhs, var_start, NULL, cctx);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user