patch 9.0.1949: Vim9: allows reserved keywords as members

Commit: 
https://github.com/vim/vim/commit/f057aca1cc2480e820b3ca5d8d407e3976369777
Author: Yegappan Lakshmanan <[email protected]>
Date:   Thu Sep 28 22:28:15 2023 +0200

    patch 9.0.1949: Vim9: allows reserved keywords as members
    
    Problem:  Vim9: allows reserved keywords as members
    Solution: Disallow reserved keywords, disallow
              duplicate object and class variables
    
    closes: #13209
    
    Signed-off-by: Christian Brabandt <[email protected]>
    Co-authored-by: Yegappan Lakshmanan <[email protected]>

diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index c272aab39..681f614c9 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -4150,7 +4150,7 @@ def Test_dup_member_variable()
     assert_equal(10, C.val)
     assert_equal(20, c.val)
   END
-  v9.CheckSourceSuccess(lines)
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
 
   # Duplicate object member variable in a derived class
   lines =<< trim END
@@ -5768,4 +5768,91 @@ def Test_freed_object_from_previous_method_call()
   v9.CheckSourceSuccess(lines)
 enddef
 
+" Test for duplicate object and class variable
+def Test_duplicate_variable()
+  # Object variable name is same as the class variable name
+  var lines =<< trim END
+    vim9script
+    class A
+      public static sval: number
+      public this.sval: number
+    endclass
+    var a = A.new()
+  END
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
+
+  # Duplicate variable name and calling a class method
+  lines =<< trim END
+    vim9script
+    class A
+      public static sval: number
+      public this.sval: number
+      def F1()
+        echo this.sval
+      enddef
+      static def F2()
+        echo sval
+      enddef
+    endclass
+    A.F2()
+  END
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
+
+  # Duplicate variable with an empty constructor
+  lines =<< trim END
+    vim9script
+    class A
+      public static sval: number
+      public this.sval: number
+      def new()
+      enddef
+    endclass
+    var a = A.new()
+  END
+  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
+enddef
+
+" Test for using a reserved keyword as a variable name
+def Test_reserved_varname()
+  for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
+                'null_function', 'null_list', 'null_partial', 'null_string',
+                'null_channel', 'null_job', 'super', 'this']
+
+    var lines =<< trim eval END
+      vim9script
+      class C
+        public this.{kword}: list<number> = [1, 2, 3]
+      endclass
+      var o = C.new()
+    END
+    v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
+
+    lines =<< trim eval END
+      vim9script
+      class C
+        public this.{kword}: list<number> = [1, 2, 3]
+        def new()
+        enddef
+      endclass
+      var o = C.new()
+    END
+    v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
+
+    lines =<< trim eval END
+      vim9script
+      class C
+        public this.{kword}: list<number> = [1, 2, 3]
+        def new()
+        enddef
+        def F()
+          echo this.{kword}
+        enddef
+      endclass
+      var o = C.new()
+      o.F()
+    END
+    v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
+  endfor
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/version.c b/src/version.c
index 49b406781..dade6d2fe 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 */
+/**/
+    1949,
 /**/
     1948,
 /**/
diff --git a/src/vim9class.c b/src/vim9class.c
index 8b07d7649..4c70f8d0f 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -893,24 +893,52 @@ check_func_arg_names(
 }
 
 /*
- * Returns TRUE if the member "varname" is already defined.
+ * Returns TRUE if 'varname' is a reserved keyword name
  */
     static int
-is_duplicate_member(garray_T *mgap, char_u *varname, char_u *varname_end)
+is_reserved_varname(char_u *varname, char_u *varname_end)
+{
+    int reserved = FALSE;
+    char_u save_varname_end = *varname_end;
+    *varname_end = NUL;
+
+    reserved = check_reserved_name(varname, FALSE) == FAIL;
+
+    *varname_end = save_varname_end;
+
+    return reserved;
+}
+
+/*
+ * Returns TRUE if the variable "varname" is already defined either as a class
+ * variable or as an object variable.
+ */
+    static int
+is_duplicate_variable(
+    garray_T   *class_members,
+    garray_T   *obj_members,
+    char_u     *varname,
+    char_u     *varname_end)
 {
     char_u     *name = vim_strnsave(varname, varname_end - varname);
     char_u     *pstr = (*name == '_') ? name + 1 : name;
     int                dup = FALSE;
 
-    for (int i = 0; i < mgap->ga_len; ++i)
+    for (int loop = 1; loop <= 2; loop++)
     {
-       ocmember_T *m = ((ocmember_T *)mgap->ga_data) + i;
-       char_u  *qstr = *m->ocm_name == '_' ? m->ocm_name + 1 : m->ocm_name;
-       if (STRCMP(pstr, qstr) == 0)
+       // loop == 1: class variables, loop == 2: object variables
+       garray_T    *vgap = (loop == 1) ? class_members : obj_members;
+       for (int i = 0; i < vgap->ga_len; ++i)
        {
-           semsg(_(e_duplicate_variable_str), name);
-           dup = TRUE;
-           break;
+           ocmember_T *m = ((ocmember_T *)vgap->ga_data) + i;
+           char_u      *qstr = *m->ocm_name == '_' ? m->ocm_name + 1
+                                                   : m->ocm_name;
+           if (STRCMP(pstr, qstr) == 0)
+           {
+               semsg(_(e_duplicate_variable_str), name);
+               dup = TRUE;
+               break;
+           }
        }
     }
 
@@ -1646,7 +1674,13 @@ early_ret:
                          &varname_end, &type_list, &type,
                          is_class ? &init_expr: NULL) == FAIL)
                break;
-           if (is_duplicate_member(&objmembers, varname, varname_end))
+           if (is_reserved_varname(varname, varname_end))
+           {
+               vim_free(init_expr);
+               break;
+           }
+           if (is_duplicate_variable(&classmembers, &objmembers, varname,
+                                                               varname_end))
            {
                vim_free(init_expr);
                break;
@@ -1768,7 +1802,13 @@ early_ret:
                      &varname_end, &type_list, &type,
                      is_class ? &init_expr : NULL) == FAIL)
                break;
-           if (is_duplicate_member(&classmembers, varname, varname_end))
+           if (is_reserved_varname(varname, varname_end))
+           {
+               vim_free(init_expr);
+               break;
+           }
+           if (is_duplicate_variable(&classmembers, &objmembers, varname,
+                                                               varname_end))
            {
                vim_free(init_expr);
                break;

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1qlxse-00G7sh-CB%40256bit.org.

Raspunde prin e-mail lui