From 912bfee71041fce0902bbcb649faf247519ec400 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 15 Jan 2023 20:18:55 +0000 Subject: [PATCH] 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. --- src/testdir/test_vim9_class.vim | 19 ++++++++++ src/version.c | 2 + src/vim9expr.c | 65 +++++++++++++++++---------------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 28af68b38..83717eb5d 100644 --- 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 index f36b66651..95b92e4a8 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1204, /**/ 1203, /**/ diff --git a/src/vim9expr.c b/src/vim9expr.c index bbf3059e2..6131f9fe6 100644 --- 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)) - { - emsg(_(e_missing_name_after_dot)); - return FAIL; + if ((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; } - 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; -- 2.40.0