patch 9.1.1105: Vim9: no support for protected new() method

Problem:  Vim9: no support for protected new() method
Solution: support the protected "_new()" object method
          (Yegappan Lakshmanan)

closes: #16604

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2025-02-11 22:07:05 +01:00
committed by Christian Brabandt
parent f0ed0e6f63
commit 7e89800988
5 changed files with 48 additions and 4 deletions

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2025 Feb 08
*version9.txt* For Vim version 9.1. Last change: 2025 Feb 11
VIM REFERENCE MANUAL by Bram Moolenaar
@ -41551,6 +41551,8 @@ Add support for internal builtin functions with vim9 objects, see
Enum support for Vim9 script |:enum|
Support for protected _new() method
*new-other-9.2*
Other new features ~
------------------

View File

@ -1,4 +1,4 @@
*vim9class.txt* For Vim version 9.1. Last change: 2024 Dec 29
*vim9class.txt* For Vim version 9.1. Last change: 2025 Feb 11
VIM REFERENCE MANUAL by Bram Moolenaar
@ -272,6 +272,9 @@ no need to call "super()" or "new()" on the parent.
When defining the new() method the return type should not be specified. It
always returns an object of the class.
The new() method can be made a protected method by using "_new()". This can
be used to support the singleton design pattern.
*E1386*
When invoking an object method, the method name should be preceded by the
object variable name. An object method cannot be invoked using the class

View File

@ -12374,4 +12374,39 @@ def Test_abstract_method_across_hierarchy()
v9.CheckSourceSuccess(lines)
enddef
" Test for using a protected new() method (singleton design pattern)
def Test_protected_new_method()
var lines =<< trim END
vim9script
class A
def _new()
enddef
endclass
var a = A.new()
END
v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "A"', 6)
lines =<< trim END
vim9script
class A
static var _instance: A
var str: string
def _new(str: string)
this.str = str
enddef
static def GetInstance(str: string): A
if _instance == null
_instance = A._new(str)
endif
return _instance
enddef
endclass
var a: A = A.GetInstance('foo')
var b: A = A.GetInstance('bar')
assert_equal('foo', a.str)
assert_equal('foo', b.str)
END
v9.CheckSourceSuccess(lines)
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1105,
/**/
1104,
/**/

View File

@ -2375,7 +2375,8 @@ early_ret:
{
exarg_T ea;
garray_T lines_to_free;
int is_new = STRNCMP(p, "new", 3) == 0;
int is_new = STRNCMP(p, "new", 3) == 0
|| STRNCMP(p, "_new", 4) == 0;
if (has_public)
{
@ -2601,7 +2602,8 @@ early_ret:
for (int i = 0; i < classfunctions.ga_len; ++i)
{
class_func = ((ufunc_T **)classfunctions.ga_data)[i];
if (STRCMP(class_func->uf_name, "new") == 0)
if (STRCMP(class_func->uf_name, "new") == 0
|| STRCMP(class_func->uf_name, "_new") == 0)
{
have_new = TRUE;
break;