2022-12-08 15:32:33 +00:00
|
|
|
" Test Vim9 classes
|
|
|
|
|
|
|
|
source check.vim
|
|
|
|
import './vim9.vim' as v9
|
|
|
|
|
|
|
|
def Test_class_basic()
|
|
|
|
var lines =<< trim END
|
|
|
|
class NotWorking
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1316:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class notWorking
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1314:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Not@working
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1315:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
abstract noclass Something
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E475:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
abstract classy Something
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E475:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
endcl
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1065:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
2023-01-28 19:19:03 +00:00
|
|
|
endclass school's out
|
2022-12-08 15:32:33 +00:00
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E488:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
endclass | echo 'done'
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E488:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
this
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1317:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
this.
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1317:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
this .count
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1317:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
this. count
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1317:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
this.count: number
|
|
|
|
that.count
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1318: Not a valid command in a class: that.count')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
this.count
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1022:')
|
|
|
|
|
2022-12-23 17:56:27 +00:00
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
def new()
|
|
|
|
this.state = 0
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
var obj = Something.new()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1089:')
|
|
|
|
|
2022-12-08 15:32:33 +00:00
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
this.count : number
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1059:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Something
|
|
|
|
this.count:number
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1069:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class TextPosition
|
|
|
|
this.lnum: number
|
2022-12-10 18:42:12 +00:00
|
|
|
this.col: number
|
2022-12-09 21:41:48 +00:00
|
|
|
|
2022-12-20 13:38:22 +00:00
|
|
|
# make a nicely formatted string
|
2022-12-09 21:41:48 +00:00
|
|
|
def ToString(): string
|
|
|
|
return $'({this.lnum}, {this.col})'
|
|
|
|
enddef
|
2022-12-08 15:32:33 +00:00
|
|
|
endclass
|
|
|
|
|
2022-12-08 20:42:00 +00:00
|
|
|
# use the automatically generated new() method
|
|
|
|
var pos = TextPosition.new(2, 12)
|
|
|
|
assert_equal(2, pos.lnum)
|
|
|
|
assert_equal(12, pos.col)
|
2022-12-09 21:41:48 +00:00
|
|
|
|
|
|
|
# call an object method
|
|
|
|
assert_equal('(2, 12)', pos.ToString())
|
2023-01-12 21:08:53 +00:00
|
|
|
|
|
|
|
assert_equal(v:t_class, type(TextPosition))
|
|
|
|
assert_equal(v:t_object, type(pos))
|
|
|
|
assert_equal('class<TextPosition>', typename(TextPosition))
|
|
|
|
assert_equal('object<TextPosition>', typename(pos))
|
2022-12-08 15:32:33 +00:00
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-02-25 19:59:31 +00:00
|
|
|
def Test_class_defined_twice()
|
|
|
|
# class defined twice should fail
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class There
|
|
|
|
endclass
|
|
|
|
class There
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1041: Redefining script item: "There"')
|
|
|
|
|
|
|
|
# one class, reload same script twice is OK
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class There
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
writefile(lines, 'XclassTwice.vim', 'D')
|
|
|
|
source XclassTwice.vim
|
|
|
|
source XclassTwice.vim
|
|
|
|
enddef
|
|
|
|
|
2023-02-26 18:58:23 +00:00
|
|
|
def Test_returning_null_object()
|
|
|
|
# this was causing an internal error
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class BufferList
|
|
|
|
def Current(): any
|
|
|
|
return null_object
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var buffers = BufferList.new()
|
|
|
|
echo buffers.Current()
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-03-11 20:56:35 +00:00
|
|
|
def Test_using_null_class()
|
|
|
|
var lines =<< trim END
|
|
|
|
@_ = null_class.member
|
|
|
|
END
|
|
|
|
v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:'])
|
|
|
|
enddef
|
|
|
|
|
2023-01-27 13:16:19 +00:00
|
|
|
def Test_class_interface_wrong_end()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
abstract class SomeName
|
|
|
|
this.member = 'text'
|
|
|
|
endinterface
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
export interface AnotherName
|
|
|
|
this.member: string
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
|
|
|
|
enddef
|
|
|
|
|
2023-02-17 21:08:50 +00:00
|
|
|
def Test_object_not_set()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class State
|
|
|
|
this.value = 'xyz'
|
|
|
|
endclass
|
|
|
|
|
2023-02-17 21:29:57 +00:00
|
|
|
var state: State
|
2023-02-17 21:08:50 +00:00
|
|
|
var db = {'xyz': 789}
|
|
|
|
echo db[state.value]
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1360:')
|
2023-02-18 14:42:44 +00:00
|
|
|
|
2023-03-02 17:38:33 +00:00
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Class
|
|
|
|
this.id: string
|
|
|
|
def Method1()
|
|
|
|
echo 'Method1' .. this.id
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var obj: Class
|
|
|
|
def Func()
|
|
|
|
obj.Method1()
|
|
|
|
enddef
|
|
|
|
Func()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1360:')
|
|
|
|
|
2023-02-18 14:42:44 +00:00
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Background
|
|
|
|
this.background = 'dark'
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class Colorscheme
|
|
|
|
this._bg: Background
|
|
|
|
|
|
|
|
def GetBackground(): string
|
|
|
|
return this._bg.background
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var bg: Background # UNINITIALIZED
|
|
|
|
echo Colorscheme.new(bg).GetBackground()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Background> but got object<Unknown>')
|
2023-03-03 15:05:30 +00:00
|
|
|
|
|
|
|
# TODO: this should not give an error but be handled at runtime
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Class
|
|
|
|
this.id: string
|
|
|
|
def Method1()
|
|
|
|
echo 'Method1' .. this.id
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var obj = null_object
|
|
|
|
def Func()
|
|
|
|
obj.Method1()
|
|
|
|
enddef
|
|
|
|
Func()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1363:')
|
2023-02-17 21:08:50 +00:00
|
|
|
enddef
|
|
|
|
|
2022-12-10 18:42:12 +00:00
|
|
|
def Test_class_member_initializer()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class TextPosition
|
|
|
|
this.lnum: number = 1
|
|
|
|
this.col: number = 1
|
|
|
|
|
2022-12-20 13:38:22 +00:00
|
|
|
# constructor with only the line number
|
2022-12-10 18:42:12 +00:00
|
|
|
def new(lnum: number)
|
|
|
|
this.lnum = lnum
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var pos = TextPosition.new(3)
|
|
|
|
assert_equal(3, pos.lnum)
|
|
|
|
assert_equal(1, pos.col)
|
|
|
|
|
|
|
|
var instr = execute('disassemble TextPosition.new')
|
|
|
|
assert_match('new\_s*' ..
|
2022-12-10 19:03:51 +00:00
|
|
|
'0 NEW TextPosition size \d\+\_s*' ..
|
2022-12-10 18:42:12 +00:00
|
|
|
'\d PUSHNR 1\_s*' ..
|
|
|
|
'\d STORE_THIS 0\_s*' ..
|
|
|
|
'\d PUSHNR 1\_s*' ..
|
|
|
|
'\d STORE_THIS 1\_s*' ..
|
|
|
|
'this.lnum = lnum\_s*' ..
|
|
|
|
'\d LOAD arg\[-1]\_s*' ..
|
|
|
|
'\d PUSHNR 0\_s*' ..
|
|
|
|
'\d LOAD $0\_s*' ..
|
|
|
|
'\d\+ STOREINDEX object\_s*' ..
|
|
|
|
'\d\+ RETURN object.*',
|
|
|
|
instr)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-02-18 18:38:37 +00:00
|
|
|
def Test_member_any_used_as_object()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Inner
|
|
|
|
this.value: number = 0
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class Outer
|
|
|
|
this.inner: any
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def F(outer: Outer)
|
|
|
|
outer.inner.value = 1
|
|
|
|
enddef
|
|
|
|
|
|
|
|
var inner_obj = Inner.new(0)
|
|
|
|
var outer_obj = Outer.new(inner_obj)
|
|
|
|
F(outer_obj)
|
|
|
|
assert_equal(1, inner_obj.value)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Inner
|
|
|
|
this.value: number = 0
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class Outer
|
|
|
|
this.inner: Inner
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def F(outer: Outer)
|
|
|
|
outer.inner.value = 1
|
|
|
|
enddef
|
|
|
|
|
|
|
|
def Test_assign_to_nested_typed_member()
|
|
|
|
var inner = Inner.new(0)
|
|
|
|
var outer = Outer.new(inner)
|
|
|
|
F(outer)
|
|
|
|
assert_equal(1, inner.value)
|
|
|
|
enddef
|
|
|
|
|
|
|
|
Test_assign_to_nested_typed_member()
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-01-15 15:51:48 +00:00
|
|
|
def Test_assignment_with_operator()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Foo
|
|
|
|
this.x: number
|
|
|
|
|
|
|
|
def Add(n: number)
|
|
|
|
this.x += n
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var f = Foo.new(3)
|
|
|
|
f.Add(17)
|
|
|
|
assert_equal(20, f.x)
|
2023-04-24 17:15:25 +01:00
|
|
|
|
|
|
|
def AddToFoo(obj: Foo)
|
|
|
|
obj.x += 3
|
|
|
|
enddef
|
|
|
|
|
|
|
|
AddToFoo(f)
|
|
|
|
assert_equal(23, f.x)
|
2023-01-15 15:51:48 +00:00
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-01-15 16:54:57 +00:00
|
|
|
def Test_list_of_objects()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Foo
|
|
|
|
def Add()
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def ProcessList(fooList: list<Foo>)
|
|
|
|
for foo in fooList
|
|
|
|
foo.Add()
|
|
|
|
endfor
|
|
|
|
enddef
|
|
|
|
|
|
|
|
var l: list<Foo> = [Foo.new()]
|
|
|
|
ProcessList(l)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-01-15 20:18:55 +00:00
|
|
|
def Test_expr_after_using_object()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Something
|
|
|
|
this.label: string = ''
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def Foo(): Something
|
|
|
|
var v = Something.new()
|
|
|
|
echo 'in Foo(): ' .. typename(v)
|
|
|
|
return v
|
|
|
|
enddef
|
|
|
|
|
|
|
|
Foo()
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2022-12-13 18:43:22 +00:00
|
|
|
def Test_class_default_new()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class TextPosition
|
|
|
|
this.lnum: number = 1
|
|
|
|
this.col: number = 1
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var pos = TextPosition.new()
|
|
|
|
assert_equal(1, pos.lnum)
|
|
|
|
assert_equal(1, pos.col)
|
|
|
|
|
|
|
|
pos = TextPosition.new(v:none, v:none)
|
|
|
|
assert_equal(1, pos.lnum)
|
|
|
|
assert_equal(1, pos.col)
|
|
|
|
|
|
|
|
pos = TextPosition.new(3, 22)
|
|
|
|
assert_equal(3, pos.lnum)
|
|
|
|
assert_equal(22, pos.col)
|
|
|
|
|
|
|
|
pos = TextPosition.new(v:none, 33)
|
|
|
|
assert_equal(1, pos.lnum)
|
|
|
|
assert_equal(33, pos.col)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Person
|
|
|
|
this.name: string
|
|
|
|
this.age: number = 42
|
|
|
|
this.education: string = "unknown"
|
|
|
|
|
|
|
|
def new(this.name, this.age = v:none, this.education = v:none)
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var piet = Person.new("Piet")
|
|
|
|
assert_equal("Piet", piet.name)
|
|
|
|
assert_equal(42, piet.age)
|
|
|
|
assert_equal("unknown", piet.education)
|
|
|
|
|
|
|
|
var chris = Person.new("Chris", 4, "none")
|
|
|
|
assert_equal("Chris", chris.name)
|
|
|
|
assert_equal(4, chris.age)
|
|
|
|
assert_equal("none", chris.education)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2022-12-13 21:14:28 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Person
|
|
|
|
this.name: string
|
|
|
|
this.age: number = 42
|
|
|
|
this.education: string = "unknown"
|
|
|
|
|
|
|
|
def new(this.name, this.age = v:none, this.education = v:none)
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var missing = Person.new()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E119:')
|
2022-12-13 18:43:22 +00:00
|
|
|
enddef
|
|
|
|
|
2022-12-13 21:14:28 +00:00
|
|
|
def Test_class_object_member_inits()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class TextPosition
|
|
|
|
this.lnum: number
|
|
|
|
this.col = 1
|
|
|
|
this.addcol: number = 2
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var pos = TextPosition.new()
|
|
|
|
assert_equal(0, pos.lnum)
|
|
|
|
assert_equal(1, pos.col)
|
|
|
|
assert_equal(2, pos.addcol)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class TextPosition
|
|
|
|
this.lnum
|
|
|
|
this.col = 1
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1022:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class TextPosition
|
|
|
|
this.lnum = v:none
|
|
|
|
this.col = 1
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1330:')
|
|
|
|
enddef
|
|
|
|
|
2022-12-14 20:59:32 +00:00
|
|
|
def Test_class_object_member_access()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Triple
|
|
|
|
this._one = 1
|
|
|
|
this.two = 2
|
|
|
|
public this.three = 3
|
|
|
|
|
|
|
|
def GetOne(): number
|
|
|
|
return this._one
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var trip = Triple.new()
|
|
|
|
assert_equal(1, trip.GetOne())
|
|
|
|
assert_equal(2, trip.two)
|
|
|
|
assert_equal(3, trip.three)
|
|
|
|
assert_fails('echo trip._one', 'E1333')
|
|
|
|
|
|
|
|
assert_fails('trip._one = 11', 'E1333')
|
|
|
|
assert_fails('trip.two = 22', 'E1335')
|
|
|
|
trip.three = 33
|
|
|
|
assert_equal(33, trip.three)
|
2022-12-18 21:42:55 +00:00
|
|
|
|
|
|
|
assert_fails('trip.four = 4', 'E1334')
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2022-12-24 21:24:06 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class MyCar
|
|
|
|
this.make: string
|
2023-01-03 19:08:50 +00:00
|
|
|
this.age = 5
|
2022-12-24 21:24:06 +00:00
|
|
|
|
|
|
|
def new(make_arg: string)
|
|
|
|
this.make = make_arg
|
|
|
|
enddef
|
|
|
|
|
|
|
|
def GetMake(): string
|
|
|
|
return $"make = {this.make}"
|
|
|
|
enddef
|
2023-01-03 19:08:50 +00:00
|
|
|
def GetAge(): number
|
|
|
|
return this.age
|
|
|
|
enddef
|
2022-12-24 21:24:06 +00:00
|
|
|
endclass
|
|
|
|
|
|
|
|
var c = MyCar.new("abc")
|
|
|
|
assert_equal('make = abc', c.GetMake())
|
|
|
|
|
|
|
|
c = MyCar.new("def")
|
|
|
|
assert_equal('make = def', c.GetMake())
|
|
|
|
|
|
|
|
var c2 = MyCar.new("123")
|
|
|
|
assert_equal('make = 123', c2.GetMake())
|
2023-01-03 19:08:50 +00:00
|
|
|
|
|
|
|
def CheckCar()
|
|
|
|
assert_equal("make = def", c.GetMake())
|
|
|
|
assert_equal(5, c.GetAge())
|
|
|
|
enddef
|
|
|
|
CheckCar()
|
2022-12-24 21:24:06 +00:00
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2022-12-25 19:31:36 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class MyCar
|
|
|
|
this.make: string
|
|
|
|
|
|
|
|
def new(make_arg: string)
|
|
|
|
this.make = make_arg
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var c = MyCar.new("abc")
|
|
|
|
var c = MyCar.new("def")
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1041:')
|
2023-01-24 13:03:37 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Foo
|
|
|
|
this.x: list<number> = []
|
|
|
|
|
|
|
|
def Add(n: number): any
|
|
|
|
this.x->add(n)
|
|
|
|
return this
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
echo Foo.new().Add(1).Add(2).x
|
|
|
|
echo Foo.new().Add(1).Add(2)
|
|
|
|
.x
|
|
|
|
echo Foo.new().Add(1)
|
|
|
|
.Add(2).x
|
|
|
|
echo Foo.new()
|
|
|
|
.Add(1).Add(2).x
|
|
|
|
echo Foo.new()
|
|
|
|
.Add(1)
|
|
|
|
.Add(2)
|
|
|
|
.x
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2022-12-18 21:42:55 +00:00
|
|
|
enddef
|
|
|
|
|
2023-01-02 20:32:24 +00:00
|
|
|
def Test_class_object_compare()
|
|
|
|
var class_lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Item
|
|
|
|
this.nr = 0
|
|
|
|
this.name = 'xx'
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
|
|
|
|
# used at the script level and in a compiled function
|
|
|
|
var test_lines =<< trim END
|
|
|
|
var i1 = Item.new()
|
|
|
|
assert_equal(i1, i1)
|
|
|
|
assert_true(i1 is i1)
|
|
|
|
var i2 = Item.new()
|
|
|
|
assert_equal(i1, i2)
|
|
|
|
assert_false(i1 is i2)
|
|
|
|
var i3 = Item.new(0, 'xx')
|
|
|
|
assert_equal(i1, i3)
|
|
|
|
|
|
|
|
var io1 = Item.new(1, 'xx')
|
|
|
|
assert_notequal(i1, io1)
|
|
|
|
var io2 = Item.new(0, 'yy')
|
|
|
|
assert_notequal(i1, io2)
|
|
|
|
END
|
|
|
|
|
|
|
|
v9.CheckScriptSuccess(class_lines + test_lines)
|
2023-01-03 14:01:21 +00:00
|
|
|
v9.CheckScriptSuccess(
|
|
|
|
class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
|
2023-01-02 20:32:24 +00:00
|
|
|
|
|
|
|
for op in ['>', '>=', '<', '<=', '=~', '!~']
|
|
|
|
var op_lines = [
|
|
|
|
'var i1 = Item.new()',
|
|
|
|
'var i2 = Item.new()',
|
|
|
|
'echo i1 ' .. op .. ' i2',
|
|
|
|
]
|
|
|
|
v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
|
2023-01-03 14:01:21 +00:00
|
|
|
v9.CheckScriptFailure(class_lines
|
|
|
|
+ ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
|
2023-01-02 20:32:24 +00:00
|
|
|
endfor
|
|
|
|
enddef
|
|
|
|
|
2023-01-11 21:14:17 +00:00
|
|
|
def Test_object_type()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class One
|
|
|
|
this.one = 1
|
|
|
|
endclass
|
|
|
|
class Two
|
|
|
|
this.two = 2
|
|
|
|
endclass
|
|
|
|
class TwoMore extends Two
|
|
|
|
this.more = 9
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var o: One = One.new()
|
|
|
|
var t: Two = Two.new()
|
|
|
|
var m: TwoMore = TwoMore.new()
|
|
|
|
var tm: Two = TwoMore.new()
|
|
|
|
|
|
|
|
t = m
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class One
|
|
|
|
this.one = 1
|
|
|
|
endclass
|
|
|
|
class Two
|
|
|
|
this.two = 2
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var o: One = Two.new()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
|
2023-01-12 15:01:32 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface One
|
|
|
|
def GetMember(): number
|
|
|
|
endinterface
|
|
|
|
class Two implements One
|
|
|
|
this.one = 1
|
|
|
|
def GetMember(): number
|
|
|
|
return this.one
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var o: One = Two.new(5)
|
|
|
|
assert_equal(5, o.GetMember())
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-16 16:39:37 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Num
|
|
|
|
this.n: number = 0
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def Ref(name: string): func(Num): Num
|
|
|
|
return (arg: Num): Num => {
|
|
|
|
return eval(name)(arg)
|
|
|
|
}
|
|
|
|
enddef
|
|
|
|
|
|
|
|
const Fn = Ref('Double')
|
|
|
|
var Double = (m: Num): Num => Num.new(m.n * 2)
|
|
|
|
|
|
|
|
echo Fn(Num.new(4))
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-11 21:14:17 +00:00
|
|
|
enddef
|
|
|
|
|
2023-01-01 19:53:30 +00:00
|
|
|
def Test_class_member()
|
|
|
|
# check access rules
|
2022-12-18 21:42:55 +00:00
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class TextPos
|
|
|
|
this.lnum = 1
|
|
|
|
this.col = 1
|
|
|
|
static counter = 0
|
2022-12-31 19:01:02 +00:00
|
|
|
static _secret = 7
|
|
|
|
public static anybody = 42
|
2022-12-18 21:42:55 +00:00
|
|
|
|
2023-01-01 12:58:33 +00:00
|
|
|
static def AddToCounter(nr: number)
|
2022-12-18 21:42:55 +00:00
|
|
|
counter += nr
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
assert_equal(0, TextPos.counter)
|
|
|
|
TextPos.AddToCounter(3)
|
|
|
|
assert_equal(3, TextPos.counter)
|
2022-12-23 17:56:27 +00:00
|
|
|
assert_fails('echo TextPos.noSuchMember', 'E1338:')
|
2023-01-28 19:19:03 +00:00
|
|
|
|
2023-01-04 18:54:09 +00:00
|
|
|
def GetCounter(): number
|
|
|
|
return TextPos.counter
|
|
|
|
enddef
|
|
|
|
assert_equal(3, GetCounter())
|
2022-12-18 21:42:55 +00:00
|
|
|
|
2022-12-23 17:56:27 +00:00
|
|
|
assert_fails('TextPos.noSuchMember = 2', 'E1337:')
|
2022-12-31 19:01:02 +00:00
|
|
|
assert_fails('TextPos.counter = 5', 'E1335:')
|
|
|
|
assert_fails('TextPos.counter += 5', 'E1335:')
|
|
|
|
|
|
|
|
assert_fails('echo TextPos._secret', 'E1333:')
|
|
|
|
assert_fails('TextPos._secret = 8', 'E1333:')
|
|
|
|
|
|
|
|
assert_equal(42, TextPos.anybody)
|
|
|
|
TextPos.anybody = 12
|
|
|
|
assert_equal(12, TextPos.anybody)
|
|
|
|
TextPos.anybody += 5
|
|
|
|
assert_equal(17, TextPos.anybody)
|
2022-12-14 20:59:32 +00:00
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-01 19:53:30 +00:00
|
|
|
|
2023-01-15 15:51:48 +00:00
|
|
|
# example in the help
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class OtherThing
|
|
|
|
this.size: number
|
|
|
|
static totalSize: number
|
|
|
|
|
|
|
|
def new(this.size)
|
|
|
|
totalSize += this.size
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
assert_equal(0, OtherThing.totalSize)
|
|
|
|
var to3 = OtherThing.new(3)
|
|
|
|
assert_equal(3, OtherThing.totalSize)
|
|
|
|
var to7 = OtherThing.new(7)
|
|
|
|
assert_equal(10, OtherThing.totalSize)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
2023-01-24 15:07:04 +00:00
|
|
|
# access private member in lambda
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Foo
|
|
|
|
this._x: number = 0
|
|
|
|
|
|
|
|
def Add(n: number): number
|
|
|
|
const F = (): number => this._x + n
|
|
|
|
return F()
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var foo = Foo.new()
|
|
|
|
assert_equal(5, foo.Add(5))
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
2023-05-19 19:01:17 +01:00
|
|
|
# access private member in lambda body
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Foo
|
|
|
|
this._x: number = 6
|
|
|
|
|
|
|
|
def Add(n: number): number
|
|
|
|
var Lam = () => {
|
|
|
|
this._x = this._x + n
|
|
|
|
}
|
|
|
|
Lam()
|
|
|
|
return this._x
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var foo = Foo.new()
|
|
|
|
assert_equal(13, foo.Add(7))
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
2023-01-01 19:53:30 +00:00
|
|
|
# check shadowing
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Some
|
|
|
|
static count = 0
|
|
|
|
def Method(count: number)
|
|
|
|
echo count
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var s = Some.new()
|
|
|
|
s.Method(7)
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Some
|
|
|
|
static count = 0
|
|
|
|
def Method(arg: number)
|
|
|
|
var count = 3
|
|
|
|
echo arg count
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var s = Some.new()
|
|
|
|
s.Method(7)
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
|
2022-12-14 20:59:32 +00:00
|
|
|
enddef
|
|
|
|
|
2023-01-05 13:16:04 +00:00
|
|
|
func Test_class_garbagecollect()
|
|
|
|
let lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Point
|
|
|
|
this.p = [2, 3]
|
|
|
|
static pl = ['a', 'b']
|
|
|
|
static pd = {a: 'a', b: 'b'}
|
|
|
|
endclass
|
|
|
|
|
|
|
|
echo Point.pl Point.pd
|
|
|
|
call test_garbagecollect_now()
|
|
|
|
echo Point.pl Point.pd
|
|
|
|
END
|
|
|
|
call v9.CheckScriptSuccess(lines)
|
|
|
|
endfunc
|
|
|
|
|
2023-01-01 12:58:33 +00:00
|
|
|
def Test_class_function()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Value
|
|
|
|
this.value = 0
|
|
|
|
static objects = 0
|
|
|
|
|
|
|
|
def new(v: number)
|
|
|
|
this.value = v
|
|
|
|
++objects
|
|
|
|
enddef
|
|
|
|
|
|
|
|
static def GetCount(): number
|
|
|
|
return objects
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
assert_equal(0, Value.GetCount())
|
|
|
|
var v1 = Value.new(2)
|
|
|
|
assert_equal(1, Value.GetCount())
|
|
|
|
var v2 = Value.new(7)
|
|
|
|
assert_equal(2, Value.GetCount())
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-02-21 19:55:14 +00:00
|
|
|
def Test_class_defcompile()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class C
|
|
|
|
def Fo(i: number): string
|
|
|
|
return i
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
defcompile C.Fo
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class C
|
|
|
|
static def Fc(): number
|
|
|
|
return 'x'
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
defcompile C.Fc
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
|
|
|
|
enddef
|
|
|
|
|
2022-12-14 17:30:37 +00:00
|
|
|
def Test_class_object_to_string()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class TextPosition
|
|
|
|
this.lnum = 1
|
|
|
|
this.col = 22
|
|
|
|
endclass
|
|
|
|
|
|
|
|
assert_equal("class TextPosition", string(TextPosition))
|
|
|
|
|
|
|
|
var pos = TextPosition.new()
|
|
|
|
assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
2022-12-13 21:14:28 +00:00
|
|
|
|
2023-01-05 19:59:18 +00:00
|
|
|
def Test_interface_basics()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
interface Something
|
|
|
|
this.value: string
|
|
|
|
static count: number
|
|
|
|
def GetCount(): number
|
|
|
|
endinterface
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
interface SomethingWrong
|
|
|
|
static count = 7
|
|
|
|
endinterface
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1342:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface Some
|
|
|
|
static count: number
|
|
|
|
def Method(count: number)
|
|
|
|
endinterface
|
|
|
|
END
|
2023-04-18 19:07:29 +01:00
|
|
|
v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count', 5)
|
2023-01-13 17:36:49 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface Some
|
|
|
|
this.value: number
|
|
|
|
def Method(value: number)
|
|
|
|
endinterface
|
|
|
|
END
|
2023-04-18 19:07:29 +01:00
|
|
|
# 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)
|
2023-01-05 19:59:18 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
interface somethingWrong
|
|
|
|
static count = 7
|
|
|
|
endinterface
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
interface SomethingWrong
|
|
|
|
this.value: string
|
|
|
|
static count = 7
|
|
|
|
def GetCount(): number
|
|
|
|
endinterface
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1344:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
interface SomethingWrong
|
|
|
|
this.value: string
|
|
|
|
static count: number
|
|
|
|
def GetCount(): number
|
|
|
|
return 5
|
|
|
|
enddef
|
|
|
|
endinterface
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
|
2023-01-26 20:36:56 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
export interface EnterExit
|
|
|
|
def Enter(): void
|
|
|
|
def Exit(): void
|
|
|
|
endinterface
|
|
|
|
END
|
|
|
|
writefile(lines, 'XdefIntf.vim', 'D')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
import './XdefIntf.vim' as defIntf
|
|
|
|
export def With(ee: defIntf.EnterExit, F: func)
|
|
|
|
ee.Enter()
|
|
|
|
try
|
|
|
|
F()
|
|
|
|
finally
|
|
|
|
ee.Exit()
|
|
|
|
endtry
|
|
|
|
enddef
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-27 13:16:19 +00:00
|
|
|
|
|
|
|
var imported =<< trim END
|
|
|
|
vim9script
|
|
|
|
export abstract class EnterExit
|
|
|
|
def Enter(): void
|
|
|
|
enddef
|
|
|
|
def Exit(): void
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
writefile(imported, 'XdefIntf2.vim', 'D')
|
|
|
|
|
|
|
|
lines[1] = " import './XdefIntf2.vim' as defIntf"
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-05 19:59:18 +00:00
|
|
|
enddef
|
|
|
|
|
2023-01-06 18:42:20 +00:00
|
|
|
def Test_class_implements_interface()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface Some
|
|
|
|
static count: number
|
|
|
|
def Method(nr: number)
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
class SomeImpl implements Some
|
|
|
|
static count: number
|
|
|
|
def Method(nr: number)
|
|
|
|
echo nr
|
|
|
|
enddef
|
|
|
|
endclass
|
2023-01-07 14:51:03 +00:00
|
|
|
|
|
|
|
interface Another
|
|
|
|
this.member: string
|
|
|
|
endinterface
|
|
|
|
|
2023-02-25 19:59:31 +00:00
|
|
|
class AnotherImpl implements Some, Another
|
2023-01-07 14:51:03 +00:00
|
|
|
this.member = 'abc'
|
|
|
|
static count: number
|
|
|
|
def Method(nr: number)
|
|
|
|
echo nr
|
|
|
|
enddef
|
|
|
|
endclass
|
2023-01-06 18:42:20 +00:00
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
2023-01-07 14:51:03 +00:00
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface Some
|
|
|
|
static counter: number
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
class SomeImpl implements Some implements Some
|
|
|
|
static count: number
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1350:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface Some
|
|
|
|
static counter: number
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
class SomeImpl implements Some, Some
|
|
|
|
static count: number
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
|
|
|
|
|
2023-01-06 18:42:20 +00:00
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface Some
|
|
|
|
static counter: number
|
|
|
|
def Method(nr: number)
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
class SomeImpl implements Some
|
|
|
|
static count: number
|
|
|
|
def Method(nr: number)
|
|
|
|
echo nr
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface Some
|
|
|
|
static count: number
|
|
|
|
def Methods(nr: number)
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
class SomeImpl implements Some
|
|
|
|
static count: number
|
|
|
|
def Method(nr: number)
|
|
|
|
echo nr
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
|
2023-01-16 19:43:47 +00:00
|
|
|
|
|
|
|
# Check different order of members in class and interface works.
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface Result
|
2023-01-16 20:47:57 +00:00
|
|
|
public this.label: string
|
2023-01-16 19:43:47 +00:00
|
|
|
this.errpos: number
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
# order of members is opposite of interface
|
|
|
|
class Failure implements Result
|
|
|
|
this.errpos: number = 42
|
2023-01-16 20:47:57 +00:00
|
|
|
public this.label: string = 'label'
|
2023-01-16 19:43:47 +00:00
|
|
|
endclass
|
|
|
|
|
|
|
|
def Test()
|
|
|
|
var result: Result = Failure.new()
|
|
|
|
|
|
|
|
assert_equal('label', result.label)
|
|
|
|
assert_equal(42, result.errpos)
|
2023-01-16 20:47:57 +00:00
|
|
|
|
|
|
|
result.label = 'different'
|
|
|
|
assert_equal('different', result.label)
|
|
|
|
assert_equal(42, result.errpos)
|
2023-01-16 19:43:47 +00:00
|
|
|
enddef
|
|
|
|
|
|
|
|
Test()
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-06 18:42:20 +00:00
|
|
|
enddef
|
|
|
|
|
2023-01-28 15:19:40 +00:00
|
|
|
def Test_call_interface_method()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
interface Base
|
|
|
|
def Enter(): void
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
class Child implements Base
|
|
|
|
def Enter(): void
|
|
|
|
g:result ..= 'child'
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def F(obj: Base)
|
|
|
|
obj.Enter()
|
|
|
|
enddef
|
|
|
|
|
|
|
|
g:result = ''
|
|
|
|
F(Child.new())
|
|
|
|
assert_equal('child', g:result)
|
|
|
|
unlet g:result
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
def Enter(): void
|
|
|
|
g:result ..= 'base'
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class Child extends Base
|
|
|
|
def Enter(): void
|
|
|
|
g:result ..= 'child'
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def F(obj: Base)
|
|
|
|
obj.Enter()
|
|
|
|
enddef
|
|
|
|
|
|
|
|
g:result = ''
|
|
|
|
F(Child.new())
|
|
|
|
assert_equal('child', g:result)
|
|
|
|
unlet g:result
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-30 20:24:23 +00:00
|
|
|
|
2023-02-04 15:45:27 +00:00
|
|
|
# method of interface returns a value
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
interface Base
|
|
|
|
def Enter(): string
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
class Child implements Base
|
|
|
|
def Enter(): string
|
|
|
|
g:result ..= 'child'
|
|
|
|
return "/resource"
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def F(obj: Base)
|
|
|
|
var r = obj.Enter()
|
|
|
|
g:result ..= r
|
|
|
|
enddef
|
|
|
|
|
|
|
|
g:result = ''
|
|
|
|
F(Child.new())
|
|
|
|
assert_equal('child/resource', g:result)
|
|
|
|
unlet g:result
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
def Enter(): string
|
|
|
|
return null_string
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class Child extends Base
|
|
|
|
def Enter(): string
|
|
|
|
g:result ..= 'child'
|
|
|
|
return "/resource"
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def F(obj: Base)
|
|
|
|
var r = obj.Enter()
|
|
|
|
g:result ..= r
|
|
|
|
enddef
|
|
|
|
|
|
|
|
g:result = ''
|
|
|
|
F(Child.new())
|
|
|
|
assert_equal('child/resource', g:result)
|
|
|
|
unlet g:result
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
|
2023-01-30 20:24:23 +00:00
|
|
|
# No class that implements the interface.
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface IWithEE
|
|
|
|
def Enter(): any
|
|
|
|
def Exit(): void
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
def With1(ee: IWithEE, F: func)
|
|
|
|
var r = ee.Enter()
|
|
|
|
enddef
|
|
|
|
|
|
|
|
defcompile
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-28 15:19:40 +00:00
|
|
|
enddef
|
|
|
|
|
2023-01-07 12:08:41 +00:00
|
|
|
def Test_class_used_as_type()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Point
|
|
|
|
this.x = 0
|
|
|
|
this.y = 0
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var p: Point
|
|
|
|
p = Point.new(2, 33)
|
|
|
|
assert_equal(2, p.x)
|
|
|
|
assert_equal(33, p.y)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
interface HasX
|
|
|
|
this.x: number
|
|
|
|
endinterface
|
|
|
|
|
|
|
|
class Point implements HasX
|
|
|
|
this.x = 0
|
|
|
|
this.y = 0
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var p: Point
|
|
|
|
p = Point.new(2, 33)
|
|
|
|
var hx = p
|
|
|
|
assert_equal(2, hx.x)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Point
|
|
|
|
this.x = 0
|
|
|
|
this.y = 0
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var p: Point
|
|
|
|
p = 'text'
|
|
|
|
END
|
2023-01-11 21:14:17 +00:00
|
|
|
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
|
2023-01-07 12:08:41 +00:00
|
|
|
enddef
|
|
|
|
|
2023-01-08 19:54:10 +00:00
|
|
|
def Test_class_extends()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
this.one = 1
|
|
|
|
def GetOne(): number
|
|
|
|
return this.one
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
class Child extends Base
|
|
|
|
this.two = 2
|
|
|
|
def GetTotal(): number
|
|
|
|
return this.one + this.two
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
var o = Child.new()
|
|
|
|
assert_equal(1, o.one)
|
|
|
|
assert_equal(2, o.two)
|
|
|
|
assert_equal(1, o.GetOne())
|
|
|
|
assert_equal(3, o.GetTotal())
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
this.one = 1
|
|
|
|
endclass
|
|
|
|
class Child extends Base
|
|
|
|
this.two = 2
|
|
|
|
endclass
|
|
|
|
var o = Child.new(3, 44)
|
|
|
|
assert_equal(3, o.one)
|
|
|
|
assert_equal(44, o.two)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
this.one = 1
|
|
|
|
endclass
|
|
|
|
class Child extends Base extends Base
|
|
|
|
this.two = 2
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Child extends BaseClass
|
|
|
|
this.two = 2
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
var SomeVar = 99
|
|
|
|
class Child extends SomeVar
|
|
|
|
this.two = 2
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
|
2023-01-11 15:59:05 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
this.name: string
|
|
|
|
def ToString(): string
|
|
|
|
return this.name
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class Child extends Base
|
|
|
|
this.age: number
|
|
|
|
def ToString(): string
|
|
|
|
return super.ToString() .. ': ' .. this.age
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var o = Child.new('John', 42)
|
|
|
|
assert_equal('John: 42', o.ToString())
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-11 17:59:38 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Child
|
|
|
|
this.age: number
|
|
|
|
def ToString(): number
|
|
|
|
return this.age
|
|
|
|
enddef
|
|
|
|
def ToString(): string
|
|
|
|
return this.age
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Child
|
|
|
|
this.age: number
|
|
|
|
def ToString(): string
|
|
|
|
return super .ToString() .. ': ' .. this.age
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
var o = Child.new(42)
|
|
|
|
echo o.ToString()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1356:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
this.name: string
|
|
|
|
def ToString(): string
|
|
|
|
return this.name
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var age = 42
|
|
|
|
def ToString(): string
|
|
|
|
return super.ToString() .. ': ' .. age
|
|
|
|
enddef
|
|
|
|
echo ToString()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1357:')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Child
|
|
|
|
this.age: number
|
|
|
|
def ToString(): string
|
|
|
|
return super.ToString() .. ': ' .. this.age
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
var o = Child.new(42)
|
|
|
|
echo o.ToString()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1358:')
|
2023-01-11 21:14:17 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
this.name: string
|
|
|
|
static def ToString(): string
|
|
|
|
return 'Base class'
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class Child extends Base
|
|
|
|
this.age: number
|
|
|
|
def ToString(): string
|
|
|
|
return Base.ToString() .. ': ' .. this.age
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var o = Child.new('John', 42)
|
|
|
|
assert_equal('Base class: 42', o.ToString())
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-15 15:51:48 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
class Base
|
|
|
|
this.value = 1
|
|
|
|
def new(init: number)
|
|
|
|
this.value = number + 1
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
class Child extends Base
|
|
|
|
def new()
|
|
|
|
this.new(3)
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
var c = Child.new()
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
|
2023-01-15 20:49:00 +00:00
|
|
|
|
|
|
|
# base class with more than one object member
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Result
|
|
|
|
this.success: bool
|
|
|
|
this.value: any = null
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class Success extends Result
|
|
|
|
def new(this.value = v:none)
|
|
|
|
this.success = true
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
var v = Success.new('asdf')
|
|
|
|
assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
2023-01-08 19:54:10 +00:00
|
|
|
enddef
|
|
|
|
|
2023-02-10 15:52:25 +00:00
|
|
|
def Test_using_base_class()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class BaseEE
|
|
|
|
def Enter(): any
|
|
|
|
return null
|
|
|
|
enddef
|
|
|
|
def Exit(resource: any): void
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class ChildEE extends BaseEE
|
|
|
|
def Enter(): any
|
|
|
|
return 42
|
|
|
|
enddef
|
|
|
|
|
|
|
|
def Exit(resource: number): void
|
|
|
|
g:result ..= '/exit'
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def With(ee: BaseEE)
|
|
|
|
var r = ee.Enter()
|
|
|
|
try
|
|
|
|
g:result ..= r
|
|
|
|
finally
|
|
|
|
g:result ..= '/finally'
|
|
|
|
ee.Exit(r)
|
|
|
|
endtry
|
|
|
|
enddef
|
|
|
|
|
|
|
|
g:result = ''
|
|
|
|
With(ChildEE.new())
|
|
|
|
assert_equal('42/finally/exit', g:result)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
unlet g:result
|
|
|
|
enddef
|
|
|
|
|
|
|
|
|
2023-01-12 17:06:27 +00:00
|
|
|
def Test_class_import()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
export class Animal
|
|
|
|
this.kind: string
|
|
|
|
this.name: string
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
writefile(lines, 'Xanimal.vim', 'D')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
import './Xanimal.vim' as animal
|
|
|
|
|
|
|
|
var a: animal.Animal
|
|
|
|
a = animal.Animal.new('fish', 'Eric')
|
|
|
|
assert_equal('fish', a.kind)
|
|
|
|
assert_equal('Eric', a.name)
|
2023-01-12 20:04:51 +00:00
|
|
|
|
|
|
|
var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
|
|
|
|
assert_equal('cat', b.kind)
|
|
|
|
assert_equal('Garfield', b.name)
|
2023-01-12 17:06:27 +00:00
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-01-14 13:12:06 +00:00
|
|
|
def Test_abstract_class()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
abstract class Base
|
|
|
|
this.name: string
|
|
|
|
endclass
|
|
|
|
class Person extends Base
|
|
|
|
this.age: number
|
|
|
|
endclass
|
|
|
|
var p: Base = Person.new('Peter', 42)
|
|
|
|
assert_equal('Peter', p.name)
|
|
|
|
assert_equal(42, p.age)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
abstract class Base
|
|
|
|
this.name: string
|
|
|
|
endclass
|
|
|
|
class Person extends Base
|
|
|
|
this.age: number
|
|
|
|
endclass
|
|
|
|
var p = Base.new('Peter')
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
|
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
abstract class Base
|
|
|
|
this.name: string
|
|
|
|
endclass
|
|
|
|
END
|
|
|
|
v9.CheckScriptFailure(lines, 'E1316:')
|
|
|
|
enddef
|
|
|
|
|
2023-01-18 14:51:07 +00:00
|
|
|
def Test_closure_in_class()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class Foo
|
|
|
|
this.y: list<string> = ['B']
|
|
|
|
|
|
|
|
def new()
|
|
|
|
g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
Foo.new()
|
|
|
|
assert_equal(['A'], g:result)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
enddef
|
|
|
|
|
2023-01-27 20:14:02 +00:00
|
|
|
def Test_defer_with_object()
|
|
|
|
var lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class CWithEE
|
|
|
|
def Enter()
|
|
|
|
g:result ..= "entered/"
|
|
|
|
enddef
|
|
|
|
def Exit()
|
|
|
|
g:result ..= "exited"
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def With(ee: CWithEE, F: func)
|
|
|
|
ee.Enter()
|
|
|
|
defer ee.Exit()
|
|
|
|
F()
|
|
|
|
enddef
|
|
|
|
|
|
|
|
g:result = ''
|
|
|
|
var obj = CWithEE.new()
|
|
|
|
obj->With(() => {
|
|
|
|
g:result ..= "called/"
|
|
|
|
})
|
|
|
|
assert_equal('entered/called/exited', g:result)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
unlet g:result
|
2023-02-08 20:55:27 +00:00
|
|
|
|
|
|
|
lines =<< trim END
|
|
|
|
vim9script
|
|
|
|
|
|
|
|
class BaseWithEE
|
|
|
|
def Enter()
|
|
|
|
g:result ..= "entered-base/"
|
|
|
|
enddef
|
|
|
|
def Exit()
|
|
|
|
g:result ..= "exited-base"
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
class CWithEE extends BaseWithEE
|
|
|
|
def Enter()
|
|
|
|
g:result ..= "entered-child/"
|
|
|
|
enddef
|
|
|
|
def Exit()
|
|
|
|
g:result ..= "exited-child"
|
|
|
|
enddef
|
|
|
|
endclass
|
|
|
|
|
|
|
|
def With(ee: BaseWithEE, F: func)
|
|
|
|
ee.Enter()
|
|
|
|
defer ee.Exit()
|
|
|
|
F()
|
|
|
|
enddef
|
|
|
|
|
|
|
|
g:result = ''
|
|
|
|
var obj = CWithEE.new()
|
|
|
|
obj->With(() => {
|
|
|
|
g:result ..= "called/"
|
|
|
|
})
|
|
|
|
assert_equal('entered-child/called/exited-child', g:result)
|
|
|
|
END
|
|
|
|
v9.CheckScriptSuccess(lines)
|
|
|
|
unlet g:result
|
2023-01-27 20:14:02 +00:00
|
|
|
enddef
|
|
|
|
|
2022-12-08 15:32:33 +00:00
|
|
|
|
|
|
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|