mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.0.1211: storing value in interface member does not always work
Problem: Storing value in interface member does not always work. Solution: Convert the index on the interface to the index on the object.
This commit is contained in:
parent
b391e1f805
commit
f7d1c6e188
@ -876,14 +876,14 @@ def Test_class_implements_interface()
|
||||
vim9script
|
||||
|
||||
interface Result
|
||||
this.label: string
|
||||
public this.label: string
|
||||
this.errpos: number
|
||||
endinterface
|
||||
|
||||
# order of members is opposite of interface
|
||||
class Failure implements Result
|
||||
this.errpos: number = 42
|
||||
this.label: string = 'label'
|
||||
public this.label: string = 'label'
|
||||
endclass
|
||||
|
||||
def Test()
|
||||
@ -891,6 +891,10 @@ def Test_class_implements_interface()
|
||||
|
||||
assert_equal('label', result.label)
|
||||
assert_equal(42, result.errpos)
|
||||
|
||||
result.label = 'different'
|
||||
assert_equal('different', result.label)
|
||||
assert_equal(42, result.errpos)
|
||||
enddef
|
||||
|
||||
Test()
|
||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1211,
|
||||
/**/
|
||||
1210,
|
||||
/**/
|
||||
|
10
src/vim9.h
10
src/vim9.h
@ -78,8 +78,8 @@ typedef enum {
|
||||
// ISN_STOREOTHER, // pop into other script variable isn_arg.other.
|
||||
|
||||
ISN_STORENR, // store number into local variable isn_arg.storenr.stnr_idx
|
||||
ISN_STOREINDEX, // store into list or dictionary, type isn_arg.vartype,
|
||||
// value/index/variable on stack
|
||||
ISN_STOREINDEX, // store into list or dictionary, using
|
||||
// isn_arg.storeindex; value/index/variable on stack
|
||||
ISN_STORERANGE, // store into blob,
|
||||
// value/index 1/index 2/variable on stack
|
||||
|
||||
@ -486,6 +486,11 @@ typedef struct {
|
||||
class_T *cm_class;
|
||||
int cm_idx;
|
||||
} classmember_T;
|
||||
// arguments to ISN_STOREINDEX
|
||||
typedef struct {
|
||||
vartype_T si_vartype;
|
||||
class_T *si_class;
|
||||
} storeindex_T;
|
||||
|
||||
/*
|
||||
* Instruction
|
||||
@ -540,6 +545,7 @@ struct isn_S {
|
||||
echowin_T echowin;
|
||||
construct_T construct;
|
||||
classmember_T classmember;
|
||||
storeindex_T storeindex;
|
||||
} isn_arg;
|
||||
};
|
||||
|
||||
|
@ -2178,7 +2178,22 @@ compile_assign_unlet(
|
||||
|
||||
if (isn == NULL)
|
||||
return FAIL;
|
||||
isn->isn_arg.vartype = dest_type;
|
||||
isn->isn_arg.storeindex.si_vartype = dest_type;
|
||||
isn->isn_arg.storeindex.si_class = NULL;
|
||||
|
||||
if (dest_type == VAR_OBJECT)
|
||||
{
|
||||
class_T *cl = (class_T *)lhs->lhs_type->tt_member;
|
||||
|
||||
if (cl->class_flags & CLASS_INTERFACE)
|
||||
{
|
||||
// "this.value": load "this" object and get the value
|
||||
// at index for an object or class member get the type
|
||||
// of the member
|
||||
isn->isn_arg.storeindex.si_class = cl;
|
||||
++cl->class_refcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (range)
|
||||
|
@ -2108,7 +2108,7 @@ handle_debug(isn_T *iptr, ectx_T *ectx)
|
||||
static int
|
||||
execute_storeindex(isn_T *iptr, ectx_T *ectx)
|
||||
{
|
||||
vartype_T dest_type = iptr->isn_arg.vartype;
|
||||
vartype_T dest_type = iptr->isn_arg.storeindex.si_vartype;
|
||||
typval_T *tv;
|
||||
typval_T *tv_idx = STACK_TV_BOT(-2);
|
||||
typval_T *tv_dest = STACK_TV_BOT(-1);
|
||||
@ -2243,6 +2243,12 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
|
||||
long idx = (long)tv_idx->vval.v_number;
|
||||
object_T *obj = tv_dest->vval.v_object;
|
||||
typval_T *otv = (typval_T *)(obj + 1);
|
||||
|
||||
class_T *itf = iptr->isn_arg.storeindex.si_class;
|
||||
if (itf != NULL)
|
||||
// convert interface member index to class member index
|
||||
idx = object_index_from_itf_index(itf, idx, obj->obj_class);
|
||||
|
||||
clear_tv(&otv[idx]);
|
||||
otv[idx] = *tv;
|
||||
}
|
||||
@ -6475,7 +6481,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
|
||||
|
||||
case ISN_STOREINDEX:
|
||||
smsg("%s%4d STOREINDEX %s", pfx, current,
|
||||
vartype_name(iptr->isn_arg.vartype));
|
||||
vartype_name(iptr->isn_arg.storeindex.si_vartype));
|
||||
break;
|
||||
|
||||
case ISN_STORERANGE:
|
||||
|
@ -2521,6 +2521,10 @@ delete_instr(isn_T *isn)
|
||||
class_unref(isn->isn_arg.classmember.cm_class);
|
||||
break;
|
||||
|
||||
case ISN_STOREINDEX:
|
||||
class_unref(isn->isn_arg.storeindex.si_class);
|
||||
break;
|
||||
|
||||
case ISN_TRY:
|
||||
vim_free(isn->isn_arg.tryref.try_ref);
|
||||
break;
|
||||
@ -2622,7 +2626,6 @@ delete_instr(isn_T *isn)
|
||||
case ISN_SLICE:
|
||||
case ISN_SOURCE:
|
||||
case ISN_STORE:
|
||||
case ISN_STOREINDEX:
|
||||
case ISN_STORENR:
|
||||
case ISN_STOREOUTER:
|
||||
case ISN_STORE_THIS:
|
||||
|
Loading…
x
Reference in New Issue
Block a user