From 3d48e25dcb661eb09ccdaa73d4e2559201ff2eb1 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 15 Jul 2020 14:15:52 +0200 Subject: [PATCH] patch 8.2.1218: Vim9: cannot use 'text'->func() Problem: Vim9: cannot use 'text'->func(). Solution: Recognize string at start of command. --- src/ex_docmd.c | 59 ++++++++++++++++++++++------------ src/testdir/test_vim9_func.vim | 9 ++++++ src/version.c | 2 ++ src/vim9compile.c | 12 ++++--- 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 64b143be5..a326d20d3 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1700,6 +1700,8 @@ do_one_cmd( char_u *cmd; #ifdef FEAT_EVAL int starts_with_colon; + int starts_with_quote; + int vim9script = in_vim9script(); #endif CLEAR_FIELD(ea); @@ -1760,12 +1762,16 @@ do_one_cmd( * We need the command to know what kind of range it uses. */ cmd = ea.cmd; - ea.cmd = skip_range(ea.cmd, NULL); +#ifdef FEAT_EVAL + starts_with_quote = vim9script && *ea.cmd == '\''; + if (!starts_with_quote) +#endif + ea.cmd = skip_range(ea.cmd, NULL); if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) ea.cmd = skipwhite(ea.cmd + 1); #ifdef FEAT_EVAL - if (in_vim9script() && !starts_with_colon) + if (vim9script && !starts_with_colon) { if (ea.cmd > cmd) { @@ -1859,8 +1865,11 @@ do_one_cmd( } ea.cmd = cmd; - if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL) - goto doend; +#ifdef FEAT_EVAL + if (!starts_with_quote) +#endif + if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL) + goto doend; /* * 5. Parse the command. @@ -1880,7 +1889,7 @@ do_one_cmd( if (*ea.cmd == NUL || *ea.cmd == '"' #ifdef FEAT_EVAL || (*ea.cmd == '#' && ea.cmd[1] != '{' - && !starts_with_colon && in_vim9script()) + && !starts_with_colon && vim9script) #endif || (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL) { @@ -3223,26 +3232,34 @@ find_ex_command( * "lvar = value", "lvar(arg)", "[1, 2 3]->Func()" */ p = eap->cmd; - if (lookup != NULL && (*p == '(' || *p == '{' - || ((p = to_name_const_end(eap->cmd)) > eap->cmd && *p != NUL) - || *p == '[')) + if (lookup != NULL && (vim_strchr((char_u *)"{('[", *p) != NULL + || ((p = to_name_const_end(eap->cmd)) > eap->cmd + && *p != NUL))) { int oplen; int heredoc; - // "funcname(" is always a function call. - // "varname[]" is an expression. - // "g:varname" is an expression. - // "varname->expr" is an expression. - // "varname.expr" is an expression. - // "(..." is an expression. - // "{..." is an dict expression. - if (*p == '(' - || *p == '{' - || (*p == '[' && p > eap->cmd) - || p[1] == ':' - || (*p == '-' && p[1] == '>') - || (*p == '.' && ASCII_ISALPHA(p[1]))) + if ( + // "(..." is an expression. + // "funcname(" is always a function call. + *p == '(' + || (p == eap->cmd + ? ( + // "{..." is an dict expression. + *eap->cmd == '{' + // "'string'->func()" is an expression. + || *eap->cmd == '\'' + // "g:varname" is an expression. + || eap->cmd[1] == ':' + ) + : ( + // "varname[]" is an expression. + *p == '[' + // "varname->func()" is an expression. + || (*p == '-' && p[1] == '>') + // "varname.expr" is an expression. + || (*p == '.' && ASCII_ISALPHA(p[1])) + ))) { eap->cmdidx = CMD_eval; return eap->cmd; diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 82146756f..f9c5a2af2 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -355,6 +355,15 @@ def Test_vim9script_call() ("some")->MyFunc() assert_equal('some', var) + 'asdfasdf'->MyFunc() + assert_equal('asdfasdf', var) + + def UseString() + 'xyork'->MyFunc() + enddef + UseString() + assert_equal('xyork', var) + MyFunc( 'continued' ) diff --git a/src/version.c b/src/version.c index 42e6f79d3..44769fc50 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1218, /**/ 1217, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index 30a92ff3c..39190c972 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -7048,13 +7048,17 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx) /* * COMMAND after range + * 'text'->func() should not be confused with 'a mark */ cmd = ea.cmd; - ea.cmd = skip_range(ea.cmd, NULL); - if (ea.cmd > cmd && !starts_with_colon) + if (*cmd != '\'') { - emsg(_(e_colon_required)); - goto erret; + ea.cmd = skip_range(ea.cmd, NULL); + if (ea.cmd > cmd && !starts_with_colon) + { + emsg(_(e_colon_required)); + goto erret; + } } p = find_ex_command(&ea, NULL, starts_with_colon ? NULL : (void *(*)(char_u *, size_t, cctx_T *))lookup_local, -- 2.40.0