]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1758: vim9 no class identifiers in stack dumps v9.0.1758
authorLemonBoy <thatlemon@gmail.com>
Sun, 20 Aug 2023 16:09:11 +0000 (18:09 +0200)
committerChristian Brabandt <cb@256bit.org>
Sun, 20 Aug 2023 16:09:11 +0000 (18:09 +0200)
Problem:  vim9 no class identifiers in stack dumps
Solution: Prefix class members in stack traces with the class name
          followed by a dot.

closes: #12866
closes: #12078

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: LemonBoy <thatlemon@gmail.com>
src/scriptfile.c
src/testdir/test_vim9_class.vim
src/version.c

index 2aca346d0fd99d502d457e5dc6d1f4aab54b97b7..aff964e4ec6faadfadd65cc7094ab0539333774a 100644 (file)
@@ -129,7 +129,6 @@ estack_sfile(estack_arg_T which UNUSED)
     size_t     len;
     int                idx;
     etype_T    last_type = ETYPE_SCRIPT;
-    char       *type_name;
 #endif
 
     entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
@@ -190,41 +189,47 @@ estack_sfile(estack_arg_T which UNUSED)
        if (entry->es_name != NULL)
        {
            long    lnum = 0;
-           char    *dots;
+           char_u  *type_name = (char_u *)"";
+           char_u  *class_name = (char_u *)"";
 
-           len = STRLEN(entry->es_name) + 15;
-           type_name = "";
            if (entry->es_type != last_type)
            {
                switch (entry->es_type)
                {
-                   case ETYPE_SCRIPT: type_name = "script "; break;
-                   case ETYPE_UFUNC: type_name = "function "; break;
-                   default: type_name = ""; break;
+                   case ETYPE_SCRIPT: type_name = (char_u *)"script "; break;
+                   case ETYPE_UFUNC: type_name = (char_u *)"function "; break;
+                   default: type_name = (char_u *)""; break;
                }
                last_type = entry->es_type;
            }
-           len += STRLEN(type_name);
-           if (ga_grow(&ga, (int)len) == FAIL)
-               break;
+           if (entry->es_type == ETYPE_UFUNC && entry->es_info.ufunc->uf_class != NULL)
+               class_name = entry->es_info.ufunc->uf_class->class_name;
            if (idx == exestack.ga_len - 1)
                lnum = which == ESTACK_STACK ? SOURCING_LNUM : 0;
            else
                lnum = entry->es_lnum;
-           dots = idx == exestack.ga_len - 1 ? "" : "..";
-           if (lnum == 0)
-               // For the bottom entry of <sfile>: do not add the line number,
-               // it is used in <slnum>.  Also leave it out when the number is
-               // not set.
-               vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s%s",
-                               type_name, entry->es_name, dots);
-           else
-               vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s[%ld]%s",
-                                   type_name, entry->es_name, lnum, dots);
-           ga.ga_len += (int)STRLEN((char *)ga.ga_data + ga.ga_len);
+           len = STRLEN(entry->es_name) + STRLEN(type_name) + STRLEN(class_name) + 26;
+           if (ga_grow(&ga, (int)len) == FAIL)
+               break;
+           ga_concat(&ga, type_name);
+           if (*class_name != NUL)
+           {
+               // For class methods prepend "<class name>." to the function name.
+               ga_concat(&ga, class_name);
+               ga_append(&ga, '.');
+           }
+           ga_concat(&ga, entry->es_name);
+           // For the bottom entry of <sfile>: do not add the line number, it is used in
+           // <slnum>.  Also leave it out when the number is not set.
+           if (lnum != 0)
+               ga.ga_len += vim_snprintf((char *)ga.ga_data + ga.ga_len, 23, "[%ld]",
+                       lnum);
+           if (idx != exestack.ga_len - 1)
+               ga_concat(&ga, (char_u *)"..");
        }
     }
 
+    ga_append(&ga, '\0');
     return (char_u *)ga.ga_data;
 #endif
 }
index a79ccc8f5361279b30085d1adf4646b7ad25f329..bc90e42597bc7b9ed178091b186297253fdc5dad 100644 (file)
@@ -2492,4 +2492,27 @@ def Test_multi_level_member_access()
   v9.CheckScriptSuccess(lines)
 enddef
 
+" Test expansion of <stack> with class methods.
+def Test_stack_expansion_with_methods()
+  var lines =<< trim END
+    vim9script
+
+    class C
+        def M1()
+            F0()
+        enddef
+    endclass
+
+    def F0()
+      assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
+    enddef
+
+    def F()
+        C.new().M1()
+    enddef
+
+    F()
+  END
+  v9.CheckScriptSuccess(lines)
+enddef
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 781d38915bd7b2d2213d2a0afabf9f6094fa5753..b858a1015d447dde1256d803b3019b5d51f7d4be 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1758,
 /**/
     1757,
 /**/