summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-01-15 20:18:55 +0000
committerBram Moolenaar <Bram@vim.org>2023-01-15 20:18:55 +0000
commit912bfee71041fce0902bbcb649faf247519ec400 (patch)
treeefebe3c414a8fd308658a26a8c72233471a6fdfc
parent32517c4c14ed3f9240fcd5b7c01d0ca2e586f7e4 (diff)
patch 9.0.1204: expression compiled the wrong way after using an objectv9.0.1204
Problem: Expression compiled the wrong way after using an object. Solution: Generate constants before getting the type.
-rw-r--r--src/testdir/test_vim9_class.vim19
-rw-r--r--src/version.c2
-rw-r--r--src/vim9expr.c65
3 files changed, 55 insertions, 31 deletions
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 28af68b386..83717eb5d3 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 f36b66651a..95b92e4a8d 100644
--- 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
index bbf3059e2b..6131f9fe60 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;