]> granicus.if.org Git - vim/commitdiff
patch 9.0.1198: abstract class not supported yet v9.0.1198
authorBram Moolenaar <Bram@vim.org>
Sat, 14 Jan 2023 13:12:06 +0000 (13:12 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 14 Jan 2023 13:12:06 +0000 (13:12 +0000)
Problem:    Abstract class not supported yet.
Solution:   Implement abstract class and add tests.

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

index de1ae4bd0362f3236d7bc6246a7d28e273d826d5..3b6307f0ba5c82de8330799ae9ad6948d0341e3b 100644 (file)
@@ -3440,4 +3440,6 @@ EXTERN char e_using_super_not_in_class_function[]
        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"));
+EXTERN char e_cannot_define_new_function_in_abstract_class[]
+       INIT(= N_("E1359: Cannot define a \"new\" function in an abstract class"));
 #endif
index a6caad2fcec8061bf6bf8e59f37bc770744f97fd..4a2b87c740c8a69a0078885d0336dd9a0eece447 100644 (file)
@@ -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
index 52eabb580705022a47c5e74510f86e0e57d0ea0f..763c79d91c5e2da9d3803b0a5ae733ba69199583 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1198,
 /**/
     1197,
 /**/
index d66fa3ecc4981cb4f35435f8bcf92fca818958a6..8dcd92b6ebd7c7074acb34138ee5457e8cae80e5 100644 (file)
@@ -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;