Skip to content

Commit 912bfee

Browse files
committed
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.
1 parent 32517c4 commit 912bfee

3 files changed

Lines changed: 55 additions & 31 deletions

File tree

src/testdir/test_vim9_class.vim

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,25 @@ def Test_list_of_objects()
240240
v9.CheckScriptSuccess(lines)
241241
enddef
242242

243+
def Test_expr_after_using_object()
244+
var lines =<< trim END
245+
vim9script
246+
247+
class Something
248+
this.label: string = ''
249+
endclass
250+
251+
def Foo(): Something
252+
var v = Something.new()
253+
echo 'in Foo(): ' .. typename(v)
254+
return v
255+
enddef
256+
257+
Foo()
258+
END
259+
v9.CheckScriptSuccess(lines)
260+
enddef
261+
243262
def Test_class_default_new()
244263
var lines =<< trim END
245264
vim9script

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
1204,
698700
/**/
699701
1203,
700702
/**/

src/vim9expr.c

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,47 +2252,50 @@ compile_subscript(
22522252
if (compile_member(is_slice, &keeping_dict, cctx) == FAIL)
22532253
return FAIL;
22542254
}
2255-
else if (*p == '.'
2256-
&& (type = get_type_on_stack(cctx, 0)) != &t_unknown
2257-
&& (type->tt_type == VAR_CLASS || type->tt_type == VAR_OBJECT))
2258-
{
2259-
// class member: SomeClass.varname
2260-
// class method: SomeClass.SomeMethod()
2261-
// class constructor: SomeClass.new()
2262-
// object member: someObject.varname, this.varname
2263-
// object method: someObject.SomeMethod(), this.SomeMethod()
2264-
*arg = p;
2265-
if (compile_class_object_index(cctx, arg, type) == FAIL)
2266-
return FAIL;
2267-
}
22682255
else if (*p == '.' && p[1] != '.')
22692256
{
22702257
// dictionary member: dict.name
22712258
if (generate_ppconst(cctx, ppconst) == FAIL)
22722259
return FAIL;
22732260
ppconst->pp_is_const = FALSE;
22742261

2275-
*arg = p + 1;
2276-
if (IS_WHITE_OR_NUL(**arg))
2277-
{
2278-
emsg(_(e_missing_name_after_dot));
2279-
return FAIL;
2262+
if ((type = get_type_on_stack(cctx, 0)) != &t_unknown
2263+
&& (type->tt_type == VAR_CLASS
2264+
|| type->tt_type == VAR_OBJECT))
2265+
{
2266+
// class member: SomeClass.varname
2267+
// class method: SomeClass.SomeMethod()
2268+
// class constructor: SomeClass.new()
2269+
// object member: someObject.varname, this.varname
2270+
// object method: someObject.SomeMethod(), this.SomeMethod()
2271+
*arg = p;
2272+
if (compile_class_object_index(cctx, arg, type) == FAIL)
2273+
return FAIL;
22802274
}
2281-
p = *arg;
2282-
if (eval_isdictc(*p))
2283-
while (eval_isnamec(*p))
2284-
MB_PTR_ADV(p);
2285-
if (p == *arg)
2275+
else
22862276
{
2287-
semsg(_(e_syntax_error_at_str), *arg);
2288-
return FAIL;
2277+
*arg = p + 1;
2278+
if (IS_WHITE_OR_NUL(**arg))
2279+
{
2280+
emsg(_(e_missing_name_after_dot));
2281+
return FAIL;
2282+
}
2283+
p = *arg;
2284+
if (eval_isdictc(*p))
2285+
while (eval_isnamec(*p))
2286+
MB_PTR_ADV(p);
2287+
if (p == *arg)
2288+
{
2289+
semsg(_(e_syntax_error_at_str), *arg);
2290+
return FAIL;
2291+
}
2292+
if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL)
2293+
return FAIL;
2294+
if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL)
2295+
return FAIL;
2296+
keeping_dict = TRUE;
2297+
*arg = p;
22892298
}
2290-
if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL)
2291-
return FAIL;
2292-
if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL)
2293-
return FAIL;
2294-
keeping_dict = TRUE;
2295-
*arg = p;
22962299
}
22972300
else
22982301
break;

0 commit comments

Comments
 (0)