comparison src/vim9compile.c @ 28281:bd1dcc605e58 v8.2.4666

patch 8.2.4666: Vim9: assignment not recognized in skipped block Commit: https://github.com/vim/vim/commit/97f8c1081ec6d6d158bb51e18fa23a36d3ed5623 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Apr 2 19:43:57 2022 +0100 patch 8.2.4666: Vim9: assignment not recognized in skipped block Problem: Vim9: assignment not recognized in skipped block. Solution: When skipping assume identifier exists. (closes https://github.com/vim/vim/issues/10059)
author Bram Moolenaar <Bram@vim.org>
date Sat, 02 Apr 2022 20:45:03 +0200
parents 662d2d5db9a6
children 060fc3b69697
comparison
equal deleted inserted replaced
28280:e998d4284855 28281:bd1dcc605e58
277 || find_imported(name, len, FALSE) != NULL; 277 || find_imported(name, len, FALSE) != NULL;
278 } 278 }
279 279
280 /* 280 /*
281 * Return TRUE if "name" is a local variable, argument, script variable, 281 * Return TRUE if "name" is a local variable, argument, script variable,
282 * imported or function. 282 * imported or function. Or commands are being skipped, a declaration may have
283 * been skipped then.
283 */ 284 */
284 static int 285 static int
285 item_exists(char_u *name, size_t len, int cmd UNUSED, cctx_T *cctx) 286 item_exists(char_u *name, size_t len, int cmd UNUSED, cctx_T *cctx)
286 { 287 {
287 return variable_exists(name, len, cctx); 288 return variable_exists(name, len, cctx);
1107 */ 1108 */
1108 int 1109 int
1109 get_var_dest( 1110 get_var_dest(
1110 char_u *name, 1111 char_u *name,
1111 assign_dest_T *dest, 1112 assign_dest_T *dest,
1112 int cmdidx, 1113 cmdidx_T cmdidx,
1113 int *option_scope, 1114 int *option_scope,
1114 int *vimvaridx, 1115 int *vimvaridx,
1115 type_T **type, 1116 type_T **type,
1116 cctx_T *cctx) 1117 cctx_T *cctx)
1117 { 1118 {
1223 } 1224 }
1224 return OK; 1225 return OK;
1225 } 1226 }
1226 1227
1227 static int 1228 static int
1228 is_decl_command(int cmdidx) 1229 is_decl_command(cmdidx_T cmdidx)
1229 { 1230 {
1230 return cmdidx == CMD_let || cmdidx == CMD_var 1231 return cmdidx == CMD_let || cmdidx == CMD_var
1231 || cmdidx == CMD_final || cmdidx == CMD_const; 1232 || cmdidx == CMD_final || cmdidx == CMD_const;
1232 } 1233 }
1233 1234
1236 * of ":unlet" with an index. 1237 * of ":unlet" with an index.
1237 * Returns OK or FAIL. 1238 * Returns OK or FAIL.
1238 */ 1239 */
1239 int 1240 int
1240 compile_lhs( 1241 compile_lhs(
1241 char_u *var_start, 1242 char_u *var_start,
1242 lhs_T *lhs, 1243 lhs_T *lhs,
1243 int cmdidx, 1244 cmdidx_T cmdidx,
1244 int heredoc, 1245 int heredoc,
1245 int oplen, 1246 int has_cmd, // "var" before "var_start"
1246 cctx_T *cctx) 1247 int oplen,
1248 cctx_T *cctx)
1247 { 1249 {
1248 char_u *var_end; 1250 char_u *var_end;
1249 int is_decl = is_decl_command(cmdidx); 1251 int is_decl = is_decl_command(cmdidx);
1250 1252
1251 CLEAR_POINTER(lhs); 1253 CLEAR_POINTER(lhs);
1491 { 1493 {
1492 // +=, /=, etc. require an existing variable 1494 // +=, /=, etc. require an existing variable
1493 semsg(_(e_cannot_use_operator_on_new_variable), lhs->lhs_name); 1495 semsg(_(e_cannot_use_operator_on_new_variable), lhs->lhs_name);
1494 return FAIL; 1496 return FAIL;
1495 } 1497 }
1496 if (!is_decl) 1498 if (!is_decl || (lhs->lhs_has_index && !has_cmd
1499 && cctx->ctx_skip != SKIP_YES))
1497 { 1500 {
1498 semsg(_(e_unknown_variable_str), lhs->lhs_name); 1501 semsg(_(e_unknown_variable_str), lhs->lhs_name);
1499 return FAIL; 1502 return FAIL;
1500 } 1503 }
1501 1504
1518 { 1521 {
1519 char_u *after = var_start + lhs->lhs_varlen; 1522 char_u *after = var_start + lhs->lhs_varlen;
1520 char_u *p; 1523 char_u *p;
1521 1524
1522 // Something follows after the variable: "var[idx]" or "var.key". 1525 // Something follows after the variable: "var[idx]" or "var.key".
1523 if (is_decl) 1526 if (is_decl && cctx->ctx_skip != SKIP_YES)
1524 { 1527 {
1525 emsg(_(e_cannot_use_index_when_declaring_variable)); 1528 if (has_cmd)
1529 emsg(_(e_cannot_use_index_when_declaring_variable));
1530 else
1531 semsg(_(e_unknown_variable_str), lhs->lhs_name);
1526 return FAIL; 1532 return FAIL;
1527 } 1533 }
1528 1534
1529 // Now: var_start[lhs->lhs_varlen] is '[' or '.' 1535 // Now: var_start[lhs->lhs_varlen] is '[' or '.'
1530 // Only the last index is used below, if there are others 1536 // Only the last index is used below, if there are others
1560 /* 1566 /*
1561 * Figure out the LHS and check a few errors. 1567 * Figure out the LHS and check a few errors.
1562 */ 1568 */
1563 int 1569 int
1564 compile_assign_lhs( 1570 compile_assign_lhs(
1565 char_u *var_start, 1571 char_u *var_start,
1566 lhs_T *lhs, 1572 lhs_T *lhs,
1567 int cmdidx, 1573 cmdidx_T cmdidx,
1568 int is_decl, 1574 int is_decl,
1569 int heredoc, 1575 int heredoc,
1570 int oplen, 1576 int has_cmd, // "var" before "var_start"
1571 cctx_T *cctx) 1577 int oplen,
1572 { 1578 cctx_T *cctx)
1573 if (compile_lhs(var_start, lhs, cmdidx, heredoc, oplen, cctx) == FAIL) 1579 {
1580 if (compile_lhs(var_start, lhs, cmdidx, heredoc, has_cmd, oplen, cctx)
1581 == FAIL)
1574 return FAIL; 1582 return FAIL;
1575 1583
1576 if (!lhs->lhs_has_index && lhs->lhs_lvar == &lhs->lhs_arg_lvar) 1584 if (!lhs->lhs_has_index && lhs->lhs_lvar == &lhs->lhs_arg_lvar)
1577 { 1585 {
1578 semsg(_(e_cannot_assign_to_argument), lhs->lhs_name); 1586 semsg(_(e_cannot_assign_to_argument), lhs->lhs_name);
2047 2055
2048 /* 2056 /*
2049 * Figure out the LHS type and other properties. 2057 * Figure out the LHS type and other properties.
2050 */ 2058 */
2051 if (compile_assign_lhs(var_start, &lhs, cmdidx, 2059 if (compile_assign_lhs(var_start, &lhs, cmdidx,
2052 is_decl, heredoc, oplen, cctx) == FAIL) 2060 is_decl, heredoc, var_start > eap->cmd,
2061 oplen, cctx) == FAIL)
2053 goto theend; 2062 goto theend;
2054 if (heredoc) 2063 if (heredoc)
2055 { 2064 {
2056 SOURCING_LNUM = start_lnum; 2065 SOURCING_LNUM = start_lnum;
2057 if (lhs.lhs_has_type 2066 if (lhs.lhs_has_type
2767 } 2776 }
2768 2777
2769 CLEAR_FIELD(ea); 2778 CLEAR_FIELD(ea);
2770 ea.cmdlinep = &line; 2779 ea.cmdlinep = &line;
2771 ea.cmd = skipwhite(line); 2780 ea.cmd = skipwhite(line);
2781 ea.skip = cctx.ctx_skip == SKIP_YES;
2772 2782
2773 if (*ea.cmd == '#') 2783 if (*ea.cmd == '#')
2774 { 2784 {
2775 // "#" starts a comment 2785 // "#" starts a comment
2776 line = (char_u *)""; 2786 line = (char_u *)"";
2955 ea.cmdidx = CMD_legacy; 2965 ea.cmdidx = CMD_legacy;
2956 } 2966 }
2957 2967
2958 if (p == ea.cmd && ea.cmdidx != CMD_SIZE) 2968 if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
2959 { 2969 {
2960 if (cctx.ctx_skip == SKIP_YES && ea.cmdidx != CMD_eval) 2970 // "eval" is used for "val->func()" and "var" for "var = val", then
2971 // "p" is equal to "ea.cmd" for a valid command.
2972 if (ea.cmdidx == CMD_eval || ea.cmdidx == CMD_var)
2973 ;
2974 else if (cctx.ctx_skip == SKIP_YES)
2961 { 2975 {
2962 line += STRLEN(line); 2976 line += STRLEN(line);
2963 goto nextline; 2977 goto nextline;
2964 } 2978 }
2965 else if (ea.cmdidx != CMD_eval) 2979 else
2966 { 2980 {
2967 // CMD_var cannot happen, compile_assignment() above would be
2968 // used. Most likely an assignment to a non-existing variable.
2969 semsg(_(e_command_not_recognized_str), ea.cmd); 2981 semsg(_(e_command_not_recognized_str), ea.cmd);
2970 goto erret; 2982 goto erret;
2971 } 2983 }
2972 } 2984 }
2973 2985