]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1201: assignment with operator doesn't work in object method v9.0.1201
authorBram Moolenaar <Bram@vim.org>
Sun, 15 Jan 2023 15:51:48 +0000 (15:51 +0000)
committerBram Moolenaar <Bram@vim.org>
Sun, 15 Jan 2023 15:51:48 +0000 (15:51 +0000)
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
src/version.c
src/vim9compile.c

index 4a2b87c740c8a69a0078885d0336dd9a0eece447..56b2dad7e07bffb54e1eb0f300b87fda6230f7a3 100644 (file)
@@ -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()
index 9427081d54d2c145cc641f3d5c10df9975afe99d..e4674e410abcd56ab813ab57584492d38f16eae0 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1201,
 /**/
     1200,
 /**/
index cc7a3bdc4319ff684b5808137c1abd45e74ea3be..2b65ff94599cb67920017097d0b01c3e0dce3245 100644 (file)
@@ -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)