]> granicus.if.org Git - vim/commitdiff
patch 8.2.1029: Vim9: cannot chain function calls with -> at line start v8.2.1029
authorBram Moolenaar <Bram@vim.org>
Sun, 21 Jun 2020 14:58:13 +0000 (16:58 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 21 Jun 2020 14:58:13 +0000 (16:58 +0200)
Problem:    Vim9: cannot chain function calls with -> at line start.
Solution:   Peek ahead for a following line starting with "->". (closes #6306)

src/testdir/test_vim9_expr.vim
src/version.c
src/vim9compile.c

index f87e920b2398fee6b64e45721b7610464480e74c..b46e04bc8ef711bf640210e9e7f67a6508e9bef1 100644 (file)
@@ -1036,6 +1036,24 @@ def Test_expr7_subscript_linebreak()
        map('string(v:key)')
   assert_equal(['0', '1', '2'], l)
 
+  l = range
+       ->map('string(v:key)')
+  assert_equal(['0', '1', '2'], l)
+
+  l = range # comment
+       ->map('string(v:key)')
+  assert_equal(['0', '1', '2'], l)
+
+  l = range
+
+       ->map('string(v:key)')
+  assert_equal(['0', '1', '2'], l)
+
+  l = range
+       # comment
+       ->map('string(v:key)')
+  assert_equal(['0', '1', '2'], l)
+
   assert_equal('1', l[
        1])
 
index 77fdac13993a0488b2f65f984f3cd08558c7469f..b4e74825efcfb60d3103a85e27ee8f055d75e25e 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1029,
 /**/
     1028,
 /**/
index 3b021afdcb4eb4b9bc73e75ea7ce31d3c236c747..871e70736fcc6815d6a9fb52996b17fc9c2f86d8 100644 (file)
@@ -2380,12 +2380,43 @@ free_imported(cctx_T *cctx)
     ga_clear(&cctx->ctx_imports);
 }
 
+/*
+ * Return TRUE if "p" points at a "#" but not at "#{".
+ */
+    static int
+comment_start(char_u *p)
+{
+    return p[0] == '#' && p[1] != '{';
+}
+
+/*
+ * Return a pointer to the next line that isn't empty or only contains a
+ * comment. Skips over white space.
+ * Returns NULL if there is none.
+ */
+    static char_u *
+peek_next_line(cctx_T *cctx)
+{
+    int lnum = cctx->ctx_lnum;
+
+    while (++lnum < cctx->ctx_ufunc->uf_lines.ga_len)
+    {
+       char_u *line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[lnum];
+       char_u *p = skipwhite(line);
+
+       if (*p != NUL && !comment_start(p))
+           return p;
+    }
+    return NULL;
+}
+
 /*
  * Get the next line of the function from "cctx".
+ * Skips over empty lines.  Skips over comment lines if "skip_comment" is TRUE.
  * Returns NULL when at the end.
  */
     static char_u *
-next_line_from_context(cctx_T *cctx)
+next_line_from_context(cctx_T *cctx, int skip_comment)
 {
     char_u     *line;
 
@@ -2400,19 +2431,11 @@ next_line_from_context(cctx_T *cctx)
        line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
        cctx->ctx_line_start = line;
        SOURCING_LNUM = cctx->ctx_lnum + 1;
-    } while (line == NULL || *skipwhite(line) == NUL);
+    } while (line == NULL || *skipwhite(line) == NUL
+                         || (skip_comment && comment_start(skipwhite(line))));
     return line;
 }
 
-/*
- * Return TRUE if "p" points at a "#" but not at "#{".
- */
-    static int
-comment_start(char_u *p)
-{
-    return p[0] == '#' && p[1] != '{';
-}
-
 /*
  * If "*arg" is at the end of the line, advance to the next line.
  * Also when "whitep" points to white space and "*arg" is on a "#".
@@ -2423,7 +2446,7 @@ may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx)
 {
     if (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
     {
-       char_u *next = next_line_from_context(cctx);
+       char_u *next = next_line_from_context(cctx, TRUE);
 
        if (next == NULL)
            return FAIL;
@@ -2752,14 +2775,8 @@ compile_arguments(char_u **arg, cctx_T *cctx, int *argcount)
 
     for (;;)
     {
-       while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
-       {
-           p = next_line_from_context(cctx);
-           if (p == NULL)
-               goto failret;
-           whitep = (char_u *)" ";
-           p = skipwhite(p);
-       }
+       if (may_get_next_line(whitep, &p, cctx) == FAIL)
+           goto failret;
        if (*p == ')')
        {
            *arg = p + 1;
@@ -2986,16 +3003,10 @@ compile_list(char_u **arg, cctx_T *cctx)
 
     for (;;)
     {
-       while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
+       if (may_get_next_line(whitep, &p, cctx) == FAIL)
        {
-           p = next_line_from_context(cctx);
-           if (p == NULL)
-           {
-               semsg(_(e_list_end), *arg);
-               return FAIL;
-           }
-           whitep = (char_u *)" ";
-           p = skipwhite(p);
+           semsg(_(e_list_end), *arg);
+           return FAIL;
        }
        if (*p == ']')
        {
@@ -3112,14 +3123,10 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
     {
        char_u *key = NULL;
 
-       while (**arg == NUL || (literal && **arg == '"')
-                             || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
+       if (may_get_next_line(whitep, arg, cctx) == FAIL)
        {
-           *arg = next_line_from_context(cctx);
-           if (*arg == NULL)
-               goto failret;
-           whitep = (char_u *)" ";
-           *arg = skipwhite(*arg);
+           *arg = NULL;
+           goto failret;
        }
 
        if (**arg == '}')
@@ -3179,13 +3186,10 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
 
        whitep = *arg + 1;
        *arg = skipwhite(*arg + 1);
-       while (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
+       if (may_get_next_line(whitep, arg, cctx) == FAIL)
        {
-           *arg = next_line_from_context(cctx);
-           if (*arg == NULL)
-               goto failret;
-           whitep = (char_u *)" ";
-           *arg = skipwhite(*arg);
+           *arg = NULL;
+           goto failret;
        }
 
        if (compile_expr0(arg, cctx) == FAIL)
@@ -3193,15 +3197,11 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
        ++count;
 
        whitep = *arg;
-       p = skipwhite(*arg);
-       while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
+       *arg = skipwhite(*arg);
+       if (may_get_next_line(whitep, arg, cctx) == FAIL)
        {
-           *arg = next_line_from_context(cctx);
-           if (*arg == NULL)
-               goto failret;
-           whitep = (char_u *)" ";
-           *arg = skipwhite(*arg);
-           p = *arg;
+           *arg = NULL;
+           goto failret;
        }
        if (**arg == '}')
            break;
@@ -3506,6 +3506,24 @@ compile_subscript(
 {
     for (;;)
     {
+       char_u *p = skipwhite(*arg);
+
+       if (*p == NUL || (VIM_ISWHITE(**arg) && comment_start(p)))
+       {
+           char_u *next = peek_next_line(cctx);
+
+           // If a following line starts with "->{" or "->X" advance to that
+           // line, so that a line break before "->" is allowed.
+           if (next != NULL && next[0] == '-' && next[1] == '>'
+                   && (next[2] == '{' || ASCII_ISALPHA(next[2])))
+           {
+               next = next_line_from_context(cctx, TRUE);
+               if (next == NULL)
+                   return FAIL;
+               *arg = skipwhite(next);
+           }
+       }
+
        if (**arg == '(')
        {
            garray_T    *stack = &cctx->ctx_type_stack;
@@ -3526,8 +3544,6 @@ compile_subscript(
        }
        else if (**arg == '-' && (*arg)[1] == '>')
        {
-           char_u *p;
-
            if (generate_ppconst(cctx, ppconst) == FAIL)
                return FAIL;
 
@@ -3570,7 +3586,6 @@ compile_subscript(
        {
            garray_T    *stack = &cctx->ctx_type_stack;
            type_T      **typep;
-           char_u      *p;
 
            // list index: list[123]
            // dict member: dict[key]
@@ -3618,8 +3633,6 @@ compile_subscript(
        }
        else if (**arg == '.' && (*arg)[1] != '.')
        {
-           char_u *p;
-
            if (generate_ppconst(cctx, ppconst) == FAIL)
                return FAIL;
 
@@ -6696,7 +6709,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
        }
        else
        {
-           line = next_line_from_context(&cctx);
+           line = next_line_from_context(&cctx, FALSE);
            if (cctx.ctx_lnum >= ufunc->uf_lines.ga_len)
                // beyond the last line
                break;