class NotWorking
endclass
END
- v9.CheckScriptFailure(lines, 'E1316:')
+ v9.CheckSourceFailure(lines, 'E1316:')
lines =<< trim END
vim9script
class notWorking
endclass
END
- v9.CheckScriptFailure(lines, 'E1314:')
+ v9.CheckSourceFailure(lines, 'E1314:')
lines =<< trim END
vim9script
class Not@working
endclass
END
- v9.CheckScriptFailure(lines, 'E1315:')
+ v9.CheckSourceFailure(lines, 'E1315:')
lines =<< trim END
vim9script
abstract noclass Something
endclass
END
- v9.CheckScriptFailure(lines, 'E475:')
+ v9.CheckSourceFailure(lines, 'E475:')
lines =<< trim END
vim9script
abstract classy Something
endclass
END
- v9.CheckScriptFailure(lines, 'E475:')
+ v9.CheckSourceFailure(lines, 'E475:')
lines =<< trim END
vim9script
class Something
endcl
END
- v9.CheckScriptFailure(lines, 'E1065:')
+ v9.CheckSourceFailure(lines, 'E1065:')
lines =<< trim END
vim9script
class Something
endclass school's out
END
- v9.CheckScriptFailure(lines, 'E488:')
+ v9.CheckSourceFailure(lines, 'E488:')
lines =<< trim END
vim9script
class Something
endclass | echo 'done'
END
- v9.CheckScriptFailure(lines, 'E488:')
+ v9.CheckSourceFailure(lines, 'E488:')
lines =<< trim END
vim9script
this
endclass
END
- v9.CheckScriptFailure(lines, 'E1317:')
+ v9.CheckSourceFailure(lines, 'E1317:')
lines =<< trim END
vim9script
this.
endclass
END
- v9.CheckScriptFailure(lines, 'E1317:')
+ v9.CheckSourceFailure(lines, 'E1317:')
lines =<< trim END
vim9script
this .count
endclass
END
- v9.CheckScriptFailure(lines, 'E1317:')
+ v9.CheckSourceFailure(lines, 'E1317:')
lines =<< trim END
vim9script
this. count
endclass
END
- v9.CheckScriptFailure(lines, 'E1317:')
+ v9.CheckSourceFailure(lines, 'E1317:')
lines =<< trim END
vim9script
that.count
endclass
END
- v9.CheckScriptFailure(lines, 'E1318: Not a valid command in a class: that.count')
+ v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count')
lines =<< trim END
vim9script
this.count
endclass
END
- v9.CheckScriptFailure(lines, 'E1022:')
+ v9.CheckSourceFailure(lines, 'E1022:')
lines =<< trim END
vim9script
endclass
var obj = Something.new()
END
- v9.CheckScriptFailure(lines, 'E1089:')
+ v9.CheckSourceFailure(lines, 'E1089:')
lines =<< trim END
vim9script
this.count : number
endclass
END
- v9.CheckScriptFailure(lines, 'E1059:')
+ v9.CheckSourceFailure(lines, 'E1059:')
lines =<< trim END
vim9script
this.count:number
endclass
END
- v9.CheckScriptFailure(lines, 'E1069:')
+ v9.CheckSourceFailure(lines, 'E1069:')
# Test for unsupported comment specifier
lines =<< trim END
#{
endclass
END
- v9.CheckScriptFailure(lines, 'E1170:')
+ v9.CheckSourceFailure(lines, 'E1170:')
lines =<< trim END
vim9script
assert_equal('class<TextPosition>', typename(TextPosition))
assert_equal('object<TextPosition>', typename(pos))
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# When referencing object methods, space cannot be used after a "."
lines =<< trim END
var a = A.new()
var v = a. Foo()
END
- v9.CheckScriptFailure(lines, 'E1202:')
+ v9.CheckSourceFailure(lines, 'E1202:')
# Using an object without specifying a method or a member variable
lines =<< trim END
var a = A.new()
var v = a.
END
- v9.CheckScriptFailure(lines, 'E15:')
+ v9.CheckSourceFailure(lines, 'E15:')
# Error when parsing the arguments of an object method.
lines =<< trim END
var a = A.new()
var v = a.Foo(,)
END
- v9.CheckScriptFailure(lines, 'E15:')
+ v9.CheckSourceFailure(lines, 'E15:')
lines =<< trim END
vim9script
endclass
var a = A.new()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_class_defined_twice()
class There
endclass
END
- v9.CheckScriptFailure(lines, 'E1041: Redefining script item: "There"')
+ v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"')
# one class, reload same script twice is OK
lines =<< trim END
var buffers = BufferList.new()
echo buffers.Current()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_using_null_class()
this.member = 'text'
endinterface
END
- v9.CheckScriptFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
+ v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
lines =<< trim END
vim9script
this.member: string
endclass
END
- v9.CheckScriptFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
+ v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
enddef
def Test_object_not_set()
var db = {'xyz': 789}
echo db[state.value]
END
- v9.CheckScriptFailure(lines, 'E1360:')
+ v9.CheckSourceFailure(lines, 'E1360:')
lines =<< trim END
vim9script
enddef
Func()
END
- v9.CheckScriptFailure(lines, 'E1360:')
+ v9.CheckSourceFailure(lines, 'E1360:')
lines =<< trim END
vim9script
var bg: Background # UNINITIALIZED
echo Colorscheme.new(bg).GetBackground()
END
- v9.CheckScriptFailure(lines, 'E1360:')
+ v9.CheckSourceFailure(lines, 'E1360:')
# TODO: this should not give an error but be handled at runtime
lines =<< trim END
enddef
Func()
END
- v9.CheckScriptFailure(lines, 'E1363:')
+ v9.CheckSourceFailure(lines, 'E1363:')
enddef
def Test_null_object_assign_compare()
o2 = null_object
assert_true(o2 == null)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_class_member_initializer()
'\d\+ RETURN object.*',
instr)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_member_any_used_as_object()
F(outer_obj)
assert_equal(1, inner_obj.value)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
Test_assign_to_nested_typed_member()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
+
+ # Try modifying a private variable using an "any" object
+ lines =<< trim END
+ vim9script
+
+ class Inner
+ this._value: string = ''
+ endclass
+
+ class Outer
+ this.inner: any
+ endclass
+
+ def F(outer: Outer)
+ outer.inner._value = 'b'
+ enddef
+
+ var inner_obj = Inner.new('a')
+ var outer_obj = Outer.new(inner_obj)
+ F(outer_obj)
+ END
+ v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _value')
+
+ # Try modifying a non-existing variable using an "any" object
+ lines =<< trim END
+ vim9script
+
+ class Inner
+ this.value: string = ''
+ endclass
+
+ class Outer
+ this.inner: any
+ endclass
+
+ def F(outer: Outer)
+ outer.inner.someval = 'b'
+ enddef
+
+ var inner_obj = Inner.new('a')
+ var outer_obj = Outer.new(inner_obj)
+ F(outer_obj)
+ END
+ v9.CheckSourceFailure(lines, 'E1326: Member not found on object "Inner": someval')
enddef
def Test_assignment_with_operator()
AddToFoo(f)
assert_equal(23, f.x)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# do the same thing, but through an interface
lines =<< trim END
AddToFoo(f)
assert_equal(23, f.x)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_list_of_objects()
var l: list<Foo> = [Foo.new()]
ProcessList(l)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_expr_after_using_object()
Foo()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_class_default_new()
assert_equal(1, pos.lnum)
assert_equal(33, pos.col)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
assert_equal(4, chris.age)
assert_equal("none", chris.education)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
var missing = Person.new()
END
- v9.CheckScriptFailure(lines, 'E119:')
+ v9.CheckSourceFailure(lines, 'E119:')
enddef
Check()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
Check()
END
- v9.CheckScriptFailure(lines, 'E1013:')
+ v9.CheckSourceFailure(lines, 'E1013:')
lines =<< trim END
vim9script
Check()
END
- v9.CheckScriptFailure(lines, 'E1013:')
+ v9.CheckSourceFailure(lines, 'E1013:')
enddef
def Test_class_object_member_inits()
assert_equal(1, pos.col)
assert_equal(2, pos.addcol)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
this.col = 1
endclass
END
- v9.CheckScriptFailure(lines, 'E1022:')
+ v9.CheckSourceFailure(lines, 'E1022:')
# If the type is not specified for a member, then it should be set during
# object creation and not when defining the class.
var a = A.new()
assert_equal(init_count, 2)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Test for initializing an object member with an unknown variable/type
lines =<< trim END
endclass
var a = A.new()
END
- v9.CheckScriptFailure(lines, 'E1001:')
+ v9.CheckSourceFailure(lines, 'E1001:')
enddef
-def Test_class_object_member_access()
+" Test for instance variable access
+def Test_instance_variable_access()
var lines =<< trim END
vim9script
class Triple
trip.three = 33
assert_equal(33, trip.three)
- assert_fails('trip.four = 4', 'E1334')
+ assert_fails('trip.four = 4', 'E1326')
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Test for a public member variable name beginning with an underscore
lines =<< trim END
public this._val = 10
endclass
END
- v9.CheckScriptFailure(lines, 'E1332:')
+ v9.CheckSourceFailure(lines, 'E1332:')
lines =<< trim END
vim9script
enddef
CheckCar()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
var c = MyCar.new("abc")
var c = MyCar.new("def")
END
- v9.CheckScriptFailure(lines, 'E1041:')
+ v9.CheckSourceFailure(lines, 'E1041:')
lines =<< trim END
vim9script
.Add(2)
.x
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Test for "public" cannot be abbreviated
lines =<< trim END
pub this.val = 1
endclass
END
- v9.CheckScriptFailure(lines, 'E1065:')
+ v9.CheckSourceFailure(lines, 'E1065:')
# Test for "public" keyword must be followed by "this" or "static".
lines =<< trim END
public val = 1
endclass
END
- v9.CheckScriptFailure(lines, 'E1331:')
+ v9.CheckSourceFailure(lines, 'E1331:')
- # Test for "static" cannot be abbreviated
+ # Modify a instance variable using the class name in the script context
lines =<< trim END
vim9script
- class Something
- stat this.val = 1
+ class A
+ public this.val = 1
endclass
+ A.val = 1
END
- v9.CheckScriptFailure(lines, 'E1065:')
+ v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
- # Test for "static" cannot be followed by "this".
+ # Read a instance variable using the class name in the script context
lines =<< trim END
vim9script
- class Something
- static this.val = 1
+ class A
+ public this.val = 1
+ endclass
+ var i = A.val
+ END
+ v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
+
+ # Modify a instance variable using the class name in a def function
+ lines =<< trim END
+ vim9script
+ class A
+ public this.val = 1
+ endclass
+ def T()
+ A.val = 1
+ enddef
+ T()
+ END
+ v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
+
+ # Read a instance variable using the class name in a def function
+ lines =<< trim END
+ vim9script
+ class A
+ public this.val = 1
endclass
+ def T()
+ var i = A.val
+ enddef
+ T()
END
- v9.CheckScriptFailure(lines, 'E1368: Static cannot be followed by "this" in a member name')
+ v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
# Access from child class extending a class:
lines =<< trim END
this.ro_obj_var = 10
public this.rw_obj_var = 20
this._priv_obj_var = 30
-
- static ro_class_var = 40
- public static rw_class_var = 50
- static _priv_class_var = 60
endclass
class B extends A
this.rw_obj_var = 0
x = this._priv_obj_var
this._priv_obj_var = 0
+ enddef
+ endclass
+
+ var b = B.new()
+ b.Foo()
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for class variable access
+def Test_class_variable_access()
+ # Test for "static" cannot be abbreviated
+ var lines =<< trim END
+ vim9script
+ class Something
+ stat this.val = 1
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1065:')
+
+ # Test for "static" cannot be followed by "this".
+ lines =<< trim END
+ vim9script
+ class Something
+ static this.val = 1
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a member name')
+
+ # Test for "static" cannot be followed by "public".
+ lines =<< trim END
+ vim9script
+ class Something
+ static public val = 1
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1022: Type or initialization required')
+
+ # A readonly class variable cannot be modified from a child class
+ lines =<< trim END
+ vim9script
+ class A
+ static ro_class_var = 40
+ endclass
+
+ class B extends A
+ def Foo()
+ A.ro_class_var = 50
+ enddef
+ endclass
+
+ var b = B.new()
+ b.Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "ro_class_var"')
+
+ # A private class variable cannot be accessed from a child class
+ lines =<< trim END
+ vim9script
+ class A
+ static _priv_class_var = 60
+ endclass
+
+ class B extends A
+ def Foo()
+ var i = A._priv_class_var
+ enddef
+ endclass
+
+ var b = B.new()
+ b.Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _priv_class_var')
+
+ # A private class variable cannot be modified from a child class
+ lines =<< trim END
+ vim9script
+ class A
+ static _priv_class_var = 60
+ endclass
+
+ class B extends A
+ def Foo()
+ A._priv_class_var = 0
+ enddef
+ endclass
+
+ var b = B.new()
+ b.Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _priv_class_var')
- x = ro_class_var
- ro_class_var = 0
- x = rw_class_var
- rw_class_var = 0
- x = _priv_class_var
- _priv_class_var = 0
+ # Access from child class extending a class and from script context
+ lines =<< trim END
+ vim9script
+ class A
+ static ro_class_var = 10
+ public static rw_class_var = 20
+ static _priv_class_var = 30
+ endclass
+ class B extends A
+ def Foo()
+ var x: number
x = A.ro_class_var
- A.ro_class_var = 0
+ assert_equal(10, x)
x = A.rw_class_var
- A.rw_class_var = 0
- x = A._priv_class_var
- A._priv_class_var = 0
+ assert_equal(25, x)
+ A.rw_class_var = 20
+ assert_equal(20, A.rw_class_var)
enddef
endclass
+ assert_equal(10, A.ro_class_var)
+ assert_equal(20, A.rw_class_var)
+ A.rw_class_var = 25
+ assert_equal(25, A.rw_class_var)
var b = B.new()
b.Foo()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_class_object_compare()
assert_notequal(i1, io2)
END
- v9.CheckScriptSuccess(class_lines + test_lines)
- v9.CheckScriptSuccess(
+ v9.CheckSourceSuccess(class_lines + test_lines)
+ v9.CheckSourceSuccess(
class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
for op in ['>', '>=', '<', '<=', '=~', '!~']
'var i2 = Item.new()',
'echo i1 ' .. op .. ' i2',
]
- v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
- v9.CheckScriptFailure(class_lines
+ v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
+ v9.CheckSourceFailure(class_lines
+ ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
endfor
enddef
t = m
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
var o: One = Two.new()
END
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
lines =<< trim END
vim9script
var o: One = Two.new(5)
assert_equal(5, o.GetMember())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
echo Fn(Num.new(4))
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_class_member()
assert_equal(0, TextPos.counter)
TextPos.AddToCounter(3)
assert_equal(3, TextPos.counter)
- assert_fails('echo TextPos.noSuchMember', 'E1338:')
+ assert_fails('echo TextPos.noSuchMember', 'E1337:')
def GetCounter(): number
return TextPos.counter
TextPos.anybody += 5
assert_equal(17, TextPos.anybody)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# example in the help
lines =<< trim END
var to7 = OtherThing.new(7)
assert_equal(10, OtherThing.totalSize)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# using static class member twice
lines =<< trim END
assert_equal('some text', HTML.MacroSubstitute('some text'))
assert_equal('some text', HTML.MacroSubstitute('some text'))
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# access private member in lambda
lines =<< trim END
var foo = Foo.new()
assert_equal(5, foo.Add(5))
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# access private member in lambda body
lines =<< trim END
var foo = Foo.new()
assert_equal(13, foo.Add(7))
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# check shadowing
lines =<< trim END
var s = Some.new()
s.Method(7)
END
- v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
+ v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count')
lines =<< trim END
vim9script
var s = Some.new()
s.Method(7)
END
- v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
+ v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count')
# Test for using an invalid type for a member variable
lines =<< trim END
this.val: xxx
endclass
END
- v9.CheckScriptFailure(lines, 'E1010:')
+ v9.CheckSourceFailure(lines, 'E1010:')
# Test for setting a member on a null object
lines =<< trim END
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1360: Using a null object')
+ v9.CheckSourceFailure(lines, 'E1360: Using a null object')
# Test for accessing a member on a null object
lines =<< trim END
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1360: Using a null object')
+ v9.CheckSourceFailure(lines, 'E1360: Using a null object')
# Test for setting a member on a null object, at script level
lines =<< trim END
obj.val = ""
END
# FIXME(in source): this should give E1360 as well!
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<A> but got string')
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<A> but got string')
# Test for accessing a member on a null object, at script level
lines =<< trim END
var obj: A
echo obj.val
END
- v9.CheckScriptFailure(lines, 'E1360: Using a null object')
+ v9.CheckSourceFailure(lines, 'E1360: Using a null object')
# Test for no space before or after the '=' when initializing a member
# variable
this.val: number= 10
endclass
END
- v9.CheckScriptFailure(lines, 'E1004:')
+ v9.CheckSourceFailure(lines, 'E1004:')
lines =<< trim END
vim9script
class A
this.val: number =10
endclass
END
- v9.CheckScriptFailure(lines, 'E1004:')
+ v9.CheckSourceFailure(lines, 'E1004:')
# Access a non-existing member
lines =<< trim END
var a = A.new()
var v = a.bar
END
- v9.CheckScriptFailure(lines, 'E1326:')
+ v9.CheckSourceFailure(lines, 'E1326: Member not found on object "A": bar')
enddef
func Test_class_garbagecollect()
call test_garbagecollect_now()
echo Point.pl Point.pd
END
- call v9.CheckScriptSuccess(lines)
+ call v9.CheckSourceSuccess(lines)
let lines =<< trim END
vim9script
view = MyView.new()
test_garbagecollect_now()
END
- call v9.CheckScriptSuccess(lines)
+ call v9.CheckSourceSuccess(lines)
endfunc
" Test interface garbage collection
assert_equal(60, A.ClassFoo())
assert_equal(150, o.ObjFoo())
END
- call v9.CheckScriptSuccess(lines)
+ call v9.CheckSourceSuccess(lines)
endfunc
def Test_class_function()
var v2 = Value.new(7)
assert_equal(2, Value.GetCount())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Test for cleaning up after a class definition failure when using class
# functions.
aaa
endclass
END
- v9.CheckScriptFailure(lines, 'E1318:')
+ v9.CheckSourceFailure(lines, 'E1318:')
enddef
def Test_class_defcompile()
defcompile C.Fo
END
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number')
lines =<< trim END
vim9script
defcompile C.Fc
END
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string')
lines =<< trim END
vim9script
defcompile C.new
END
- v9.CheckScriptFailure(lines, 'E1370: Cannot define a "new" function as static')
+ v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" function as static')
# Trying to compile a function using a non-existing class variable
lines =<< trim END
vim9script
defcompile x.Foo()
END
- v9.CheckScriptFailure(lines, 'E475:')
+ v9.CheckSourceFailure(lines, 'E475:')
# Trying to compile a function using a variable which is not a class
lines =<< trim END
var x: number
defcompile x.Foo()
END
- v9.CheckScriptFailure(lines, 'E475:')
+ v9.CheckSourceFailure(lines, 'E475:')
# Trying to compile a function without specifying the name
lines =<< trim END
endclass
defcompile A.
END
- v9.CheckScriptFailure(lines, 'E475:')
+ v9.CheckSourceFailure(lines, 'E475:')
# Trying to compile a non-existing class object member function
lines =<< trim END
var a = A.new()
defcompile a.Foo()
END
- v9.CheckScriptFailureList(lines, ['E1334:', 'E475:'])
+ v9.CheckSourceFailureList(lines, ['E1326:', 'E475:'])
enddef
def Test_class_object_to_string()
var pos = TextPosition.new()
assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_interface_basics()
def GetCount(): number
endinterface
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
interface SomethingWrong
static count = 7
endinterface
END
- v9.CheckScriptFailure(lines, 'E1342:')
+ v9.CheckSourceFailure(lines, 'E1342:')
lines =<< trim END
vim9script
def Method(count: number)
endinterface
END
- v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count', 5)
+ v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
lines =<< trim END
vim9script
END
# The argument name and the object member name are the same, but this is not a
# problem because object members are always accessed with the "this." prefix.
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
static count = 7
endinterface
END
- v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
+ v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
lines =<< trim END
vim9script
def GetCount(): number
endinterface
END
- v9.CheckScriptFailure(lines, 'E1344:')
+ v9.CheckSourceFailure(lines, 'E1344:')
lines =<< trim END
vim9script
enddef
endinterface
END
- v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
+ v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5')
lines =<< trim END
vim9script
enddef
endclass
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
static count: number
endclass
END
- v9.CheckScriptFailure(lines, 'E1350:')
+ v9.CheckSourceFailure(lines, 'E1350:')
lines =<< trim END
vim9script
static count: number
endclass
END
- v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
+ v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some')
lines =<< trim END
vim9script
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
+ v9.CheckSourceFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
lines =<< trim END
vim9script
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
+ v9.CheckSourceFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
# Check different order of members in class and interface works.
lines =<< trim END
Test()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Interface name after "extends" doesn't end in a space or NUL character
lines =<< trim END
class B extends A"
endclass
END
- v9.CheckScriptFailure(lines, 'E1315:')
+ v9.CheckSourceFailure(lines, 'E1315:')
# Trailing characters after a class name
lines =<< trim END
class A bbb
endclass
END
- v9.CheckScriptFailure(lines, 'E488:')
+ v9.CheckSourceFailure(lines, 'E488:')
# using "implements" with a non-existing class
lines =<< trim END
class A implements B
endclass
END
- v9.CheckScriptFailure(lines, 'E1346:')
+ v9.CheckSourceFailure(lines, 'E1346:')
# using "implements" with a regular class
lines =<< trim END
class B implements A
endclass
END
- v9.CheckScriptFailure(lines, 'E1347:')
+ v9.CheckSourceFailure(lines, 'E1347:')
# using "implements" with a variable
lines =<< trim END
class A implements T
endclass
END
- v9.CheckScriptFailure(lines, 'E1347:')
+ v9.CheckSourceFailure(lines, 'E1347:')
# all the class methods in an "interface" should be implemented
lines =<< trim END
class B implements A
endclass
END
- v9.CheckScriptFailure(lines, 'E1349:')
+ v9.CheckSourceFailure(lines, 'E1349:')
# implements should be followed by a white space
lines =<< trim END
class B implements A;
endclass
END
- v9.CheckScriptFailure(lines, 'E1315:')
+ v9.CheckSourceFailure(lines, 'E1315:')
lines =<< trim END
vim9script
static matching: bool
endclass
END
- v9.CheckScriptFailure(lines, 'E1406: Member "not_matching": type mismatch, expected number but got string')
+ v9.CheckSourceFailure(lines, 'E1406: Member "not_matching": type mismatch, expected number but got string')
lines =<< trim END
vim9script
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string')
+ v9.CheckSourceFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string')
lines =<< trim END
vim9script
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool')
+ v9.CheckSourceFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool')
lines =<< trim END
vim9script
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool')
+ v9.CheckSourceFailure(lines, 'E1407: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool')
# access superclass interface members from subclass, mix variable order
lines =<< trim END
class B extends A
def new()
- svar1 = 21
- svar2 = 22
this.mvar1 = 121
this.mvar2 = 122
enddef
class C extends B
def new()
- svar1 = 31
- svar2 = 32
this.mvar1 = 131
this.mvar2 = 132
enddef
assert_equal([121, 122], F2(ob))
assert_equal([131, 132], F2(oc))
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Access superclass interface members from subclass, mix variable order.
# Two interfaces, one on A, one on B; each has both kinds of variables
public this.mvar3: number
public this.mvar4: number
def new()
- svar1 = 21
- svar2 = 22
svar3 = 23
svar4 = 24
this.mvar1 = 121
class C extends B
public static svar5: number
def new()
- svar1 = 31
- svar2 = 32
- svar3 = 33
- svar4 = 34
svar5 = 1001
this.mvar1 = 131
this.mvar2 = 132
assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_call_interface_method()
assert_equal('child', g:result)
unlet g:result
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
assert_equal('child', g:result)
unlet g:result
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# method of interface returns a value
lines =<< trim END
assert_equal('child/resource', g:result)
unlet g:result
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
assert_equal('child/resource', g:result)
unlet g:result
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# No class that implements the interface.
defcompile
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_class_used_as_type()
assert_equal(2, p.x)
assert_equal(33, p.y)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
var hx = p
assert_equal(2, hx.x)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
var p: Point
p = 'text'
END
- v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
enddef
def Test_class_extends()
assert_equal(1, o.GetOne())
assert_equal(3, o.GetTotal())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
assert_equal(3, o.one)
assert_equal(44, o.two)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
this.two = 2
endclass
END
- v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
+ v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"')
lines =<< trim END
vim9script
this.two = 2
endclass
END
- v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
+ v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass')
lines =<< trim END
vim9script
this.two = 2
endclass
END
- v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
+ v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar')
lines =<< trim END
vim9script
var o = Child.new('John', 42)
assert_equal('John: 42', o.ToString())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString')
lines =<< trim END
vim9script
var o = Child.new(42)
echo o.ToString()
END
- v9.CheckScriptFailure(lines, 'E1356:')
+ v9.CheckSourceFailure(lines, 'E1356:')
lines =<< trim END
vim9script
enddef
echo ToString()
END
- v9.CheckScriptFailure(lines, 'E1357:')
+ v9.CheckSourceFailure(lines, 'E1357:')
lines =<< trim END
vim9script
var o = Child.new(42)
echo o.ToString()
END
- v9.CheckScriptFailure(lines, 'E1358:')
+ v9.CheckSourceFailure(lines, 'E1358:')
lines =<< trim END
vim9script
var o = Child.new('John', 42)
assert_equal('Base class: 42', o.ToString())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
endclass
var c = Child.new()
END
- v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
+ v9.CheckSourceFailure(lines, 'E1375: Class member "new" accessible only using class "Child"')
# base class with more than one object member
lines =<< trim END
var v = Success.new('asdf')
assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# class name after "extends" doesn't end in a space or NUL character
lines =<< trim END
class B extends A"
endclass
END
- v9.CheckScriptFailure(lines, 'E1315:')
+ v9.CheckSourceFailure(lines, 'E1315:')
enddef
def Test_using_base_class()
With(ChildEE.new())
assert_equal('42/finally/exit', g:result)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
unlet g:result
# Using super, Child invokes Base method which has optional arg. #12471
var obj = Child.new()
assert_equal(true, obj.success)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
assert_equal('Peter', p.name)
assert_equal(42, p.age)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
endclass
var p = Base.new('Peter')
END
- v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
+ v9.CheckSourceFailure(lines, 'E1325: Method not found on class "Base": new')
lines =<< trim END
abstract class Base
this.name: string
endclass
END
- v9.CheckScriptFailure(lines, 'E1316:')
+ v9.CheckSourceFailure(lines, 'E1316:')
# Abstract class cannot have a "new" function
lines =<< trim END
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1359:')
+ v9.CheckSourceFailure(lines, 'E1359:')
enddef
def Test_closure_in_class()
Foo.new()
assert_equal(['A'], g:result)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_call_constructor_from_legacy()
legacy call p.new()
assert_equal('true', newCalled)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_defer_with_object()
})
assert_equal('entered/called/exited', g:result)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
unlet g:result
lines =<< trim END
})
assert_equal('entered-child/called/exited-child', g:result)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
unlet g:result
enddef
p.Set(true)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for calling a method in a class that is extended
assert_true(prop_init_called)
assert_true(prop_register_called)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_instanceof()
enddef
Foo()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for calling a method in the parent class that is extended partially.
var foo2 = Foo.new()
var l = Stack(foo1, foo2)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for calling methods from three levels of classes
assert_equal(0, B_func3)
assert_equal(3, C_func3)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for using members from three levels of classes
assert_equal(2, cobj.val2)
assert_equal(1, cobj.val3)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test expansion of <stack> with class methods.
F()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test the return type of the new() constructor
enddef
F()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# new() uses the default return type and an empty 'return' statement
lines =<< trim END
enddef
F()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# new() uses "any" return type and returns "this"
lines =<< trim END
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1365:')
+ v9.CheckSourceFailure(lines, 'E1365:')
# new() uses 'Dict' return type and returns a Dict
lines =<< trim END
var c = C.new()
assert_equal('object<C>', typename(c))
END
- v9.CheckScriptFailure(lines, 'E1365:')
+ v9.CheckSourceFailure(lines, 'E1365:')
enddef
" Test for checking a member initialization type at run time.
var c1 = C.new()
var c2 = C.new()
END
- v9.CheckScriptFailure(lines, 'E1012:')
+ v9.CheckSourceFailure(lines, 'E1012:')
enddef
" Test for locking a variable referring to an object and reassigning to another
G()
assert_equal(2, current.val)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for a private object method
var a = A.new()
a._Foo()
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Try calling a private method using an object (from a def function)
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Use a private method from another object method (in script context)
lines =<< trim END
var a = A.new()
assert_equal(1234, a.Bar())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Use a private method from another object method (def function context)
lines =<< trim END
enddef
T()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Try calling a private method without the "this" prefix
lines =<< trim END
var a = A.new()
a.Bar()
END
- v9.CheckScriptFailure(lines, 'E117: Unknown function: _Foo')
+ v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo')
# Try calling a private method using the class name
lines =<< trim END
endclass
A._Foo()
END
- v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
# Try to use "public" keyword when defining a private method
lines =<< trim END
var a = A.new()
a._Foo()
END
- v9.CheckScriptFailure(lines, 'E1331: Public must be followed by "this" or "static"')
+ v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"')
# Define two private methods with the same name
lines =<< trim END
endclass
var a = A.new()
END
- v9.CheckScriptFailure(lines, 'E1355: Duplicate function: _Foo')
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
# Define a private method and a object method with the same name
lines =<< trim END
endclass
var a = A.new()
END
- v9.CheckScriptFailure(lines, 'E1355: Duplicate function: Foo')
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
# Define an object method and a private method with the same name
lines =<< trim END
endclass
var a = A.new()
END
- v9.CheckScriptFailure(lines, 'E1355: Duplicate function: _Foo')
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
# Call a public method and a private method from a private method
lines =<< trim END
var a = A.new()
a.T()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Try calling a private method from another class
lines =<< trim END
var b = B.new()
b.Foo()
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Call a private object method from a child class object method
lines =<< trim END
var c = C.new()
assert_equal(1234, c.Baz())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Call a private object method from a child class object
lines =<< trim END
var c = C.new()
assert_equal(1234, c._Foo())
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Using "_" prefix in a method name should fail outside of a class
lines =<< trim END
enddef
var a = _Foo()
END
- v9.CheckScriptFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number')
+ v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number')
enddef
" Test for an private class method
endclass
A._Foo()
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Try calling a class private method (from a def function)
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Try calling a class private method using an object (at the script level)
lines =<< trim END
var a = A.new()
a._Foo()
END
- v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
# Try calling a class private method using an object (from a def function)
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
# Use a class private method from an object method
lines =<< trim END
var a = A.new()
a.Bar()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Use a class private method from another class private method
lines =<< trim END
var a = A.new()
a.Bar()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Declare a class method and a class private method with the same name
lines =<< trim END
endclass
var a = A.new()
END
- v9.CheckScriptFailure(lines, 'E1355: Duplicate function: Foo')
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
# Try calling a class private method from another class
lines =<< trim END
var b = B.new()
assert_equal(1234, b.Foo())
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Call a private class method from a child class object method
lines =<< trim END
var c = C.new()
assert_equal(1234, c.Baz())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Call a private class method from a child class private class method
lines =<< trim END
endclass
assert_equal(1234, C.Baz())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Call a private class method from a child class object
lines =<< trim END
var c = C.new()
assert_equal(1234, C._Foo())
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo')
enddef
" Test for an interface private object_method
var a = A.new()
assert_equal(1234, a.Bar())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Call an interface private class method (script context)
lines =<< trim END
var a = A.new()
assert_equal(1234, a._Foo())
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Call an interface private class method (def context)
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
# Implement an interface private object method as a private class method
lines =<< trim END
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
+ v9.CheckSourceFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
enddef
" Test for an interface private class method
var a = A.new()
assert_equal(1234, a.Bar())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Call an interface private class method (script context)
lines =<< trim END
endclass
assert_equal(1234, A._Foo())
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo())')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo())')
# Call an interface private class method (def context)
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo())')
+ v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo())')
# Implement an interface private class method as a private object method
lines =<< trim END
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
+ v9.CheckSourceFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
enddef
" Test for using the return value of a class/object method as a function
var t = C.new()
Baz(t)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
Baz()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
def Test_static_inheritence()
class B extends A
def new()
- _svar = 2
this._mvar = 102
enddef
endclass
class C extends B
def new()
- _svar = 3
this._mvar = 103
enddef
def AccessPrivateStaticThroughClassName(): number
assert_equal(1, A._svar)
- assert_equal(2, B._svar)
- assert_equal(3, C._svar)
return 444
enddef
endclass
assert_equal(102, ob.AccessObject())
assert_equal(103, oc.AccessObject())
- assert_equal(444, oc.AccessPrivateStaticThroughClassName())
+ assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private member: _svar')
# verify object properly resolves to correct static
assert_equal(1, oa.AccessStaticThroughObject())
- assert_equal(2, ob.AccessStaticThroughObject())
- assert_equal(3, oc.AccessStaticThroughObject())
+ assert_equal(1, ob.AccessStaticThroughObject())
+ assert_equal(1, oc.AccessStaticThroughObject())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for declaring duplicate object and class members
this.val = 20
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
# Duplicate private member variable
lines =<< trim END
this._val = 20
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
# Duplicate public member variable
lines =<< trim END
public this.val = 20
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
# Duplicate private member variable
lines =<< trim END
this._val = 20
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
# Duplicate public and private member variable
lines =<< trim END
public this.val = 10
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
# Duplicate class member variable
lines =<< trim END
static _s: string = "def"
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _s')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _s')
# Duplicate public and private class member variable
lines =<< trim END
static _s: string = "def"
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _s')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _s')
# Duplicate class and object member variable
lines =<< trim END
assert_equal(10, C.val)
assert_equal(20, c.val)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Duplicate object member variable in a derived class
lines =<< trim END
this.val = 20
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
# Duplicate object private member variable in a derived class
lines =<< trim END
this._val = 20
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
# Duplicate object private member variable in a derived class
lines =<< trim END
this._val = 20
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
# Duplicate object member variable in a derived class
lines =<< trim END
this.val = 20
endclass
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+ v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
- # Duplicate class member variable in a derived class
+ # Two member variables with a common prefix
lines =<< trim END
vim9script
class A
- static val = 10
- endclass
- class B extends A
+ public static svar2: number
+ public static svar: number
endclass
- class C extends B
- static val = 20
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+def Test_interface_static_member_access()
+ # In a class cannot read from interface static
+ var lines =<< trim END
+ vim9script
+ interface I
+ public static num: number
+ endinterface
+ class C implements I
+ public static num = 3
+ def F()
+ var x = I.num
+ enddef
endclass
+ C.new().F()
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
+ v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
- # Duplicate private class member variable in a derived class
+ # In a class cannot write to interface static
lines =<< trim END
vim9script
- class A
- static _val = 10
- endclass
- class B extends A
- endclass
- class C extends B
- static _val = 20
+ interface I
+ public static num: number
+ endinterface
+ class C implements I
+ public static num = 3
+ def F()
+ I.num = 7
+ enddef
endclass
+ C.new().F()
END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
+ v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
- # Duplicate private class member variable in a derived class
- lines =<< trim END
- vim9script
- class A
- static val = 10
- endclass
- class B extends A
- endclass
- class C extends B
- static _val = 20
- endclass
- END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
-
- # Duplicate class member variable in a derived class
- lines =<< trim END
- vim9script
- class A
- static _val = 10
- endclass
- class B extends A
- endclass
- class C extends B
- static val = 20
- endclass
- END
- v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
-
- # Two member variables with a common prefix
- lines =<< trim END
- vim9script
- class A
- public static svar2: number
- public static svar: number
- endclass
- END
- v9.CheckScriptSuccess(lines)
-enddef
-
-def Test_interface_static_member_access()
- # In a class cannot read from interface static
- var lines =<< trim END
- vim9script
- interface I
- public static num: number
- endinterface
- class C implements I
- public static num = 3
- def F()
- var x = I.num
- enddef
- endclass
- C.new().F()
- END
- v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
-
- # In a class cannot write to interface static
- lines =<< trim END
- vim9script
- interface I
- public static num: number
- endinterface
- class C implements I
- public static num = 3
- def F()
- I.num = 7
- enddef
- endclass
- C.new().F()
- END
- v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
-
- # In a def cannot read from interface static
+ # In a def cannot read from interface static
lines =<< trim END
vim9script
interface I
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
+ v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
# In a def cannot write to interface static
lines =<< trim END
enddef
F()
END
- v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
+ v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "num"')
# script level cannot read interface static
lines =<< trim END
var x = I.s_var1
END
- v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "s_var1"')
+ v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "s_var1"')
# script level cannot write interface static
lines =<< trim END
I.s_var1 = 3
END
- v9.CheckScriptFailure(lines, 'E1409: Cannot directly access interface "I" static member "I.s_var1 = 3"')
+ v9.CheckSourceFailure(lines, 'E1409: Cannot directly access interface "I" static member "I.s_var1 = 3"')
enddef
assert_equal(11, F1())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for accessing a private member outside a class in a def function
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
+ v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
# access a non-existing private object member variable
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1089: Unknown variable: _a = 1')
+ v9.CheckSourceFailure(lines, 'E1089: Unknown variable: _a')
# private static member variable
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": _val')
+ v9.CheckSourceFailure(lines, 'E1375: Class member "_val" accessible only using class "A"')
# private static member variable
lines =<< trim END
enddef
T()
END
- # TODO: wrong error, should be about private member
- v9.CheckScriptFailure(lines, 'E1089: Unknown variable')
+ v9.CheckSourceFailure(lines, 'E1374: Class member "_val" accessible only inside class "A"')
# private static class variable
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
+ v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
# private static class variable
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
+ v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
enddef
" Test for changing the member access of an interface in a implementation class
this.val = 10
endclass
END
- v9.CheckScriptFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
+ v9.CheckSourceFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
lines =<< trim END
vim9script
public this.val = 10
endclass
END
- v9.CheckScriptFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
+ v9.CheckSourceFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
enddef
" Test for trying to change a readonly member from a def function
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E46: Cannot change read-only variable "val"')
+ v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "val"')
enddef
" Test for reading and writing a class member from a def function
enddef
T()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for accessing a class member variable using an object
enddef
Foo()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Cannot read from a class variable using an object in script context
lines =<< trim END
var a = A.new()
echo a.svar2
END
- v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": svar2')
+ v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
# Cannot write to a class variable using an object in script context
lines =<< trim END
var a = A.new()
a.svar2 = [2]
END
- v9.CheckScriptFailure(lines, 'E1334: Object member not found: svar2 = [2]')
+ v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
# Cannot read from a class variable using an object in def method context
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1326: Member not found on object "A": svar2')
+ v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
# Cannot write to a class variable using an object in def method context
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1089: Unknown variable: svar2 = [2]')
+ v9.CheckSourceFailure(lines, 'E1374: Class member "svar2" accessible only inside class "A"')
enddef
" Test for using a interface method using a child object
T1(c)
T2(c)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
enddef
" Test for using an interface method using a child object when it is overridden
" T1(c)
" T2(c)
" END
-" v9.CheckScriptSuccess(lines)
+" v9.CheckSourceSuccess(lines)
" enddef
" Test for abstract methods
var b = B.new()
assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Don't define an abstract method
lines =<< trim END
class B extends A
endclass
END
- v9.CheckScriptFailure(lines, 'E1373: Abstract method "Foo" is not implemented')
+ v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented')
# Use abstract method in a concrete class
lines =<< trim END
class B extends A
endclass
END
- v9.CheckScriptFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
+ v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
# Use abstract method in an interface
lines =<< trim END
class B implements A
endclass
END
- v9.CheckScriptFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
+ v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
# Abbreviate the "abstract" keyword
lines =<< trim END
abs def Foo()
endclass
END
- v9.CheckScriptFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()')
+ v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()')
# Use "abstract" with a member variable
lines =<< trim END
abstract this.val = 10
endclass
END
- v9.CheckScriptFailure(lines, 'E1371: Abstract must be followed by "def" or "static"')
+ v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"')
# Use a static abstract method
lines =<< trim END
endclass
assert_equal(4, B.Foo())
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Type mismatch between abstract method and concrete method
lines =<< trim END
enddef
endclass
END
- v9.CheckScriptFailure(lines, 'E1407: Method "Foo": type mismatch, expected func(string, number): list<number> but got func(number, string): list<string>')
+ v9.CheckSourceFailure(lines, 'E1407: Method "Foo": type mismatch, expected func(string, number): list<number> but got func(number, string): list<string>')
# Use an abstract class to invoke an abstract method
# FIXME: This should fail
endclass
A.Foo()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# Invoke an abstract method from a def function
lines =<< trim END
var b = B.new()
Bar(b)
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for calling a class method from a subclass
+def Test_class_method_call_from_subclass()
+ # class method call from a subclass
+ var lines =<< trim END
+ vim9script
+
+ class A
+ static def Foo()
+ echo "foo"
+ enddef
+ endclass
+
+ class B extends A
+ def Bar()
+ Foo()
+ enddef
+ endclass
+
+ var b = B.new()
+ b.Bar()
+ END
+ v9.CheckSourceFailure(lines, 'E1374: Class member "Foo" accessible only inside class "A"')
enddef
" Test for calling a class method using an object in a def function context and
a.Bar()
T()
END
- v9.CheckScriptSuccess(lines)
+ v9.CheckSourceSuccess(lines)
# script context
lines =<< trim END
var a = A.new()
assert_equal('foo', a.Foo())
END
- v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": Foo()')
+ v9.CheckSourceFailure(lines, 'E1375: Class member "Foo" accessible only using class "A"')
# def function context
lines =<< trim END
enddef
T()
END
- v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": Foo()')
+ v9.CheckSourceFailure(lines, 'E1375: Class member "Foo" accessible only using class "A"')
+enddef
+
+def Test_class_variable()
+ var lines =<< trim END
+ vim9script
+
+ class A
+ public static val: number = 10
+ static def ClassFunc()
+ assert_equal(10, val)
+ enddef
+ def ObjFunc()
+ assert_equal(10, val)
+ enddef
+ endclass
+
+ class B extends A
+ endclass
+
+ assert_equal(10, A.val)
+ A.ClassFunc()
+ var a = A.new()
+ a.ObjFunc()
+ var b = B.new()
+ b.ObjFunc()
+
+ def T1(a1: A)
+ a1.ObjFunc()
+ A.ClassFunc()
+ enddef
+ T1(b)
+
+ A.val = 20
+ assert_equal(20, A.val)
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Modifying a parent class variable from a child class method
+ lines =<< trim END
+ vim9script
+
+ class A
+ static val: number = 10
+ endclass
+
+ class B extends A
+ static def ClassFunc()
+ val = 20
+ enddef
+ endclass
+ B.ClassFunc()
+ END
+ v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+ # Reading a parent class variable from a child class method
+ lines =<< trim END
+ vim9script
+
+ class A
+ static val: number = 10
+ endclass
+
+ class B extends A
+ static def ClassFunc()
+ var i = val
+ enddef
+ endclass
+ B.ClassFunc()
+ END
+ v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+ # Modifying a parent class variable from a child object method
+ lines =<< trim END
+ vim9script
+
+ class A
+ static val: number = 10
+ endclass
+
+ class B extends A
+ def ObjFunc()
+ val = 20
+ enddef
+ endclass
+ var b = B.new()
+ b.ObjFunc()
+ END
+ v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+ # Reading a parent class variable from a child object method
+ lines =<< trim END
+ vim9script
+
+ class A
+ static val: number = 10
+ endclass
+
+ class B extends A
+ def ObjFunc()
+ var i = val
+ enddef
+ endclass
+ var b = B.new()
+ b.ObjFunc()
+ END
+ v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+ # Modifying a class variable using an object at script level
+ lines =<< trim END
+ vim9script
+
+ class A
+ static val: number = 10
+ endclass
+ var a = A.new()
+ a.val = 20
+ END
+ v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
+
+ # Reading a class variable using an object at script level
+ lines =<< trim END
+ vim9script
+
+ class A
+ static val: number = 10
+ endclass
+ var a = A.new()
+ var i = a.val
+ END
+ v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
+
+ # Modifying a class variable using an object at function level
+ lines =<< trim END
+ vim9script
+
+ class A
+ static val: number = 10
+ endclass
+
+ def T()
+ var a = A.new()
+ a.val = 20
+ enddef
+ T()
+ END
+ v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
+
+ # Reading a class variable using an object at function level
+ lines =<< trim END
+ vim9script
+
+ class A
+ static val: number = 10
+ endclass
+ def T()
+ var a = A.new()
+ var i = a.val
+ enddef
+ T()
+ END
+ v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
+enddef
+
+" Test for using a duplicate class method and class variable in a child class
+def Test_dup_class_member()
+ # duplicate class variable, class method and overridden object method
+ var lines =<< trim END
+ vim9script
+ class A
+ static sval = 100
+ static def Check()
+ assert_equal(100, sval)
+ enddef
+ def GetVal(): number
+ return sval
+ enddef
+ endclass
+
+ class B extends A
+ static sval = 200
+ static def Check()
+ assert_equal(200, sval)
+ enddef
+ def GetVal(): number
+ return sval
+ enddef
+ endclass
+
+ def T1(aa: A): number
+ return aa.GetVal()
+ enddef
+
+ def T2(bb: B): number
+ return bb.GetVal()
+ enddef
+
+ assert_equal(100, A.sval)
+ assert_equal(200, B.sval)
+ var a = A.new()
+ assert_equal(100, a.GetVal())
+ var b = B.new()
+ assert_equal(200, b.GetVal())
+ assert_equal(200, T1(b))
+ assert_equal(200, T2(b))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # duplicate class variable and class method
+ lines =<< trim END
+ vim9script
+ class A
+ static sval = 100
+ static def Check()
+ assert_equal(100, sval)
+ enddef
+ def GetVal(): number
+ return sval
+ enddef
+ endclass
+
+ class B extends A
+ static sval = 200
+ static def Check()
+ assert_equal(200, sval)
+ enddef
+ endclass
+
+ def T1(aa: A): number
+ return aa.GetVal()
+ enddef
+
+ def T2(bb: B): number
+ return bb.GetVal()
+ enddef
+
+ assert_equal(100, A.sval)
+ assert_equal(200, B.sval)
+ var a = A.new()
+ assert_equal(100, a.GetVal())
+ var b = B.new()
+ assert_equal(100, b.GetVal())
+ assert_equal(100, T1(b))
+ assert_equal(100, T2(b))
+ END
+ v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for calling an instance method using the class
+def Test_instance_method_call_using_class()
+ # Invoke an object method using a class in script context
+ var lines =<< trim END
+ vim9script
+ class A
+ def Foo()
+ echo "foo"
+ enddef
+ endclass
+ A.Foo()
+ END
+ v9.CheckSourceFailure(lines, 'E1376: Object member "Foo" accessible only using class "A" object')
+
+ # Invoke an object method using a class in def function context
+ lines =<< trim END
+ vim9script
+ class A
+ def Foo()
+ echo "foo"
+ enddef
+ endclass
+ def T()
+ A.Foo()
+ enddef
+ T()
+ END
+ v9.CheckSourceFailure(lines, 'E1376: Object member "Foo" accessible only using class "A" object')
+enddef
+
+" Test for duplicate class method and instance method
+def Test_dup_classmethod_objmethod()
+ # Duplicate instance method
+ var lines =<< trim END
+ vim9script
+ class A
+ static def Foo()
+ enddef
+ def Foo()
+ enddef
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
+
+ # Duplicate private instance method
+ lines =<< trim END
+ vim9script
+ class A
+ static def Foo()
+ enddef
+ def _Foo()
+ enddef
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
+
+ # Duplicate class method
+ lines =<< trim END
+ vim9script
+ class A
+ def Foo()
+ enddef
+ static def Foo()
+ enddef
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
+
+ # Duplicate private class method
+ lines =<< trim END
+ vim9script
+ class A
+ def Foo()
+ enddef
+ static def _Foo()
+ enddef
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
+
+ # Duplicate private class and object method
+ lines =<< trim END
+ vim9script
+ class A
+ def _Foo()
+ enddef
+ static def _Foo()
+ enddef
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
+enddef
+
+" Test for an instance method access level comparison with parent instance
+" methods.
+def Test_instance_method_access_level()
+ # Private method in subclass
+ var lines =<< trim END
+ vim9script
+ class A
+ def Foo()
+ enddef
+ endclass
+ class B extends A
+ endclass
+ class C extends B
+ def _Foo()
+ enddef
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1378: Access level of method "_Foo" is different in class "A"')
+
+ # Public method in subclass
+ lines =<< trim END
+ vim9script
+ class A
+ def _Foo()
+ enddef
+ endclass
+ class B extends A
+ endclass
+ class C extends B
+ def Foo()
+ enddef
+ endclass
+ END
+ v9.CheckSourceFailure(lines, 'E1378: Access level of method "Foo" is different in class "A"')
+enddef
+
+def Test_extend_empty_class()
+ var lines =<< trim END
+ vim9script
+ class A
+ endclass
+ class B extends A
+ endclass
+ class C extends B
+ public static rw_class_var = 1
+ public this.rw_obj_var = 2
+ static def ClassMethod(): number
+ return 3
+ enddef
+ def ObjMethod(): number
+ return 4
+ enddef
+ endclass
+ assert_equal(1, C.rw_class_var)
+ assert_equal(3, C.ClassMethod())
+ var c = C.new()
+ assert_equal(2, c.rw_obj_var)
+ assert_equal(4, c.ObjMethod())
+ END
+ v9.CheckSourceSuccess(lines)
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
}
/*
- * Check whether a class/object member variable in "classmembers_gap" /
- * "objmembers_gap" is a duplicate of a member in any of the extended parent
- * class lineage. Returns TRUE if there are no duplicates.
+ * Check method names in the parent class lineage to make sure the access is
+ * the same for overridden methods.
*/
static int
-validate_extends_members(
- garray_T *classmembers_gap,
- garray_T *objmembers_gap,
+validate_extends_methods(
+ garray_T *objmethods_gap,
class_T *extends_cl)
{
- for (int loop = 1; loop <= 2; ++loop)
+ class_T *super = extends_cl;
+ int method_count = objmethods_gap->ga_len;
+ ufunc_T **cl_fp = (ufunc_T **)(objmethods_gap->ga_data);
+
+ while (super != NULL)
{
- // loop == 1: check class members
- // loop == 2: check object members
- int member_count = loop == 1 ? classmembers_gap->ga_len
- : objmembers_gap->ga_len;
- if (member_count == 0)
+ int extends_method_count = super->class_obj_method_count_child;
+ if (extends_method_count == 0)
+ {
+ super = super->class_extends;
continue;
- ocmember_T *members = (ocmember_T *)(loop == 1
- ? classmembers_gap->ga_data
- : objmembers_gap->ga_data);
+ }
- // Validate each member variable
- for (int c_i = 0; c_i < member_count; c_i++)
+ ufunc_T **extends_methods = super->class_obj_methods;
+
+ for (int i = 0; i < extends_method_count; i++)
{
- class_T *p_cl = extends_cl;
- ocmember_T *c_m = members + c_i;
- char_u *pstr = (*c_m->ocm_name == '_')
- ? c_m->ocm_name + 1 : c_m->ocm_name;
+ char_u *pstr = extends_methods[i]->uf_name;
+ int extends_private = (*pstr == '_');
+ if (extends_private)
+ pstr++;
- // Check in all the parent classes in the lineage
- while (p_cl != NULL)
+ for (int j = 0; j < method_count; j++)
{
- int p_member_count = loop == 1
- ? p_cl->class_class_member_count
- : p_cl->class_obj_member_count;
- if (p_member_count == 0)
- continue;
- ocmember_T *p_members = (loop == 1
- ? p_cl->class_class_members
- : p_cl->class_obj_members);
-
- // Compare against all the members in the parent class
- for (int p_i = 0; p_i < p_member_count; p_i++)
+ char_u *qstr = cl_fp[j]->uf_name;
+ int priv_method = (*qstr == '_');
+ if (priv_method)
+ qstr++;
+ if (STRCMP(pstr, qstr) == 0 && priv_method != extends_private)
{
- ocmember_T *p_m = p_members + p_i;
- char_u *qstr = (*p_m->ocm_name == '_')
- ? p_m->ocm_name + 1 : p_m->ocm_name;
- if (STRCMP(pstr, qstr) == 0)
- {
- semsg(_(e_duplicate_member_str), c_m->ocm_name);
- return FALSE;
- }
+ // Method access is different between the super class and
+ // the subclass
+ semsg(_(e_method_str_of_class_str_has_different_access),
+ cl_fp[j]->uf_name, super->class_name);
+ return FALSE;
}
+ }
+ }
+ super = super->class_extends;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Check whether a object member variable in "objmembers_gap" is a duplicate of
+ * a member in any of the extended parent class lineage. Returns TRUE if there
+ * are no duplicates.
+ */
+ static int
+validate_extends_members(
+ garray_T *objmembers_gap,
+ class_T *extends_cl)
+{
+ // loop == 1: check class members
+ // loop == 2: check object members
+ int member_count = objmembers_gap->ga_len;
+ if (member_count == 0)
+ return TRUE;
+
+ ocmember_T *members = (ocmember_T *)(objmembers_gap->ga_data);
+ // Validate each member variable
+ for (int c_i = 0; c_i < member_count; c_i++)
+ {
+ class_T *p_cl = extends_cl;
+ ocmember_T *c_m = members + c_i;
+ char_u *pstr = (*c_m->ocm_name == '_')
+ ? c_m->ocm_name + 1 : c_m->ocm_name;
+
+ // Check in all the parent classes in the lineage
+ while (p_cl != NULL)
+ {
+ int p_member_count = p_cl->class_obj_member_count;
+ if (p_member_count == 0)
+ {
p_cl = p_cl->class_extends;
+ continue;
}
+ ocmember_T *p_members = p_cl->class_obj_members;
+
+ // Compare against all the members in the parent class
+ for (int p_i = 0; p_i < p_member_count; p_i++)
+ {
+ ocmember_T *p_m = p_members + p_i;
+ char_u *qstr = (*p_m->ocm_name == '_')
+ ? p_m->ocm_name + 1 : p_m->ocm_name;
+ if (STRCMP(pstr, qstr) == 0)
+ {
+ semsg(_(e_duplicate_member_str), c_m->ocm_name);
+ return FALSE;
+ }
+ }
+
+ p_cl = p_cl->class_extends;
}
}
* implemented.
*/
static int
-validate_extends_methods(
+validate_abstract_class_methods(
garray_T *classmethods_gap,
garray_T *objmethods_gap,
class_T *extends_cl)
* Returns TRUE if the method "name" is already defined.
*/
static int
-is_duplicate_method(garray_T *fgap, char_u *name)
+is_duplicate_method(
+ garray_T *classmethods_gap,
+ garray_T *objmethods_gap,
+ char_u *name)
{
char_u *pstr = (*name == '_') ? name + 1 : name;
- for (int i = 0; i < fgap->ga_len; ++i)
+ // loop 1: class methods, loop 2: object methods
+ for (int loop = 1; loop <= 2; loop++)
{
- char_u *n = ((ufunc_T **)fgap->ga_data)[i]->uf_name;
- char_u *qstr = *n == '_' ? n + 1 : n;
- if (STRCMP(pstr, qstr) == 0)
+ garray_T *fgap = (loop == 1) ? classmethods_gap : objmethods_gap;
+ for (int i = 0; i < fgap->ga_len; ++i)
{
- semsg(_(e_duplicate_function_str), name);
- return TRUE;
+ char_u *n = ((ufunc_T **)fgap->ga_data)[i]->uf_name;
+ char_u *qstr = *n == '_' ? n + 1 : n;
+ if (STRCMP(pstr, qstr) == 0)
+ {
+ semsg(_(e_duplicate_function_str), name);
+ return TRUE;
+ }
}
}
return FAIL;
}
- // Update the lookup table for the extended class, if nay
+ // Update the lookup table for the extended class, if any
if (extends_cl != NULL)
{
class_T *pclass = extends_cl;
int parent_count = 0;
if (extends_cl != NULL)
- // Include functions from the parent.
+ // Include object methods from the parent.
+ // Don't include the parent class methods.
parent_count = loop == 1
- ? extends_cl->class_class_function_count
+ ? 0
: extends_cl->class_obj_method_count;
*fcount = parent_count + gap->ga_len;
{
ufunc_T *fp = (*fup)[i];
fp->uf_class = cl;
+ if (i < gap->ga_len)
+ fp->uf_defclass = cl;
if (loop == 2)
fp->uf_flags |= FC_OBJECT;
}
break;
}
- garray_T *fgap = has_static || is_new
- ? &classfunctions : &objmethods;
// Check the name isn't used already.
- if (is_duplicate_method(fgap, name))
+ if (is_duplicate_method(&classfunctions, &objmethods, name))
{
success = FALSE;
func_clear_free(uf, FALSE);
break;
}
+ garray_T *fgap = has_static || is_new
+ ? &classfunctions : &objmethods;
if (ga_grow(fgap, 1) == OK)
{
if (is_new)
success = validate_extends_class(extends, &extends_cl);
VIM_CLEAR(extends);
- // Check the new class members and object members are not duplicates of the
- // members in the extended class lineage.
+ // Check the new object methods to make sure their access (public or
+ // private) is the same as that in the extended class lineage.
+ if (success && extends_cl != NULL)
+ success = validate_extends_methods(&objmethods, extends_cl);
+
+ // Check the new class and object variables are not duplicates of the
+ // variables in the extended class lineage.
if (success && extends_cl != NULL)
- success = validate_extends_members(&classmembers, &objmembers,
- extends_cl);
+ success = validate_extends_members(&objmembers, extends_cl);
// When extending an abstract class, make sure all the abstract methods in
// the parent class are implemented. If the current class is an abstract
// class, then there is no need for this check.
if (success && !is_abstract && extends_cl != NULL
&& (extends_cl->class_flags & CLASS_ABSTRACT))
- success = validate_extends_methods(&classfunctions, &objmethods,
- extends_cl);
+ success = validate_abstract_class_methods(&classfunctions,
+ &objmethods, extends_cl);
class_T **intf_classes = NULL;
extends_cl->class_flags |= CLASS_EXTENDED;
}
- // Add class and object members to "cl".
+ // Add class and object variables to "cl".
if (add_members_to_class(&classmembers,
- extends_cl == NULL ? NULL
- : extends_cl->class_class_members,
- extends_cl == NULL ? 0
- : extends_cl->class_class_member_count,
+ NULL,
+ 0,
&cl->class_class_members,
&cl->class_class_member_count) == FAIL
|| add_members_to_class(&objmembers,
member_idx);
if (m == NULL)
{
- semsg(_(e_unknown_variable_str), name);
+ char_u *varname = vim_strnsave(name, len);
+ if (varname != NULL)
+ {
+ if (is_object && class_member_idx(cl, name, len) >= 0)
+ // A class variable with this name is present
+ semsg(_(e_class_member_str_accessible_only_inside_class_str),
+ varname, cl->class_name);
+ else if (!is_object && object_member_idx(cl, name, len) >= 0)
+ // An instance variable with this name is present
+ semsg(_(e_object_member_str_accessible_only_using_object_str),
+ varname, cl->class_name);
+ else
+ semsg(_(e_unknown_variable_str), varname);
+ }
+ vim_free(varname);
return &t_any;
}
fp = method_lookup(cl, rettv->v_type, name, len, NULL);
if (fp == NULL)
{
- semsg(_(e_method_not_found_on_class_str_str), cl->class_name,
- name);
+ method_not_found_msg(cl, rettv->v_type, name, len);
return FAIL;
}
return OK;
}
- semsg(_(e_member_not_found_on_object_str_str), cl->class_name, name);
+ member_not_found_msg(cl, VAR_OBJECT, name, len);
}
else if (rettv->v_type == VAR_CLASS)
ocmember_T *m = class_member_lookup(cl, name, len, &m_idx);
if (m == NULL)
{
- semsg(_(e_member_not_found_on_class_str_str), cl->class_name, name);
+ member_not_found_msg(cl, VAR_CLASS, name, len);
return FAIL;
}
}
/*
- * Returns the index of class member variable "name" in the class "cl".
+ * Returns the index of class variable "name" in the class "cl".
* Returns -1, if the variable is not found.
* If "namelen" is zero, then it is assumed that "name" is NUL terminated.
*/
return did_free;
}
+/*
+ * Echo a class or object method not found message.
+ */
+ void
+method_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len)
+{
+ char_u *method_name = vim_strnsave(name, len);
+ if ((v_type == VAR_OBJECT)
+ && (class_method_idx(cl, name, len) >= 0))
+ {
+ // If this is a class method, then give a different error
+ if (*name == '_')
+ semsg(_(e_cannot_access_private_method_str), method_name);
+ else
+ semsg(_(e_class_member_str_accessible_only_using_class_str),
+ method_name, cl->class_name);
+ }
+ else if ((v_type == VAR_CLASS)
+ && (object_method_idx(cl, name, len) >= 0))
+ {
+ // If this is an object method, then give a different error
+ if (*name == '_')
+ semsg(_(e_cannot_access_private_method_str), method_name);
+ else
+ semsg(_(e_object_member_str_accessible_only_using_object_str),
+ method_name, cl->class_name);
+ }
+ else
+ semsg(_(e_method_not_found_on_class_str_str), cl->class_name,
+ method_name);
+ vim_free(method_name);
+}
+
+/*
+ * Echo a class or object member not found message.
+ */
+ void
+member_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len)
+{
+ char_u *varname = len ? vim_strnsave(name, len) : vim_strsave(name);
+
+ if (v_type == VAR_OBJECT)
+ {
+ if (class_member_idx(cl, name, len) >= 0)
+ semsg(_(e_class_member_str_accessible_only_using_class_str),
+ varname, cl->class_name);
+ else
+ semsg(_(e_member_not_found_on_object_str_str), cl->class_name,
+ varname);
+ }
+ else
+ {
+ if (object_member_idx(cl, name, len) >= 0)
+ semsg(_(e_object_member_str_accessible_only_using_object_str),
+ varname, cl->class_name);
+ else
+ semsg(_(e_class_member_str_not_found_in_class_str),
+ varname, cl->class_name);
+ }
+ vim_free(varname);
+}
+
/*
* Return TRUE when the class "cl", its base class or one of the implemented
* interfaces matches the class "other_cl".