patch 9.1.2012: Vim9: cannot initialize class member with protected var

Commit: 
https://github.com/vim/vim/commit/cbcc5babbad8dc15bc20ebbd2ffb18709816bc04
Author: Foxe Chen <[email protected]>
Date:   Tue Dec 23 20:17:30 2025 +0000

    patch 9.1.2012: Vim9: cannot initialize class member with protected var
    
    Problem:  Vim9: cannot initialize class member with protected var
    Solution: Allow this to work if this happens within the same class
              (Foxe Chen)
    
    closes: #18949
    
    Signed-off-by: Foxe Chen <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/eval.c b/src/eval.c
index 5fa45a961..d7ce2a17e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -131,6 +131,7 @@ fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int 
skip)
        evalarg->eval_getline = eap->ea_getline;
        evalarg->eval_cookie = eap->cookie;
     }
+    evalarg->eval_class = eap->class;
 }
 
 /*
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 48b69ea82..638a5faa9 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -1973,6 +1973,8 @@ struct exarg
     void       *cookie;        // argument for getline()
 #ifdef FEAT_EVAL
     cstack_T   *cstack;        // condition stack for ":if" etc.
+    class_T    *class;         // Name of class being defined. Used by :class
+                               // and :enum commands.
 #endif
 };
 
diff --git a/src/globals.h b/src/globals.h
index 9b101d8f2..2aed9378e 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -2025,7 +2025,7 @@ EXTERN listitem_T range_list_item;
 EXTERN evalarg_T EVALARG_EVALUATE
 # ifdef DO_INIT
        = {EVAL_EVALUATE, 0, NULL, NULL, NULL, NULL, GA_EMPTY, GA_EMPTY, NULL,
-                        {0, 0, (int)sizeof(char_u *), 20, NULL}, 0, NULL}
+                        {0, 0, (int)sizeof(char_u *), 20, NULL}, 0, NULL, NULL}
 # endif
        ;
 #endif
diff --git a/src/structs.h b/src/structs.h
index bc2f49f7d..9b095c328 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -2282,6 +2282,9 @@ typedef struct {
 
     // pointer to the lines concatenated for a lambda.
     char_u     *eval_tofree_lambda;
+
+    // pointer to name of class being constructed
+    class_T    *eval_class;
 } evalarg_T;
 
 // Flag for expression evaluation.
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index d0260c202..69fad3381 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -12407,10 +12407,14 @@ def Test_protected_new_method()
     vim9script
     class A
       static var _instance: A
+      static var handler: func = A._Internal
       var str: string
       def _new(str: string)
         this.str = str
       enddef
+      static def _Internal(): string
+        return "test"
+      enddef
       static def GetInstance(str: string): A
         if _instance == null
           _instance = A._new(str)
@@ -12422,6 +12426,24 @@ def Test_protected_new_method()
     var b: A = A.GetInstance('bar')
     assert_equal('foo', a.str)
     assert_equal('foo', b.str)
+    assert_equal('test', A.handler())
+  END
+  v9.CheckSourceSuccess(lines)
+
+  lines =<< trim END
+    vim9script
+    enum Test
+      A,
+      B,
+      C
+
+      static var handler: func = Test._Internal
+
+      static def _Internal(): string
+        return "test"
+      enddef
+    endenum
+    assert_equal('test', Test.handler())
   END
   v9.CheckSourceSuccess(lines)
 enddef
diff --git a/src/version.c b/src/version.c
index 247fc47aa..01967fcec 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2012,
 /**/
     2011,
 /**/
diff --git a/src/vim9class.c b/src/vim9class.c
index 409bb50f7..11b4c43f5 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -2122,6 +2122,8 @@ early_ret:
     cl->class_object_type.tt_type = VAR_OBJECT;
     cl->class_object_type.tt_class = cl;
 
+    eap->class = cl;
+
     // Add the class to the script-local variables.
     // TODO: handle other context, e.g. in a function
     // TODO: does uf_hash need to be cleared?
@@ -3243,7 +3245,8 @@ class_object_index(
        if (fp != NULL)
        {
            // Protected methods are not accessible outside the class
-           if (*name == '_')
+           if (fp->uf_defclass != evalarg->eval_class
+                   && *name == '_')
            {
                semsg(_(e_cannot_access_protected_method_str), fp->uf_name);
                goto done;

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vY91F-00CG7u-Vo%40256bit.org.

Raspunde prin e-mail lui