comparison src/vim9compile.c @ 23072:4b398a229b0b v8.2.2082

patch 8.2.2082: Vim9: can still use the depricated #{} dict syntax Commit: https://github.com/vim/vim/commit/e0de171ecd2ff7acd56deda2cf81f0d13a69c803 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Dec 2 17:36:54 2020 +0100 patch 8.2.2082: Vim9: can still use the depricated #{} dict syntax Problem: Vim9: can still use the depricated #{} dict syntax. Solution: Remove support for #{} in Vim9 script. (closes https://github.com/vim/vim/issues/7406, closes https://github.com/vim/vim/issues/7405)
author Bram Moolenaar <Bram@vim.org>
date Wed, 02 Dec 2020 17:45:05 +0100
parents 6a70803f4cbe
children 2120e4b40e12
comparison
equal deleted inserted replaced
23071:20dac5998fa6 23072:4b398a229b0b
2125 } 2125 }
2126 ga_clear(&cctx->ctx_imports); 2126 ga_clear(&cctx->ctx_imports);
2127 } 2127 }
2128 2128
2129 /* 2129 /*
2130 * Return TRUE if "p" points at a "#" but not at "#{". 2130 * Return TRUE if "p" points at a "#". Does not check for white space.
2131 */ 2131 */
2132 int 2132 int
2133 vim9_comment_start(char_u *p) 2133 vim9_comment_start(char_u *p)
2134 { 2134 {
2135 return p[0] == '#' && p[1] != '{'; 2135 return p[0] == '#';
2136 } 2136 }
2137 2137
2138 /* 2138 /*
2139 * Return a pointer to the next line that isn't empty or only contains a 2139 * Return a pointer to the next line that isn't empty or only contains a
2140 * comment. Skips over white space. 2140 * comment. Skips over white space.
2838 2838
2839 // Can be "[1, 2, 3]->Func()". 2839 // Can be "[1, 2, 3]->Func()".
2840 if (eval_list(&p, &rettv, NULL, FALSE) == FAIL) 2840 if (eval_list(&p, &rettv, NULL, FALSE) == FAIL)
2841 p = arg; 2841 p = arg;
2842 } 2842 }
2843 else if (p == arg && *arg == '#' && arg[1] == '{')
2844 {
2845 // Can be "#{a: 1}->Func()".
2846 ++p;
2847 if (eval_dict(&p, &rettv, NULL, TRUE) == FAIL)
2848 p = arg;
2849 }
2850
2851 return p; 2843 return p;
2852 } 2844 }
2853 2845
2854 /* 2846 /*
2855 * parse a list: [expr, expr] 2847 * parse a list: [expr, expr]
2997 func_ptr_unref(ufunc); 2989 func_ptr_unref(ufunc);
2998 return ret; 2990 return ret;
2999 } 2991 }
3000 2992
3001 /* 2993 /*
3002 * parse a dict: {'key': val} or #{key: val} 2994 * parse a dict: {key: val, [key]: val}
3003 * "*arg" points to the '{'. 2995 * "*arg" points to the '{'.
3004 * ppconst->pp_is_const is set if all item values are a constant. 2996 * ppconst->pp_is_const is set if all item values are a constant.
3005 */ 2997 */
3006 static int 2998 static int
3007 compile_dict(char_u **arg, cctx_T *cctx, int literal, ppconst_T *ppconst) 2999 compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
3008 { 3000 {
3009 garray_T *instr = &cctx->ctx_instr; 3001 garray_T *instr = &cctx->ctx_instr;
3010 garray_T *stack = &cctx->ctx_type_stack; 3002 garray_T *stack = &cctx->ctx_type_stack;
3011 int count = 0; 3003 int count = 0;
3012 dict_T *d = dict_alloc(); 3004 dict_T *d = dict_alloc();
3020 return FAIL; 3012 return FAIL;
3021 *arg = skipwhite(*arg + 1); 3013 *arg = skipwhite(*arg + 1);
3022 for (;;) 3014 for (;;)
3023 { 3015 {
3024 char_u *key = NULL; 3016 char_u *key = NULL;
3025 char_u *end;
3026 3017
3027 if (may_get_next_line(whitep, arg, cctx) == FAIL) 3018 if (may_get_next_line(whitep, arg, cctx) == FAIL)
3028 { 3019 {
3029 *arg = NULL; 3020 *arg = NULL;
3030 goto failret; 3021 goto failret;
3031 } 3022 }
3032 3023
3033 if (**arg == '}') 3024 if (**arg == '}')
3034 break; 3025 break;
3035 3026
3036 // Eventually {name: value} will use "name" as a literal key and 3027 // {name: value} uses "name" as a literal key and
3037 // {[expr]: value} for an evaluated key. 3028 // {[expr]: value} uses an evaluated key.
3038 // Temporarily: if "name" is indeed a valid key, or "[expr]" is 3029 if (**arg != '[')
3039 // used, use the new method, like JavaScript. Otherwise fall back 3030 {
3040 // to the old method. 3031 char_u *end = skip_literal_key(*arg);
3041 end = to_name_end(*arg, FALSE); 3032
3042 if (literal || *end == ':')
3043 {
3044 if (end == *arg) 3033 if (end == *arg)
3045 { 3034 {
3046 semsg(_(e_invalid_key_str), *arg); 3035 semsg(_(e_invalid_key_str), *arg);
3047 return FAIL; 3036 return FAIL;
3048 } 3037 }
3052 *arg = end; 3041 *arg = end;
3053 } 3042 }
3054 else 3043 else
3055 { 3044 {
3056 isn_T *isn; 3045 isn_T *isn;
3057 int has_bracket = **arg == '['; 3046
3058 3047 *arg = skipwhite(*arg + 1);
3059 if (has_bracket)
3060 *arg = skipwhite(*arg + 1);
3061 if (compile_expr0(arg, cctx) == FAIL) 3048 if (compile_expr0(arg, cctx) == FAIL)
3062 return FAIL; 3049 return FAIL;
3063 isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1; 3050 isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
3064 if (isn->isn_type == ISN_PUSHS) 3051 if (isn->isn_type == ISN_PUSHS)
3065 key = isn->isn_arg.string; 3052 key = isn->isn_arg.string;
3069 [stack->ga_len - 1]; 3056 [stack->ga_len - 1];
3070 if (need_type(keytype, &t_string, -1, cctx, 3057 if (need_type(keytype, &t_string, -1, cctx,
3071 FALSE, FALSE) == FAIL) 3058 FALSE, FALSE) == FAIL)
3072 return FAIL; 3059 return FAIL;
3073 } 3060 }
3074 if (has_bracket) 3061 *arg = skipwhite(*arg);
3075 { 3062 if (**arg != ']')
3076 *arg = skipwhite(*arg); 3063 {
3077 if (**arg != ']') 3064 emsg(_(e_missing_matching_bracket_after_dict_key));
3078 { 3065 return FAIL;
3079 emsg(_(e_missing_matching_bracket_after_dict_key)); 3066 }
3080 return FAIL; 3067 ++*arg;
3081 }
3082 ++*arg;
3083 }
3084 } 3068 }
3085 3069
3086 // Check for duplicate keys, if using string keys. 3070 // Check for duplicate keys, if using string keys.
3087 if (key != NULL) 3071 if (key != NULL)
3088 { 3072 {
3764 * identifier variable value 3748 * identifier variable value
3765 * function() function call 3749 * function() function call
3766 * $VAR environment variable 3750 * $VAR environment variable
3767 * (expression) nested expression 3751 * (expression) nested expression
3768 * [expr, expr] List 3752 * [expr, expr] List
3769 * {key: val, key: val} Dictionary 3753 * {key: val, [key]: val} Dictionary
3770 * #{key: val, key: val} Dictionary with literal keys
3771 * 3754 *
3772 * Also handle: 3755 * Also handle:
3773 * ! in front logical NOT 3756 * ! in front logical NOT
3774 * - in front unary minus 3757 * - in front unary minus
3775 * + in front unary plus (ignored) 3758 * + in front unary plus (ignored)
3882 */ 3865 */
3883 case '[': ret = compile_list(arg, cctx, ppconst); 3866 case '[': ret = compile_list(arg, cctx, ppconst);
3884 break; 3867 break;
3885 3868
3886 /* 3869 /*
3887 * Dictionary: #{key: val, key: val}
3888 */
3889 case '#': if ((*arg)[1] == '{')
3890 {
3891 ++*arg;
3892 ret = compile_dict(arg, cctx, TRUE, ppconst);
3893 }
3894 else
3895 ret = NOTDONE;
3896 break;
3897
3898 /*
3899 * Lambda: {arg, arg -> expr} 3870 * Lambda: {arg, arg -> expr}
3900 * Dictionary: {'key': val, 'key': val} 3871 * Dictionary: {'key': val, 'key': val}
3901 */ 3872 */
3902 case '{': { 3873 case '{': {
3903 char_u *start = skipwhite(*arg + 1); 3874 char_u *start = skipwhite(*arg + 1);
3908 &ga_arg, TRUE, NULL, NULL, 3879 &ga_arg, TRUE, NULL, NULL,
3909 TRUE, NULL, NULL); 3880 TRUE, NULL, NULL);
3910 if (ret != FAIL && *start == '>') 3881 if (ret != FAIL && *start == '>')
3911 ret = compile_lambda(arg, cctx); 3882 ret = compile_lambda(arg, cctx);
3912 else 3883 else
3913 ret = compile_dict(arg, cctx, FALSE, ppconst); 3884 ret = compile_dict(arg, cctx, ppconst);
3914 } 3885 }
3915 break; 3886 break;
3916 3887
3917 /* 3888 /*
3918 * Option value: &name 3889 * Option value: &name
4198 error_white_both(op, oplen); 4169 error_white_both(op, oplen);
4199 return FAIL; 4170 return FAIL;
4200 } 4171 }
4201 4172
4202 *arg = skipwhite(op + oplen); 4173 *arg = skipwhite(op + oplen);
4203 if (may_get_next_line(op + oplen, arg, cctx) == FAIL) 4174 if (may_get_next_line_error(op + oplen, arg, cctx) == FAIL)
4204 return FAIL; 4175 return FAIL;
4205 4176
4206 // get the second expression 4177 // get the second expression
4207 if (compile_expr6(arg, cctx, ppconst) == FAIL) 4178 if (compile_expr6(arg, cctx, ppconst) == FAIL)
4208 return FAIL; 4179 return FAIL;
7482 7453
7483 // Some things can be recognized by the first character. 7454 // Some things can be recognized by the first character.
7484 switch (*ea.cmd) 7455 switch (*ea.cmd)
7485 { 7456 {
7486 case '#': 7457 case '#':
7487 // "#" starts a comment, but "#{" does not. 7458 // "#" starts a comment
7488 if (ea.cmd[1] != '{') 7459 line = (char_u *)"";
7489 { 7460 continue;
7490 line = (char_u *)"";
7491 continue;
7492 }
7493 break;
7494 7461
7495 case '}': 7462 case '}':
7496 { 7463 {
7497 // "}" ends a block scope 7464 // "}" ends a block scope
7498 scopetype_T stype = cctx.ctx_scope == NULL 7465 scopetype_T stype = cctx.ctx_scope == NULL