patch 9.1.0148: Vim9: can't call internal methods with objects

Problem:  Vim9: can't call internal methods with objects
Solution: Add support for empty(), len() and string() function
          calls for objects (Yegappan Lakshmanan)

closes: #14129

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index dbad880..0d47e36 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt*	For Vim version 9.1.  Last change: 2024 Mar 01
+*builtin.txt*	For Vim version 9.1.  Last change: 2024 Mar 03
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -2265,6 +2265,8 @@
 		- A |Job| is empty when it failed to start.
 		- A |Channel| is empty when it is closed.
 		- A |Blob| is empty when its length is zero.
+		- An |Object| is empty, when the |empty()| builtin method in
+		  the object (if present) returns true.
 
 		For a long |List| this is much faster than comparing the
 		length with zero.
@@ -5476,7 +5478,9 @@
 		When {expr} is a |Blob| the number of bytes is returned.
 		When {expr} is a |Dictionary| the number of entries in the
 		|Dictionary| is returned.
-		Otherwise an error is given and returns zero.
+		When {expr} is an |Object|, invokes the |len()| method in the
+		object (if present) to get the length.  Otherwise returns
+		zero.
 
 		Can also be used as a |method|: >
 			mylist->len()
@@ -9587,6 +9591,10 @@
 		replaced by "[...]" or "{...}".  Using eval() on the result
 		will then fail.
 
+		For an object, invokes the |string()| method to get a textual
+		representation of the object.  If the method is not present,
+		then the default representation is used.
+
 		Can also be used as a |method|: >
 			mylist->string()
 
diff --git a/runtime/doc/tags b/runtime/doc/tags
index efecedf..d6ed03a 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -4518,6 +4518,8 @@
 E141	message.txt	/*E141*
 E1410	vim9class.txt	/*E1410*
 E1411	vim9class.txt	/*E1411*
+E1412	vim9class.txt	/*E1412*
+E1413	vim9class.txt	/*E1413*
 E142	message.txt	/*E142*
 E143	autocmd.txt	/*E143*
 E144	various.txt	/*E144*
@@ -6183,6 +6185,7 @@
 builtin-function-details	builtin.txt	/*builtin-function-details*
 builtin-function-list	builtin.txt	/*builtin-function-list*
 builtin-functions	builtin.txt	/*builtin-functions*
+builtin-object-methods	vim9class.txt	/*builtin-object-methods*
 builtin-terms	term.txt	/*builtin-terms*
 builtin-tools	gui.txt	/*builtin-tools*
 builtin.txt	builtin.txt	/*builtin.txt*
@@ -9153,9 +9156,12 @@
 o_v	motion.txt	/*o_v*
 object	vim9class.txt	/*object*
 object-const-variable	vim9class.txt	/*object-const-variable*
+object-empty()	vim9class.txt	/*object-empty()*
 object-final-variable	vim9class.txt	/*object-final-variable*
+object-len()	vim9class.txt	/*object-len()*
 object-motions	motion.txt	/*object-motions*
 object-select	motion.txt	/*object-select*
+object-string()	vim9class.txt	/*object-string()*
 objects	index.txt	/*objects*
 obtaining-exted	netbeans.txt	/*obtaining-exted*
 ocaml.vim	syntax.txt	/*ocaml.vim*
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 953ae47..2b4a70a 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 9.1.  Last change: 2024 Feb 01
+*todo.txt*      For Vim version 9.1.  Last change: 2024 Mar 03
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -132,7 +132,6 @@
     Possibly issue #11981 can be fixed at the same time (has two examples).
   - Forward declaration of a class?  E.g. for Clone() function.
 	Email lifepillar 2023 Mar 26
-  - object empty(), len() - can class define a method to be used for them?
   - When "Meta" is a class, is "const MetaAlias = Meta" allowed?  It should
     either work or given an error. Possibly give an error now and implement it
     later (using a typedef).  #12006
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 7947cb2..bf16d49 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -41543,6 +41543,11 @@
 
 Support for Wayland UI.
 
+Vim9 script
+-----------
+Add support for internal builtin functions with vim9 objects, see
+|builtin-object-methods|
+
 Other improvements				*new-other-9.2*
 ------------------
 
diff --git a/runtime/doc/vim9class.txt b/runtime/doc/vim9class.txt
index ba821c1..a00a5b7 100644
--- a/runtime/doc/vim9class.txt
+++ b/runtime/doc/vim9class.txt
@@ -1,4 +1,4 @@
-*vim9class.txt*	For Vim version 9.1.  Last change: 2024 Jan 12
+*vim9class.txt*	For Vim version 9.1.  Last change: 2024 Mar 03
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -710,6 +710,32 @@
 							*E1330*
 Some types cannot be used, such as "void", "null" and "v:none".
 
+Builtin Object Methods ~
+                                                       *builtin-object-methods*
+Some of the builtin functions like |empty()|, |len()| and |string()| can be
+used with an object.  An object can implement a method with the same name as
+these builtin functions to return an object-specific value.
+
+                                                       *E1412*
+The following builtin methods are supported:
+                                                       *object-empty()*
+    empty()  Invoked by the |empty()| function to check whether an object is
+	     empty.  If this method is missing, then true is returned.  This
+	     method should not accept any arguments and must return a boolean.
+                                                       *object-len()*
+    len()    Invoked by the |len()| function to return the length of an
+	     object.  If this method is missing in the class, then an error is
+	     given and zero is returned.  This method should not accept any
+	     arguments and must return a number.
+                                                       *object-string()*
+    string() Invoked by the |string()| function to get a textual
+	     representation of an object.  Also used by the |:echo| command
+	     for an object.  If this method is missing in the class, then a
+	     built-in default textual representation is used.  This method
+	     should not accept any arguments and must return a string.
+
+                                                       *E1413*
+A class method cannot be used as a builtin method.
 
 Defining an interface ~
 					*Interface* *:interface* *:endinterface*