summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-01-07 14:51:03 +0000
committerBram Moolenaar <Bram@vim.org>2023-01-07 14:51:03 +0000
commitdf8f9473596c8fb18ec893de677dba455e8925b3 (patch)
tree3ce744abe59af5f138012ba5d8c9faec1f7b77c3
parent0cb3ca9f7a1b027973239bbea3d1a20dd1676a9c (diff)
patch 9.0.1157: "implements" only handles one interface namev9.0.1157
Problem: "implements" only handles one interface name. Solution: Handle a comma separated list of names. Check for duplicate names.
-rw-r--r--src/errors.h4
-rw-r--r--src/testdir/test_vim9_class.vim39
-rw-r--r--src/version.c2
-rw-r--r--src/vim9class.c45
4 files changed, 79 insertions, 11 deletions
diff --git a/src/errors.h b/src/errors.h
index 7344e2ef4a..5a59f7fbc7 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -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
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 2f2f62ac88..ef9ef5562d 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -627,6 +627,19 @@ 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)
@@ -635,6 +648,32 @@ def Test_class_implements_interface()
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
+
+ interface Some
+ static counter: number
def Method(nr: number)
endinterface
diff --git a/src/version.c b/src/version.c
index f30cdfd750..d2efc12c60 100644
--- 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 */
/**/
+ 1157,
+/**/
1156,
/**/
1155,
diff --git a/src/vim9class.c b/src/vim9class.c
index 92e3c6316b..4a8dd7c0ef 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -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
{