changeset 33540:86dbcbb94fdb v9.0.2019

patch 9.0.2019: Vim9: no support for funcrefs Commit: https://github.com/vim/vim/commit/29bb67f1beefc7fd393dbfd9ee77d92f1db3a3c0 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Sat Oct 14 11:18:50 2023 +0200 patch 9.0.2019: Vim9: no support for funcrefs Problem: Vim9: no support for funcrefs Solution: Add support for object/class funcref members closes: #11981 #12417 #12960 #12324 #13333 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
author Christian Brabandt <cb@256bit.org>
date Sat, 14 Oct 2023 11:30:07 +0200
parents 98e6eaaf8458
children 281c18121b19
files src/eval.c src/evalfunc.c src/proto/vim9class.pro src/proto/vim9instr.pro src/structs.h src/testdir/test_vim9_class.vim src/testdir/test_vim9_func.vim src/version.c src/vim9.h src/vim9class.c src/vim9compile.c src/vim9execute.c src/vim9expr.c src/vim9instr.c src/vim9type.c
diffstat 15 files changed, 731 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -5256,6 +5256,7 @@ partial_free(partial_T *pt)
     }
     else
 	func_ptr_unref(pt->pt_func);
+    object_unref(pt->pt_obj);
 
     // "out_up" is no longer used, decrement refcount on partial that owns it.
     partial_unref(pt->pt_outer.out_up_partial);
@@ -5578,6 +5579,7 @@ free_unref_items(int copyID)
     /*
      * PASS 2: free the items themselves.
      */
+    object_free_items(copyID);
     dict_free_items(copyID);
     list_free_items(copyID);
 
@@ -5818,6 +5820,15 @@ set_ref_in_item_partial(
 	set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
     }
 
+    if (pt->pt_obj != NULL)
+    {
+	typval_T objtv;
+
+	objtv.v_type = VAR_OBJECT;
+	objtv.vval.v_object = pt->pt_obj;
+	set_ref_in_item(&objtv, copyID, ht_stack, list_stack);
+    }
+
     for (int i = 0; i < pt->pt_argc; ++i)
 	abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
 		ht_stack, list_stack);
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -4801,6 +4801,9 @@ common_function(typval_T *argvars, typva
 		    pt->pt_auto = arg_pt->pt_auto;
 		    if (pt->pt_dict != NULL)
 			++pt->pt_dict->dv_refcount;
+		    pt->pt_obj = arg_pt->pt_obj;
+		    if (pt->pt_obj != NULL)
+			++pt->pt_obj->obj_refcount;
 		}
 
 		pt->pt_refcount = 1;
--- a/src/proto/vim9class.pro
+++ b/src/proto/vim9class.pro
@@ -17,13 +17,14 @@ void emsg_var_cl_define(char *msg, char_
 ufunc_T *method_lookup(class_T *cl, vartype_T v_type, char_u *name, size_t namelen, int *idx);
 int inside_class(cctx_T *cctx_arg, class_T *cl);
 void copy_object(typval_T *from, typval_T *to);
-void object_unref(object_T *obj);
 void copy_class(typval_T *from, typval_T *to);
 void class_unref(class_T *cl);
 int class_free_nonref(int copyID);
 int set_ref_in_classes(int copyID);
 void object_created(object_T *obj);
+void object_unref(object_T *obj);
 int object_free_nonref(int copyID);
+void object_free_items(int copyID);
 void method_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len);
 void member_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len);
 void f_instanceof(typval_T *argvars, typval_T *rettv);
--- a/src/proto/vim9instr.pro
+++ b/src/proto/vim9instr.pro
@@ -45,7 +45,7 @@ int generate_OLDSCRIPT(cctx_T *cctx, isn
 int generate_VIM9SCRIPT(cctx_T *cctx, isntype_T isn_type, int sid, int idx, type_T *type);
 int generate_NEWLIST(cctx_T *cctx, int count, int use_null);
 int generate_NEWDICT(cctx_T *cctx, int count, int use_null);
-int generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int fi, int *isn_idx);
+int generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int object_method, int fi, int *isn_idx);
 int generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name);
 int generate_DEF(cctx_T *cctx, char_u *name, size_t len);
 int generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where);
--- a/src/structs.h
+++ b/src/structs.h
@@ -2316,6 +2316,7 @@ struct partial_S
 
     int		pt_copyID;	// funcstack may contain pointer to partial
     dict_T	*pt_dict;	// dict for "self"
+    object_T	*pt_obj;	// object method
 };
 
 typedef struct {
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -7477,4 +7477,480 @@ def Test_op_and_assignment()
   v9.CheckSourceSuccess(lines)
 enddef
 
+" Test for using an object method as a funcref
+def Test_object_funcref()
+  # Using object method funcref from a def function
+  var lines =<< trim END
+    vim9script
+    class A
+      def Foo(): list<number>
+        return [3, 2, 1]
+      enddef
+    endclass
+    def Bar()
+      var a = A.new()
+      var Fn = a.Foo
+      assert_equal([3, 2, 1], Fn())
+    enddef
+    Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using object method funcref at the script level
+  lines =<< trim END
+    vim9script
+    class A
+      def Foo(): dict<number>
+        return {a: 1, b: 2}
+      enddef
+    endclass
+    var a = A.new()
+    var Fn = a.Foo
+    assert_equal({a: 1, b: 2}, Fn())
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using object method funcref from another object method
+  lines =<< trim END
+    vim9script
+    class A
+      def Foo(): list<number>
+        return [3, 2, 1]
+      enddef
+      def Bar()
+        var Fn = this.Foo
+        assert_equal([3, 2, 1], Fn())
+      enddef
+    endclass
+    var a = A.new()
+    a.Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using function() to get a object method funcref
+  lines =<< trim END
+    vim9script
+    class A
+      def Foo(l: list<any>): list<any>
+        return l
+      enddef
+    endclass
+    var a = A.new()
+    var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
+    assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Use an object method with a function returning a funcref and then call the
+  # funcref.
+  lines =<< trim END
+    vim9script
+
+    def Map(F: func(number): number): func(number): number
+      return (n: number) => F(n)
+    enddef
+
+    class Math
+      def Double(n: number): number
+        return 2 * n
+      enddef
+    endclass
+
+    const math = Math.new()
+    assert_equal(48, Map(math.Double)(24))
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Try using a private object method funcref from a def function
+  lines =<< trim END
+    vim9script
+    class A
+      def _Foo()
+      enddef
+    endclass
+    def Bar()
+      var a = A.new()
+      var Fn = a._Foo
+    enddef
+    Bar()
+  END
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2)
+
+  # Try using a private object method funcref at the script level
+  lines =<< trim END
+    vim9script
+    class A
+      def _Foo()
+      enddef
+    endclass
+    var a = A.new()
+    var Fn = a._Foo
+  END
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 7)
+
+  # Using a private object method funcref from another object method
+  lines =<< trim END
+    vim9script
+    class A
+      def _Foo(): list<number>
+        return [3, 2, 1]
+      enddef
+      def Bar()
+        var Fn = this._Foo
+        assert_equal([3, 2, 1], Fn())
+      enddef
+    endclass
+    var a = A.new()
+    a.Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using a class method as a funcref
+def Test_class_funcref()
+  # Using class method funcref in a def function
+  var lines =<< trim END
+    vim9script
+    class A
+      static def Foo(): list<number>
+        return [3, 2, 1]
+      enddef
+    endclass
+    def Bar()
+      var Fn = A.Foo
+      assert_equal([3, 2, 1], Fn())
+    enddef
+    Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using class method funcref at script level
+  lines =<< trim END
+    vim9script
+    class A
+      static def Foo(): dict<number>
+        return {a: 1, b: 2}
+      enddef
+    endclass
+    var Fn = A.Foo
+    assert_equal({a: 1, b: 2}, Fn())
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using function() to get a class method funcref
+  lines =<< trim END
+    vim9script
+    class A
+      static def Foo(l: list<any>): list<any>
+        return l
+      enddef
+    endclass
+    var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
+    assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a class method funcref from another class method
+  lines =<< trim END
+    vim9script
+    class A
+      static def Foo(): list<number>
+        return [3, 2, 1]
+      enddef
+      static def Bar()
+        var Fn = Foo
+        assert_equal([3, 2, 1], Fn())
+      enddef
+    endclass
+    A.Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Use a class method with a function returning a funcref and then call the
+  # funcref.
+  lines =<< trim END
+    vim9script
+
+    def Map(F: func(number): number): func(number): number
+      return (n: number) => F(n)
+    enddef
+
+    class Math
+      static def StaticDouble(n: number): number
+        return 2 * n
+      enddef
+    endclass
+
+    assert_equal(48, Map(Math.StaticDouble)(24))
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Try using a private class method funcref in a def function
+  lines =<< trim END
+    vim9script
+    class A
+      static def _Foo()
+      enddef
+    endclass
+    def Bar()
+      var Fn = A._Foo
+    enddef
+    Bar()
+  END
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 1)
+
+  # Try using a private class method funcref at script level
+  lines =<< trim END
+    vim9script
+    class A
+      static def _Foo()
+      enddef
+    endclass
+    var Fn = A._Foo
+  END
+  v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 6)
+
+  # Using a private class method funcref from another class method
+  lines =<< trim END
+    vim9script
+    class A
+      static def _Foo(): list<number>
+        return [3, 2, 1]
+      enddef
+      static def Bar()
+        var Fn = _Foo
+        assert_equal([3, 2, 1], Fn())
+      enddef
+    endclass
+    A.Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using an object member as a funcref
+def Test_object_member_funcref()
+  # Using a funcref object variable in an object method
+  var lines =<< trim END
+    vim9script
+    def Foo(n: number): number
+      return n * 10
+    enddef
+
+    class A
+      this.Cb: func(number): number = Foo
+      def Bar()
+        assert_equal(200, this.Cb(20))
+      enddef
+    endclass
+
+    var a = A.new()
+    a.Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref object variable in a def method
+  lines =<< trim END
+    vim9script
+    def Foo(n: number): number
+      return n * 10
+    enddef
+
+    class A
+      this.Cb: func(number): number = Foo
+    endclass
+
+    def Bar()
+      var a = A.new()
+      assert_equal(200, a.Cb(20))
+    enddef
+    Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref object variable at script level
+  lines =<< trim END
+    vim9script
+    def Foo(n: number): number
+      return n * 10
+    enddef
+
+    class A
+      this.Cb: func(number): number = Foo
+    endclass
+
+    var a = A.new()
+    assert_equal(200, a.Cb(20))
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref object variable pointing to an object method in an object
+  # method.
+  lines =<< trim END
+    vim9script
+    class A
+      this.Cb: func(number): number = this.Foo
+      def Foo(n: number): number
+        return n * 10
+      enddef
+      def Bar()
+        assert_equal(200, this.Cb(20))
+      enddef
+    endclass
+
+    var a = A.new()
+    a.Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref object variable pointing to an object method in a def
+  # method.
+  lines =<< trim END
+    vim9script
+    class A
+      this.Cb: func(number): number = this.Foo
+      def Foo(n: number): number
+        return n * 10
+      enddef
+    endclass
+
+    def Bar()
+      var a = A.new()
+      assert_equal(200, a.Cb(20))
+    enddef
+    Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref object variable pointing to an object method at script
+  # level.
+  lines =<< trim END
+    vim9script
+    class A
+      this.Cb = this.Foo
+      def Foo(n: number): number
+        return n * 10
+      enddef
+    endclass
+
+    var a = A.new()
+    assert_equal(200, a.Cb(20))
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for using a class member as a funcref
+def Test_class_member_funcref()
+  # Using a funcref class variable in a class method
+  var lines =<< trim END
+    vim9script
+    def Foo(n: number): number
+      return n * 10
+    enddef
+
+    class A
+      static Cb = Foo
+      static def Bar()
+        assert_equal(200, Cb(20))
+      enddef
+    endclass
+
+    A.Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref class variable in a def method
+  lines =<< trim END
+    vim9script
+    def Foo(n: number): number
+      return n * 10
+    enddef
+
+    class A
+      public static Cb = Foo
+    endclass
+
+    def Bar()
+      assert_equal(200, A.Cb(20))
+    enddef
+    Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref class variable at script level
+  lines =<< trim END
+    vim9script
+    def Foo(n: number): number
+      return n * 10
+    enddef
+
+    class A
+      public static Cb = Foo
+    endclass
+
+    assert_equal(200, A.Cb(20))
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref class variable pointing to a class method in a class
+  # method.
+  lines =<< trim END
+    vim9script
+    class A
+      static Cb: func(number): number
+      static def Foo(n: number): number
+        return n * 10
+      enddef
+      static def Init()
+        Cb = Foo
+      enddef
+      static def Bar()
+        assert_equal(200, Cb(20))
+      enddef
+    endclass
+
+    A.Init()
+    A.Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref class variable pointing to a class method in a def method.
+  lines =<< trim END
+    vim9script
+    class A
+      static Cb: func(number): number
+      static def Foo(n: number): number
+        return n * 10
+      enddef
+      static def Init()
+        Cb = Foo
+      enddef
+    endclass
+
+    def Bar()
+      A.Init()
+      assert_equal(200, A.Cb(20))
+    enddef
+    Bar()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Using a funcref class variable pointing to a class method at script level.
+  lines =<< trim END
+    vim9script
+    class A
+      static Cb: func(number): number
+      static def Foo(n: number): number
+        return n * 10
+      enddef
+      static def Init()
+        Cb = Foo
+      enddef
+    endclass
+
+    A.Init()
+    assert_equal(200, A.Cb(20))
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 852f3a7edec49b7277bb5141ef7481cfcbeb7875..597a10c581882c180a1f96a5ae1000680c2edeb0
GIT binary patch
literal 106605
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
N>HOI|%r4<L`#&Q~csc+8
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2019,
+/**/
     2018,
 /**/
     2017,
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -383,6 +383,7 @@ typedef struct {
     char_u	  *fre_func_name;	// function name for legacy function
     loopvarinfo_T fre_loopvar_info;	// info about variables inside loops
     class_T	  *fre_class;		// class for a method
+    int		  fre_object_method;	// class or object method
     int		  fre_method_idx;	// method index on "fre_class"
 } funcref_extra_T;
 
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -2167,15 +2167,35 @@ call_oc_method(
     ufunc_T	*fp;
     typval_T	argvars[MAX_FUNC_ARGS + 1];
     int		argcount = 0;
+    ocmember_T	*ocm = NULL;
+    int		m_idx;
 
     fp = method_lookup(cl, rettv->v_type, name, len, NULL);
     if (fp == NULL)
     {
-	method_not_found_msg(cl, rettv->v_type, name, len);
-	return FAIL;
+	// could be an object or class funcref variable
+	ocm = member_lookup(cl, rettv->v_type, name, len, &m_idx);
+	if (ocm == NULL || ocm->ocm_type->tt_type != VAR_FUNC)
+	{
+	    method_not_found_msg(cl, rettv->v_type, name, len);
+	    return FAIL;
+	}
+
+	if (rettv->v_type == VAR_OBJECT)
+	{
+	    // funcref object variable
+	    object_T	*obj = rettv->vval.v_object;
+	    typval_T	*tv = (typval_T *)(obj + 1) + m_idx;
+	    copy_tv(tv, rettv);
+	}
+	else
+	    // funcref class variable
+	    copy_tv(&cl->class_members_tv[m_idx], rettv);
+	*arg = name_end;
+	return OK;
     }
 
-    if (*fp->uf_name == '_')
+    if (ocm == NULL && *fp->uf_name == '_')
     {
 	// Cannot access a private method outside of a class
 	semsg(_(e_cannot_access_private_method_str), fp->uf_name);
@@ -2288,6 +2308,37 @@ class_object_index(
 	    return OK;
 	}
 
+	// could be a class method or an object method
+	int	fidx;
+	ufunc_T	*fp = method_lookup(cl, rettv->v_type, name, len, &fidx);
+	if (fp != NULL)
+	{
+	    // Private methods are not accessible outside the class
+	    if (*name == '_')
+	    {
+		semsg(_(e_cannot_access_private_method_str), fp->uf_name);
+		return FAIL;
+	    }
+
+	    partial_T	*pt = ALLOC_CLEAR_ONE(partial_T);
+	    if (pt == NULL)
+		return FAIL;
+
+	    pt->pt_refcount = 1;
+	    if (is_object)
+	    {
+		pt->pt_obj = rettv->vval.v_object;
+		++pt->pt_obj->obj_refcount;
+	    }
+	    pt->pt_auto = TRUE;
+	    pt->pt_func = fp;
+	    func_ptr_ref(pt->pt_func);
+	    rettv->v_type = VAR_PARTIAL;
+	    rettv->vval.v_partial = pt;
+	    *arg = name_end;
+	    return OK;
+	}
+
 	if (did_emsg == did_emsg_save)
 	    member_not_found_msg(cl, is_object, name, len);
     }
@@ -2774,8 +2825,6 @@ object_created(object_T *obj)
     first_object = obj;
 }
 
-static object_T	*next_nonref_obj = NULL;
-
 /*
  * Call this function when an object has been cleared and is about to be freed.
  * It is removed from the list headed by "first_object".
@@ -2789,30 +2838,35 @@ object_cleared(object_T *obj)
 	obj->obj_prev_used->obj_next_used = obj->obj_next_used;
     else if (first_object == obj)
 	first_object = obj->obj_next_used;
-
-    // update the next object to check if needed
-    if (obj == next_nonref_obj)
-	next_nonref_obj = obj->obj_next_used;
 }
 
 /*
- * Free an object.
+ * Free the contents of an object ignoring the reference count.
  */
     static void
-object_clear(object_T *obj)
+object_free_contents(object_T *obj)
 {
-    // Avoid a recursive call, it can happen if "obj" has a circular reference.
-    obj->obj_refcount = INT_MAX;
-
     class_T *cl = obj->obj_class;
 
     if (!cl)
 	return;
 
+    // Avoid a recursive call, it can happen if "obj" has a circular reference.
+    obj->obj_refcount = INT_MAX;
+
     // the member values are just after the object structure
     typval_T *tv = (typval_T *)(obj + 1);
     for (int i = 0; i < cl->class_obj_member_count; ++i)
 	clear_tv(tv + i);
+}
+
+    static void
+object_free_object(object_T *obj)
+{
+    class_T *cl = obj->obj_class;
+
+    if (!cl)
+	return;
 
     // Remove from the list headed by "first_object".
     object_cleared(obj);
@@ -2821,6 +2875,16 @@ object_clear(object_T *obj)
     class_unref(cl);
 }
 
+    static void
+object_free(object_T *obj)
+{
+    if (in_free_unref_items)
+	return;
+
+    object_free_contents(obj);
+    object_free_object(obj);
+}
+
 /*
  * Unreference an object.
  */
@@ -2828,7 +2892,7 @@ object_clear(object_T *obj)
 object_unref(object_T *obj)
 {
     if (obj != NULL && --obj->obj_refcount <= 0)
-	object_clear(obj);
+	object_free(obj);
 }
 
 /*
@@ -2839,21 +2903,32 @@ object_free_nonref(int copyID)
 {
     int		did_free = FALSE;
 
-    for (object_T *obj = first_object; obj != NULL; obj = next_nonref_obj)
+    for (object_T *obj = first_object; obj != NULL; obj = obj->obj_next_used)
     {
-	next_nonref_obj = obj->obj_next_used;
 	if ((obj->obj_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
 	{
-	    // Free the object and items it contains.
-	    object_clear(obj);
+	    // Free the object contents.  Object itself will be freed later.
+	    object_free_contents(obj);
 	    did_free = TRUE;
 	}
     }
 
-    next_nonref_obj = NULL;
     return did_free;
 }
 
+    void
+object_free_items(int copyID)
+{
+    object_T	*obj_next;
+
+    for (object_T *obj = first_object; obj != NULL; obj = obj_next)
+    {
+	obj_next = obj->obj_next_used;
+	if ((obj->obj_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
+	    object_free_object(obj);
+    }
+}
+
 /*
  * Output message which takes a variable name and the class that defines it.
  * "cl" is that class where the name was found. Search "cl"'s hierarchy to
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1148,7 +1148,7 @@ compile_nested_function(exarg_T *eap, cc
 					    ASSIGN_CONST, ufunc->uf_func_type);
 	if (lvar == NULL)
 	    goto theend;
-	if (generate_FUNCREF(cctx, ufunc, NULL, 0, &funcref_isn_idx) == FAIL)
+	if (generate_FUNCREF(cctx, ufunc, NULL, FALSE, 0, &funcref_isn_idx) == FAIL)
 	    goto theend;
 	r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
     }
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -616,6 +616,12 @@ call_dfunc(
     // the first local variable.
     if (IS_OBJECT_METHOD(ufunc))
     {
+	if (obj->v_type != VAR_OBJECT)
+	{
+	    semsg(_(e_internal_error_str), "type in stack is not an object");
+	    return FAIL;
+	}
+
 	*STACK_TV_VAR(0) = *obj;
 	obj->v_type = VAR_UNKNOWN;
     }
@@ -1497,6 +1503,23 @@ call_partial(
 	partial_T   *pt = tv->vval.v_partial;
 	int	    i;
 
+	if (pt->pt_obj != NULL)
+	{
+	    // partial with an object method.  Push the object before the
+	    // function arguments.
+	    if (GA_GROW_FAILS(&ectx->ec_stack, 1))
+		return FAIL;
+	    for (i = 1; i <= argcount; ++i)
+		*STACK_TV_BOT(-i + 1) = *STACK_TV_BOT(-i);
+
+	    typval_T *obj_tv = STACK_TV_BOT(-argcount);
+	    obj_tv->v_type = VAR_OBJECT;
+	    obj_tv->v_lock = 0;
+	    obj_tv->vval.v_object = pt->pt_obj;
+	    ++pt->pt_obj->obj_refcount;
+	    ++ectx->ec_stack.ga_len;
+	}
+
 	if (pt->pt_argc > 0)
 	{
 	    // Make space for arguments from the partial, shift the "argcount"
@@ -4447,20 +4470,44 @@ exec_instructions(ectx_T *ectx)
 		    }
 		    if (extra != NULL && extra->fre_class != NULL)
 		    {
-			tv = STACK_TV_BOT(-1);
-			if (tv->v_type != VAR_OBJECT)
+			class_T	*cl;
+			if (extra->fre_object_method)
 			{
-			    object_required_error(tv);
-			    vim_free(pt);
-			    goto on_error;
+			    tv = STACK_TV_BOT(-1);
+			    if (tv->v_type != VAR_OBJECT)
+			    {
+				object_required_error(tv);
+				vim_free(pt);
+				goto on_error;
+			    }
+
+			    object_T *obj = tv->vval.v_object;
+			    cl = obj->obj_class;
+			    // drop the value from the stack
+			    clear_tv(tv);
+			    --ectx->ec_stack.ga_len;
+
+			    pt->pt_obj = obj;
+			    ++obj->obj_refcount;
 			}
-			object_T *obj = tv->vval.v_object;
-			class_T *cl = obj->obj_class;
-
-			// convert the interface index to the object index
-			int idx = object_index_from_itf_index(extra->fre_class,
-					      TRUE, extra->fre_method_idx, cl);
-			ufunc = cl->class_obj_methods[idx];
+			else
+			    cl = extra->fre_class;
+
+			if (extra->fre_object_method)
+			{
+			    // object method
+			    // convert the interface index to the object index
+			    int idx =
+				object_index_from_itf_index(extra->fre_class,
+					TRUE, extra->fre_method_idx, cl);
+			    ufunc = cl->class_obj_methods[idx];
+			}
+			else
+			{
+			    // class method
+			    ufunc =
+				cl->class_class_functions[extra->fre_method_idx];
+			}
 		    }
 		    else if (extra == NULL || extra->fre_func_name == NULL)
 		    {
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -281,6 +281,8 @@ inside_class_hierarchy(cctx_T *cctx_arg,
     static int
 compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
 {
+    int m_idx;
+
     if (VIM_ISWHITE((*arg)[1]))
     {
 	semsg(_(e_no_white_space_allowed_after_str_str), ".", *arg);
@@ -365,17 +367,34 @@ compile_class_object_index(cctx_T *cctx,
 		break;
 	    }
 	}
+	ocmember_T  *ocm = NULL;
 	if (ufunc == NULL)
 	{
-	    method_not_found_msg(cl, type->tt_type, name, len);
-	    return FAIL;
+	    // could be a funcref in a member variable
+	    ocm = member_lookup(cl, type->tt_type, name, len, &m_idx);
+	    if (ocm == NULL || ocm->ocm_type->tt_type != VAR_FUNC)
+	    {
+		method_not_found_msg(cl, type->tt_type, name, len);
+		return FAIL;
+	    }
+	    if (type->tt_type == VAR_CLASS)
+	    {
+		if (generate_CLASSMEMBER(cctx, TRUE, cl, m_idx) == FAIL)
+		    return FAIL;
+	    }
+	    else
+	    {
+		if (generate_GET_OBJ_MEMBER(cctx, m_idx, ocm->ocm_type) ==
+									FAIL)
+		    return FAIL;
+	    }
 	}
 
 	// A private object method can be used only inside the class where it
 	// is defined or in one of the child classes.
 	// A private class method can be used only in the class where it is
 	// defined.
-	if (*ufunc->uf_name == '_' &&
+	if (ocm == NULL && *ufunc->uf_name == '_' &&
 		((type->tt_type == VAR_OBJECT
 		  && !inside_class_hierarchy(cctx, cl))
 		 || (type->tt_type == VAR_CLASS
@@ -393,6 +412,8 @@ compile_class_object_index(cctx_T *cctx,
 	if (compile_arguments(arg, cctx, &argcount, CA_NOT_SPECIAL) == FAIL)
 	    return FAIL;
 
+	if (ocm != NULL)
+	    return generate_PCALL(cctx, argcount, name, ocm->ocm_type, TRUE);
 	if (type->tt_type == VAR_OBJECT
 		     && (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)))
 	    return generate_CALL(cctx, ufunc, cl, fi, argcount);
@@ -401,7 +422,6 @@ compile_class_object_index(cctx_T *cctx,
 
     if (type->tt_type == VAR_OBJECT)
     {
-        int m_idx;
         ocmember_T *m = object_member_lookup(cl, name, len, &m_idx);
 	if (m_idx >= 0)
 	{
@@ -418,15 +438,21 @@ compile_class_object_index(cctx_T *cctx,
 	    return generate_GET_OBJ_MEMBER(cctx, m_idx, m->ocm_type);
 	}
 
-	// Could be a function reference: "obj.Func".
+	// Could be an object method reference: "obj.Func".
 	m_idx = object_method_idx(cl, name, len);
 	if (m_idx >= 0)
 	{
 	    ufunc_T *fp = cl->class_obj_methods[m_idx];
-	    if (type->tt_type == VAR_OBJECT
-		    && (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)))
-		return generate_FUNCREF(cctx, fp, cl, m_idx, NULL);
-	    return generate_FUNCREF(cctx, fp, NULL, 0, NULL);
+	    // Private methods are not accessible outside the class
+	    if (*name == '_' && !inside_class(cctx, cl))
+	    {
+		semsg(_(e_cannot_access_private_method_str), fp->uf_name);
+		return FAIL;
+	    }
+	    *arg = name_end;
+	    if (type->tt_type == VAR_OBJECT)
+		return generate_FUNCREF(cctx, fp, cl, TRUE, m_idx, NULL);
+	    return generate_FUNCREF(cctx, fp, NULL, FALSE, 0, NULL);
 	}
 
 	member_not_found_msg(cl, VAR_OBJECT, name, len);
@@ -451,6 +477,24 @@ compile_class_object_index(cctx_T *cctx,
 	    *arg = name_end;
 	    return generate_CLASSMEMBER(cctx, TRUE, cl, idx);
 	}
+
+	// Could be a class method reference: "class.Func".
+	m_idx = class_method_idx(cl, name, len);
+	if (m_idx >= 0)
+	{
+	    ufunc_T *fp = cl->class_class_functions[m_idx];
+	    // Private methods are not accessible outside the class
+	    if (*name == '_' && !inside_class(cctx, cl))
+	    {
+		semsg(_(e_cannot_access_private_method_str), fp->uf_name);
+		return FAIL;
+	    }
+	    *arg = name_end;
+	    if (type->tt_type == VAR_CLASS)
+		return generate_FUNCREF(cctx, fp, cl, FALSE, m_idx, NULL);
+	    return generate_FUNCREF(cctx, fp, NULL, FALSE, 0, NULL);
+	}
+
 	member_not_found_msg(cl, VAR_CLASS, name, len);
     }
 
@@ -716,6 +760,7 @@ compile_load(
     {
 	size_t	    len = end - *arg;
 	int	    idx;
+	int	    method_idx;
 	int	    gen_load = FALSE;
 	int	    gen_load_outer = 0;
 	int	    outer_loop_depth = -1;
@@ -764,13 +809,27 @@ compile_load(
 		else
 		    gen_load = TRUE;
 	    }
-	    else if ((idx = cctx_class_member_idx(cctx, *arg, len, &cl)) >= 0)
+	    else if (cctx->ctx_ufunc->uf_defclass != NULL &&
+		    (((idx =
+		       cctx_class_member_idx(cctx, *arg, len, &cl)) >= 0)
+		     || ((method_idx =
+			     cctx_class_method_idx(cctx, *arg, len, &cl)) >= 0)))
 	    {
-		// Referencing a class variable without the class name.
-		// A class variable can be referenced without the class name
-		// only in the class where the function is defined.
+		// Referencing a class variable or method without the class
+		// name.  A class variable or method can be referenced without
+		// the class name only in the class where the function is
+		// defined.
 		if (cctx->ctx_ufunc->uf_defclass == cl)
-		    res = generate_CLASSMEMBER(cctx, TRUE, cl, idx);
+		{
+		    if (idx >= 0)
+			res = generate_CLASSMEMBER(cctx, TRUE, cl, idx);
+		    else
+		    {
+			ufunc_T *fp = cl->class_class_functions[method_idx];
+			res = generate_FUNCREF(cctx, fp, cl, FALSE, method_idx,
+									NULL);
+		    }
+		}
 		else
 		{
 		    semsg(_(e_class_variable_str_accessible_only_inside_class_str),
@@ -1387,7 +1446,7 @@ compile_lambda(char_u **arg, cctx_T *cct
 	// The function reference count will be 1.  When the ISN_FUNCREF
 	// instruction is deleted the reference count is decremented and the
 	// function is freed.
-	return generate_FUNCREF(cctx, ufunc, NULL, 0, NULL);
+	return generate_FUNCREF(cctx, ufunc, NULL, FALSE, 0, NULL);
     }
 
     func_ptr_unref(ufunc);
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -1384,6 +1384,7 @@ generate_FUNCREF(
 	cctx_T	    *cctx,
 	ufunc_T	    *ufunc,
 	class_T	    *cl,
+	int	    object_method,
 	int	    fi,
 	int	    *isn_idx)
 {
@@ -1412,6 +1413,7 @@ generate_FUNCREF(
 	{
 	    extra->fre_class = cl;
 	    ++cl->class_refcount;
+	    extra->fre_object_method = object_method;
 	    extra->fre_method_idx = fi;
 	}
     }
--- a/src/vim9type.c
+++ b/src/vim9type.c
@@ -144,7 +144,7 @@ alloc_type(type_T *type)
     if (ret->tt_member != NULL)
 	ret->tt_member = alloc_type(ret->tt_member);
 
-    if (type->tt_args != NULL)
+    if (type->tt_argcount > 0 && type->tt_args != NULL)
     {
 	int i;
 
@@ -153,6 +153,8 @@ alloc_type(type_T *type)
 	    for (i = 0; i < type->tt_argcount; ++i)
 		ret->tt_args[i] = alloc_type(type->tt_args[i]);
     }
+    else
+	ret->tt_args = NULL;
 
     return ret;
 }