patch 9.0.1804: Vim9: no support for private object methods

Problem:  Vim9: no support for private object methods
Solution: Add support for private object/class methods

closes: #12920

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
diff --git a/src/vim9class.c b/src/vim9class.c
index bf1b120..36a5d0a 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -357,6 +357,13 @@
 		    if (check_type_maybe(if_fp[if_i]->uf_func_type,
 				cl_fp[cl_i]->uf_func_type, TRUE, where) != OK)
 			success = FALSE;
+		    // Ensure the public/private access level is matching.
+		    if (if_fp[if_i]->uf_private != cl_fp[cl_i]->uf_private)
+		    {
+			semsg(_(e_interface_str_and_class_str_function_access_not_same),
+				cl_name, if_name);
+			success = FALSE;
+		    }
 		    break;
 		}
 	    }
@@ -1150,7 +1157,9 @@
 		for (int i = 0; i < fgap->ga_len; ++i)
 		{
 		    char_u *n = ((ufunc_T **)fgap->ga_data)[i]->uf_name;
-		    if (STRCMP(name, n) == 0)
+		    char_u *pstr = *name == '_' ? name + 1 : name;
+		    char_u *qstr = *n == '_' ? n + 1 : n;
+		    if (STRCMP(pstr, qstr) == 0)
 		    {
 			semsg(_(e_duplicate_function_str), name);
 			break;
@@ -1162,6 +1171,11 @@
 		    if (is_new)
 			uf->uf_flags |= FC_NEW;
 
+		    // If the method name starts with '_', then it a private
+		    // method.
+		    if (*name == '_')
+			uf->uf_private = TRUE;
+
 		    ((ufunc_T **)fgap->ga_data)[fgap->ga_len] = uf;
 		    ++fgap->ga_len;
 		}
@@ -1523,6 +1537,13 @@
 		typval_T    argvars[MAX_FUNC_ARGS + 1];
 		int	    argcount = 0;
 
+		if (fp->uf_private)
+		{
+		    // Cannot access a private method outside of a class
+		    semsg(_(e_cannot_access_private_method_str), name);
+		    return FAIL;
+		}
+
 		char_u *argp = name_end;
 		int ret = get_func_arguments(&argp, evalarg, 0,
 							   argvars, &argcount);