comparison src/vim9compile.c @ 20955:396fe712eb0f v8.2.1029

patch 8.2.1029: Vim9: cannot chain function calls with -> at line start Commit: https://github.com/vim/vim/commit/23c55273739b2fb09912140e2e03a4b8ff15dd04 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jun 21 16:58:13 2020 +0200 patch 8.2.1029: Vim9: cannot chain function calls with -> at line start Problem: Vim9: cannot chain function calls with -> at line start. Solution: Peek ahead for a following line starting with "->". (closes https://github.com/vim/vim/issues/6306)
author Bram Moolenaar <Bram@vim.org>
date Sun, 21 Jun 2020 17:00:04 +0200
parents 6b4b887a12f0
children 0e01976dfd3b
comparison
equal deleted inserted replaced
20954:fef8406c5c10 20955:396fe712eb0f
2379 } 2379 }
2380 ga_clear(&cctx->ctx_imports); 2380 ga_clear(&cctx->ctx_imports);
2381 } 2381 }
2382 2382
2383 /* 2383 /*
2384 * Return TRUE if "p" points at a "#" but not at "#{".
2385 */
2386 static int
2387 comment_start(char_u *p)
2388 {
2389 return p[0] == '#' && p[1] != '{';
2390 }
2391
2392 /*
2393 * Return a pointer to the next line that isn't empty or only contains a
2394 * comment. Skips over white space.
2395 * Returns NULL if there is none.
2396 */
2397 static char_u *
2398 peek_next_line(cctx_T *cctx)
2399 {
2400 int lnum = cctx->ctx_lnum;
2401
2402 while (++lnum < cctx->ctx_ufunc->uf_lines.ga_len)
2403 {
2404 char_u *line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[lnum];
2405 char_u *p = skipwhite(line);
2406
2407 if (*p != NUL && !comment_start(p))
2408 return p;
2409 }
2410 return NULL;
2411 }
2412
2413 /*
2384 * Get the next line of the function from "cctx". 2414 * Get the next line of the function from "cctx".
2415 * Skips over empty lines. Skips over comment lines if "skip_comment" is TRUE.
2385 * Returns NULL when at the end. 2416 * Returns NULL when at the end.
2386 */ 2417 */
2387 static char_u * 2418 static char_u *
2388 next_line_from_context(cctx_T *cctx) 2419 next_line_from_context(cctx_T *cctx, int skip_comment)
2389 { 2420 {
2390 char_u *line; 2421 char_u *line;
2391 2422
2392 do 2423 do
2393 { 2424 {
2398 break; 2429 break;
2399 } 2430 }
2400 line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum]; 2431 line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
2401 cctx->ctx_line_start = line; 2432 cctx->ctx_line_start = line;
2402 SOURCING_LNUM = cctx->ctx_lnum + 1; 2433 SOURCING_LNUM = cctx->ctx_lnum + 1;
2403 } while (line == NULL || *skipwhite(line) == NUL); 2434 } while (line == NULL || *skipwhite(line) == NUL
2435 || (skip_comment && comment_start(skipwhite(line))));
2404 return line; 2436 return line;
2405 }
2406
2407 /*
2408 * Return TRUE if "p" points at a "#" but not at "#{".
2409 */
2410 static int
2411 comment_start(char_u *p)
2412 {
2413 return p[0] == '#' && p[1] != '{';
2414 } 2437 }
2415 2438
2416 /* 2439 /*
2417 * If "*arg" is at the end of the line, advance to the next line. 2440 * If "*arg" is at the end of the line, advance to the next line.
2418 * Also when "whitep" points to white space and "*arg" is on a "#". 2441 * Also when "whitep" points to white space and "*arg" is on a "#".
2421 static int 2444 static int
2422 may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx) 2445 may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx)
2423 { 2446 {
2424 if (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg))) 2447 if (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
2425 { 2448 {
2426 char_u *next = next_line_from_context(cctx); 2449 char_u *next = next_line_from_context(cctx, TRUE);
2427 2450
2428 if (next == NULL) 2451 if (next == NULL)
2429 return FAIL; 2452 return FAIL;
2430 *arg = skipwhite(next); 2453 *arg = skipwhite(next);
2431 } 2454 }
2750 char_u *p = *arg; 2773 char_u *p = *arg;
2751 char_u *whitep = *arg; 2774 char_u *whitep = *arg;
2752 2775
2753 for (;;) 2776 for (;;)
2754 { 2777 {
2755 while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p))) 2778 if (may_get_next_line(whitep, &p, cctx) == FAIL)
2756 { 2779 goto failret;
2757 p = next_line_from_context(cctx);
2758 if (p == NULL)
2759 goto failret;
2760 whitep = (char_u *)" ";
2761 p = skipwhite(p);
2762 }
2763 if (*p == ')') 2780 if (*p == ')')
2764 { 2781 {
2765 *arg = p + 1; 2782 *arg = p + 1;
2766 return OK; 2783 return OK;
2767 } 2784 }
2984 char_u *whitep = *arg + 1; 3001 char_u *whitep = *arg + 1;
2985 int count = 0; 3002 int count = 0;
2986 3003
2987 for (;;) 3004 for (;;)
2988 { 3005 {
2989 while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p))) 3006 if (may_get_next_line(whitep, &p, cctx) == FAIL)
2990 { 3007 {
2991 p = next_line_from_context(cctx); 3008 semsg(_(e_list_end), *arg);
2992 if (p == NULL) 3009 return FAIL;
2993 {
2994 semsg(_(e_list_end), *arg);
2995 return FAIL;
2996 }
2997 whitep = (char_u *)" ";
2998 p = skipwhite(p);
2999 } 3010 }
3000 if (*p == ']') 3011 if (*p == ']')
3001 { 3012 {
3002 ++p; 3013 ++p;
3003 // Allow for following comment, after at least one space. 3014 // Allow for following comment, after at least one space.
3110 *arg = skipwhite(*arg + 1); 3121 *arg = skipwhite(*arg + 1);
3111 for (;;) 3122 for (;;)
3112 { 3123 {
3113 char_u *key = NULL; 3124 char_u *key = NULL;
3114 3125
3115 while (**arg == NUL || (literal && **arg == '"') 3126 if (may_get_next_line(whitep, arg, cctx) == FAIL)
3116 || (VIM_ISWHITE(*whitep) && comment_start(*arg))) 3127 {
3117 { 3128 *arg = NULL;
3118 *arg = next_line_from_context(cctx); 3129 goto failret;
3119 if (*arg == NULL)
3120 goto failret;
3121 whitep = (char_u *)" ";
3122 *arg = skipwhite(*arg);
3123 } 3130 }
3124 3131
3125 if (**arg == '}') 3132 if (**arg == '}')
3126 break; 3133 break;
3127 3134
3177 return FAIL; 3184 return FAIL;
3178 } 3185 }
3179 3186
3180 whitep = *arg + 1; 3187 whitep = *arg + 1;
3181 *arg = skipwhite(*arg + 1); 3188 *arg = skipwhite(*arg + 1);
3182 while (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg))) 3189 if (may_get_next_line(whitep, arg, cctx) == FAIL)
3183 { 3190 {
3184 *arg = next_line_from_context(cctx); 3191 *arg = NULL;
3185 if (*arg == NULL) 3192 goto failret;
3186 goto failret;
3187 whitep = (char_u *)" ";
3188 *arg = skipwhite(*arg);
3189 } 3193 }
3190 3194
3191 if (compile_expr0(arg, cctx) == FAIL) 3195 if (compile_expr0(arg, cctx) == FAIL)
3192 return FAIL; 3196 return FAIL;
3193 ++count; 3197 ++count;
3194 3198
3195 whitep = *arg; 3199 whitep = *arg;
3196 p = skipwhite(*arg); 3200 *arg = skipwhite(*arg);
3197 while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p))) 3201 if (may_get_next_line(whitep, arg, cctx) == FAIL)
3198 { 3202 {
3199 *arg = next_line_from_context(cctx); 3203 *arg = NULL;
3200 if (*arg == NULL) 3204 goto failret;
3201 goto failret;
3202 whitep = (char_u *)" ";
3203 *arg = skipwhite(*arg);
3204 p = *arg;
3205 } 3205 }
3206 if (**arg == '}') 3206 if (**arg == '}')
3207 break; 3207 break;
3208 if (**arg != ',') 3208 if (**arg != ',')
3209 { 3209 {
3504 char_u *end_leader, 3504 char_u *end_leader,
3505 ppconst_T *ppconst) 3505 ppconst_T *ppconst)
3506 { 3506 {
3507 for (;;) 3507 for (;;)
3508 { 3508 {
3509 char_u *p = skipwhite(*arg);
3510
3511 if (*p == NUL || (VIM_ISWHITE(**arg) && comment_start(p)))
3512 {
3513 char_u *next = peek_next_line(cctx);
3514
3515 // If a following line starts with "->{" or "->X" advance to that
3516 // line, so that a line break before "->" is allowed.
3517 if (next != NULL && next[0] == '-' && next[1] == '>'
3518 && (next[2] == '{' || ASCII_ISALPHA(next[2])))
3519 {
3520 next = next_line_from_context(cctx, TRUE);
3521 if (next == NULL)
3522 return FAIL;
3523 *arg = skipwhite(next);
3524 }
3525 }
3526
3509 if (**arg == '(') 3527 if (**arg == '(')
3510 { 3528 {
3511 garray_T *stack = &cctx->ctx_type_stack; 3529 garray_T *stack = &cctx->ctx_type_stack;
3512 type_T *type; 3530 type_T *type;
3513 int argcount = 0; 3531 int argcount = 0;
3524 if (generate_PCALL(cctx, argcount, end_leader, type, TRUE) == FAIL) 3542 if (generate_PCALL(cctx, argcount, end_leader, type, TRUE) == FAIL)
3525 return FAIL; 3543 return FAIL;
3526 } 3544 }
3527 else if (**arg == '-' && (*arg)[1] == '>') 3545 else if (**arg == '-' && (*arg)[1] == '>')
3528 { 3546 {
3529 char_u *p;
3530
3531 if (generate_ppconst(cctx, ppconst) == FAIL) 3547 if (generate_ppconst(cctx, ppconst) == FAIL)
3532 return FAIL; 3548 return FAIL;
3533 3549
3534 // something->method() 3550 // something->method()
3535 // Apply the '!', '-' and '+' first: 3551 // Apply the '!', '-' and '+' first:
3568 } 3584 }
3569 else if (**arg == '[') 3585 else if (**arg == '[')
3570 { 3586 {
3571 garray_T *stack = &cctx->ctx_type_stack; 3587 garray_T *stack = &cctx->ctx_type_stack;
3572 type_T **typep; 3588 type_T **typep;
3573 char_u *p;
3574 3589
3575 // list index: list[123] 3590 // list index: list[123]
3576 // dict member: dict[key] 3591 // dict member: dict[key]
3577 // TODO: blob index 3592 // TODO: blob index
3578 // TODO: more arguments 3593 // TODO: more arguments
3616 return FAIL; 3631 return FAIL;
3617 } 3632 }
3618 } 3633 }
3619 else if (**arg == '.' && (*arg)[1] != '.') 3634 else if (**arg == '.' && (*arg)[1] != '.')
3620 { 3635 {
3621 char_u *p;
3622
3623 if (generate_ppconst(cctx, ppconst) == FAIL) 3636 if (generate_ppconst(cctx, ppconst) == FAIL)
3624 return FAIL; 3637 return FAIL;
3625 3638
3626 ++*arg; 3639 ++*arg;
3627 if (may_get_next_line(*arg, arg, cctx) == FAIL) 3640 if (may_get_next_line(*arg, arg, cctx) == FAIL)
6694 semsg(_("E488: Trailing characters: %s"), line); 6707 semsg(_("E488: Trailing characters: %s"), line);
6695 goto erret; 6708 goto erret;
6696 } 6709 }
6697 else 6710 else
6698 { 6711 {
6699 line = next_line_from_context(&cctx); 6712 line = next_line_from_context(&cctx, FALSE);
6700 if (cctx.ctx_lnum >= ufunc->uf_lines.ga_len) 6713 if (cctx.ctx_lnum >= ufunc->uf_lines.ga_len)
6701 // beyond the last line 6714 // beyond the last line
6702 break; 6715 break;
6703 } 6716 }
6704 emsg_before = called_emsg; 6717 emsg_before = called_emsg;