# HG changeset patch # User Bram Moolenaar # Date 1673814603 -3600 # Node ID 1b2bde0c64f2db16aef3091455497bae2334d0da # Parent 3ebf441d9f888354748f5b936927d363f0d09620 patch 9.0.1204: expression compiled the wrong way after using an object Commit: https://github.com/vim/vim/commit/912bfee71041fce0902bbcb649faf247519ec400 Author: Bram Moolenaar Date: Sun Jan 15 20:18:55 2023 +0000 patch 9.0.1204: expression compiled the wrong way after using an object Problem: Expression compiled the wrong way after using an object. Solution: Generate constants before getting the type. diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -240,6 +240,25 @@ def Test_list_of_objects() v9.CheckScriptSuccess(lines) enddef +def Test_expr_after_using_object() + var lines =<< trim END + vim9script + + class Something + this.label: string = '' + endclass + + def Foo(): Something + var v = Something.new() + echo 'in Foo(): ' .. typename(v) + return v + enddef + + Foo() + END + v9.CheckScriptSuccess(lines) +enddef + def Test_class_default_new() var lines =<< trim END vim9script diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1204, +/**/ 1203, /**/ 1202, diff --git a/src/vim9expr.c b/src/vim9expr.c --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -2252,19 +2252,6 @@ compile_subscript( if (compile_member(is_slice, &keeping_dict, cctx) == FAIL) return FAIL; } - else if (*p == '.' - && (type = get_type_on_stack(cctx, 0)) != &t_unknown - && (type->tt_type == VAR_CLASS || type->tt_type == VAR_OBJECT)) - { - // class member: SomeClass.varname - // class method: SomeClass.SomeMethod() - // class constructor: SomeClass.new() - // object member: someObject.varname, this.varname - // object method: someObject.SomeMethod(), this.SomeMethod() - *arg = p; - if (compile_class_object_index(cctx, arg, type) == FAIL) - return FAIL; - } else if (*p == '.' && p[1] != '.') { // dictionary member: dict.name @@ -2272,27 +2259,43 @@ compile_subscript( return FAIL; ppconst->pp_is_const = FALSE; - *arg = p + 1; - if (IS_WHITE_OR_NUL(**arg)) + if ((type = get_type_on_stack(cctx, 0)) != &t_unknown + && (type->tt_type == VAR_CLASS + || type->tt_type == VAR_OBJECT)) { - emsg(_(e_missing_name_after_dot)); - return FAIL; + // class member: SomeClass.varname + // class method: SomeClass.SomeMethod() + // class constructor: SomeClass.new() + // object member: someObject.varname, this.varname + // object method: someObject.SomeMethod(), this.SomeMethod() + *arg = p; + if (compile_class_object_index(cctx, arg, type) == FAIL) + return FAIL; } - p = *arg; - if (eval_isdictc(*p)) - while (eval_isnamec(*p)) - MB_PTR_ADV(p); - if (p == *arg) + else { - semsg(_(e_syntax_error_at_str), *arg); - return FAIL; + *arg = p + 1; + if (IS_WHITE_OR_NUL(**arg)) + { + emsg(_(e_missing_name_after_dot)); + return FAIL; + } + p = *arg; + if (eval_isdictc(*p)) + while (eval_isnamec(*p)) + MB_PTR_ADV(p); + if (p == *arg) + { + semsg(_(e_syntax_error_at_str), *arg); + return FAIL; + } + if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL) + return FAIL; + if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL) + return FAIL; + keeping_dict = TRUE; + *arg = p; } - if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL) - return FAIL; - if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL) - return FAIL; - keeping_dict = TRUE; - *arg = p; } else break;