Skip to content

Commit 23c92d9

Browse files
yegappanchrisbra
authored andcommitted
patch 9.0.1887: Vim9: class members are accessible via object
Problem: Vim9: class members are accessible via object Solution: Disable class member variable access using an object Class methods can be accessed only using the class name and cannot be accessed using an object. To be consistent with this, do the same for class member variables also. They can be accessed only using the class name and not using an object. closes: #13057 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Yegappan Lakshmanan <[email protected]>
1 parent ee17b6f commit 23c92d9

4 files changed

Lines changed: 65 additions & 78 deletions

File tree

src/testdir/test_vim9_class.vim

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,10 +1955,6 @@ def Test_class_implements_interface()
19551955
enddef
19561956
endclass
19571957

1958-
def F1(i: I1): list<number>
1959-
return [ i.svar1, i.svar2 ]
1960-
enddef
1961-
19621958
def F2(i: I1): list<number>
19631959
return [ i.mvar1, i.mvar2 ]
19641960
enddef
@@ -1967,10 +1963,6 @@ def Test_class_implements_interface()
19671963
var ob = B.new()
19681964
var oc = C.new()
19691965

1970-
assert_equal([11, 12], F1(oa))
1971-
assert_equal([21, 22], F1(ob))
1972-
assert_equal([31, 32], F1(oc))
1973-
19741966
assert_equal([111, 112], F2(oa))
19751967
assert_equal([121, 122], F2(ob))
19761968
assert_equal([131, 132], F2(oc))
@@ -2041,39 +2033,21 @@ def Test_class_implements_interface()
20412033
enddef
20422034
endclass
20432035

2044-
def F1(i: I1): list<number>
2045-
return [ i.svar1, i.svar2 ]
2046-
enddef
2047-
20482036
def F2(i: I1): list<number>
20492037
return [ i.mvar1, i.mvar2 ]
20502038
enddef
20512039

2052-
def F3(i: I2): list<number>
2053-
return [ i.svar3, i.svar4 ]
2054-
enddef
2055-
20562040
def F4(i: I2): list<number>
20572041
return [ i.mvar3, i.mvar4 ]
20582042
enddef
20592043

2060-
def F5(o: C): number
2061-
return o.svar5
2062-
enddef
2063-
20642044
var oa = A.new()
20652045
var ob = B.new()
20662046
var oc = C.new()
20672047

2068-
assert_equal([[11, 12]], [F1(oa)])
2069-
assert_equal([[21, 22], [23, 24]], [F1(ob), F3(ob)])
2070-
assert_equal([[31, 32], [33, 34]], [F1(oc), F3(oc)])
2071-
20722048
assert_equal([[111, 112]], [F2(oa)])
20732049
assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
20742050
assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
2075-
2076-
assert_equal(1001, F5(oc))
20772051
END
20782052
v9.CheckScriptSuccess(lines)
20792053
enddef
@@ -4182,25 +4156,7 @@ def Test_static_member_access_outside_class()
41824156
return 11
41834157
enddef
41844158

4185-
# access the class static through an interface argument
4186-
def F2(i: I): number
4187-
assert_equal(1, i.s_var1)
4188-
assert_equal(2, i.s_var2)
4189-
return 22
4190-
enddef
4191-
4192-
# access the class static through an object interface
4193-
def F3(o: C): number
4194-
assert_equal(1, o.s_var1)
4195-
assert_equal(2, o.s_var2)
4196-
assert_equal(7, o.x_static)
4197-
return 33
4198-
enddef
4199-
42004159
assert_equal(11, F1())
4201-
var c = C.new()
4202-
assert_equal(22, F2(c))
4203-
assert_equal(33, F3(c))
42044160
END
42054161
v9.CheckScriptSuccess(lines)
42064162
enddef
@@ -4250,7 +4206,7 @@ def Test_private_member_access_outside_class()
42504206
enddef
42514207
T()
42524208
END
4253-
v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
4209+
v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": _val')
42544210

42554211
# private static member variable
42564212
lines =<< trim END
@@ -4362,7 +4318,7 @@ def Test_modify_class_member_from_def_function()
43624318
enddef
43634319

43644320
" Test for accessing a class member variable using an object
4365-
def Test_class_member_access_using_object()
4321+
def Test_class_variable_access_using_object()
43664322
var lines =<< trim END
43674323
vim9script
43684324
class A
@@ -4374,26 +4330,74 @@ def Test_class_member_access_using_object()
43744330
A.svar2->add(4)
43754331
assert_equal([1, 3], A.svar1)
43764332
assert_equal([2, 4], A.svar2)
4377-
var a1 = A.new()
4378-
a1.svar1->add(5)
4379-
a1.svar2->add(6)
4380-
assert_equal([1, 3, 5], a1.svar1)
4381-
assert_equal([2, 4, 6], a1.svar2)
43824333

43834334
def Foo()
43844335
A.svar1->add(7)
43854336
A.svar2->add(8)
4386-
assert_equal([1, 3, 5, 7], A.svar1)
4387-
assert_equal([2, 4, 6, 8], A.svar2)
4388-
var a2 = A.new()
4389-
a2.svar1->add(9)
4390-
a2.svar2->add(10)
4391-
assert_equal([1, 3, 5, 7, 9], a2.svar1)
4392-
assert_equal([2, 4, 6, 8, 10], a2.svar2)
4337+
assert_equal([1, 3, 7], A.svar1)
4338+
assert_equal([2, 4, 8], A.svar2)
43934339
enddef
43944340
Foo()
43954341
END
43964342
v9.CheckScriptSuccess(lines)
4343+
4344+
# Cannot read from a class variable using an object in script context
4345+
lines =<< trim END
4346+
vim9script
4347+
class A
4348+
public this.var1: number
4349+
public static svar2: list<number> = [1]
4350+
endclass
4351+
4352+
var a = A.new()
4353+
echo a.svar2
4354+
END
4355+
v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": svar2')
4356+
4357+
# Cannot write to a class variable using an object in script context
4358+
lines =<< trim END
4359+
vim9script
4360+
class A
4361+
public this.var1: number
4362+
public static svar2: list<number> = [1]
4363+
endclass
4364+
4365+
var a = A.new()
4366+
a.svar2 = [2]
4367+
END
4368+
v9.CheckScriptFailure(lines, 'E1334: Object member not found: svar2 = [2]')
4369+
4370+
# Cannot read from a class variable using an object in def method context
4371+
lines =<< trim END
4372+
vim9script
4373+
class A
4374+
public this.var1: number
4375+
public static svar2: list<number> = [1]
4376+
endclass
4377+
4378+
def T()
4379+
var a = A.new()
4380+
echo a.svar2
4381+
enddef
4382+
T()
4383+
END
4384+
v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": svar2')
4385+
4386+
# Cannot write to a class variable using an object in def method context
4387+
lines =<< trim END
4388+
vim9script
4389+
class A
4390+
public this.var1: number
4391+
public static svar2: list<number> = [1]
4392+
endclass
4393+
4394+
def T()
4395+
var a = A.new()
4396+
a.svar2 = [2]
4397+
enddef
4398+
T()
4399+
END
4400+
v9.CheckScriptFailure(lines, 'E1089: Unknown variable: svar2 = [2]')
43974401
enddef
43984402

43994403
" Test for using a interface method using a child object

src/version.c

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

700700
static int included_patches[] =
701701
{ /* Add new patch number below this line */
702+
/**/
703+
1887,
702704
/**/
703705
1886,
704706
/**/

src/vim9class.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,8 +1966,7 @@ class_object_index(
19661966
{
19671967
// Search in the object member variable table and the class member
19681968
// variable table.
1969-
if (get_member_tv(cl, TRUE, name, len, rettv) == OK
1970-
|| get_member_tv(cl, FALSE, name, len, rettv) == OK)
1969+
if (get_member_tv(cl, TRUE, name, len, rettv) == OK)
19711970
{
19721971
*arg = name_end;
19731972
return OK;

src/vim9expr.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -413,24 +413,6 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
413413
}
414414
}
415415

416-
for (int i = 0; i < cl->class_class_member_count; ++i)
417-
{
418-
ocmember_T *m = &cl->class_class_members[i];
419-
if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL)
420-
{
421-
if (*name == '_' && !inside_class(cctx, cl))
422-
{
423-
semsg(_(e_cannot_access_private_member_str), m->ocm_name);
424-
return FAIL;
425-
}
426-
*arg = name_end;
427-
if (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED))
428-
return generate_GET_ITF_MEMBER(cctx, cl, i, m->ocm_type,
429-
TRUE);
430-
return generate_GET_OBJ_MEMBER(cctx, i, m->ocm_type, TRUE);
431-
}
432-
}
433-
434416
// Could be a function reference: "obj.Func".
435417
for (int i = 0; i < cl->class_obj_method_count; ++i)
436418
{

0 commit comments

Comments
 (0)