diff options
-rw-r--r-- | src/proto/vim9class.pro | 4 | ||||
-rw-r--r-- | src/testdir/test_vim9_class.vim | 46 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9class.c | 4 | ||||
-rw-r--r-- | src/vim9compile.c | 20 |
5 files changed, 70 insertions, 6 deletions
diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro index c9e19d0067..362e2cac5e 100644 --- a/src/proto/vim9class.pro +++ b/src/proto/vim9class.pro @@ -1,8 +1,8 @@ /* vim9class.c */ int object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl); 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 *class_member_type_by_idx(class_T *cl, int is_object, 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 *oc_member_type_by_idx(class_T *cl, int is_object, int member_idx); void ex_enum(exarg_T *eap); void ex_type(exarg_T *eap); int class_object_index(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int verbose); diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index eead19283a..1aa9de7b99 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -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) 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 diff --git a/src/version.c b/src/version.c index 61f6289e28..4031debd86 100644 --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2016, +/**/ 2015, /**/ 2014, diff --git a/src/vim9class.c b/src/vim9class.c index 0cb353bb57..5dda700fa3 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -2032,7 +2032,7 @@ cleanup: * Set *p_m ocmmember_T if not NULL */ type_T * -class_member_type( +oc_member_type( class_T *cl, int is_object, char_u *name, @@ -2060,7 +2060,7 @@ class_member_type( * Given a class or object variable index, return the variable type */ type_T * -class_member_type_by_idx( +oc_member_type_by_idx( class_T *cl, int is_object, int member_idx) diff --git a/src/vim9compile.c b/src/vim9compile.c index 7e1914b694..544ad17e10 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1770,7 +1770,7 @@ compile_lhs( lhs->lhs_dest = dest_class_member; lhs->lhs_class = cctx->ctx_ufunc->uf_class; 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); } else @@ -2254,7 +2254,7 @@ compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx) return FAIL; 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); if (lhs->lhs_member_idx < 0) 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_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); |