]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0507: Vim9 class: public/protected member name clash uses same error v9.2.0507
authorHirohito Higashi <h.east.727@gmail.com>
Thu, 21 May 2026 19:45:59 +0000 (19:45 +0000)
committerChristian Brabandt <cb@256bit.org>
Thu, 21 May 2026 19:45:59 +0000 (19:45 +0000)
Problem:  When a public member and a protected member in a Vim9
          class have the same name (differing only in the leading '_'),
          Vim reports E1369 "Duplicate variable", which is also used for
          plain duplicate definitions.  Users cannot tell from the
          message whether the conflict is the public/protected naming
          rule or a real duplicate.
Solution: Add a dedicated error E1406 "Public and protected member
          have the same name" and emit it only when the name clash is
          between a public and a protected member.  Keep E1369 for
          genuine duplicate variable definitions (Hirohito Higashi).

fixes:  #20240
closes: #20277

Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/tags
runtime/doc/vim9class.txt
src/errors.h
src/po/vim.pot
src/testdir/test_vim9_class.vim
src/version.c
src/vim9class.c

index 6cac191f33de2a294ee0e14e9a741ee2cedb82d7..7a4c09031b1568fccb0272e2f133ab753eed620e 100644 (file)
@@ -4650,6 +4650,7 @@ E140      message.txt     /*E140*
 E1403  vim9class.txt   /*E1403*
 E1404  vim9class.txt   /*E1404*
 E1405  vim9class.txt   /*E1405*
+E1406  vim9class.txt   /*E1406*
 E1407  vim9class.txt   /*E1407*
 E1408  vim9class.txt   /*E1408*
 E1409  vim9class.txt   /*E1409*
index 7c92c455caf55235444b35a21e214e4ba61a3c80..58458b627d340d50da349adc6777ce2b3e8f099c 100644 (file)
@@ -635,7 +635,7 @@ once.  They can appear in any order, although this order is recommended: >
 <
 The "specifies" feature is currently not implemented.
 
-                                                       *E1355* *E1369*
+                                               *E1355* *E1369* *E1406*
 Each variable and method name can be used only once.  It is not possible to
 define a method with the same name and different type of arguments.  It is not
 possible to use a public and protected member variable with the same name.  An
index 3ba7eca8f50d9284b287933fa016fa35f6502c94..4e261c9232e73ee9b6e92789877ea83ab66cb0ee 100644 (file)
@@ -3564,7 +3564,8 @@ EXTERN char e_abstract_cannot_be_used_in_interface[]
        INIT(= N_("E1404: Abstract cannot be used in an interface"));
 EXTERN char e_using_class_as_value_str[]
        INIT(= N_("E1405: Class \"%s\" cannot be used as a value"));
-// E1406 unused
+EXTERN char e_public_and_protected_member_have_same_name_str_str[]
+       INIT(= N_("E1406: Public and protected member have the same name: %s and _%s"));
 EXTERN char e_using_typealias_as_var_val[]
        INIT(= N_("E1407: Cannot use a Typealias as a variable or value"));
 EXTERN char e_final_variable_not_supported_in_interface[]
index e5cf8c102d30c138a6e97b47cbc0044ce5767a32..ad805b30b7d1a2e42a55dc8cf90ec0de8a90b9c5 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vim\n"
 "Report-Msgid-Bugs-To: vim-dev@vim.org\n"
-"POT-Creation-Date: 2026-05-20 18:41+0000\n"
+"POT-Creation-Date: 2026-05-21 19:38+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -8488,6 +8488,10 @@ msgstr ""
 msgid "E1405: Class \"%s\" cannot be used as a value"
 msgstr ""
 
+#, c-format
+msgid "E1406: Public and protected member have the same name: %s and _%s"
+msgstr ""
+
 msgid "E1407: Cannot use a Typealias as a variable or value"
 msgstr ""
 
index 5db6c65d12c56ca41b2de84b6672fead11dde342..35b87b208af7493795e897d4a4469ddfe3529664 100644 (file)
@@ -5143,7 +5143,7 @@ def Test_dup_member_variable()
       var _val = 20
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: val and _val', 4)
 
   # Duplicate public and protected member variable
   lines =<< trim END
@@ -5153,7 +5153,7 @@ def Test_dup_member_variable()
       public var val = 10
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: val and _val', 4)
 
   # Duplicate class member variable
   lines =<< trim END
@@ -5163,7 +5163,7 @@ def Test_dup_member_variable()
       static var _s: string = "def"
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: s and _s', 4)
 
   # Duplicate public and protected class member variable
   lines =<< trim END
@@ -5173,7 +5173,7 @@ def Test_dup_member_variable()
       static var _s: string = "def"
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: s and _s', 4)
 
   # Duplicate class and object member variable
   lines =<< trim END
@@ -5230,7 +5230,7 @@ def Test_dup_member_variable()
       var _val = 20
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: val and _val', 9)
 
   # Duplicate object member variable in a derived class
   lines =<< trim END
@@ -5244,7 +5244,7 @@ def Test_dup_member_variable()
       var val = 20
     endclass
   END
-  v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
+  v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: val and _val', 9)
 
   # Two member variables with a common prefix
   lines =<< trim END
index dc31e54a775a5b72a312ac0c250d3da0b5aa49ed..863043dabdec04d275dfc2626ee060b42ce6efec 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    507,
 /**/
     506,
 /**/
index 8edd022bd91e52f923ea7acef18efd98c9ac5302..bc10ce8b0780f683096655b85d65e09e4f988ee4 100644 (file)
@@ -461,13 +461,14 @@ extends_check_dup_members(
     {
        class_T     *p_cl = extends_cl;
        ocmember_T  *c_m = members + c_i;
-       char_u      *pstr = (*c_m->ocm_name.string == '_')
-                                   ? c_m->ocm_name.string + 1 : c_m->ocm_name.string;
+       bool        c_protected = (*c_m->ocm_name.string == '_');
+       char_u      *pstr = c_m->ocm_name.string + c_protected;
 
        // Check in all the parent classes in the lineage
        while (p_cl != NULL)
        {
            int p_member_count = p_cl->class_obj_member_count;
+
            if (p_member_count == 0)
            {
                p_cl = p_cl->class_extends;
@@ -478,12 +479,17 @@ extends_check_dup_members(
            // Compare against all the members in the parent class
            for (int p_i = 0; p_i < p_member_count; p_i++)
            {
-               ocmember_T      *p_m = p_members + p_i;
-               char_u  *qstr = (*p_m->ocm_name.string == '_')
-                   ? p_m->ocm_name.string + 1 : p_m->ocm_name.string;
+               ocmember_T  *p_m = p_members + p_i;
+               bool        p_protected = (*p_m->ocm_name.string == '_');
+               char_u      *qstr = p_m->ocm_name.string + p_protected;
                if (STRCMP(pstr, qstr) == 0)
                {
-                   semsg(_(e_duplicate_variable_str), c_m->ocm_name.string);
+                   if (c_protected != p_protected)
+                       semsg(_(e_public_and_protected_member_have_same_name_str_str),
+                               pstr, pstr);
+                   else
+                       semsg(_(e_duplicate_variable_str),
+                               c_m->ocm_name.string);
                    return FALSE;
                }
            }
@@ -1040,18 +1046,18 @@ is_duplicate_variable(
     char_u     *varname,
     char_u     *varname_end)
 {
-    string_T   pstr = {varname, (size_t)(varname_end - varname)};  // Note: the .string field may
-                                                                   // point to a string longer
-                                                                   // than the .length field.
-                                                                   // So we need to use STRNCMP()
-                                                                   // to compare it.
+    // Note: the .string field may point to a string longer than the .length
+    // field.  So we need to use STRNCMP() to compare it.
+    string_T   pstr = {varname, (size_t)(varname_end - varname)};
     int                dup = FALSE;
+    bool       p_protected = false;
 
     // Step over a leading '_'.
     if (*pstr.string == '_')
     {
        pstr.string++;
        pstr.length--;
+       p_protected = true;
     }
 
     // loop == 1: class variables, loop == 2: object variables
@@ -1062,12 +1068,14 @@ is_duplicate_variable(
        {
            ocmember_T *m = ((ocmember_T *)vgap->ga_data) + i;
            string_T    qstr = {m->ocm_name.string, m->ocm_name.length};
+           bool        q_protected = false;
 
            // Step over a leading '_'.
            if (*qstr.string == '_')
            {
                qstr.string++;
                qstr.length--;
+               q_protected = true;
            }
 
            if (pstr.length == qstr.length
@@ -1076,7 +1084,11 @@ is_duplicate_variable(
                char_u  save_c = *varname_end;
 
                *varname_end = NUL;
-               semsg(_(e_duplicate_variable_str), varname);
+               if (p_protected != q_protected)
+                   semsg(_(e_public_and_protected_member_have_same_name_str_str),
+                                              pstr.string, pstr.string);
+               else
+                   semsg(_(e_duplicate_variable_str), varname);
                *varname_end = save_c;
                dup = TRUE;
                break;