From 98e68c07ce229148c994a42ead9f010b0d0a1be4 Mon Sep 17 00:00:00 2001 From: Ernie Rael Date: Wed, 20 Sep 2023 20:13:06 +0200 Subject: [PATCH] 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 Co-authored-by: Ernie Rael --- src/eval.c | 3 ++ src/testdir/test_vim9_class.vim | 55 +++++++++++++++++++++++++++++++++ src/version.c | 2 ++ 3 files changed, 60 insertions(+) diff --git a/src/eval.c b/src/eval.c index 931d510451..93b840e61e 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1564,6 +1564,9 @@ get_lval( 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 763b5a539b..f57bf44d04 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -613,8 +613,63 @@ def Test_assignment_nested_type() 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 ec6cce3084..5abc4f733c 100644 --- a/src/version.c +++ b/src/version.c @@ -699,6 +699,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1920, /**/ 1919, /**/