Skip to content

Commit

Permalink
patch 9.0.1204: expression compiled the wrong way after using an object
Browse files Browse the repository at this point in the history
Problem:    Expression compiled the wrong way after using an object.
Solution:   Generate constants before getting the type.
  • Loading branch information
brammool committed Jan 15, 2023
1 parent 32517c4 commit 912bfee
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 31 deletions.
19 changes: 19 additions & 0 deletions src/testdir/test_vim9_class.vim
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -695,6 +695,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1204,
/**/
1203,
/**/
Expand Down
65 changes: 34 additions & 31 deletions src/vim9expr.c
Expand Up @@ -2252,47 +2252,50 @@ 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
if (generate_ppconst(cctx, ppconst) == FAIL)
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;
Expand Down

0 comments on commit 912bfee

Please sign in to comment.