]> granicus.if.org Git - vim/commitdiff
patch 9.0.1155: cannot use a class as a type v9.0.1155
authorBram Moolenaar <Bram@vim.org>
Sat, 7 Jan 2023 12:08:41 +0000 (12:08 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 7 Jan 2023 12:08:41 +0000 (12:08 +0000)
Problem:    Cannot use a class as a type.
Solution:   Accept a class and interface name as a type.

src/testdir/test_vim9_class.vim
src/version.c
src/vim9type.c

index f8fb494c41cc962dbe8493045279fc2bb18ecb25..2f2f62ac885a4081f99adfaea562c21cdbc16072 100644 (file)
@@ -665,5 +665,54 @@ def Test_class_implements_interface()
   v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
 enddef
 
+def Test_class_used_as_type()
+  var lines =<< trim END
+      vim9script
+
+      class Point
+        this.x = 0
+        this.y = 0
+      endclass
+
+      var p: Point
+      p = Point.new(2, 33)
+      assert_equal(2, p.x)
+      assert_equal(33, p.y)
+  END
+  v9.CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+
+      interface HasX
+        this.x: number
+      endinterface
+
+      class Point implements HasX
+        this.x = 0
+        this.y = 0
+      endclass
+
+      var p: Point
+      p = Point.new(2, 33)
+      var hx = p
+      assert_equal(2, hx.x)
+  END
+  v9.CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+
+      class Point
+        this.x = 0
+        this.y = 0
+      endclass
+
+      var p: Point
+      p = 'text'
+  END
+  v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object but got string')
+enddef
+
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 4352c83b21647326139531d359feee82a5c8b9bf..57143ec9b8d30f6b7d8d315ac010a61c51ba658e 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1155,
 /**/
     1154,
 /**/
index c85c3f6c7d3beb3976513bcd0745ab64e23f859d..1078861674eed6b486192a3282331d16c6b87f8c 100644 (file)
@@ -1272,6 +1272,30 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
            break;
     }
 
+    // It can be a class or interface name.
+    typval_T tv;
+    tv.v_type = VAR_UNKNOWN;
+    if (eval_variable(*arg, len, 0, &tv, NULL,
+                                    EVAL_VAR_VERBOSE + EVAL_VAR_IMPORT) == OK)
+    {
+       if (tv.v_type == VAR_CLASS && tv.vval.v_class != NULL)
+       {
+           type_T *type = get_type_ptr(type_gap);
+           if (type != NULL)
+           {
+               // Although the name is that of a class or interface, the type
+               // uses will be an object.
+               type->tt_type = VAR_OBJECT;
+               type->tt_member = (type_T *)tv.vval.v_class;
+               clear_tv(&tv);
+               *arg += len;
+               return type;
+           }
+       }
+
+       clear_tv(&tv);
+    }
+
     if (give_error)
        semsg(_(e_type_not_recognized_str), *arg);
     return NULL;