]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.2012: Vim9: cannot initialize class member with protected var v9.1.2012
authorFoxe Chen <chen.foxe@gmail.com>
Tue, 23 Dec 2025 20:17:30 +0000 (20:17 +0000)
committerChristian Brabandt <cb@256bit.org>
Tue, 23 Dec 2025 20:17:30 +0000 (20:17 +0000)
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 <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/eval.c
src/ex_cmds.h
src/globals.h
src/structs.h
src/testdir/test_vim9_class.vim
src/version.c
src/vim9class.c

index 5fa45a961c94b41985f3cbf719b1155089348227..d7ce2a17e457e9ec8e589bca0ed811dd0f343fe3 100644 (file)
@@ -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;
 }
 
 /*
index 48b69ea824ff09da173950f702a6bfde25acba26..638a5faa9998dd33b88269517e5b514b53efc51d 100644 (file)
@@ -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
 };
 
index 9b101d8f20bf3f99ee276a0da4423af1beb795c8..2aed9378e1f9e32c62324857c5cc14a1c953e4df 100644 (file)
@@ -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
index bc2f49f7d5940202bfa9bf6a41054c03a80e5b32..9b095c328ec23ca632bab89c43b846c68fcefc48 100644 (file)
@@ -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.
index d0260c202c122a1b53a8303425e307854885a2c3..69fad33813c8fd44d4529a38a30a38f4943a1a69 100644 (file)
@@ -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
index 247fc47aa5862952c9a761319046cf56d2f26caf..01967fcec395dcf8f35cc020fcb3257b7d7cec19 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2012,
 /**/
     2011,
 /**/
index 409bb50f73cd72e8072490a9048a8cbf2467e991..11b4c43f58e84285dab2d69276dc398afb1a2609 100644 (file)
@@ -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;