Patch 8.2.1067
Problem:    Expression "!expr->func()" does not work.
Solution:   Apply plus and minus earlier. (closes #6348)
Files:      src/eval.c, src/proto/eval.pro, src/evalvars.c, src/userfunc.c,
            src/testdir/test_expr.vim, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.1066/src/eval.c  2020-06-26 22:46:23.229370947 +0200
--- src/eval.c  2020-06-27 12:55:24.069015504 +0200
***************
*** 51,57 ****
  static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
  static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int 
want_string);
  static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int 
want_string);
! static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u 
**end_leaderp);
  
  static int free_unref_items(int copyID);
  static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, 
char_u *expr_end, char_u *in_end);
--- 51,57 ----
  static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
  static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int 
want_string);
  static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int 
want_string);
! static int eval7_leader(typval_T *rettv, int numeric_only, char_u 
*start_leader, char_u **end_leaderp);
  
  static int free_unref_items(int copyID);
  static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, 
char_u *expr_end, char_u *in_end);
***************
*** 2756,2761 ****
--- 2756,2766 ----
      case '8':
      case '9':
      case '.': ret = get_number_tv(arg, rettv, evaluate, want_string);
+ 
+               // Apply prefixed "-" and "+" now.  Matters especially when
+               // "->" follows.
+               if (ret == OK && evaluate && end_leader > start_leader)
+                   ret = eval7_leader(rettv, TRUE, start_leader, &end_leader);
                break;
  
      /*
***************
*** 2879,2901 ****
      // Handle following '[', '(' and '.' for expr[expr], expr.name,
      // expr(expr), expr->name(expr)
      if (ret == OK)
!       ret = handle_subscript(arg, rettv, flags, TRUE,
!                                                   start_leader, &end_leader);
  
      /*
       * Apply logical NOT and unary '-', from right to left, ignore '+'.
       */
      if (ret == OK && evaluate && end_leader > start_leader)
!       ret = eval7_leader(rettv, start_leader, &end_leader);
      return ret;
  }
  
  /*
   * Apply the leading "!" and "-" before an eval7 expression to "rettv".
   * Adjusts "end_leaderp" until it is at "start_leader".
   */
      static int
! eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp)
  {
      char_u    *end_leader = *end_leaderp;
      int               ret = OK;
--- 2884,2910 ----
      // Handle following '[', '(' and '.' for expr[expr], expr.name,
      // expr(expr), expr->name(expr)
      if (ret == OK)
!       ret = handle_subscript(arg, rettv, flags, TRUE);
  
      /*
       * Apply logical NOT and unary '-', from right to left, ignore '+'.
       */
      if (ret == OK && evaluate && end_leader > start_leader)
!       ret = eval7_leader(rettv, FALSE, start_leader, &end_leader);
      return ret;
  }
  
  /*
   * Apply the leading "!" and "-" before an eval7 expression to "rettv".
+  * When "numeric_only" is TRUE only handle "+" and "-".
   * Adjusts "end_leaderp" until it is at "start_leader".
   */
      static int
! eval7_leader(
!       typval_T    *rettv,
!       int         numeric_only,
!       char_u      *start_leader,
!       char_u      **end_leaderp)
  {
      char_u    *end_leader = *end_leaderp;
      int               ret = OK;
***************
*** 2921,2926 ****
--- 2930,2940 ----
            --end_leader;
            if (*end_leader == '!')
            {
+               if (numeric_only)
+               {
+                   ++end_leader;
+                   break;
+               }
  #ifdef FEAT_FLOAT
                if (rettv->v_type == VAR_FLOAT)
                    f = !f;
***************
*** 4871,4879 ****
      char_u    **arg,
      typval_T  *rettv,
      int               flags,          // do more than finding the end
!     int               verbose,        // give error messages
!     char_u    *start_leader,  // start of '!' and '-' prefixes
!     char_u    **end_leaderp)  // end of '!' and '-' prefixes
  {
      int               evaluate = flags & EVAL_EVALUATE;
      int               ret = OK;
--- 4885,4891 ----
      char_u    **arg,
      typval_T  *rettv,
      int               flags,          // do more than finding the end
!     int               verbose)        // give error messages
  {
      int               evaluate = flags & EVAL_EVALUATE;
      int               ret = OK;
***************
*** 4910,4919 ****
        }
        else if (**arg == '-')
        {
-           // Expression "-1.0->method()" applies the leader "-" before
-           // applying ->.
-           if (evaluate && *end_leaderp > start_leader)
-               ret = eval7_leader(rettv, start_leader, end_leaderp);
            if (ret == OK)
            {
                if ((*arg)[2] == '{')
--- 4922,4927 ----
*** ../vim-8.2.1066/src/proto/eval.pro  2020-06-26 22:46:23.233370940 +0200
--- src/proto/eval.pro  2020-06-27 12:57:32.324317482 +0200
***************
*** 53,59 ****
  char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, 
int flags);
  int eval_isnamec(int c);
  int eval_isnamec1(int c);
! int handle_subscript(char_u **arg, typval_T *rettv, int flags, int verbose, 
char_u *start_leader, char_u **end_leaderp);
  int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
  void echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr);
  void ex_echo(exarg_T *eap);
--- 53,59 ----
  char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, 
int flags);
  int eval_isnamec(int c);
  int eval_isnamec1(int c);
! int handle_subscript(char_u **arg, typval_T *rettv, int flags, int verbose);
  int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
  void echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr);
  void ex_echo(exarg_T *eap);
*** ../vim-8.2.1066/src/evalvars.c      2020-06-24 20:33:59.565106319 +0200
--- src/evalvars.c      2020-06-27 12:57:09.224406396 +0200
***************
*** 1125,1132 ****
                {
                    // handle d.key, l[idx], f(expr)
                    arg_subsc = arg;
!                   if (handle_subscript(&arg, &tv, EVAL_EVALUATE, TRUE,
!                                                         name, &name) == FAIL)
                        error = TRUE;
                    else
                    {
--- 1125,1132 ----
                {
                    // handle d.key, l[idx], f(expr)
                    arg_subsc = arg;
!                   if (handle_subscript(&arg, &tv, EVAL_EVALUATE, TRUE)
!                                                                      == FAIL)
                        error = TRUE;
                    else
                    {
***************
*** 3341,3348 ****
        if (n)
        {
            // handle d.key, l[idx], f(expr)
!           n = (handle_subscript(&var, &tv, EVAL_EVALUATE,
!                                                   FALSE, name, &name) == OK);
            if (n)
                clear_tv(&tv);
        }
--- 3341,3347 ----
        if (n)
        {
            // handle d.key, l[idx], f(expr)
!           n = (handle_subscript(&var, &tv, EVAL_EVALUATE, FALSE) == OK);
            if (n)
                clear_tv(&tv);
        }
*** ../vim-8.2.1066/src/userfunc.c      2020-06-25 19:27:53.036387595 +0200
--- src/userfunc.c      2020-06-27 12:57:16.540376614 +0200
***************
*** 3926,3932 ****
  
        // Handle a function returning a Funcref, Dictionary or List.
        if (handle_subscript(&arg, &rettv, eap->skip ? 0 : EVAL_EVALUATE,
!                                                   TRUE, name, &name) == FAIL)
        {
            failed = TRUE;
            break;
--- 3926,3932 ----
  
        // Handle a function returning a Funcref, Dictionary or List.
        if (handle_subscript(&arg, &rettv, eap->skip ? 0 : EVAL_EVALUATE,
!                                                                TRUE) == FAIL)
        {
            failed = TRUE;
            break;
*** ../vim-8.2.1066/src/testdir/test_expr.vim   2020-04-26 15:59:51.202952140 
+0200
--- src/testdir/test_expr.vim   2020-06-27 13:06:47.393393602 +0200
***************
*** 110,115 ****
--- 110,122 ----
    call assert_fails('echo "\<C-">')
  endfunc
  
+ func Test_method_with_prefix()
+   call assert_equal(1, !range(5)->empty())
+   call assert_equal([0, 1, 2], --3->range())
+   call assert_equal(0, !-3)
+   call assert_equal(1, !+-+0)
+ endfunc
+ 
  func Test_option_value()
    " boolean
    set bri
*** ../vim-8.2.1066/src/testdir/test_vim9_expr.vim      2020-06-26 
22:46:23.233370940 +0200
--- src/testdir/test_vim9_expr.vim      2020-06-27 13:09:21.730382191 +0200
***************
*** 1081,1086 ****
--- 1081,1088 ----
    assert_equal(6, --6)
    assert_equal(6, -+-6)
    assert_equal(-6, ---6)
+   assert_equal(false, !-3)
+   assert_equal(true, !+-+0)
  enddef
  
  def Test_expr7_negate()
***************
*** 1102,1107 ****
--- 1104,1111 ----
  def Test_expr7_call()
    assert_equal('yes', 'yes'->Echo())
    assert_equal('yes', 'yes'->s:EchoArg())
+   assert_equal(1, !range(5)->empty())
+   assert_equal([0, 1, 2], --3->range())
  
    call CheckDefFailure(["let x = 'yes'->Echo"], 'E107:')
  enddef
*** ../vim-8.2.1066/src/version.c       2020-06-27 12:32:54.315608887 +0200
--- src/version.c       2020-06-27 13:10:01.210663462 +0200
***************
*** 756,757 ****
--- 756,759 ----
  {   /* Add new patch number below this line */
+ /**/
+     1067,
  /**/

-- 
If you only have a hammer, you tend to see every problem as a nail.
If you only have MS-Windows, you tend to solve every problem by rebooting.

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202006271112.05RBCGaY019969%40masaka.moolenaar.net.

Raspunde prin e-mail lui