# HG changeset patch # User Bram Moolenaar # Date 1673702106 -3600 # Node ID ef7a9a7eb19797597f342ce178686a68676fc509 # Parent 00a05ce19bd64725c9d74bd59160927f116db82d patch 9.0.1198: abstract class not supported yet Commit: https://github.com/vim/vim/commit/24a8d06d7f4db0865f374ced2f4d4b57cbc5b9e4 Author: Bram Moolenaar Date: Sat Jan 14 13:12:06 2023 +0000 patch 9.0.1198: abstract class not supported yet Problem: Abstract class not supported yet. Solution: Implement abstract class and add tests. diff --git a/src/errors.h b/src/errors.h --- a/src/errors.h +++ b/src/errors.h @@ -3440,4 +3440,6 @@ EXTERN char e_using_super_not_in_class_f INIT(= N_("E1357: Using \"super\" not in a class function")); EXTERN char e_using_super_not_in_child_class[] INIT(= N_("E1358: Using \"super\" not in a child class")); -#endif +EXTERN char e_cannot_define_new_function_in_abstract_class[] + INIT(= N_("E1359: Cannot define a \"new\" function in an abstract class")); +#endif diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -1014,5 +1014,40 @@ def Test_class_import() v9.CheckScriptSuccess(lines) enddef +def Test_abstract_class() + var lines =<< trim END + vim9script + abstract class Base + this.name: string + endclass + class Person extends Base + this.age: number + endclass + var p: Base = Person.new('Peter', 42) + assert_equal('Peter', p.name) + assert_equal(42, p.age) + END + v9.CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + abstract class Base + this.name: string + endclass + class Person extends Base + this.age: number + endclass + var p = Base.new('Peter') + END + v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(') + + lines =<< trim END + abstract class Base + this.name: string + endclass + END + v9.CheckScriptFailure(lines, 'E1316:') +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 1198, +/**/ 1197, /**/ 1196, diff --git a/src/vim9class.c b/src/vim9class.c --- a/src/vim9class.c +++ b/src/vim9class.c @@ -204,17 +204,6 @@ ex_class(exarg_T *eap) { int is_class = eap->cmdidx == CMD_class; // FALSE for :interface - if (!current_script_is_vim9() - || (cmdmod.cmod_flags & CMOD_LEGACY) - || !getline_equal(eap->getline, eap->cookie, getsourceline)) - { - if (is_class) - emsg(_(e_class_can_only_be_defined_in_vim9_script)); - else - emsg(_(e_interface_can_only_be_defined_in_vim9_script)); - return; - } - char_u *arg = eap->arg; int is_abstract = eap->cmdidx == CMD_abstract; if (is_abstract) @@ -225,6 +214,18 @@ ex_class(exarg_T *eap) return; } arg = skipwhite(arg + 5); + is_class = TRUE; + } + + if (!current_script_is_vim9() + || (cmdmod.cmod_flags & CMOD_LEGACY) + || !getline_equal(eap->getline, eap->cookie, getsourceline)) + { + if (is_class) + emsg(_(e_class_can_only_be_defined_in_vim9_script)); + else + emsg(_(e_interface_can_only_be_defined_in_vim9_script)); + return; } if (!ASCII_ISUPPER(*arg)) @@ -493,6 +494,12 @@ early_ret: { char_u *name = uf->uf_name; int is_new = STRNCMP(name, "new", 3) == 0; + if (is_new && is_abstract) + { + emsg(_(e_cannot_define_new_function_in_abstract_class)); + success = FALSE; + break; + } garray_T *fgap = has_static || is_new ? &classfunctions : &objmethods; // Check the name isn't used already. @@ -826,7 +833,7 @@ early_ret: have_new = TRUE; break; } - if (is_class && !have_new) + if (is_class && !is_abstract && !have_new) { // No new() method was defined, add the default constructor. garray_T fga;