]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0994: Vim9: not able to use comment after opening curly brace v9.1.0994
authorYegappan Lakshmanan <yegappan@yahoo.com>
Tue, 7 Jan 2025 19:22:32 +0000 (20:22 +0100)
committerChristian Brabandt <cb@256bit.org>
Tue, 7 Jan 2025 19:22:32 +0000 (20:22 +0100)
Problem:  Vim9: not able to use comment after opening curly brace
          (lifepillar)
Solution: allow to use comments after curly braces of an inner-block,
          modify the logic to search for comment in a line, update Vim9
          tests to use specific class type instead of any
          (Yegappan Lakshmanan)

fixes: #16363
closes: #16405

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/testdir/test_vim9_class.vim
src/testdir/test_vim9_func.vim
src/testdir/test_vim9_script.vim
src/userfunc.c
src/version.c

index 0c11c078e721ec25fa86f8860134b34ef62cf0d3..799230a98b00c22c75f2199c9615cdfd20ce1792 100644 (file)
@@ -4345,23 +4345,20 @@ def Test_lockvar_object_variable()
   END
   v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
 
-  # TODO: the following tests use type "any" for argument. Need a run time
-  #       check for access. Probably OK as is for now.
-
   # read-only lockvar from object method arg
   lines =<< trim END
     vim9script
 
     class C
       var val5: number
-      def Lock(o_any: any)
-        lockvar o_any.val5
+      def Lock(c: C)
+        lockvar c.val5
       enddef
     endclass
     var o = C.new(3)
     o.Lock(C.new(5))
   END
-  v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
+  v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val5" in class "C"')
 
   # read-only lockvar from class method arg
   lines =<< trim END
@@ -4369,14 +4366,14 @@ def Test_lockvar_object_variable()
 
     class C
       var val6: number
-      static def Lock(o_any: any)
-        lockvar o_any.val6
+      static def Lock(c: C)
+        lockvar c.val6
       enddef
     endclass
     var o = C.new(3)
     C.Lock(o)
   END
-  v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
+  v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val6" in class "C"')
 
   #
   # lockvar of public object variable
@@ -4444,14 +4441,14 @@ def Test_lockvar_object_variable()
 
     class C
       public var val5: number
-      def Lock(o_any: any)
-        lockvar o_any.val5
+      def Lock(c: C)
+        lockvar c.val5
       enddef
     endclass
     var o = C.new(3)
     o.Lock(C.new(5))
   END
-  v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
+  v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val5" in class "C"', 1)
 
   # lockvar from class method arg
   lines =<< trim END
@@ -4459,14 +4456,14 @@ def Test_lockvar_object_variable()
 
     class C
       public var val6: number
-      static def Lock(o_any: any)
-        lockvar o_any.val6
+      static def Lock(c: C)
+        lockvar c.val6
       enddef
     endclass
     var o = C.new(3)
     C.Lock(o)
   END
-  v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
+  v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val6" in class "C"', 1)
 enddef
 
 " Test trying to lock a class variable from various places
index 79bb9d8216cdacbaf27352bb25708d9dc13dabaa..4188f82e5d0656e5d4d47dd279af7556bddbd4b2 100644 (file)
@@ -4697,6 +4697,23 @@ def Test_test_override_defcompile()
   test_override('defcompile', 0)
 enddef
 
+" Test for using a comment after the opening curly brace of an inner block.
+def Test_comment_after_inner_block()
+  var lines =<< trim END
+    vim9script
+
+    def F(G: func)
+    enddef
+
+    F(() => {       # comment1
+      F(() => {     # comment2
+        echo 'ok'   # comment3
+      })            # comment4
+    })              # comment5
+  END
+  v9.CheckScriptSuccess(lines)
+enddef
+
 " The following messes up syntax highlight, keep near the end.
 if has('python3')
   def Test_python3_command()
index 82f808862db174e61bf034376238a9236f089617..550c725dd7641520de620bac34409e0d1cc29ed6 100644 (file)
@@ -595,6 +595,27 @@ def Test_autocommand_block()
   unlet g:otherVar
 enddef
 
+def Test_block_in_a_string()
+  var lines =<< trim END
+    vim9script
+
+    def Foo(): string
+      var x = ' => { # abc'
+      return x
+    enddef
+
+    assert_equal(' => { # abc', Foo())
+
+    def Bar(): string
+      var x = " => { # abc"
+      return x
+    enddef
+
+    assert_equal(" => { # abc", Bar())
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
 func g:NoSuchFunc()
   echo 'none'
 endfunc
index 5bf7e9558ed4d2f61c0721d75f6efa6549229bd5..b4ee0a2675a087f5e3d1de989e8ab30fb0ec7527 100644 (file)
@@ -859,6 +859,92 @@ function_using_block_scopes(ufunc_T *fp, cstack_T *cstack)
        cstack->cs_flags[i] |= CSF_FUNC_DEF;
 }
 
+/*
+ * Skip over all the characters in a single quoted string starting at "p" and
+ * return a pointer to the character following the ending single quote.
+ * If the ending single quote is missing, then return a pointer to the NUL
+ * character.
+ */
+    static char_u *
+skip_single_quote_string(char_u *p)
+{
+    p++;           // skip the beginning single quote
+    while (*p != NUL)
+    {
+       // Within the string, a single quote can be escaped by using
+       // two single quotes.
+       if (*p == '\'' && *(p + 1) == '\'')
+           p += 2;
+       else if (*p == '\'')
+       {
+           p++;    // skip the ending single quote
+           break;
+       }
+       else
+           MB_PTR_ADV(p);
+    }
+
+    return p;
+}
+
+/*
+ * Skip over all the characters in a double quoted string starting at "p" and
+ * return a pointer to the character following the ending double quote.
+ * If the ending double quote is missing, then return a pointer to the NUL
+ * character.
+ */
+    static char_u *
+skip_double_quote_string(char_u *p)
+{
+    p++;           // skip the beginning double quote
+    while (*p != NUL)
+    {
+       // Within the string, a double quote can be escaped by
+       // preceding it with a backslash.
+       if (*p == '\\' && *(p + 1) == '"')
+           p += 2;
+       else if (*p == '"')
+       {
+           p++;    // skip the ending double quote
+           break;
+       }
+       else
+           MB_PTR_ADV(p);
+    }
+
+    return p;
+}
+
+/*
+ * Return the start of a Vim9 comment (#) in the line starting at "line".
+ * If a comment is not found, then returns a pointer to the end of the
+ * string (NUL).
+ */
+    static char_u *
+find_start_of_vim9_comment(char_u *line)
+{
+    char_u     *p = line;
+
+    while (*p != NUL)
+    {
+       if (*p == '\'')
+           // Skip a single quoted string.
+           p = skip_single_quote_string(p);
+       else if (*p == '"')
+           // Skip a double quoted string.
+           p = skip_double_quote_string(p);
+       else
+       {
+           if (*p == '#')
+               // Found the start of a Vim9 comment
+               break;
+           MB_PTR_ADV(p);
+       }
+    }
+
+    return p;
+}
+
 /*
  * Read the body of a function, put every line in "newlines".
  * This stops at "}", "endfunction" or "enddef".
@@ -1123,7 +1209,17 @@ get_function_body(
            if (nesting_def[nesting] ? *p != '#' : *p != '"')
            {
                // Not a comment line: check for nested inline function.
-               end = p + STRLEN(p) - 1;
+
+               if (nesting_inline[nesting])
+               {
+                   // A comment (#) can follow the opening curly brace of a
+                   // block statement.  Need to ignore the comment and look
+                   // for the opening curly brace before the comment.
+                   end = find_start_of_vim9_comment(p) - 1;
+               }
+               else
+                   end = p + STRLEN(p) - 1;
+
                while (end > p && VIM_ISWHITE(*end))
                    --end;
                if (end > p + 1 && *end == '{' && VIM_ISWHITE(end[-1]))
index 60de70238c7d254250b94014bbb55c01528aeb7f..699ad36254aad27fdb3125faf0191030ad6996dc 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    994,
 /**/
     993,
 /**/