changeset 32475:a44d7e4ac1c0 v9.0.1569

patch 9.0.1569: cannot use "this.member" in lambda in class method Commit: https://github.com/vim/vim/commit/2bd6a09691fc71974ca7ab5973f8e08fdd2a889a Author: h-east <h.east.727@gmail.com> Date: Fri May 19 19:01:17 2023 +0100 patch 9.0.1569: cannot use "this.member" in lambda in class method Problem: Cannot use "this.member" in lambda in class method. Solution: Adjust check for reserved keyword. (Hirohito Higashi, closes #12416, closes #12076, closes #12336)
author Bram Moolenaar <Bram@vim.org>
date Fri, 19 May 2023 20:15:04 +0200
parents a715c20f474f
children 2dd215ad5fc2
files src/eval.c src/proto/vim9script.pro src/testdir/test_vim9_class.vim src/version.c src/vim9compile.c src/vim9script.c
diffstat 6 files changed, 30 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -1654,7 +1654,7 @@ set_var_lval(
     {
 	cc = *endp;
 	*endp = NUL;
-	if (in_vim9script() && check_reserved_name(lp->ll_name, NULL) == FAIL)
+	if (in_vim9script() && check_reserved_name(lp->ll_name, FALSE) == FAIL)
 	    return;
 
 	if (lp->ll_blob != NULL)
--- a/src/proto/vim9script.pro
+++ b/src/proto/vim9script.pro
@@ -19,5 +19,5 @@ void update_vim9_script_var(int create, 
 void hide_script_var(scriptitem_T *si, int idx, int func_defined);
 svar_T *find_typval_in_script(typval_T *dest, scid_T sid, int must_find);
 int check_script_var_type(svar_T *sv, typval_T *value, char_u *name, where_T where);
-int check_reserved_name(char_u *name, cctx_T *cctx);
+int check_reserved_name(char_u *name, int is_objm_access);
 /* vim: set ft=c : */
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -856,6 +856,27 @@ def Test_class_member()
   END
   v9.CheckScriptSuccess(lines)
 
+  # access private member in lambda body
+  lines =<< trim END
+      vim9script
+
+      class Foo
+        this._x: number = 6
+
+        def Add(n: number): number
+          var Lam = () => {
+            this._x = this._x + n
+          }
+          Lam()
+          return this._x
+        enddef
+      endclass
+
+      var foo = Foo.new()
+      assert_equal(13, foo.Add(7))
+  END
+  v9.CheckScriptSuccess(lines)
+
   # check shadowing
   lines =<< trim END
       vim9script
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1569,
+/**/
     1568,
 /**/
     1567,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1580,7 +1580,8 @@ compile_lhs(
 	else
 	{
 	    // No specific kind of variable recognized, just a name.
-	    if (check_reserved_name(lhs->lhs_name, cctx) == FAIL)
+	    if (check_reserved_name(lhs->lhs_name, lhs->lhs_has_index
+						&& *var_end == '.') == FAIL)
 		return FAIL;
 
 	    if (lookup_local(var_start, lhs->lhs_varlen,
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -838,7 +838,7 @@ vim9_declare_scriptvar(exarg_T *eap, cha
     // parse type, check for reserved name
     p = skipwhite(p + 1);
     type = parse_type(&p, &si->sn_type_list, TRUE);
-    if (type == NULL || check_reserved_name(name, NULL) == FAIL)
+    if (type == NULL || check_reserved_name(name, FALSE) == FAIL)
     {
 	vim_free(name);
 	return p;
@@ -1127,17 +1127,13 @@ static char *reserved[] = {
 };
 
     int
-check_reserved_name(char_u *name, cctx_T *cctx)
+check_reserved_name(char_u *name, int is_objm_access)
 {
     int idx;
 
     for (idx = 0; reserved[idx] != NULL; ++idx)
 	if (STRCMP(reserved[idx], name) == 0
-		// "this" can be used in an object method
-		&& !(STRCMP("this", name) == 0
-		    && cctx != NULL
-		    && cctx->ctx_ufunc != NULL
-		    && (cctx->ctx_ufunc->uf_flags & (FC_OBJECT|FC_NEW))))
+		&& !(STRCMP("this", name) == 0 && is_objm_access))
 	{
 	    semsg(_(e_cannot_use_reserved_name_str), name);
 	    return FAIL;