Skip to content

Commit

Permalink
patch 8.2.3178: Vim9: the file name of an :import cannot be an expres…
Browse files Browse the repository at this point in the history
…sion

Problem:    Vim9: the file name of an :import cannot be an expression.
Solution:   Accept an expression that results in a string.  Do not support
            :import in a function.
  • Loading branch information
brammool committed Jul 18, 2021
1 parent ad2d496 commit 4db572e
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 65 deletions.
4 changes: 4 additions & 0 deletions runtime/doc/vim9.txt
Expand Up @@ -1354,6 +1354,9 @@ script file to avoid confusion.
`:import` can also be used in legacy Vim script. The imported items still
become script-local, even when the "s:" prefix is not given.

`:import` can not be used in a function. Imported items are intended to exist
at the script level and only imported once.

The script name after `import` can be:
- A relative path, starting "." or "..". This finds a file relative to the
location of the script file itself. This is useful to split up a large
Expand All @@ -1363,6 +1366,7 @@ The script name after `import` can be:
- A path not being relative or absolute. This will be found in the
"import" subdirectories of 'runtimepath' entries. The name will usually be
longer and unique, to avoid loading the wrong file.
Note that "after/import" is not used.

Once a vim9 script file has been imported, the result is cached and used the
next time the same script is imported. It will not be read again.
Expand Down
49 changes: 8 additions & 41 deletions src/testdir/test_vim9_script.vim
Expand Up @@ -1085,7 +1085,9 @@ def Test_vim9_import_export()
enddef
g:funcref_result = GetExported()

import {exp_name} from './Xexport.vim'
var dir = './'
var ext = ".vim"
import {exp_name} from dir .. 'Xexport' .. ext
g:imported_name = exp_name
exp_name ..= ' Doe'
g:imported_name_appended = exp_name
Expand Down Expand Up @@ -1148,26 +1150,6 @@ def Test_vim9_import_export()
unlet g:imported_func
delete('Ximport_lbr.vim')

# import inside :def function
var import_in_def_lines =<< trim END
vim9script
def ImportInDef()
import exported from './Xexport.vim'
g:imported = exported
exported += 7
g:imported_added = exported
enddef
ImportInDef()
END
writefile(import_in_def_lines, 'Ximport2.vim')
source Ximport2.vim
# TODO: this should be 9879
assert_equal(9876, g:imported)
assert_equal(9883, g:imported_added)
unlet g:imported
unlet g:imported_added
delete('Ximport2.vim')

var import_star_as_lines =<< trim END
vim9script
import * as Export from './Xexport.vim'
Expand All @@ -1181,8 +1163,9 @@ def Test_vim9_import_export()
END
writefile(import_star_as_lines, 'Ximport.vim')
source Ximport.vim
assert_equal(9883, g:imported_def)
assert_equal(9883, g:imported_script)
# FIXME: this should be 9881
assert_equal(9876, g:imported_def)
assert_equal(9876, g:imported_script)

var import_star_as_lines_no_dot =<< trim END
vim9script
Expand Down Expand Up @@ -1257,7 +1240,7 @@ def Test_vim9_import_export()
END
writefile(import_star_as_lbr_lines, 'Ximport.vim')
source Ximport.vim
assert_equal(9883, g:imported)
assert_equal(9876, g:imported)

var import_star_lines =<< trim END
vim9script
Expand Down Expand Up @@ -1345,7 +1328,7 @@ def Test_vim9_import_export()
import name from Xexport.vim
END
writefile(import_invalid_string_lines, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1071:', '', 2, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')

var import_wrong_name_lines =<< trim END
vim9script
Expand Down Expand Up @@ -1659,22 +1642,6 @@ def Test_vim9script_reload_import()
source Xreload.vim
source Xreload.vim

var testlines =<< trim END
vim9script
def TheFunc()
import GetValtwo from './Xreload.vim'
assert_equal(222, GetValtwo())
enddef
TheFunc()
END
writefile(testlines, 'Ximport.vim')
source Ximport.vim

# Test that when not using "morelines" GetValtwo() and valtwo are still
# defined, because import doesn't reload a script.
writefile(lines, 'Xreload.vim')
source Ximport.vim

# cannot declare a var twice
lines =<< trim END
vim9script
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -755,6 +755,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3178,
/**/
3177,
/**/
Expand Down
13 changes: 2 additions & 11 deletions src/vim9compile.c
Expand Up @@ -4335,7 +4335,6 @@ compile_subscript(
semsg(_(e_missing_paren), *arg);
return FAIL;
}
// TODO: base value may not be the first argument
if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL)
return FAIL;
}
Expand Down Expand Up @@ -7293,15 +7292,6 @@ compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
}

/*
* Compile an :import command.
*/
static char_u *
compile_import(char_u *arg, cctx_T *cctx)
{
return handle_import(arg, &cctx->ctx_imports, 0, NULL, cctx);
}

/*
* generate a jump to the ":endif"/":endfor"/":endwhile"/":finally"/":endtry".
*/
Expand Down Expand Up @@ -9638,7 +9628,8 @@ compile_def_function(
break;

case CMD_import:
line = compile_import(p, &cctx);
emsg(_(e_import_can_only_be_used_in_script));
line = NULL;
break;

case CMD_if:
Expand Down
22 changes: 9 additions & 13 deletions src/vim9script.c
Expand Up @@ -412,6 +412,7 @@ handle_import(
garray_T names;
garray_T as_names;

tv.v_type = VAR_UNKNOWN;
ga_init2(&names, sizeof(char_u *), 10);
ga_init2(&as_names, sizeof(char_u *), 10);
if (*arg == '{')
Expand Down Expand Up @@ -496,14 +497,14 @@ handle_import(
goto erret;
}

// The name of the file can be an expression, which must evaluate to a
// string.
arg = skipwhite_and_linebreak(arg + 4, evalarg);
tv.v_type = VAR_UNKNOWN;
// TODO: should we accept any expression?
if (*arg == '\'')
ret = eval_lit_string(&arg, &tv, TRUE);
else if (*arg == '"')
ret = eval_string(&arg, &tv, TRUE);
if (ret == FAIL || tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
ret = eval0(arg, &tv, NULL, evalarg);
if (ret == FAIL)
goto erret;
if (tv.v_type != VAR_STRING
|| tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
{
emsg(_(e_invalid_string_after_from));
goto erret;
Expand All @@ -524,10 +525,7 @@ handle_import(
len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
from_name = alloc((int)len);
if (from_name == NULL)
{
clear_tv(&tv);
goto erret;
}
vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
add_pathsep(from_name);
STRCAT(from_name, tv.vval.v_string);
Expand All @@ -550,7 +548,6 @@ handle_import(
from_name = alloc((int)len);
if (from_name == NULL)
{
clear_tv(&tv);
goto erret;
}
vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string);
Expand All @@ -561,10 +558,8 @@ handle_import(
if (res == FAIL || sid <= 0)
{
semsg(_(e_could_not_import_str), tv.vval.v_string);
clear_tv(&tv);
goto erret;
}
clear_tv(&tv);

if (*arg_start == '*')
{
Expand Down Expand Up @@ -669,6 +664,7 @@ handle_import(
}
}
erret:
clear_tv(&tv);
ga_clear_strings(&names);
ga_clear_strings(&as_names);
return cmd_end;
Expand Down

0 comments on commit 4db572e

Please sign in to comment.