Mirror of the Vim source from https://github.com/vim/vim
Revisão | 17f0d6dc6a73cd025b81d86a89f0d4f8830fd345 (tree) |
---|---|
Hora | 2020-02-24 05:30:03 |
Autor | Bram Moolenaar <Bram@vim....> |
Commiter | Bram Moolenaar |
patch 8.2.0312: Vim9: insufficient script tests
Commit: https://github.com/vim/vim/commit/f2d5c240a56853c0bbbc7979e9bff095de6c73ec
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Feb 23 21:25:54 2020 +0100
@@ -4,5 +4,6 @@ | ||
4 | 4 | void ex_export(exarg_T *eap); |
5 | 5 | void free_imports(int sid); |
6 | 6 | void ex_import(exarg_T *eap); |
7 | -char_u *handle_import(char_u *arg_start, garray_T *gap, int sid); | |
7 | +int find_exported(int sid, char_u **argp, int *name_len, ufunc_T **ufunc, type_T **type); | |
8 | +char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid); | |
8 | 9 | /* vim: set ft=c : */ |
@@ -331,6 +331,28 @@ | ||
331 | 331 | unlet g:imported_func |
332 | 332 | unlet g:imported_name g:imported_name_appended |
333 | 333 | delete('Ximport.vim') |
334 | + | |
335 | + let import_star_as_lines =<< trim END | |
336 | + vim9script | |
337 | + import * as Export from './Xexport.vim' | |
338 | + def UseExport() | |
339 | + g:imported = Export.exported | |
340 | + enddef | |
341 | + UseExport() | |
342 | + END | |
343 | + writefile(import_star_as_lines, 'Ximport.vim') | |
344 | + source Ximport.vim | |
345 | + assert_equal(9876, g:imported) | |
346 | + | |
347 | + let import_star_lines =<< trim END | |
348 | + vim9script | |
349 | + import * from './Xexport.vim' | |
350 | + g:imported = exported | |
351 | + END | |
352 | + writefile(import_star_lines, 'Ximport.vim') | |
353 | + assert_fails('source Ximport.vim', 'E1045:') | |
354 | + | |
355 | + delete('Ximport.vim') | |
334 | 356 | delete('Xexport.vim') |
335 | 357 | |
336 | 358 | " Check that in a Vim9 script 'cpo' is set to the Vim default. |
@@ -352,6 +374,7 @@ | ||
352 | 374 | CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:') |
353 | 375 | CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:') |
354 | 376 | CheckScriptFailure(['export let some = 123'], 'E1042:') |
377 | + CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:') | |
355 | 378 | CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:') |
356 | 379 | CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:') |
357 | 380 |
@@ -739,6 +739,8 @@ | ||
739 | 739 | static int included_patches[] = |
740 | 740 | { /* Add new patch number below this line */ |
741 | 741 | /**/ |
742 | + 312, | |
743 | +/**/ | |
742 | 744 | 311, |
743 | 745 | /**/ |
744 | 746 | 310, |
@@ -1522,7 +1522,11 @@ | ||
1522 | 1522 | * Generate an instruction to load script-local variable "name". |
1523 | 1523 | */ |
1524 | 1524 | static int |
1525 | -compile_load_scriptvar(cctx_T *cctx, char_u *name) | |
1525 | +compile_load_scriptvar( | |
1526 | + cctx_T *cctx, | |
1527 | + char_u *name, // variable NUL terminated | |
1528 | + char_u *start, // start of variable | |
1529 | + char_u **end) // end of variable | |
1526 | 1530 | { |
1527 | 1531 | scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); |
1528 | 1532 | int idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE); |
@@ -1546,11 +1550,40 @@ | ||
1546 | 1550 | import = find_imported(name, 0, cctx); |
1547 | 1551 | if (import != NULL) |
1548 | 1552 | { |
1549 | - // TODO: check this is a variable, not a function | |
1550 | - generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT, | |
1551 | - import->imp_sid, | |
1552 | - import->imp_var_vals_idx, | |
1553 | - import->imp_type); | |
1553 | + if (import->imp_all) | |
1554 | + { | |
1555 | + char_u *p = skipwhite(*end); | |
1556 | + int name_len; | |
1557 | + ufunc_T *ufunc; | |
1558 | + type_T *type; | |
1559 | + | |
1560 | + // Used "import * as Name", need to lookup the member. | |
1561 | + if (*p != '.') | |
1562 | + { | |
1563 | + semsg(_("E1060: expected dot after name: %s"), start); | |
1564 | + return FAIL; | |
1565 | + } | |
1566 | + ++p; | |
1567 | + | |
1568 | + idx = find_exported(import->imp_sid, &p, &name_len, &ufunc, &type); | |
1569 | + // TODO: what if it is a function? | |
1570 | + if (idx < 0) | |
1571 | + return FAIL; | |
1572 | + *end = p; | |
1573 | + | |
1574 | + generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT, | |
1575 | + import->imp_sid, | |
1576 | + idx, | |
1577 | + type); | |
1578 | + } | |
1579 | + else | |
1580 | + { | |
1581 | + // TODO: check this is a variable, not a function | |
1582 | + generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT, | |
1583 | + import->imp_sid, | |
1584 | + import->imp_var_vals_idx, | |
1585 | + import->imp_type); | |
1586 | + } | |
1554 | 1587 | return OK; |
1555 | 1588 | } |
1556 | 1589 |
@@ -1564,10 +1597,11 @@ | ||
1564 | 1597 | * When "error" is FALSE do not give an error when not found. |
1565 | 1598 | */ |
1566 | 1599 | static int |
1567 | -compile_load(char_u **arg, char_u *end, cctx_T *cctx, int error) | |
1600 | +compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error) | |
1568 | 1601 | { |
1569 | 1602 | type_T *type; |
1570 | 1603 | char_u *name; |
1604 | + char_u *end = end_arg; | |
1571 | 1605 | int res = FAIL; |
1572 | 1606 | |
1573 | 1607 | if (*(*arg + 1) == ':') |
@@ -1589,7 +1623,7 @@ | ||
1589 | 1623 | } |
1590 | 1624 | else if (**arg == 's') |
1591 | 1625 | { |
1592 | - res = compile_load_scriptvar(cctx, name); | |
1626 | + res = compile_load_scriptvar(cctx, name, NULL, NULL); | |
1593 | 1627 | } |
1594 | 1628 | else |
1595 | 1629 | { |
@@ -1645,7 +1679,7 @@ | ||
1645 | 1679 | else if (SCRIPT_ITEM(current_sctx.sc_sid)->sn_version |
1646 | 1680 | == SCRIPT_VERSION_VIM9) |
1647 | 1681 | // in Vim9 script "var" can be script-local. |
1648 | - res = compile_load_scriptvar(cctx, name); | |
1682 | + res = compile_load_scriptvar(cctx, name, *arg, &end); | |
1649 | 1683 | } |
1650 | 1684 | } |
1651 | 1685 | if (gen_load) |
@@ -3412,7 +3446,7 @@ | ||
3412 | 3446 | generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type); |
3413 | 3447 | break; |
3414 | 3448 | case dest_script: |
3415 | - compile_load_scriptvar(cctx, name + (name[1] == ':' ? 2 : 0)); | |
3449 | + compile_load_scriptvar(cctx, name + (name[1] == ':' ? 2 : 0), NULL, NULL); | |
3416 | 3450 | break; |
3417 | 3451 | case dest_env: |
3418 | 3452 | // Include $ in the name here |
@@ -151,6 +151,88 @@ | ||
151 | 151 | } |
152 | 152 | |
153 | 153 | /* |
154 | + * Find an exported item in "sid" matching the name at "*argp". | |
155 | + * When it is a variable return the index. | |
156 | + * When it is a user function return "*ufunc". | |
157 | + * When not found returns -1 and "*ufunc" is NULL. | |
158 | + */ | |
159 | + int | |
160 | +find_exported( | |
161 | + int sid, | |
162 | + char_u **argp, | |
163 | + int *name_len, | |
164 | + ufunc_T **ufunc, | |
165 | + type_T **type) | |
166 | +{ | |
167 | + char_u *name = *argp; | |
168 | + char_u *arg = *argp; | |
169 | + int cc; | |
170 | + int idx = -1; | |
171 | + svar_T *sv; | |
172 | + scriptitem_T *script = SCRIPT_ITEM(sid); | |
173 | + | |
174 | + // isolate one name | |
175 | + while (eval_isnamec1(*arg)) | |
176 | + ++arg; | |
177 | + *name_len = (int)(arg - name); | |
178 | + | |
179 | + // find name in "script" | |
180 | + // TODO: also find script-local user function | |
181 | + cc = *arg; | |
182 | + *arg = NUL; | |
183 | + idx = get_script_item_idx(sid, name, FALSE); | |
184 | + if (idx >= 0) | |
185 | + { | |
186 | + sv = ((svar_T *)script->sn_var_vals.ga_data) + idx; | |
187 | + if (!sv->sv_export) | |
188 | + { | |
189 | + semsg(_("E1049: Item not exported in script: %s"), name); | |
190 | + *arg = cc; | |
191 | + return -1; | |
192 | + } | |
193 | + *type = sv->sv_type; | |
194 | + *ufunc = NULL; | |
195 | + } | |
196 | + else | |
197 | + { | |
198 | + char_u buffer[200]; | |
199 | + char_u *funcname; | |
200 | + | |
201 | + // it could be a user function. | |
202 | + if (STRLEN(name) < sizeof(buffer) - 10) | |
203 | + funcname = buffer; | |
204 | + else | |
205 | + { | |
206 | + funcname = alloc(STRLEN(name) + 10); | |
207 | + if (funcname == NULL) | |
208 | + { | |
209 | + *arg = cc; | |
210 | + return -1; | |
211 | + } | |
212 | + } | |
213 | + funcname[0] = K_SPECIAL; | |
214 | + funcname[1] = KS_EXTRA; | |
215 | + funcname[2] = (int)KE_SNR; | |
216 | + sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); | |
217 | + *ufunc = find_func(funcname, NULL); | |
218 | + if (funcname != buffer) | |
219 | + vim_free(funcname); | |
220 | + | |
221 | + if (*ufunc == NULL) | |
222 | + { | |
223 | + semsg(_("E1048: Item not found in script: %s"), name); | |
224 | + *arg = cc; | |
225 | + return -1; | |
226 | + } | |
227 | + } | |
228 | + *arg = cc; | |
229 | + arg = skipwhite(arg); | |
230 | + *argp = arg; | |
231 | + | |
232 | + return idx; | |
233 | +} | |
234 | + | |
235 | +/* | |
154 | 236 | * Handle an ":import" command and add the resulting imported_T to "gap", when |
155 | 237 | * not NULL, or script "import_sid" sn_imports. |
156 | 238 | * Returns a pointer to after the command or NULL in case of failure |
@@ -289,8 +371,6 @@ | ||
289 | 371 | } |
290 | 372 | else |
291 | 373 | { |
292 | - scriptitem_T *script = SCRIPT_ITEM(sid); | |
293 | - | |
294 | 374 | arg = arg_start; |
295 | 375 | if (*arg == '{') |
296 | 376 | arg = skipwhite(arg + 1); |
@@ -298,68 +378,15 @@ | ||
298 | 378 | { |
299 | 379 | char_u *name = arg; |
300 | 380 | int name_len; |
301 | - int cc; | |
302 | 381 | int idx; |
303 | - svar_T *sv; | |
304 | 382 | imported_T *imported; |
305 | - ufunc_T *ufunc; | |
306 | - | |
307 | - // isolate one name | |
308 | - while (eval_isnamec1(*arg)) | |
309 | - ++arg; | |
310 | - name_len = (int)(arg - name); | |
383 | + ufunc_T *ufunc = NULL; | |
384 | + type_T *type; | |
311 | 385 | |
312 | - // find name in "script" | |
313 | - // TODO: also find script-local user function | |
314 | - cc = *arg; | |
315 | - *arg = NUL; | |
316 | - idx = get_script_item_idx(sid, name, FALSE); | |
317 | - if (idx >= 0) | |
318 | - { | |
319 | - sv = ((svar_T *)script->sn_var_vals.ga_data) + idx; | |
320 | - if (!sv->sv_export) | |
321 | - { | |
322 | - semsg(_("E1049: Item not exported in script: %s"), name); | |
323 | - *arg = cc; | |
324 | - return NULL; | |
325 | - } | |
326 | - ufunc = NULL; | |
327 | - } | |
328 | - else | |
329 | - { | |
330 | - char_u buffer[200]; | |
331 | - char_u *funcname; | |
386 | + idx = find_exported(sid, &arg, &name_len, &ufunc, &type); | |
332 | 387 | |
333 | - // it could be a user function. | |
334 | - if (STRLEN(name) < sizeof(buffer) - 10) | |
335 | - funcname = buffer; | |
336 | - else | |
337 | - { | |
338 | - funcname = alloc(STRLEN(name) + 10); | |
339 | - if (funcname == NULL) | |
340 | - { | |
341 | - *arg = cc; | |
342 | - return NULL; | |
343 | - } | |
344 | - } | |
345 | - funcname[0] = K_SPECIAL; | |
346 | - funcname[1] = KS_EXTRA; | |
347 | - funcname[2] = (int)KE_SNR; | |
348 | - sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); | |
349 | - ufunc = find_func(funcname, NULL); | |
350 | - if (funcname != buffer) | |
351 | - vim_free(funcname); | |
352 | - | |
353 | - if (ufunc == NULL) | |
354 | - { | |
355 | - semsg(_("E1048: Item not found in script: %s"), name); | |
356 | - *arg = cc; | |
357 | - return NULL; | |
358 | - } | |
359 | - sv = NULL; | |
360 | - } | |
361 | - *arg = cc; | |
362 | - arg = skipwhite(arg); | |
388 | + if (idx < 0 && ufunc == NULL) | |
389 | + return NULL; | |
363 | 390 | |
364 | 391 | imported = new_imported(gap != NULL ? gap |
365 | 392 | : &SCRIPT_ITEM(import_sid)->sn_imports); |
@@ -372,7 +399,7 @@ | ||
372 | 399 | imported->imp_sid = sid; |
373 | 400 | if (idx >= 0) |
374 | 401 | { |
375 | - imported->imp_type = sv->sv_type; | |
402 | + imported->imp_type = type; | |
376 | 403 | imported->imp_var_vals_idx = idx; |
377 | 404 | } |
378 | 405 | else |