blob: 52812eac73896b2c1639391afb0dd1102ca86593 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
7 var lines =<< trim END
8 class NotWorking
9 endclass
10 END
11 v9.CheckScriptFailure(lines, 'E1316:')
12
13 lines =<< trim END
14 vim9script
15 class notWorking
16 endclass
17 END
18 v9.CheckScriptFailure(lines, 'E1314:')
19
20 lines =<< trim END
21 vim9script
22 class Not@working
23 endclass
24 END
25 v9.CheckScriptFailure(lines, 'E1315:')
26
27 lines =<< trim END
28 vim9script
29 abstract noclass Something
30 endclass
31 END
32 v9.CheckScriptFailure(lines, 'E475:')
33
34 lines =<< trim END
35 vim9script
36 abstract classy Something
37 endclass
38 END
39 v9.CheckScriptFailure(lines, 'E475:')
40
41 lines =<< trim END
42 vim9script
43 class Something
44 endcl
45 END
46 v9.CheckScriptFailure(lines, 'E1065:')
47
48 lines =<< trim END
49 vim9script
50 class Something
Bram Moolenaar94722c52023-01-28 19:19:03 +000051 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000052 END
53 v9.CheckScriptFailure(lines, 'E488:')
54
55 lines =<< trim END
56 vim9script
57 class Something
58 endclass | echo 'done'
59 END
60 v9.CheckScriptFailure(lines, 'E488:')
61
62 lines =<< trim END
63 vim9script
64 class Something
65 this
66 endclass
67 END
68 v9.CheckScriptFailure(lines, 'E1317:')
69
70 lines =<< trim END
71 vim9script
72 class Something
73 this.
74 endclass
75 END
76 v9.CheckScriptFailure(lines, 'E1317:')
77
78 lines =<< trim END
79 vim9script
80 class Something
81 this .count
82 endclass
83 END
84 v9.CheckScriptFailure(lines, 'E1317:')
85
86 lines =<< trim END
87 vim9script
88 class Something
89 this. count
90 endclass
91 END
92 v9.CheckScriptFailure(lines, 'E1317:')
93
94 lines =<< trim END
95 vim9script
96 class Something
97 this.count: number
98 that.count
99 endclass
100 END
101 v9.CheckScriptFailure(lines, 'E1318: Not a valid command in a class: that.count')
102
103 lines =<< trim END
104 vim9script
105 class Something
106 this.count
107 endclass
108 END
109 v9.CheckScriptFailure(lines, 'E1022:')
110
111 lines =<< trim END
112 vim9script
113 class Something
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000114 def new()
115 this.state = 0
116 enddef
117 endclass
118 var obj = Something.new()
119 END
120 v9.CheckScriptFailure(lines, 'E1089:')
121
122 lines =<< trim END
123 vim9script
124 class Something
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000125 this.count : number
126 endclass
127 END
128 v9.CheckScriptFailure(lines, 'E1059:')
129
130 lines =<< trim END
131 vim9script
132 class Something
133 this.count:number
134 endclass
135 END
136 v9.CheckScriptFailure(lines, 'E1069:')
137
138 lines =<< trim END
139 vim9script
140
141 class TextPosition
142 this.lnum: number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000143 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000144
Bram Moolenaar418b5472022-12-20 13:38:22 +0000145 # make a nicely formatted string
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000146 def ToString(): string
147 return $'({this.lnum}, {this.col})'
148 enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000149 endclass
150
Bram Moolenaard28d7b92022-12-08 20:42:00 +0000151 # use the automatically generated new() method
152 var pos = TextPosition.new(2, 12)
153 assert_equal(2, pos.lnum)
154 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000155
156 # call an object method
157 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000158
159 assert_equal(v:t_class, type(TextPosition))
160 assert_equal(v:t_object, type(pos))
161 assert_equal('class<TextPosition>', typename(TextPosition))
162 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000163 END
164 v9.CheckScriptSuccess(lines)
165enddef
166
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000167def Test_class_defined_twice()
168 # class defined twice should fail
169 var lines =<< trim END
170 vim9script
171 class There
172 endclass
173 class There
174 endclass
175 END
176 v9.CheckScriptFailure(lines, 'E1041: Redefining script item: "There"')
177
178 # one class, reload same script twice is OK
179 lines =<< trim END
180 vim9script
181 class There
182 endclass
183 END
184 writefile(lines, 'XclassTwice.vim', 'D')
185 source XclassTwice.vim
186 source XclassTwice.vim
187enddef
188
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000189def Test_returning_null_object()
190 # this was causing an internal error
191 var lines =<< trim END
192 vim9script
193
194 class BufferList
195 def Current(): any
196 return null_object
197 enddef
198 endclass
199
200 var buffers = BufferList.new()
201 echo buffers.Current()
202 END
203 v9.CheckScriptSuccess(lines)
204enddef
205
Bram Moolenaard13dd302023-03-11 20:56:35 +0000206def Test_using_null_class()
207 var lines =<< trim END
208 @_ = null_class.member
209 END
210 v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:'])
211enddef
212
Bram Moolenaar657aea72023-01-27 13:16:19 +0000213def Test_class_interface_wrong_end()
214 var lines =<< trim END
215 vim9script
216 abstract class SomeName
217 this.member = 'text'
218 endinterface
219 END
220 v9.CheckScriptFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
221
222 lines =<< trim END
223 vim9script
224 export interface AnotherName
225 this.member: string
226 endclass
227 END
228 v9.CheckScriptFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
229enddef
230
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000231def Test_object_not_set()
232 var lines =<< trim END
233 vim9script
234
235 class State
236 this.value = 'xyz'
237 endclass
238
Bram Moolenaarf2017f22023-02-17 21:29:57 +0000239 var state: State
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000240 var db = {'xyz': 789}
241 echo db[state.value]
242 END
243 v9.CheckScriptFailure(lines, 'E1360:')
Bram Moolenaar0917e862023-02-18 14:42:44 +0000244
245 lines =<< trim END
246 vim9script
247
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000248 class Class
249 this.id: string
250 def Method1()
251 echo 'Method1' .. this.id
252 enddef
253 endclass
254
255 var obj: Class
256 def Func()
257 obj.Method1()
258 enddef
259 Func()
260 END
261 v9.CheckScriptFailure(lines, 'E1360:')
262
263 lines =<< trim END
264 vim9script
265
Bram Moolenaar0917e862023-02-18 14:42:44 +0000266 class Background
267 this.background = 'dark'
268 endclass
269
270 class Colorscheme
271 this._bg: Background
272
273 def GetBackground(): string
274 return this._bg.background
275 enddef
276 endclass
277
278 var bg: Background # UNINITIALIZED
279 echo Colorscheme.new(bg).GetBackground()
280 END
281 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Background> but got object<Unknown>')
Ernie Raelf77a7f72023-03-03 15:05:30 +0000282
283 # TODO: this should not give an error but be handled at runtime
284 lines =<< trim END
285 vim9script
286
287 class Class
288 this.id: string
289 def Method1()
290 echo 'Method1' .. this.id
291 enddef
292 endclass
293
294 var obj = null_object
295 def Func()
296 obj.Method1()
297 enddef
298 Func()
299 END
300 v9.CheckScriptFailure(lines, 'E1363:')
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000301enddef
302
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000303def Test_class_member_initializer()
304 var lines =<< trim END
305 vim9script
306
307 class TextPosition
308 this.lnum: number = 1
309 this.col: number = 1
310
Bram Moolenaar418b5472022-12-20 13:38:22 +0000311 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000312 def new(lnum: number)
313 this.lnum = lnum
314 enddef
315 endclass
316
317 var pos = TextPosition.new(3)
318 assert_equal(3, pos.lnum)
319 assert_equal(1, pos.col)
320
321 var instr = execute('disassemble TextPosition.new')
322 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000323 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000324 '\d PUSHNR 1\_s*' ..
325 '\d STORE_THIS 0\_s*' ..
326 '\d PUSHNR 1\_s*' ..
327 '\d STORE_THIS 1\_s*' ..
328 'this.lnum = lnum\_s*' ..
329 '\d LOAD arg\[-1]\_s*' ..
330 '\d PUSHNR 0\_s*' ..
331 '\d LOAD $0\_s*' ..
332 '\d\+ STOREINDEX object\_s*' ..
333 '\d\+ RETURN object.*',
334 instr)
335 END
336 v9.CheckScriptSuccess(lines)
337enddef
338
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000339def Test_member_any_used_as_object()
340 var lines =<< trim END
341 vim9script
342
343 class Inner
344 this.value: number = 0
345 endclass
346
347 class Outer
348 this.inner: any
349 endclass
350
351 def F(outer: Outer)
352 outer.inner.value = 1
353 enddef
354
355 var inner_obj = Inner.new(0)
356 var outer_obj = Outer.new(inner_obj)
357 F(outer_obj)
358 assert_equal(1, inner_obj.value)
359 END
360 v9.CheckScriptSuccess(lines)
361
362 lines =<< trim END
363 vim9script
364
365 class Inner
366 this.value: number = 0
367 endclass
368
369 class Outer
370 this.inner: Inner
371 endclass
372
373 def F(outer: Outer)
374 outer.inner.value = 1
375 enddef
376
377 def Test_assign_to_nested_typed_member()
378 var inner = Inner.new(0)
379 var outer = Outer.new(inner)
380 F(outer)
381 assert_equal(1, inner.value)
382 enddef
383
384 Test_assign_to_nested_typed_member()
385 END
386 v9.CheckScriptSuccess(lines)
387enddef
388
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000389def Test_assignment_with_operator()
390 var lines =<< trim END
391 vim9script
392
393 class Foo
394 this.x: number
395
396 def Add(n: number)
397 this.x += n
398 enddef
399 endclass
400
401 var f = Foo.new(3)
402 f.Add(17)
403 assert_equal(20, f.x)
Bram Moolenaar22363c62023-04-24 17:15:25 +0100404
405 def AddToFoo(obj: Foo)
406 obj.x += 3
407 enddef
408
409 AddToFoo(f)
410 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000411 END
412 v9.CheckScriptSuccess(lines)
413enddef
414
Bram Moolenaarf4508042023-01-15 16:54:57 +0000415def Test_list_of_objects()
416 var lines =<< trim END
417 vim9script
418
419 class Foo
420 def Add()
421 enddef
422 endclass
423
424 def ProcessList(fooList: list<Foo>)
425 for foo in fooList
426 foo.Add()
427 endfor
428 enddef
429
430 var l: list<Foo> = [Foo.new()]
431 ProcessList(l)
432 END
433 v9.CheckScriptSuccess(lines)
434enddef
435
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000436def Test_expr_after_using_object()
437 var lines =<< trim END
438 vim9script
439
440 class Something
441 this.label: string = ''
442 endclass
443
444 def Foo(): Something
445 var v = Something.new()
446 echo 'in Foo(): ' .. typename(v)
447 return v
448 enddef
449
450 Foo()
451 END
452 v9.CheckScriptSuccess(lines)
453enddef
454
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000455def Test_class_default_new()
456 var lines =<< trim END
457 vim9script
458
459 class TextPosition
460 this.lnum: number = 1
461 this.col: number = 1
462 endclass
463
464 var pos = TextPosition.new()
465 assert_equal(1, pos.lnum)
466 assert_equal(1, pos.col)
467
468 pos = TextPosition.new(v:none, v:none)
469 assert_equal(1, pos.lnum)
470 assert_equal(1, pos.col)
471
472 pos = TextPosition.new(3, 22)
473 assert_equal(3, pos.lnum)
474 assert_equal(22, pos.col)
475
476 pos = TextPosition.new(v:none, 33)
477 assert_equal(1, pos.lnum)
478 assert_equal(33, pos.col)
479 END
480 v9.CheckScriptSuccess(lines)
481
482 lines =<< trim END
483 vim9script
484 class Person
485 this.name: string
486 this.age: number = 42
487 this.education: string = "unknown"
488
489 def new(this.name, this.age = v:none, this.education = v:none)
490 enddef
491 endclass
492
493 var piet = Person.new("Piet")
494 assert_equal("Piet", piet.name)
495 assert_equal(42, piet.age)
496 assert_equal("unknown", piet.education)
497
498 var chris = Person.new("Chris", 4, "none")
499 assert_equal("Chris", chris.name)
500 assert_equal(4, chris.age)
501 assert_equal("none", chris.education)
502 END
503 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000504
505 lines =<< trim END
506 vim9script
507 class Person
508 this.name: string
509 this.age: number = 42
510 this.education: string = "unknown"
511
512 def new(this.name, this.age = v:none, this.education = v:none)
513 enddef
514 endclass
515
516 var missing = Person.new()
517 END
518 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000519enddef
520
Bram Moolenaar74e12742022-12-13 21:14:28 +0000521def Test_class_object_member_inits()
522 var lines =<< trim END
523 vim9script
524 class TextPosition
525 this.lnum: number
526 this.col = 1
527 this.addcol: number = 2
528 endclass
529
530 var pos = TextPosition.new()
531 assert_equal(0, pos.lnum)
532 assert_equal(1, pos.col)
533 assert_equal(2, pos.addcol)
534 END
535 v9.CheckScriptSuccess(lines)
536
537 lines =<< trim END
538 vim9script
539 class TextPosition
540 this.lnum
541 this.col = 1
542 endclass
543 END
544 v9.CheckScriptFailure(lines, 'E1022:')
545
546 lines =<< trim END
547 vim9script
548 class TextPosition
549 this.lnum = v:none
550 this.col = 1
551 endclass
552 END
553 v9.CheckScriptFailure(lines, 'E1330:')
554enddef
555
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000556def Test_class_object_member_access()
557 var lines =<< trim END
558 vim9script
559 class Triple
560 this._one = 1
561 this.two = 2
562 public this.three = 3
563
564 def GetOne(): number
565 return this._one
566 enddef
567 endclass
568
569 var trip = Triple.new()
570 assert_equal(1, trip.GetOne())
571 assert_equal(2, trip.two)
572 assert_equal(3, trip.three)
573 assert_fails('echo trip._one', 'E1333')
574
575 assert_fails('trip._one = 11', 'E1333')
576 assert_fails('trip.two = 22', 'E1335')
577 trip.three = 33
578 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000579
580 assert_fails('trip.four = 4', 'E1334')
581 END
582 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000583
584 lines =<< trim END
585 vim9script
586
587 class MyCar
588 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000589 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000590
591 def new(make_arg: string)
592 this.make = make_arg
593 enddef
594
595 def GetMake(): string
596 return $"make = {this.make}"
597 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000598 def GetAge(): number
599 return this.age
600 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000601 endclass
602
603 var c = MyCar.new("abc")
604 assert_equal('make = abc', c.GetMake())
605
606 c = MyCar.new("def")
607 assert_equal('make = def', c.GetMake())
608
609 var c2 = MyCar.new("123")
610 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +0000611
612 def CheckCar()
613 assert_equal("make = def", c.GetMake())
614 assert_equal(5, c.GetAge())
615 enddef
616 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +0000617 END
618 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000619
620 lines =<< trim END
621 vim9script
622
623 class MyCar
624 this.make: string
625
626 def new(make_arg: string)
627 this.make = make_arg
628 enddef
629 endclass
630
631 var c = MyCar.new("abc")
632 var c = MyCar.new("def")
633 END
634 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +0000635
636 lines =<< trim END
637 vim9script
638
639 class Foo
640 this.x: list<number> = []
641
642 def Add(n: number): any
643 this.x->add(n)
644 return this
645 enddef
646 endclass
647
648 echo Foo.new().Add(1).Add(2).x
649 echo Foo.new().Add(1).Add(2)
650 .x
651 echo Foo.new().Add(1)
652 .Add(2).x
653 echo Foo.new()
654 .Add(1).Add(2).x
655 echo Foo.new()
656 .Add(1)
657 .Add(2)
658 .x
659 END
660 v9.CheckScriptSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +0000661enddef
662
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000663def Test_class_object_compare()
664 var class_lines =<< trim END
665 vim9script
666 class Item
667 this.nr = 0
668 this.name = 'xx'
669 endclass
670 END
671
672 # used at the script level and in a compiled function
673 var test_lines =<< trim END
674 var i1 = Item.new()
675 assert_equal(i1, i1)
676 assert_true(i1 is i1)
677 var i2 = Item.new()
678 assert_equal(i1, i2)
679 assert_false(i1 is i2)
680 var i3 = Item.new(0, 'xx')
681 assert_equal(i1, i3)
682
683 var io1 = Item.new(1, 'xx')
684 assert_notequal(i1, io1)
685 var io2 = Item.new(0, 'yy')
686 assert_notequal(i1, io2)
687 END
688
689 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000690 v9.CheckScriptSuccess(
691 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000692
693 for op in ['>', '>=', '<', '<=', '=~', '!~']
694 var op_lines = [
695 'var i1 = Item.new()',
696 'var i2 = Item.new()',
697 'echo i1 ' .. op .. ' i2',
698 ]
699 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000700 v9.CheckScriptFailure(class_lines
701 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000702 endfor
703enddef
704
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000705def Test_object_type()
706 var lines =<< trim END
707 vim9script
708
709 class One
710 this.one = 1
711 endclass
712 class Two
713 this.two = 2
714 endclass
715 class TwoMore extends Two
716 this.more = 9
717 endclass
718
719 var o: One = One.new()
720 var t: Two = Two.new()
721 var m: TwoMore = TwoMore.new()
722 var tm: Two = TwoMore.new()
723
724 t = m
725 END
726 v9.CheckScriptSuccess(lines)
727
728 lines =<< trim END
729 vim9script
730
731 class One
732 this.one = 1
733 endclass
734 class Two
735 this.two = 2
736 endclass
737
738 var o: One = Two.new()
739 END
740 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000741
742 lines =<< trim END
743 vim9script
744
745 interface One
746 def GetMember(): number
747 endinterface
748 class Two implements One
749 this.one = 1
750 def GetMember(): number
751 return this.one
752 enddef
753 endclass
754
755 var o: One = Two.new(5)
756 assert_equal(5, o.GetMember())
757 END
758 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +0000759
760 lines =<< trim END
761 vim9script
762
763 class Num
764 this.n: number = 0
765 endclass
766
767 def Ref(name: string): func(Num): Num
768 return (arg: Num): Num => {
769 return eval(name)(arg)
770 }
771 enddef
772
773 const Fn = Ref('Double')
774 var Double = (m: Num): Num => Num.new(m.n * 2)
775
776 echo Fn(Num.new(4))
777 END
778 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000779enddef
780
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000781def Test_class_member()
782 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000783 var lines =<< trim END
784 vim9script
785 class TextPos
786 this.lnum = 1
787 this.col = 1
788 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000789 static _secret = 7
790 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000791
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000792 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000793 counter += nr
794 enddef
795 endclass
796
797 assert_equal(0, TextPos.counter)
798 TextPos.AddToCounter(3)
799 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000800 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000801
Bram Moolenaar3259ff32023-01-04 18:54:09 +0000802 def GetCounter(): number
803 return TextPos.counter
804 enddef
805 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +0000806
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000807 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000808 assert_fails('TextPos.counter = 5', 'E1335:')
809 assert_fails('TextPos.counter += 5', 'E1335:')
810
811 assert_fails('echo TextPos._secret', 'E1333:')
812 assert_fails('TextPos._secret = 8', 'E1333:')
813
814 assert_equal(42, TextPos.anybody)
815 TextPos.anybody = 12
816 assert_equal(12, TextPos.anybody)
817 TextPos.anybody += 5
818 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000819 END
820 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000821
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000822 # example in the help
823 lines =<< trim END
824 vim9script
825 class OtherThing
826 this.size: number
827 static totalSize: number
828
829 def new(this.size)
830 totalSize += this.size
831 enddef
832 endclass
833 assert_equal(0, OtherThing.totalSize)
834 var to3 = OtherThing.new(3)
835 assert_equal(3, OtherThing.totalSize)
836 var to7 = OtherThing.new(7)
837 assert_equal(10, OtherThing.totalSize)
838 END
839 v9.CheckScriptSuccess(lines)
840
Bram Moolenaar62a69232023-01-24 15:07:04 +0000841 # access private member in lambda
842 lines =<< trim END
843 vim9script
844
845 class Foo
846 this._x: number = 0
847
848 def Add(n: number): number
849 const F = (): number => this._x + n
850 return F()
851 enddef
852 endclass
853
854 var foo = Foo.new()
855 assert_equal(5, foo.Add(5))
856 END
857 v9.CheckScriptSuccess(lines)
858
h-east2bd6a092023-05-19 19:01:17 +0100859 # access private member in lambda body
860 lines =<< trim END
861 vim9script
862
863 class Foo
864 this._x: number = 6
865
866 def Add(n: number): number
867 var Lam = () => {
868 this._x = this._x + n
869 }
870 Lam()
871 return this._x
872 enddef
873 endclass
874
875 var foo = Foo.new()
876 assert_equal(13, foo.Add(7))
877 END
878 v9.CheckScriptSuccess(lines)
879
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000880 # check shadowing
881 lines =<< trim END
882 vim9script
883
884 class Some
885 static count = 0
886 def Method(count: number)
887 echo count
888 enddef
889 endclass
890
891 var s = Some.new()
892 s.Method(7)
893 END
894 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
895
896 lines =<< trim END
897 vim9script
898
899 class Some
900 static count = 0
901 def Method(arg: number)
902 var count = 3
903 echo arg count
904 enddef
905 endclass
906
907 var s = Some.new()
908 s.Method(7)
909 END
910 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000911enddef
912
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000913func Test_class_garbagecollect()
914 let lines =<< trim END
915 vim9script
916
917 class Point
918 this.p = [2, 3]
919 static pl = ['a', 'b']
920 static pd = {a: 'a', b: 'b'}
921 endclass
922
923 echo Point.pl Point.pd
924 call test_garbagecollect_now()
925 echo Point.pl Point.pd
926 END
927 call v9.CheckScriptSuccess(lines)
928endfunc
929
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000930def Test_class_function()
931 var lines =<< trim END
932 vim9script
933 class Value
934 this.value = 0
935 static objects = 0
936
937 def new(v: number)
938 this.value = v
939 ++objects
940 enddef
941
942 static def GetCount(): number
943 return objects
944 enddef
945 endclass
946
947 assert_equal(0, Value.GetCount())
948 var v1 = Value.new(2)
949 assert_equal(1, Value.GetCount())
950 var v2 = Value.new(7)
951 assert_equal(2, Value.GetCount())
952 END
953 v9.CheckScriptSuccess(lines)
954enddef
955
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +0000956def Test_class_defcompile()
957 var lines =<< trim END
958 vim9script
959
960 class C
961 def Fo(i: number): string
962 return i
963 enddef
964 endclass
965
966 defcompile C.Fo
967 END
968 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
969
970 lines =<< trim END
971 vim9script
972
973 class C
974 static def Fc(): number
975 return 'x'
976 enddef
977 endclass
978
979 defcompile C.Fc
980 END
981 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
982enddef
983
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +0000984def Test_class_object_to_string()
985 var lines =<< trim END
986 vim9script
987 class TextPosition
988 this.lnum = 1
989 this.col = 22
990 endclass
991
992 assert_equal("class TextPosition", string(TextPosition))
993
994 var pos = TextPosition.new()
995 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
996 END
997 v9.CheckScriptSuccess(lines)
998enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +0000999
Bram Moolenaar554d0312023-01-05 19:59:18 +00001000def Test_interface_basics()
1001 var lines =<< trim END
1002 vim9script
1003 interface Something
1004 this.value: string
1005 static count: number
1006 def GetCount(): number
1007 endinterface
1008 END
1009 v9.CheckScriptSuccess(lines)
1010
1011 lines =<< trim END
1012 interface SomethingWrong
1013 static count = 7
1014 endinterface
1015 END
1016 v9.CheckScriptFailure(lines, 'E1342:')
1017
1018 lines =<< trim END
1019 vim9script
1020
1021 interface Some
1022 static count: number
1023 def Method(count: number)
1024 endinterface
1025 END
h-east61378a12023-04-18 19:07:29 +01001026 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaard40f00c2023-01-13 17:36:49 +00001027
1028 lines =<< trim END
1029 vim9script
1030
1031 interface Some
1032 this.value: number
1033 def Method(value: number)
1034 endinterface
1035 END
h-east61378a12023-04-18 19:07:29 +01001036 # The argument name and the object member name are the same, but this is not a
1037 # problem because object members are always accessed with the "this." prefix.
1038 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001039
1040 lines =<< trim END
1041 vim9script
1042 interface somethingWrong
1043 static count = 7
1044 endinterface
1045 END
1046 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
1047
1048 lines =<< trim END
1049 vim9script
1050 interface SomethingWrong
1051 this.value: string
1052 static count = 7
1053 def GetCount(): number
1054 endinterface
1055 END
1056 v9.CheckScriptFailure(lines, 'E1344:')
1057
1058 lines =<< trim END
1059 vim9script
1060 interface SomethingWrong
1061 this.value: string
1062 static count: number
1063 def GetCount(): number
1064 return 5
1065 enddef
1066 endinterface
1067 END
1068 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001069
1070 lines =<< trim END
1071 vim9script
1072 export interface EnterExit
1073 def Enter(): void
1074 def Exit(): void
1075 endinterface
1076 END
1077 writefile(lines, 'XdefIntf.vim', 'D')
1078
1079 lines =<< trim END
1080 vim9script
1081 import './XdefIntf.vim' as defIntf
1082 export def With(ee: defIntf.EnterExit, F: func)
1083 ee.Enter()
1084 try
1085 F()
1086 finally
1087 ee.Exit()
1088 endtry
1089 enddef
1090 END
1091 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001092
1093 var imported =<< trim END
1094 vim9script
1095 export abstract class EnterExit
1096 def Enter(): void
1097 enddef
1098 def Exit(): void
1099 enddef
1100 endclass
1101 END
1102 writefile(imported, 'XdefIntf2.vim', 'D')
1103
1104 lines[1] = " import './XdefIntf2.vim' as defIntf"
1105 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001106enddef
1107
Bram Moolenaar94674f22023-01-06 18:42:20 +00001108def Test_class_implements_interface()
1109 var lines =<< trim END
1110 vim9script
1111
1112 interface Some
1113 static count: number
1114 def Method(nr: number)
1115 endinterface
1116
1117 class SomeImpl implements Some
1118 static count: number
1119 def Method(nr: number)
1120 echo nr
1121 enddef
1122 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001123
1124 interface Another
1125 this.member: string
1126 endinterface
1127
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001128 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001129 this.member = 'abc'
1130 static count: number
1131 def Method(nr: number)
1132 echo nr
1133 enddef
1134 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001135 END
1136 v9.CheckScriptSuccess(lines)
1137
1138 lines =<< trim END
1139 vim9script
1140
1141 interface Some
1142 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001143 endinterface
1144
1145 class SomeImpl implements Some implements Some
1146 static count: number
1147 endclass
1148 END
1149 v9.CheckScriptFailure(lines, 'E1350:')
1150
1151 lines =<< trim END
1152 vim9script
1153
1154 interface Some
1155 static counter: number
1156 endinterface
1157
1158 class SomeImpl implements Some, Some
1159 static count: number
1160 endclass
1161 END
1162 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
1163
1164 lines =<< trim END
1165 vim9script
1166
1167 interface Some
1168 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001169 def Method(nr: number)
1170 endinterface
1171
1172 class SomeImpl implements Some
1173 static count: number
1174 def Method(nr: number)
1175 echo nr
1176 enddef
1177 endclass
1178 END
1179 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
1180
1181 lines =<< trim END
1182 vim9script
1183
1184 interface Some
1185 static count: number
1186 def Methods(nr: number)
1187 endinterface
1188
1189 class SomeImpl implements Some
1190 static count: number
1191 def Method(nr: number)
1192 echo nr
1193 enddef
1194 endclass
1195 END
1196 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001197
1198 # Check different order of members in class and interface works.
1199 lines =<< trim END
1200 vim9script
1201
1202 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001203 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001204 this.errpos: number
1205 endinterface
1206
1207 # order of members is opposite of interface
1208 class Failure implements Result
1209 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001210 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001211 endclass
1212
1213 def Test()
1214 var result: Result = Failure.new()
1215
1216 assert_equal('label', result.label)
1217 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001218
1219 result.label = 'different'
1220 assert_equal('different', result.label)
1221 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001222 enddef
1223
1224 Test()
1225 END
1226 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00001227enddef
1228
Bram Moolenaard0200c82023-01-28 15:19:40 +00001229def Test_call_interface_method()
1230 var lines =<< trim END
1231 vim9script
1232 interface Base
1233 def Enter(): void
1234 endinterface
1235
1236 class Child implements Base
1237 def Enter(): void
1238 g:result ..= 'child'
1239 enddef
1240 endclass
1241
1242 def F(obj: Base)
1243 obj.Enter()
1244 enddef
1245
1246 g:result = ''
1247 F(Child.new())
1248 assert_equal('child', g:result)
1249 unlet g:result
1250 END
1251 v9.CheckScriptSuccess(lines)
1252
1253 lines =<< trim END
1254 vim9script
1255 class Base
1256 def Enter(): void
1257 g:result ..= 'base'
1258 enddef
1259 endclass
1260
1261 class Child extends Base
1262 def Enter(): void
1263 g:result ..= 'child'
1264 enddef
1265 endclass
1266
1267 def F(obj: Base)
1268 obj.Enter()
1269 enddef
1270
1271 g:result = ''
1272 F(Child.new())
1273 assert_equal('child', g:result)
1274 unlet g:result
1275 END
1276 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001277
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00001278 # method of interface returns a value
1279 lines =<< trim END
1280 vim9script
1281 interface Base
1282 def Enter(): string
1283 endinterface
1284
1285 class Child implements Base
1286 def Enter(): string
1287 g:result ..= 'child'
1288 return "/resource"
1289 enddef
1290 endclass
1291
1292 def F(obj: Base)
1293 var r = obj.Enter()
1294 g:result ..= r
1295 enddef
1296
1297 g:result = ''
1298 F(Child.new())
1299 assert_equal('child/resource', g:result)
1300 unlet g:result
1301 END
1302 v9.CheckScriptSuccess(lines)
1303
1304 lines =<< trim END
1305 vim9script
1306 class Base
1307 def Enter(): string
1308 return null_string
1309 enddef
1310 endclass
1311
1312 class Child extends Base
1313 def Enter(): string
1314 g:result ..= 'child'
1315 return "/resource"
1316 enddef
1317 endclass
1318
1319 def F(obj: Base)
1320 var r = obj.Enter()
1321 g:result ..= r
1322 enddef
1323
1324 g:result = ''
1325 F(Child.new())
1326 assert_equal('child/resource', g:result)
1327 unlet g:result
1328 END
1329 v9.CheckScriptSuccess(lines)
1330
1331
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001332 # No class that implements the interface.
1333 lines =<< trim END
1334 vim9script
1335
1336 interface IWithEE
1337 def Enter(): any
1338 def Exit(): void
1339 endinterface
1340
1341 def With1(ee: IWithEE, F: func)
1342 var r = ee.Enter()
1343 enddef
1344
1345 defcompile
1346 END
1347 v9.CheckScriptSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00001348enddef
1349
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001350def Test_class_used_as_type()
1351 var lines =<< trim END
1352 vim9script
1353
1354 class Point
1355 this.x = 0
1356 this.y = 0
1357 endclass
1358
1359 var p: Point
1360 p = Point.new(2, 33)
1361 assert_equal(2, p.x)
1362 assert_equal(33, p.y)
1363 END
1364 v9.CheckScriptSuccess(lines)
1365
1366 lines =<< trim END
1367 vim9script
1368
1369 interface HasX
1370 this.x: number
1371 endinterface
1372
1373 class Point implements HasX
1374 this.x = 0
1375 this.y = 0
1376 endclass
1377
1378 var p: Point
1379 p = Point.new(2, 33)
1380 var hx = p
1381 assert_equal(2, hx.x)
1382 END
1383 v9.CheckScriptSuccess(lines)
1384
1385 lines =<< trim END
1386 vim9script
1387
1388 class Point
1389 this.x = 0
1390 this.y = 0
1391 endclass
1392
1393 var p: Point
1394 p = 'text'
1395 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001396 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001397enddef
1398
Bram Moolenaar83677162023-01-08 19:54:10 +00001399def Test_class_extends()
1400 var lines =<< trim END
1401 vim9script
1402 class Base
1403 this.one = 1
1404 def GetOne(): number
1405 return this.one
1406 enddef
1407 endclass
1408 class Child extends Base
1409 this.two = 2
1410 def GetTotal(): number
1411 return this.one + this.two
1412 enddef
1413 endclass
1414 var o = Child.new()
1415 assert_equal(1, o.one)
1416 assert_equal(2, o.two)
1417 assert_equal(1, o.GetOne())
1418 assert_equal(3, o.GetTotal())
1419 END
1420 v9.CheckScriptSuccess(lines)
1421
1422 lines =<< trim END
1423 vim9script
1424 class Base
1425 this.one = 1
1426 endclass
1427 class Child extends Base
1428 this.two = 2
1429 endclass
1430 var o = Child.new(3, 44)
1431 assert_equal(3, o.one)
1432 assert_equal(44, o.two)
1433 END
1434 v9.CheckScriptSuccess(lines)
1435
1436 lines =<< trim END
1437 vim9script
1438 class Base
1439 this.one = 1
1440 endclass
1441 class Child extends Base extends Base
1442 this.two = 2
1443 endclass
1444 END
1445 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1446
1447 lines =<< trim END
1448 vim9script
1449 class Child extends BaseClass
1450 this.two = 2
1451 endclass
1452 END
1453 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1454
1455 lines =<< trim END
1456 vim9script
1457 var SomeVar = 99
1458 class Child extends SomeVar
1459 this.two = 2
1460 endclass
1461 END
1462 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001463
1464 lines =<< trim END
1465 vim9script
1466 class Base
1467 this.name: string
1468 def ToString(): string
1469 return this.name
1470 enddef
1471 endclass
1472
1473 class Child extends Base
1474 this.age: number
1475 def ToString(): string
1476 return super.ToString() .. ': ' .. this.age
1477 enddef
1478 endclass
1479
1480 var o = Child.new('John', 42)
1481 assert_equal('John: 42', o.ToString())
1482 END
1483 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001484
1485 lines =<< trim END
1486 vim9script
1487 class Child
1488 this.age: number
1489 def ToString(): number
1490 return this.age
1491 enddef
1492 def ToString(): string
1493 return this.age
1494 enddef
1495 endclass
1496 END
1497 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1498
1499 lines =<< trim END
1500 vim9script
1501 class Child
1502 this.age: number
1503 def ToString(): string
1504 return super .ToString() .. ': ' .. this.age
1505 enddef
1506 endclass
1507 var o = Child.new(42)
1508 echo o.ToString()
1509 END
1510 v9.CheckScriptFailure(lines, 'E1356:')
1511
1512 lines =<< trim END
1513 vim9script
1514 class Base
1515 this.name: string
1516 def ToString(): string
1517 return this.name
1518 enddef
1519 endclass
1520
1521 var age = 42
1522 def ToString(): string
1523 return super.ToString() .. ': ' .. age
1524 enddef
1525 echo ToString()
1526 END
1527 v9.CheckScriptFailure(lines, 'E1357:')
1528
1529 lines =<< trim END
1530 vim9script
1531 class Child
1532 this.age: number
1533 def ToString(): string
1534 return super.ToString() .. ': ' .. this.age
1535 enddef
1536 endclass
1537 var o = Child.new(42)
1538 echo o.ToString()
1539 END
1540 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001541
1542 lines =<< trim END
1543 vim9script
1544 class Base
1545 this.name: string
1546 static def ToString(): string
1547 return 'Base class'
1548 enddef
1549 endclass
1550
1551 class Child extends Base
1552 this.age: number
1553 def ToString(): string
1554 return Base.ToString() .. ': ' .. this.age
1555 enddef
1556 endclass
1557
1558 var o = Child.new('John', 42)
1559 assert_equal('Base class: 42', o.ToString())
1560 END
1561 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001562
1563 lines =<< trim END
1564 vim9script
1565 class Base
1566 this.value = 1
1567 def new(init: number)
1568 this.value = number + 1
1569 enddef
1570 endclass
1571 class Child extends Base
1572 def new()
1573 this.new(3)
1574 enddef
1575 endclass
1576 var c = Child.new()
1577 END
1578 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001579
1580 # base class with more than one object member
1581 lines =<< trim END
1582 vim9script
1583
1584 class Result
1585 this.success: bool
1586 this.value: any = null
1587 endclass
1588
1589 class Success extends Result
1590 def new(this.value = v:none)
1591 this.success = true
1592 enddef
1593 endclass
1594
1595 var v = Success.new('asdf')
1596 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1597 END
1598 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001599enddef
1600
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00001601def Test_using_base_class()
1602 var lines =<< trim END
1603 vim9script
1604
1605 class BaseEE
1606 def Enter(): any
1607 return null
1608 enddef
1609 def Exit(resource: any): void
1610 enddef
1611 endclass
1612
1613 class ChildEE extends BaseEE
1614 def Enter(): any
1615 return 42
1616 enddef
1617
1618 def Exit(resource: number): void
1619 g:result ..= '/exit'
1620 enddef
1621 endclass
1622
1623 def With(ee: BaseEE)
1624 var r = ee.Enter()
1625 try
1626 g:result ..= r
1627 finally
1628 g:result ..= '/finally'
1629 ee.Exit(r)
1630 endtry
1631 enddef
1632
1633 g:result = ''
1634 With(ChildEE.new())
1635 assert_equal('42/finally/exit', g:result)
1636 END
1637 v9.CheckScriptSuccess(lines)
1638 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01001639
1640 # Using super, Child invokes Base method which has optional arg. #12471
1641 lines =<< trim END
1642 vim9script
1643
1644 class Base
1645 this.success: bool = false
1646 def Method(arg = 0)
1647 this.success = true
1648 enddef
1649 endclass
1650
1651 class Child extends Base
1652 def new()
1653 super.Method()
1654 enddef
1655 endclass
1656
1657 var obj = Child.new()
1658 assert_equal(true, obj.success)
1659 END
1660 v9.CheckScriptSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00001661enddef
1662
1663
Bram Moolenaara86655a2023-01-12 17:06:27 +00001664def Test_class_import()
1665 var lines =<< trim END
1666 vim9script
1667 export class Animal
1668 this.kind: string
1669 this.name: string
1670 endclass
1671 END
1672 writefile(lines, 'Xanimal.vim', 'D')
1673
1674 lines =<< trim END
1675 vim9script
1676 import './Xanimal.vim' as animal
1677
1678 var a: animal.Animal
1679 a = animal.Animal.new('fish', 'Eric')
1680 assert_equal('fish', a.kind)
1681 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001682
1683 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1684 assert_equal('cat', b.kind)
1685 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001686 END
1687 v9.CheckScriptSuccess(lines)
1688enddef
1689
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001690def Test_abstract_class()
1691 var lines =<< trim END
1692 vim9script
1693 abstract class Base
1694 this.name: string
1695 endclass
1696 class Person extends Base
1697 this.age: number
1698 endclass
1699 var p: Base = Person.new('Peter', 42)
1700 assert_equal('Peter', p.name)
1701 assert_equal(42, p.age)
1702 END
1703 v9.CheckScriptSuccess(lines)
1704
1705 lines =<< trim END
1706 vim9script
1707 abstract class Base
1708 this.name: string
1709 endclass
1710 class Person extends Base
1711 this.age: number
1712 endclass
1713 var p = Base.new('Peter')
1714 END
1715 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1716
1717 lines =<< trim END
1718 abstract class Base
1719 this.name: string
1720 endclass
1721 END
1722 v9.CheckScriptFailure(lines, 'E1316:')
1723enddef
1724
Bram Moolenaar486fc252023-01-18 14:51:07 +00001725def Test_closure_in_class()
1726 var lines =<< trim END
1727 vim9script
1728
1729 class Foo
1730 this.y: list<string> = ['B']
1731
1732 def new()
1733 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
1734 enddef
1735 endclass
1736
1737 Foo.new()
1738 assert_equal(['A'], g:result)
1739 END
1740 v9.CheckScriptSuccess(lines)
1741enddef
1742
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001743def Test_defer_with_object()
1744 var lines =<< trim END
1745 vim9script
1746
1747 class CWithEE
1748 def Enter()
1749 g:result ..= "entered/"
1750 enddef
1751 def Exit()
1752 g:result ..= "exited"
1753 enddef
1754 endclass
1755
1756 def With(ee: CWithEE, F: func)
1757 ee.Enter()
1758 defer ee.Exit()
1759 F()
1760 enddef
1761
1762 g:result = ''
1763 var obj = CWithEE.new()
1764 obj->With(() => {
1765 g:result ..= "called/"
1766 })
1767 assert_equal('entered/called/exited', g:result)
1768 END
1769 v9.CheckScriptSuccess(lines)
1770 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00001771
1772 lines =<< trim END
1773 vim9script
1774
1775 class BaseWithEE
1776 def Enter()
1777 g:result ..= "entered-base/"
1778 enddef
1779 def Exit()
1780 g:result ..= "exited-base"
1781 enddef
1782 endclass
1783
1784 class CWithEE extends BaseWithEE
1785 def Enter()
1786 g:result ..= "entered-child/"
1787 enddef
1788 def Exit()
1789 g:result ..= "exited-child"
1790 enddef
1791 endclass
1792
1793 def With(ee: BaseWithEE, F: func)
1794 ee.Enter()
1795 defer ee.Exit()
1796 F()
1797 enddef
1798
1799 g:result = ''
1800 var obj = CWithEE.new()
1801 obj->With(() => {
1802 g:result ..= "called/"
1803 })
1804 assert_equal('entered-child/called/exited-child', g:result)
1805 END
1806 v9.CheckScriptSuccess(lines)
1807 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001808enddef
1809
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001810
1811" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker