From 4cae845ce32797bcae845aacf740ed865b479f34 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 15 Jan 2023 15:51:48 +0000 Subject: [PATCH] patch 9.0.1201: assignment with operator doesn't work in object method Problem: Assignment with operator doesn't work in object method. Solution: Handle loading the object member. (closes #11820) Add a few more tests. --- src/testdir/test_vim9_class.vim | 55 +++++++++++++++++++++++++++++++++ src/version.c | 2 ++ src/vim9compile.c | 15 +++++++++ 3 files changed, 72 insertions(+) diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 4a2b87c740..56b2dad7e0 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -200,6 +200,25 @@ def Test_class_member_initializer() v9.CheckScriptSuccess(lines) enddef +def Test_assignment_with_operator() + var lines =<< trim END + vim9script + + class Foo + this.x: number + + def Add(n: number) + this.x += n + enddef + endclass + + var f = Foo.new(3) + f.Add(17) + assert_equal(20, f.x) + END + v9.CheckScriptSuccess(lines) +enddef + def Test_class_default_new() var lines =<< trim END vim9script @@ -521,6 +540,25 @@ def Test_class_member() END v9.CheckScriptSuccess(lines) + # example in the help + lines =<< trim END + vim9script + class OtherThing + this.size: number + static totalSize: number + + def new(this.size) + totalSize += this.size + enddef + endclass + assert_equal(0, OtherThing.totalSize) + var to3 = OtherThing.new(3) + assert_equal(3, OtherThing.totalSize) + var to7 = OtherThing.new(7) + assert_equal(10, OtherThing.totalSize) + END + v9.CheckScriptSuccess(lines) + # check shadowing lines =<< trim END vim9script @@ -986,6 +1024,23 @@ def Test_class_extends() assert_equal('Base class: 42', o.ToString()) END v9.CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + class Base + this.value = 1 + def new(init: number) + this.value = number + 1 + enddef + endclass + class Child extends Base + def new() + this.new(3) + enddef + endclass + var c = Child.new() + END + v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(') enddef def Test_class_import() diff --git a/src/version.c b/src/version.c index 9427081d54..e4674e410a 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1201, /**/ 1200, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index cc7a3bdc43..2b65ff9459 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2044,6 +2044,21 @@ compile_load_lhs( int compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx) { + if (lhs->lhs_type->tt_type == VAR_OBJECT) + { + // "this.value": load "this" object and get the value at index + // for an object or class member get the type of the member + class_T *cl = (class_T *)lhs->lhs_type->tt_member; + type_T *type = class_member_type(cl, var_start + 5, + lhs->lhs_end, &lhs->lhs_member_idx); + if (lhs->lhs_member_idx < 0) + return FAIL; + + if (generate_LOAD(cctx, ISN_LOAD, 0, NULL, lhs->lhs_type) == FAIL) + return FAIL; + return generate_GET_OBJ_MEMBER(cctx, lhs->lhs_member_idx, type); + } + compile_load_lhs(lhs, var_start, NULL, cctx); if (lhs->lhs_has_index) -- 2.47.2