diff options
author | Bram Moolenaar <Bram@vim.org> | 2023-01-07 14:51:03 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2023-01-07 14:51:03 +0000 |
commit | df8f9473596c8fb18ec893de677dba455e8925b3 (patch) | |
tree | 3ce744abe59af5f138012ba5d8c9faec1f7b77c3 | |
parent | 0cb3ca9f7a1b027973239bbea3d1a20dd1676a9c (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.h | 4 | ||||
-rw-r--r-- | src/testdir/test_vim9_class.vim | 39 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9class.c | 45 |
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 { |