patch 9.1.0994: Vim9: not able to use comment after opening curly brace
Commit:
https://github.com/vim/vim/commit/0072ceedc66c4bc26c98d2e9bd81973bbe3f7f74
Author: Yegappan Lakshmanan <[email protected]>
Date: Tue Jan 7 20:22:32 2025 +0100
patch 9.1.0994: Vim9: not able to use comment after opening curly brace
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 <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 0c11c078e..799230a98 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -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
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 79bb9d821..4188f82e5 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -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()
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 82f808862..550c725dd 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -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
diff --git a/src/userfunc.c b/src/userfunc.c
index 5bf7e9558..b4ee0a267 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -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]))
diff --git a/src/version.c b/src/version.c
index 60de70238..699ad3625 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 994,
/**/
993,
/**/
--
--
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/E1tVFHF-00EChZ-JQ%40256bit.org.