patch 9.0.1920: Vim9: cannot write public var in nested object
Problem: Vim9: cannot write public var in nested object
Solution: Write variable in nested read-only object reference.
Also test write fails.
closes: #13130
closes: #13131
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Ernie Rael <errael@raelity.com>
diff --git a/src/eval.c b/src/eval.c
index 931d510..93b840e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1564,6 +1564,9 @@
om->ocm_name);
return NULL;
case VIM_ACCESS_READ:
+ // If [idx] or .key following, read only OK.
+ if (*p == '[' || *p == '.')
+ break;
if ((flags & GLV_READ_ONLY) == 0)
{
semsg(_(e_member_is_not_writable_str),
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 763b5a5..f57bf44 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -613,8 +613,63 @@
enddef
Test_assign_to_nested_typed_member()
+
+ var script_inner = Inner.new(0)
+ var script_outer = Outer.new(script_inner)
+ script_outer.inner.value = 1
+ assert_equal(1, script_inner.value)
END
v9.CheckSourceSuccess(lines)
+
+ # Assignment where target item is read only in :def
+ lines =<< trim END
+ vim9script
+
+ class Inner
+ this.value: number = 0
+ endclass
+
+ class Outer
+ this.inner: Inner
+ endclass
+
+ def F(outer: Outer)
+ outer.inner.value = 1
+ enddef
+
+ def Test_assign_to_nested_typed_member()
+ var inner = Inner.new(0)
+ var outer = Outer.new(inner)
+ F(outer)
+ assert_equal(1, inner.value)
+ enddef
+
+ Test_assign_to_nested_typed_member()
+ END
+ v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "value"')
+
+ # Assignment where target item is read only script level
+ lines =<< trim END
+ vim9script
+
+ class Inner
+ this.value: number = 0
+ endclass
+
+ class Outer
+ this.inner: Inner
+ endclass
+
+ def F(outer: Outer)
+ outer.inner.value = 1
+ enddef
+
+ var script_inner = Inner.new(0)
+ var script_outer = Outer.new(script_inner)
+ script_outer.inner.value = 1
+ assert_equal(1, script_inner.value)
+ END
+ v9.CheckSourceFailure(lines, 'E1335: Member is not writable: value')
enddef
def Test_assignment_with_operator()
diff --git a/src/version.c b/src/version.c
index ec6cce3..5abc4f7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1920,
+/**/
1919,
/**/
1918,