]> granicus.if.org Git - vim/commitdiff
patch 9.0.1157: "implements" only handles one interface name v9.0.1157
authorBram Moolenaar <Bram@vim.org>
Sat, 7 Jan 2023 14:51:03 +0000 (14:51 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 7 Jan 2023 14:51:03 +0000 (14:51 +0000)
Problem:    "implements" only handles one interface name.
Solution:   Handle a comma separated list of names.  Check for duplicate
            names.

src/errors.h
src/testdir/test_vim9_class.vim
src/version.c
src/vim9class.c

index 7344e2ef4a9d7542ce54435efad03350741c8b2b..5a59f7fbc71800371c82f0c5543e3e4a0dd04e68 100644 (file)
@@ -3422,4 +3422,8 @@ EXTERN char e_member_str_of_interface_str_not_implemented[]
        INIT(= N_("E1348: Member \"%s\" of interface \"%s\" not implemented"));
 EXTERN char e_function_str_of_interface_str_not_implemented[]
        INIT(= N_("E1349: Function \"%s\" of interface \"%s\" not implemented"));
+EXTERN char e_duplicate_implements[]
+       INIT(= N_("E1350: Duplicate \"implements\""));
+EXTERN char e_duplicate_interface_after_implements_str[]
+       INIT(= N_("E1351: Duplicate interface after \"implements\": %s"));
 #endif
index 2f2f62ac885a4081f99adfaea562c21cdbc16072..ef9ef5562d38d732bbe86b8e4ca5d9b88f5f54c5 100644 (file)
@@ -627,9 +627,48 @@ def Test_class_implements_interface()
           echo nr
         enddef
       endclass
+
+      interface Another
+        this.member: string
+      endinterface
+
+      class SomeImpl implements Some, Another
+        this.member = 'abc'
+        static count: number
+        def Method(nr: number)
+          echo nr
+        enddef
+      endclass
+
   END
   v9.CheckScriptSuccess(lines)
 
+  lines =<< trim END
+      vim9script
+
+      interface Some
+        static counter: number
+      endinterface
+
+      class SomeImpl implements Some implements Some
+        static count: number
+      endclass
+  END
+  v9.CheckScriptFailure(lines, 'E1350:')
+
+  lines =<< trim END
+      vim9script
+
+      interface Some
+        static counter: number
+      endinterface
+
+      class SomeImpl implements Some, Some
+        static count: number
+      endclass
+  END
+  v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
+
   lines =<< trim END
       vim9script
 
index f30cdfd750682e67dc28f1f9d4b5594440784048..d2efc12c60a92c522aa869fb8511971dfe096708 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1157,
 /**/
     1156,
 /**/
index 92e3c6316b69691faa6fe5185554469930833137..4a8dd7c0ef654012ea684fe656f920e074eb160d 100644 (file)
@@ -245,22 +245,45 @@ ex_class(exarg_T *eap)
        //    specifies SomeInterface
        if (STRNCMP(arg, "implements", 10) == 0 && IS_WHITE_OR_NUL(arg[10]))
        {
-           arg = skipwhite(arg + 10);
-           char_u *impl_end = find_name_end(arg, NULL, NULL, FNE_CHECK_START);
-           if (!IS_WHITE_OR_NUL(*impl_end))
+           if (ga_impl.ga_len > 0)
            {
-               semsg(_(e_white_space_required_after_name_str), arg);
+               emsg(_(e_duplicate_implements));
                goto early_ret;
            }
-           char_u *iname = vim_strnsave(arg, impl_end - arg);
-           if (iname == NULL)
-               goto early_ret;
-           if (ga_add_string(&ga_impl, iname) == FAIL)
+           arg = skipwhite(arg + 10);
+
+           for (;;)
            {
-               vim_free(iname);
-               goto early_ret;
+               char_u *impl_end = find_name_end(arg, NULL, NULL,
+                                                             FNE_CHECK_START);
+               if (!IS_WHITE_OR_NUL(*impl_end) && *impl_end != ',')
+               {
+                   semsg(_(e_white_space_required_after_name_str), arg);
+                   goto early_ret;
+               }
+               char_u *iname = vim_strnsave(arg, impl_end - arg);
+               if (iname == NULL)
+                   goto early_ret;
+               for (int i = 0; i < ga_impl.ga_len; ++i)
+                   if (STRCMP(((char_u **)ga_impl.ga_data)[i], iname) == 0)
+                   {
+                       semsg(_(e_duplicate_interface_after_implements_str),
+                                                                       iname);
+                       vim_free(iname);
+                       goto early_ret;
+                   }
+               if (ga_add_string(&ga_impl, iname) == FAIL)
+               {
+                   vim_free(iname);
+                   goto early_ret;
+               }
+               if (*impl_end != ',')
+               {
+                   arg = skipwhite(impl_end);
+                   break;
+               }
+               arg = skipwhite(impl_end + 1);
            }
-           arg = skipwhite(impl_end);
        }
        else
        {