Patch 9.0.1334
Problem:    Using tt_member for the class leads to mistakes.
Solution:   Add a separate tt_class field.
Files:      src/structs.h, src/globals.h, src/vim9compile.c, src/vim9expr.c,
            src/vim9type.c, src/vim9class.c, src/evalfunc.c


*** ../vim-9.0.1333/src/structs.h       2023-02-20 12:16:33.340269410 +0000
--- src/structs.h       2023-02-20 20:45:56.884106740 +0000
***************
*** 1451,1457 ****
      int8_T        tt_min_argcount; // number of non-optional arguments
      char_u        tt_flags;       // TTFLAG_ values
      type_T        *tt_member;     // for list, dict, func return type
!                                   // for class: class_T
      type_T        **tt_args;      // func argument types, allocated
  };
  
--- 1451,1457 ----
      int8_T        tt_min_argcount; // number of non-optional arguments
      char_u        tt_flags;       // TTFLAG_ values
      type_T        *tt_member;     // for list, dict, func return type
!     class_T       *tt_class;      // for class and object
      type_T        **tt_args;      // func argument types, allocated
  };
  
*** ../vim-9.0.1333/src/globals.h       2023-01-20 18:49:42.763170966 +0000
--- src/globals.h       2023-02-20 20:55:02.051866937 +0000
***************
*** 538,705 ****
  #ifdef DO_INIT
  = {
      // 0: t_unknown
!     {VAR_UNKNOWN, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_UNKNOWN, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 2: t_any
!     {VAR_ANY, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_ANY, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 4: t_void
!     {VAR_VOID, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_VOID, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 6: t_bool
!     {VAR_BOOL, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_BOOL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 8: t_null
!     {VAR_SPECIAL, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_SPECIAL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 10: t_none
!     {VAR_SPECIAL, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_SPECIAL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 12: t_number
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 14: t_number_bool
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK, NULL, NULL},
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK|TTFLAG_CONST, NULL, NULL},
  
      // 16: t_number_float
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_FLOAT_OK, NULL, NULL},
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_FLOAT_OK|TTFLAG_CONST, NULL, 
NULL},
  
      // 18: t_float
!     {VAR_FLOAT, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_FLOAT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 20: t_string
!     {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 22: t_blob
!     {VAR_BLOB, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 24: t_blob_null
!     {VAR_BLOB, 0, 0, TTFLAG_STATIC, &t_void, NULL},
!     {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL},
  
      // 26: t_job
!     {VAR_JOB, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_JOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 28: t_channel
!     {VAR_CHANNEL, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_CHANNEL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 30: t_number_or_string
!     {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL},
!     {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL},
  
      // 32: t_func_unknown
!     {VAR_FUNC, -1, -1, TTFLAG_STATIC, &t_unknown, NULL},
!     {VAR_FUNC, -1, -1, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL},
  
      // 34: t_func_void
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_void, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL},
  
      // 36: t_func_any
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_any, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL},
  
      // 38: t_func_number
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_number, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL},
  
      // 40: t_func_string
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_string, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL},
  
      // 42: t_func_bool
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_bool, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL},
  
      // 44: t_func_0_void
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_void, NULL},
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL},
  
      // 46: t_func_0_any
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_any, NULL},
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL},
  
      // 48: t_func_0_number
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_number, NULL},
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL},
  
      // 50: t_func_0_string
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_string, NULL},
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL},
  
      // 52: t_list_any
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_any, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL},
  
      // 54: t_dict_any
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_any, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL},
  
      // 56: t_list_empty
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_unknown, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL},
  
      // 58: t_dict_empty
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_unknown, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL},
  
      // 60: t_list_bool
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_bool, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL},
  
      // 62: t_list_number
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_number, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL},
  
      // 64: t_list_string
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_string, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL},
  
      // 66: t_list_job
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_job, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_job, NULL},
  
      // 68: t_list_dict_any
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_dict_any, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_dict_any, NULL},
  
      // 70: t_list_list_any
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_any, NULL},
  
      // 72: t_list_list_string
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_string, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_string, NULL},
  
      // 74: t_dict_bool
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL},
  
      // 76: t_dict_number
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL},
  
      // 78: t_dict_string
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_string, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL},
  
      // 80: t_super (VAR_CLASS with tt_member set to &t_bool
!     {VAR_CLASS, 0, 0, TTFLAG_STATIC, &t_bool, NULL},
!     {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL},
  }
  #endif
  ;
--- 538,705 ----
  #ifdef DO_INIT
  = {
      // 0: t_unknown
!     {VAR_UNKNOWN, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_UNKNOWN, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 2: t_any
!     {VAR_ANY, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_ANY, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 4: t_void
!     {VAR_VOID, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_VOID, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 6: t_bool
!     {VAR_BOOL, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_BOOL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 8: t_null
!     {VAR_SPECIAL, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_SPECIAL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 10: t_none
!     {VAR_SPECIAL, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_SPECIAL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 12: t_number
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 14: t_number_bool
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK, NULL, NULL, NULL},
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK|TTFLAG_CONST, NULL, NULL, 
NULL},
  
      // 16: t_number_float
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_FLOAT_OK, NULL, NULL, NULL},
!     {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_FLOAT_OK|TTFLAG_CONST, NULL, 
NULL, NULL},
  
      // 18: t_float
!     {VAR_FLOAT, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_FLOAT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 20: t_string
!     {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 22: t_blob
!     {VAR_BLOB, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 24: t_blob_null
!     {VAR_BLOB, 0, 0, TTFLAG_STATIC, &t_void, NULL, NULL},
!     {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL, NULL},
  
      // 26: t_job
!     {VAR_JOB, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_JOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 28: t_channel
!     {VAR_CHANNEL, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_CHANNEL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 30: t_number_or_string
!     {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL},
!     {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL},
  
      // 32: t_func_unknown
!     {VAR_FUNC, -1, -1, TTFLAG_STATIC, &t_unknown, NULL, NULL},
!     {VAR_FUNC, -1, -1, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL, NULL},
  
      // 34: t_func_void
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_void, NULL, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL, NULL},
  
      // 36: t_func_any
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_any, NULL, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL, NULL},
  
      // 38: t_func_number
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_number, NULL, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL, NULL},
  
      // 40: t_func_string
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_string, NULL, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL, NULL},
  
      // 42: t_func_bool
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_bool, NULL, NULL},
!     {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL},
  
      // 44: t_func_0_void
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_void, NULL, NULL},
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL, NULL},
  
      // 46: t_func_0_any
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_any, NULL, NULL},
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL, NULL},
  
      // 48: t_func_0_number
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_number, NULL, NULL},
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL, NULL},
  
      // 50: t_func_0_string
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_string, NULL, NULL},
!     {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL, NULL},
  
      // 52: t_list_any
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_any, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL, NULL},
  
      // 54: t_dict_any
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_any, NULL, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL, NULL},
  
      // 56: t_list_empty
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_unknown, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL, NULL},
  
      // 58: t_dict_empty
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_unknown, NULL, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL, NULL},
  
      // 60: t_list_bool
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL},
  
      // 62: t_list_number
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_number, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL, NULL},
  
      // 64: t_list_string
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_string, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL, NULL},
  
      // 66: t_list_job
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_job, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_job, NULL, NULL},
  
      // 68: t_list_dict_any
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_dict_any, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_dict_any, NULL, NULL},
  
      // 70: t_list_list_any
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_any, NULL, NULL},
  
      // 72: t_list_list_string
!     {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_string, NULL, NULL},
!     {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_string, NULL, NULL},
  
      // 74: t_dict_bool
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL},
  
      // 76: t_dict_number
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL, NULL},
  
      // 78: t_dict_string
!     {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_string, NULL, NULL},
!     {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL, NULL},
  
      // 80: t_super (VAR_CLASS with tt_member set to &t_bool
!     {VAR_CLASS, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL},
!     {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL},
  }
  #endif
  ;
*** ../vim-9.0.1333/src/vim9compile.c   2023-02-18 18:38:33.375180762 +0000
--- src/vim9compile.c   2023-02-21 12:36:11.571449569 +0000
***************
*** 333,339 ****
  
  /*
   * Return TRUE if "name" is a local variable, argument, script variable or
!  * imported.
   */
      static int
  variable_exists(char_u *name, size_t len, cctx_T *cctx)
--- 333,339 ----
  
  /*
   * Return TRUE if "name" is a local variable, argument, script variable or
!  * imported.  Also if "name" is "this" and in a class method.
   */
      static int
  variable_exists(char_u *name, size_t len, cctx_T *cctx)
***************
*** 1848,1867 ****
            lhs->lhs_type = &t_any;
        }
  
!       if (lhs->lhs_type == NULL || lhs->lhs_type->tt_member == NULL)
            lhs->lhs_member_type = &t_any;
!       else if (lhs->lhs_type->tt_type == VAR_CLASS
!               || lhs->lhs_type->tt_type == VAR_OBJECT)
        {
            // for an object or class member get the type of the member
!           class_T *cl = (class_T *)lhs->lhs_type->tt_member;
            lhs->lhs_member_type = class_member_type(cl, after + 1,
                                           lhs->lhs_end, &lhs->lhs_member_idx);
            if (lhs->lhs_member_idx < 0)
                return FAIL;
        }
        else
            lhs->lhs_member_type = lhs->lhs_type->tt_member;
      }
      return OK;
  }
--- 1848,1874 ----
            lhs->lhs_type = &t_any;
        }
  
!       int use_class = lhs->lhs_type->tt_type == VAR_CLASS
!                                      || lhs->lhs_type->tt_type == VAR_OBJECT;
!       if (lhs->lhs_type == NULL
!               || (use_class ? lhs->lhs_type->tt_class == NULL
!                                          : lhs->lhs_type->tt_member == NULL))
!       {
            lhs->lhs_member_type = &t_any;
!       }
!       else if (use_class)
        {
            // for an object or class member get the type of the member
!           class_T *cl = lhs->lhs_type->tt_class;
            lhs->lhs_member_type = class_member_type(cl, after + 1,
                                           lhs->lhs_end, &lhs->lhs_member_idx);
            if (lhs->lhs_member_idx < 0)
                return FAIL;
        }
        else
+       {
            lhs->lhs_member_type = lhs->lhs_type->tt_member;
+       }
      }
      return OK;
  }
***************
*** 2059,2065 ****
      {
        // "this.value": load "this" object and get the value at index
        // for an object or class member get the type of the member
!       class_T *cl = (class_T *)lhs->lhs_type->tt_member;
        type_T *type = class_member_type(cl, var_start + 5,
                                           lhs->lhs_end, &lhs->lhs_member_idx);
        if (lhs->lhs_member_idx < 0)
--- 2066,2072 ----
      {
        // "this.value": load "this" object and get the value at index
        // for an object or class member get the type of the member
!       class_T *cl = lhs->lhs_type->tt_class;
        type_T *type = class_member_type(cl, var_start + 5,
                                           lhs->lhs_end, &lhs->lhs_member_idx);
        if (lhs->lhs_member_idx < 0)
***************
*** 2194,2200 ****
  
                if (dest_type == VAR_OBJECT)
                {
!                   class_T *cl = (class_T *)lhs->lhs_type->tt_member;
  
                    if (cl->class_flags & CLASS_INTERFACE)
                    {
--- 2201,2207 ----
  
                if (dest_type == VAR_OBJECT)
                {
!                   class_T *cl = lhs->lhs_type->tt_class;
  
                    if (cl->class_flags & CLASS_INTERFACE)
                    {
*** ../vim-9.0.1333/src/vim9expr.c      2023-02-18 19:49:28.126600526 +0000
--- src/vim9expr.c      2023-02-20 20:47:57.432005338 +0000
***************
*** 263,269 ****
        return FAIL;
      }
  
!     class_T *cl = (class_T *)type->tt_member;
      int is_super = type->tt_flags & TTFLAG_SUPER;
      if (type == &t_super)
      {
--- 263,269 ----
        return FAIL;
      }
  
!     class_T *cl = type->tt_class;
      int is_super = type->tt_flags & TTFLAG_SUPER;
      if (type == &t_super)
      {
*** ../vim-9.0.1333/src/vim9type.c      2023-02-18 14:42:40.113005575 +0000
--- src/vim9type.c      2023-02-20 21:58:37.255794651 +0000
***************
*** 86,96 ****
      ((type_T **)seen_types->ga_data)[seen_types->ga_len * 2 + 1] = copy;
      ++seen_types->ga_len;
  
!     if (copy->tt_member != NULL
!           && copy->tt_type != VAR_OBJECT && copy->tt_type != VAR_CLASS)
        copy->tt_member = copy_type_deep_rec(copy->tt_member,
                                                         type_gap, seen_types);
- 
      if (type->tt_args != NULL)
        for (int i = 0; i < type->tt_argcount; ++i)
            copy->tt_args[i] = copy_type_deep_rec(copy->tt_args[i],
--- 86,94 ----
      ((type_T **)seen_types->ga_data)[seen_types->ga_len * 2 + 1] = copy;
      ++seen_types->ga_len;
  
!     if (copy->tt_member != NULL)
        copy->tt_member = copy_type_deep_rec(copy->tt_member,
                                                         type_gap, seen_types);
      if (type->tt_args != NULL)
        for (int i = 0; i < type->tt_argcount; ++i)
            copy->tt_args[i] = copy_type_deep_rec(copy->tt_args[i],
***************
*** 144,154 ****
      *ret = *type;
  
      if (ret->tt_member != NULL)
!     {
!       // tt_member points to the class_T for VAR_CLASS and VAR_OBJECT
!       if (type->tt_type != VAR_CLASS && type->tt_type != VAR_OBJECT)
!           ret->tt_member = alloc_type(ret->tt_member);
!     }
  
      if (type->tt_args != NULL)
      {
--- 142,148 ----
      *ret = *type;
  
      if (ret->tt_member != NULL)
!       ret->tt_member = alloc_type(ret->tt_member);
  
      if (type->tt_args != NULL)
      {
***************
*** 180,188 ****
        vim_free(type->tt_args);
      }
  
!     // for an object and class tt_member is a pointer to the class
!     if (type->tt_type != VAR_OBJECT && type->tt_type != VAR_CLASS)
!       free_type(type->tt_member);
  
      vim_free(type);
  }
--- 174,180 ----
        vim_free(type->tt_args);
      }
  
!     free_type(type->tt_member);
  
      vim_free(type);
  }
***************
*** 419,424 ****
--- 411,417 ----
  {
      type_T  *type;
      type_T  *member_type = NULL;
+     class_T *class_type = NULL;
      int           argcount = 0;
      int           min_argcount = 0;
  
***************
*** 584,592 ****
      }
  
      if (tv->v_type == VAR_CLASS)
!       member_type = (type_T *)tv->vval.v_class;
      else if (tv->v_type == VAR_OBJECT && tv->vval.v_object != NULL)
!       member_type = (type_T *)tv->vval.v_object->obj_class;
  
      type = get_type_ptr(type_gap);
      if (type == NULL)
--- 577,585 ----
      }
  
      if (tv->v_type == VAR_CLASS)
!       class_type = tv->vval.v_class;
      else if (tv->v_type == VAR_OBJECT && tv->vval.v_object != NULL)
!       class_type = tv->vval.v_object->obj_class;
  
      type = get_type_ptr(type_gap);
      if (type == NULL)
***************
*** 601,606 ****
--- 594,600 ----
        type->tt_min_argcount -= tv->vval.v_partial->pt_argc;
      }
      type->tt_member = member_type;
+     type->tt_class = class_type;
  
      return type;
  }
***************
*** 887,905 ****
            if (actual->tt_type == VAR_ANY)
                return MAYBE;   // use runtime type check
            if (actual->tt_type != VAR_OBJECT)
!               return FAIL;    // don't use tt_member
  
            // check the class, base class or an implemented interface matches
            class_T *cl;
!           for (cl = (class_T *)actual->tt_member; cl != NULL;
!                                                       cl = cl->class_extends)
            {
!               if ((class_T *)expected->tt_member == cl)
                    break;
                int i;
                for (i = cl->class_interface_count - 1; i >= 0; --i)
!                   if ((class_T *)expected->tt_member
!                                                == cl->class_interfaces_cl[i])
                        break;
                if (i >= 0)
                    break;
--- 881,897 ----
            if (actual->tt_type == VAR_ANY)
                return MAYBE;   // use runtime type check
            if (actual->tt_type != VAR_OBJECT)
!               return FAIL;    // don't use tt_class
  
            // check the class, base class or an implemented interface matches
            class_T *cl;
!           for (cl = actual->tt_class; cl != NULL; cl = cl->class_extends)
            {
!               if (expected->tt_class == cl)
                    break;
                int i;
                for (i = cl->class_interface_count - 1; i >= 0; --i)
!                   if (expected->tt_class == cl->class_interfaces_cl[i])
                        break;
                if (i >= 0)
                    break;
***************
*** 1321,1327 ****
                // Although the name is that of a class or interface, the type
                // uses will be an object.
                type->tt_type = VAR_OBJECT;
!               type->tt_member = (type_T *)tv.vval.v_class;
                clear_tv(&tv);
  
                *arg += len;
--- 1313,1319 ----
                // Although the name is that of a class or interface, the type
                // uses will be an object.
                type->tt_type = VAR_OBJECT;
!               type->tt_class = tv.vval.v_class;
                clear_tv(&tv);
  
                *arg += len;
***************
*** 1659,1666 ****
  
      if (type->tt_type == VAR_OBJECT || type->tt_type == VAR_CLASS)
      {
!       char_u *class_name = type->tt_member == NULL ? (char_u *)"Unknown"
!                                   : ((class_T *)type->tt_member)->class_name;
        size_t len = STRLEN(name) + STRLEN(class_name) + 3;
        *tofree = alloc(len);
        if (*tofree != NULL)
--- 1651,1658 ----
  
      if (type->tt_type == VAR_OBJECT || type->tt_type == VAR_CLASS)
      {
!       char_u *class_name = type->tt_class == NULL ? (char_u *)"Unknown"
!                                   : type->tt_class->class_name;
        size_t len = STRLEN(name) + STRLEN(class_name) + 3;
        *tofree = alloc(len);
        if (*tofree != NULL)
*** ../vim-9.0.1333/src/vim9class.c     2023-02-17 21:08:46.433731097 +0000
--- src/vim9class.c     2023-02-20 20:49:58.847906348 +0000
***************
*** 990,996 ****
                if (nf->uf_ret_type != NULL)
                {
                    nf->uf_ret_type->tt_type = VAR_OBJECT;
!                   nf->uf_ret_type->tt_member = (type_T *)cl;
                    nf->uf_ret_type->tt_argcount = 0;
                    nf->uf_ret_type->tt_args = NULL;
                }
--- 990,996 ----
                if (nf->uf_ret_type != NULL)
                {
                    nf->uf_ret_type->tt_type = VAR_OBJECT;
!                   nf->uf_ret_type->tt_class = cl;
                    nf->uf_ret_type->tt_argcount = 0;
                    nf->uf_ret_type->tt_args = NULL;
                }
***************
*** 1083,1091 ****
        }
  
        cl->class_type.tt_type = VAR_CLASS;
!       cl->class_type.tt_member = (type_T *)cl;
        cl->class_object_type.tt_type = VAR_OBJECT;
!       cl->class_object_type.tt_member = (type_T *)cl;
        cl->class_type_list = type_list;
  
        // TODO:
--- 1083,1091 ----
        }
  
        cl->class_type.tt_type = VAR_CLASS;
!       cl->class_type.tt_class = cl;
        cl->class_object_type.tt_type = VAR_OBJECT;
!       cl->class_object_type.tt_class = cl;
        cl->class_type_list = type_list;
  
        // TODO:
*** ../vim-9.0.1333/src/evalfunc.c      2023-02-20 12:16:33.328269404 +0000
--- src/evalfunc.c      2023-02-20 20:52:20.847793601 +0000
***************
*** 585,591 ****
  {
      type_T *expected_member = NULL;
      type_T *(args[2]);
!     type_T t_func_exp = {VAR_FUNC, 2, 0, 0, NULL, args};
  
      if (context->arg_types[0].type_curr->tt_type == VAR_LIST
            || context->arg_types[0].type_curr->tt_type == VAR_DICT)
--- 585,591 ----
  {
      type_T *expected_member = NULL;
      type_T *(args[2]);
!     type_T t_func_exp = {VAR_FUNC, 2, 0, 0, NULL, NULL, args};
  
      if (context->arg_types[0].type_curr->tt_type == VAR_LIST
            || context->arg_types[0].type_curr->tt_type == VAR_DICT)
***************
*** 699,705 ****
      if (type->tt_type == VAR_FUNC)
      {
        type_T *(args[2]);
!       type_T t_func_exp = {VAR_FUNC, 2, 0, 0, &t_number, args};
  
        if (context->arg_types[0].type_curr->tt_type == VAR_LIST)
            args[0] = context->arg_types[0].type_curr->tt_member;
--- 699,705 ----
      if (type->tt_type == VAR_FUNC)
      {
        type_T *(args[2]);
!       type_T t_func_exp = {VAR_FUNC, 2, 0, 0, &t_number, NULL, args};
  
        if (context->arg_types[0].type_curr->tt_type == VAR_LIST)
            args[0] = context->arg_types[0].type_curr->tt_member;
*** ../vim-9.0.1333/src/version.c       2023-02-20 18:44:29.594912053 +0000
--- src/version.c       2023-02-20 20:58:18.712177093 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1334,
  /**/

-- 
Send $25.00 for handy leaflet on how to make money by selling leaflets

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20230221123917.8EA581C07A0%40moolenaar.net.

Raspunde prin e-mail lui